2016-01-06 2 views
3

У меня есть три пролета с краем внизу и нужно, чтобы оно затухало и исчезало сверху вниз и в обратном направлении. Он работает нормально, если у меня есть 2 итерации, но с бесконечной неработоспособностью.Бесконечные линии затухания с обратным направлением

.line { 
 
    border-bottom: 0.2em solid #333; 
 
    display: block; 
 
    margin: 0 auto; 
 
    margin-top: 0.3em; 
 
    width: 1.5em; 
 
} 
 
.lines span[class='line']:nth-child(1) { 
 
    animation: 1.5s ease-in-out 0.2s 2 alternate fade_line; 
 
} 
 
.lines span[class='line']:nth-child(2) { 
 
    animation: 1s ease-in-out 0.7s 2 alternate fade_line; 
 
} 
 
.line { 
 
    animation: 0.5s ease-in-out 1.2s 2 alternate fade_line; 
 
} 
 
@keyframes fade_line { 
 
    0%, 50% { 
 
    border-bottom: 0.2em solid #333; 
 
    } 
 
    50%, 
 
    100% { 
 
    border-bottom: 0.2em solid #ddd; 
 
    } 
 
}
<div class="lines"> 
 
    <span class="line"></span> 
 
    <span class="line"></span> 
 
    <span class="line"></span> 
 
</div>

Fiddle Demo

+1

Я немного потерял о том, как это исправить, но причина проблемы заключается в том, как из-за 'анимационная-delay' работ. Задержка добавляется только в первый раз. Таким образом, анимации перекрываются. Вы можете найти [эту тему] (http://stackoverflow.com/questions/32223835/repeat-animation-every-3-seconds/32223950#32223950), немного полезную при поиске решения. – Harry

+0

Я не смог найти способ исправить эту анимацию, но [** здесь **] (https://jsfiddle.net/70w8mLq4/3/) - это часть кода, которая создает нечто подобное. Не уверен, что это вам поможет. – Harry

ответ

3

Проблема с анимацией является то, что на самом деле animation-delay относится только к первой итерации анимации. Ниже приведено объяснение, почему оно работает, когда есть только 2 итерации и почему это не происходит, когда есть бесконечные итерации.

Почему это работает, когда есть только 2 итерации?

  • Первый span начинает свою анимацию на 0.2s (после animation-delay). Между 0.2s к 1.7s, цвет рамки идет от #333 к #ddd (при 0.95s которая 50% из 1.5s длительности, чтобы быть точным), а также между 1.7s и 3.2s он идет назад (в обратном направлении) от #ddd к #333 (при 2.45s, чтобы быть точным).
  • Второй span начинает свою анимацию по адресу 0.7s. Между 0.7s к 1.7s, цвет рамки идет от #333 к #ddd (при 1.2s, чтобы быть точным), а также между 1.7s к 2.7s он идет назад (обратный) от #ddd к #333 (при 2.2s, чтобы быть точным).
  • Третий span начинает свою анимацию 1.2s. Между 1.2s к 1.7s, цвет рамки идет от #333 к #ddd (при 1.45s, чтобы быть точным), а также между 1.7s к 2.2s он идет назад (обратный) от #ddd к #333 (при 1.95s, чтобы быть точным).
Element   | Iteration 1  | Iteration 2 
--------------------------------------------------- 
First Span  | 0.95s    | 2.45s 
Second Span  | 1.2s    | 2.2s 
Third Span  | 1.45s    | 1.95s 

Как вы можете видеть, есть хороший поток к нему, насколько есть только две итерации.


Почему это не работает, когда количество итераций установлено до бесконечности?

Теперь давайте посмотрим, что происходит с третьей и последующих итераций:

  • Первый span - Между 3.2s до 4.7s, граница цвет идет от #333 к #ddd3.95s, чтобы быть точным), а также между 4.7s и 6.2s он возвращается (назад) от #ddd до #333 (при 5.45s, если быть точным).
  • Второй span - Между 2.7s до 3.7s граница цвет идет от #333 к #ddd (при 3.2s, чтобы быть точным), а также между 3.7s к 4.7s он идет назад (обратный) от #ddd к #333 (при 4.2s, чтобы быть точным).
  • Третий span - Между 2.2s до 2.7s границы цвет идет от #333 к #ddd2.45s, чтобы быть точным), а также между 2.7s к 3.2s он идет назад (реверс) от #ddd до #3332.95s быть точным).
Element   | Iteration 1  | Iteration 2  | Iteration 3  | Iteration 4 
------------------------------------------------------------------------------------------ 
First Span  | 0.95s    | 2.45s    | 3.95s    | 5.45s 
Second Span  | 1.2s    | 2.2s    | 3.2s    | 4.2s 
Third Span  | 1.45s    | 1.95s    | 2.45s    | 2.95s 

Как вы можете видеть поток полностью перепутались, потому что анимация начинают перекрываться в связи с тем, как продолжительность анимации и задержки настроены.


Решение:

В целом, подход для введения задержки между каждой итерацией бесконечной анимации петли является изменением ключевых кадров таким образом, что они добавляют равные задержки для каждой итерации. Я объяснил это в my answer here. К сожалению, ваш случай намного сложнее из-за обратной анимации. Я не мог изменить ключевые кадры, чтобы соответствовать вашим ожиданиям, но я надеюсь, что вы найдете объяснение abov полезным для понимания проблемы.

Если вы хотите использовать альтернативные методы для достижения такого же эффекта, вы можете посмотреть фоновые изображения linear-gradient, чтобы создать эффект гамбургера, а затем добавить к нему анимацию.

.lines { 
 
    margin: 0 auto; 
 
    height: 30px; 
 
    width: 30px; 
 
    background-image: linear-gradient(#333, #333), linear-gradient(#333, #333), linear-gradient(#333, #333); 
 
    background-size: 100% 5px; 
 
    background-position: 0px 5px, 0px 15px, 0px 25px; 
 
    background-repeat: no-repeat; 
 
    animation: bars 1.7s infinite alternate ease-in-out; 
 
} 
 
@keyframes bars { 
 
    0% { 
 
    background-image: linear-gradient(#333, #333), linear-gradient(#333, #333), linear-gradient(#333, #333); 
 
    } 
 
    33% { 
 
    background-image: linear-gradient(#ddd, #ddd), linear-gradient(#333, #333), linear-gradient(#333, #333); 
 
    } 
 
    66% { 
 
    background-image: linear-gradient(#ddd, #ddd), linear-gradient(#ddd, #ddd), linear-gradient(#333, #333); 
 
    } 
 
    100% { 
 
    background-image: linear-gradient(#ddd, #ddd), linear-gradient(#ddd, #ddd), linear-gradient(#ddd, #ddd); 
 
    } 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script> 
 
<div class="lines"></div>

Ниже приводится решение, используя свой первоначальный подход (любезно предоставлены vals). Но вы не можете повторно использовать ключевые кадры!

.line { 
 
    border-bottom: 0.2em solid #333; 
 
    display: block; 
 
    margin: 0 auto; 
 
    margin-top: 0.3em; 
 
    width: 1.5em; 
 
} 
 
.line { 
 
    animation: 1.7s ease-in-out infinite alternate fade_line1; 
 
} 
 
.line:nth-child(2) { 
 
    animation-name: fade_line2; 
 
} 
 
.line:nth-child(3) { 
 
    animation-name: fade_line3; 
 
} 
 
@keyframes fade_line1 { /* use 25% instead of 30% if the splits need to be equal among all 3 */ 
 
    0%, 30% { 
 
    border-bottom-color: #333; 
 
    } 
 
    30%, 100% { 
 
    border-bottom-color: #ddd; 
 
    } 
 
} 
 
@keyframes fade_line2 { 
 
    0%, 50% { 
 
    border-bottom-color: #333; 
 
    } 
 
    50%, 100% { 
 
    border-bottom-color: #ddd; 
 
    } 
 
} 
 
@keyframes fade_line3 { /* use 75% instead of 70% if the splits need to be equal among all 3 */ 
 
    0%, 70% { 
 
    border-bottom-color: #333; 
 
    } 
 
    70%, 100% { 
 
    border-bottom-color: #ddd; 
 
    } 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script> 
 
<div class="lines"> 
 
    <span class="line"></span> 
 
    <span class="line"></span> 
 
    <span class="line"></span> 
 
</div>

+1

Отлично! Спасибо за решение и объяснение. Я попытался нарисовать каждый ключевой кадр на бумаге для лучшего понимания :) – DimmuBoy

0

После использования много времени, и усилий я хотел создать (простой) альтернативный ответ с помощью SVG.

После часа кодирования javascript, я собираюсь опубликовать, как это до сих пор. Я не доволен кодом, так как он сложный и использует довольно некоторый код javascript для анимации перехода цвета.

var stop = document.getElementById("stop2"); 
 

 
var dir = false; 
 
var amount = 1; 
 
var pause = false; 
 

 
startanim(); 
 

 
function fade() { 
 
    if (amount >= 100) { 
 
    if (amount == 150) { 
 
     dir = true; 
 
    } 
 
    amount++; 
 
    } else if (amount <= 0) { 
 
    if (amount == -50) { 
 
     dir = false; 
 
    } 
 
    amount--; 
 
    } 
 
    if (dir) { 
 
    stop.setAttribute("offset", amount + "%"); 
 
    amount--; 
 
    } else { 
 
    stop.setAttribute("offset", amount + "%"); 
 
    amount++; 
 
    } 
 
} 
 

 
var interval = "id"; 
 

 
function startanim() { 
 
    interval = setInterval(function() { 
 
    fade(); 
 
    }, 10); 
 
}
.handle { 
 
    mask: url(#myMask); 
 
}
<svg id="burger" viewBox="0 0 50 50" width="100" xmlns="http://www.w3.org/2000/svg"> 
 
    <defs> 
 
    <linearGradient id="Gradient1" x1="0" x2="0" y1="0" y2="1"> 
 
     <stop id="stop1" stop-color="black" offset="0%" /> 
 
     <stop id="stop2" stop-color="#ddd" offset="1%" /> 
 
     <stop id="stop4" stop-color="#ddd" offset="100%" /> 
 
    </linearGradient> 
 
    <mask id="myMask" maskUnits="userSpaceOnUse" x="0" y="0" width="50" height="50"> 
 
     <rect x="0" y="0" width="50" height="50" fill="url(#Gradient1)" /> 
 
    </mask> 
 
    </defs> 
 
    <rect class="handle" x="20" y="12" width="30" height="5" /> 
 
    <rect class="handle" x="20" y="25" width="30" height="5" /> 
 
    <rect class="handle" x="20" y="37" width="30" height="5" /> 
 
</svg>

Смежные вопросы