Страницы

Поиск по вопросам

пятница, 29 ноября 2019 г.

Как сделать плавную пунктированную анимацию c поворотом границы, такую как “марширующие муравьи”

#css #css3 #анимация #svg #css_animation


Я работаю над анимацией css, в которой используются зубья шестеренки  и цепь, но
я не могу создать smooth последовательность вращения границы.  

Вы можете видеть в fiddle, как  я использую псевдоэлемент для создания эффекта вращения.Это
делается путем переключения между пунктирной белой и пунктирной границей золотого цвета,
из-за чего кажется, что "граница вращается".    

Вот код:   



#one{
  -webkit-animation: rotateClockwiseAnimation 5s linear infinite; /* Safari 4+ */
  -moz-animation:    rotateClockwiseAnimation 5s linear infinite; /* Fx 5+ */
  -o-animation:      rotateClockwiseAnimation 5s linear infinite; /* Opera 12+ */
  animation:         rotateClockwiseAnimation 5s linear infinite; /* IE 10+, Fx 29+ */

}
#two{
  -webkit-animation: rotateAntiClockwiseAnimation 5s linear infinite; /* Safari 4+ */
  -moz-animation:    rotateAntiClockwiseAnimation 5s linear infinite; /* Fx 5+ */
  -o-animation:      rotateAntiClockwiseAnimation 5s linear infinite; /* Opera 12+ */
  animation:         rotateAntiClockwiseAnimation 5s linear infinite; /* IE 10+,
Fx 29+ */

 position:absolute;
    top:30px;
    left:42px;
    width:80px;
}

@-webkit-keyframes rotateClockwiseAnimation {
  0%   { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}
@-moz-keyframes rotateClockwiseAnimation{
  0%   { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}
@-o-keyframes rotateClockwiseAnimation {
  0%   { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}
@keyframes rotateClockwiseAnimation {
  0%   { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

@-webkit-keyframes rotateAntiClockwiseAnimation {
  0%   { transform: rotate(0deg); }
  100% { transform: rotate(-360deg); }
}
@-moz-keyframes rotateAntiClockwiseAnimation {
  0%   { transform: rotate(0deg); }
  100% { transform: rotate(-360deg); }
}
@-o-keyframes rotateAntiClockwiseAnimation {
  0%   { transform: rotate(0deg); }
  100% { transform: rotate(-360deg); }
}
@keyframes rotateAntiClockwiseAnimation {
  0%   { transform: rotate(0deg); }
  100% { transform: rotate(-360deg); }
}

/******************************************************************************/

.chain{
    height:70px;
    width:80%;
    border:5px dashed gold;
    border-radius:30px;
    position:absolute;
    top:30px;
    left:40px;
          -webkit-animation: switchGoldBlackBorder 0.8s infinite; /* Safari 4+ */
  -moz-animation:    switchGoldBlackBorder 0.8s infinite; /* Fx 5+ */
  -o-animation:      switchGoldBlackBorder 0.8s infinite; /* Opera 12+ */
  animation:         switchGoldBlackBorder 0.8s infinite; /* IE 10+, Fx 29+ */
}


@-webkit-keyframes switchBlackGoldBorder {
    0%   { border: 5px dashed transparent; }
    49%   { border: 5px dashed transparent; }
    50%   { border: 5px dashed gold; }
    100%   { border: 5px dashed gold; }
}
@-moz-keyframes switchBlackGoldBorder{
    0%   { border: 5px dashed transparent; }
    49%   { border: 5px dashed transparent; }
    50%   { border: 5px dashed gold; }
    100%   { border: 5px dashed gold; }
}
@-o-keyframes switchBlackGoldBorder {
    0%   { border: 5px dashed transparent; }
    49%   { border: 5px dashed transparent; }
    50%   { border: 5px dashed gold; }
    100%   { border: 5px dashed gold; }
}
@keyframes switchBlackGoldBorder {  
    0%   { border: 5px dashed transparent; }
    49%   { border: 5px dashed transparent; }
    50%   { border: 5px dashed gold; }
    100%   { border: 5px dashed gold; }
}



.chain:after{
    content:"";
    position:absolute;
    height:70px;
    border-radius:30px;
    width:100%;
    top:-5px;
    left:-5px;
    border:5px solid gold;
    z-index:-1;
          -webkit-animation: switchBlackGoldBorder 0.8s infinite; /* Safari 4+ */
  -moz-animation:    switchBlackGoldBorder 0.8s infinite; /* Fx 5+ */
  -o-animation:      switchBlackGoldBorder 0.8s infinite; /* Opera 12+ */
  animation:         switchBlackGoldBorder 0.8s infinite; /* IE 10+, Fx 29+ */
}

@-webkit-keyframes switchGoldBlackBorder {
  0%   { border: 5px solid gold; }
    49%   { border: 5px solid gold; }
    50%   { border: 5px solid white; }
    100%   { border: 5px solid white; }
}
@-moz-keyframes switchGoldBlackBorder{
  0%   { border: 5px solid gold; }
    49%   { border: 5px solid gold; }
    50%   { border: 5px solid white; }
    100%   { border: 5px solid white; }
}
@-o-keyframes switchGoldBlackBorder {
  0%   { border: 5px solid gold; }
    49%   { border: 5px solid gold; }
    50%   { border: 5px solid white; }
    100%   { border: 5px solid white; }
}
@keyframes switchGoldBlackBorder {  
    0%   { border: 5px solid gold; }
    49%   { border: 5px solid gold; }
    50%   { border: 5px solid white; }
    100%   { border: 5px solid white; }
}

    
        
        
        
    
    
    



        

Итак, в нижней части snippet вы можете увидеть, как я создал эффект вращающейся цепочки, используя keyframes. Что бы я хотел в целом получить Подумайте о поперечном сечении конвейерной ленты и о том, как шестерни в конце ленты зацепляют её. Я пытаюсь воспроизвести это. То есть впадины пунктирной ленты должны находиться на зубьях шестерни и тянуть её. #one{ -webkit-animation: rotateClockwiseAnimation 5s linear infinite; /* Safari 4+ */ -moz-animation: rotateClockwiseAnimation 5s linear infinite; /* Fx 5+ */ -o-animation: rotateClockwiseAnimation 5s linear infinite; /* Opera 12+ */ animation: rotateClockwiseAnimation 5s linear infinite; /* IE 10+, Fx 29+ */ border:5px dashed gold; border-radius:50%; } @-webkit-keyframes rotateClockwiseAnimation { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } @-moz-keyframes rotateClockwiseAnimation{ 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } @-o-keyframes rotateClockwiseAnimation { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } @keyframes rotateClockwiseAnimation { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } Но с золотыми черточками, чтобы они поместились между зубьями шестеренки, а также весь механизм занимал бы 80% ширины экрана (если это имеет смысл). В конечном счете я хотел бы создать что-то вроде этого изображения: Перевод вопроса: How to make a smooth dashed border rotation animation like 'marching ants' @jbutler483


Ответы

Ответ 1



Анимация цепи и зубьев шестеренки: Полностью переписал код (CSS и HTML), теперь это: Короче (особенно CSS) Проще Вид механизма стал более реалистичный: исправил проблему синхронизации между цепочкой и шестеренками и добавил недостающую шестерню справа, потому что ваша цепь, казалось,- парила в воздухе: svg{width:100%;} #chain_st{ -webkit-animation: dash 1s infinite linear; -moz-animation: dash 1s infinite linear; -o-animation: dash 1s infinite linear; animation: dash 1s infinite linear; } @-webkit-keyframes dash { to { stroke-dashoffset: -5; } } @-moz-keyframes dash { to { stroke-dashoffset: -5; } } @-o-keyframes dash { to { stroke-dashoffset: -5; } } @keyframes dash { to { stroke-dashoffset: -5; } } Подход тот же, что и анимация угла поворота для зубцов и смещение штрихов для цепи. Я настроил синхронизацию между двумя анимациями, чтобы она выглядела так, как будто шестерни тянут цепь. Browser support : Поскольку IE не поддерживает элемент svg animate, я также сделал эту версию анимации с библиотекой snap.svg, которая также поддерживает IE9 и более (протестирована в IE9 с crossbrowsertesting). DEMO с поддержкой IE var cont = new Snap('#svg'), chain = cont.select('#chain'), cogAcw = cont.select('#cog_acw'), cogCw = cont.select('#cog_cw'), speed = 500; // Lower this number to make the animation faster function infChain(el) { var len = el.getTotalLength(); el.attr({"stroke-dasharray": len/62,"stroke-dashoffset": 0}); el.animate({"stroke-dashoffset": -len/31}, speed, mina.linear, infChain.bind(null, el)); } function rotateAcw(el) { el.transform('r22.5,20,20'); el.animate({ transform: 'r-22.5,20,20' }, speed, mina.linear, rotateAcw.bind( null, el)); } function rotateCw(el) { el.transform('r0,20,20'); el.animate({ transform: 'r45,20,20' }, speed, mina.linear, rotateCw.bind( null, el)); } infChain(chain); rotateAcw(cogAcw); rotateCw(cogCw); svg { width:100%; } Для современных браузеров svg{width:100%;} #chain_st{ -webkit-animation: dash 1s infinite linear; -moz-animation: dash 1s infinite linear; -o-animation: dash 1s infinite linear; animation: dash 1s infinite linear; } @-webkit-keyframes dash { to { stroke-dashoffset: -5; } } @-moz-keyframes dash { to { stroke-dashoffset: -5; } } @-o-keyframes dash { to { stroke-dashoffset: -5; } } @keyframes dash { to { stroke-dashoffset: -5; } } Предложения к коду автора вопроса: Вы можете использовать другой svg dashed path и анимировать свойство dash-offset с помощью keyframe animation. Это можно и нужно упростить / настроить для использования в "real world": Все элементы могут быть помещены в один тэг (это упростит задачу, и оба элемента шестеренка + цепь могут совместно изменять размер) Синхронизация между цепью и зубчатым колесом не идеальна, и скорость / размер цепи необходимо подкорректировать. Прим. переводчика Ниже в сниппете отвечающий подправил оригинальный код, который был в вопросе топика #one { -webkit-animation: rotateClockwiseAnimation 5s linear infinite; /* Safari 4+ */ -moz-animation: rotateClockwiseAnimation 5s linear infinite; /* Fx 5+ */ -o-animation: rotateClockwiseAnimation 5s linear infinite; /* Opera 12+ */ animation: rotateClockwiseAnimation 5s linear infinite; /* IE 10+, Fx 29+ */ } #two { -webkit-animation: rotateAntiClockwiseAnimation 5s linear infinite; /* Safari 4+ */ -moz-animation: rotateAntiClockwiseAnimation 5s linear infinite; /* Fx 5+ */ -o-animation: rotateAntiClockwiseAnimation 5s linear infinite; /* Opera 12+ */ animation: rotateAntiClockwiseAnimation 5s linear infinite; /* IE 10+, Fx 29+ */ position: absolute; top: 30px; left: 42px; width: 80px; } @-webkit-keyframes rotateClockwiseAnimation { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } @-moz-keyframes rotateClockwiseAnimation { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } @-o-keyframes rotateClockwiseAnimation { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } @keyframes rotateClockwiseAnimation { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } @-webkit-keyframes rotateAntiClockwiseAnimation { 0% { transform: rotate(0deg); } 100% { transform: rotate(-360deg); } } @-moz-keyframes rotateAntiClockwiseAnimation { 0% { transform: rotate(0deg); } 100% { transform: rotate(-360deg); } } @-o-keyframes rotateAntiClockwiseAnimation { 0% { transform: rotate(0deg); } 100% { transform: rotate(-360deg); } } @keyframes rotateAntiClockwiseAnimation { 0% { transform: rotate(0deg); } 100% { transform: rotate(-360deg); } } /******************************************************************************/ #chain { width: 650px; position: absolute; top: 24px; left: 35px; } .chain_st { stroke-dasharray: 1.5; stroke-dashoffset: 10; -webkit-animation: dash 18s infinite linear; -moz-animation: dash 18s infinite linear; -o-animation: dash 18s infinite linear; animation: dash 18s infinite linear; } @-webkit-keyframes dash { to { stroke-dashoffset: 100; } } @-moz-keyframes dash { to { stroke-dashoffset: 100; } } @-o-keyframes dash { to { stroke-dashoffset: 100; } } keyframes dash { to { stroke-dashoffset: 100; } } Перевод ответа: How to make a smooth dashed border rotation animation like 'marching ants' @web-tiki

Ответ 2



Примечание. Я переделал всю анимацию в box-shadow, потому что использование dashed borders не имеет согласованного вывода во всех браузерах. Работает .. и работает кроссбраузерно. FF 5+, GC 4+, IE9+, Safari 4+, Opera 12.1+ Вы можете попробовать это с помощью box-shadow: Чтобы сделать зубья шестеренок, используйте box-shadow с отрицательным spread radius. Размер моей шестеренки был, например: 50px , поэтому, чтобы использовать box-shadow с d = 8px, я установил -46px, как spread radius. Я разместил зубья шестеренки, используя координаты geo, и сделал только 8 зубьев для упрощения. Теперь для прямого участка конвейера, нам нужно узнать расстояние между зубьями . Мы получаем это следующим образом: 2*pi*(r шестеренки) / кол. зубьев = (pi * r) / 4 результат = (55 * 3.1415) / 4 = 43 (приблизительно) Я взял радиус 55, потому что зубья имеют радиус 4px и находятся на расстоянии 1px от окружности шестерни. прим. переводчика: 55 - это диаметр. Для выравнивания верхних и нижних прямых участков ленты конвейера, необходимо их перевести на любое кратное расстояние. Для моих шестеренок я установил их на 43px. Каркас FIDDLE body { background: rgba(25,80,175, 0.4); } .rect { height: 116px; width: 401px; border-radius: 58px; position: relative; overflow: hidden; } .rect:before, .rect:after { content: ''; position: absolute; left: 46px; /*50-half width*/ height: 8px; width: 8px; border-radius: 50%; background: transparent; box-shadow: 43px 0 0 0 white, 86px 0 0 0 white, 129px 0 0 0 white, 172px 0 0 0 white, 215px 0 0 0 white, 258px 0 0 0 white, 301px 0 0 0 white; -webkit-animation: apple 0.3s linear infinite; -moz-animation: apple 0.3s linear infinite; animation: apple 0.3s linear infinite; } .rect:before { top: 0px; } .rect:after { bottom: 0px; -webkit-animation-direction: reverse; -moz-animation-direction: reverse; animation-direction: reverse; } @-webkit-keyframes apple { 0% {-webkit-transform: translatex(0px);} 100% {-webkit-transform: translateX(-43px);} } @-moz-keyframes apple { 0% {-moz-transform: translatex(0px);} 100% {-moz-transform: translateX(-43px);} } @keyframes apple { 0% {transform: translatex(0px);} 100% {transform: translateX(-43px);} } .left, .right { content: ''; position: relative; height: 100px; width: 100px; border-radius: 50px; background-color: #222; box-shadow: 0 55px 0 -46px white, 55px 0 0 -46px white, 0 -55px 0 -46px white, -55px 0 0 -46px white, 39px 39px 0 -46px white, -39px -39px 0 -46px white, 39px -39px 0 -46px white, -39px 39px 0 -46px white; -webkit-animation: mango 2.4s linear infinite; -moz-animation: mango 2.4s linear infinite; animation: mango 2.4s linear infinite; } .left { top: -108px; left: 0px; } .right { top: -208px; left: 301px; } @-webkit-keyframes mango { 0% {-webkit-transform: rotate(0deg);} 100% {-webkit-transform: rotate(-360deg);} } @-moz-keyframes mango { 0% {-moz-transform: rotate(0deg);} 100% {-moz-transform: rotate(-360deg);} } @keyframes mango { 0% {transform: rotate(0deg);} 100% {transform: rotate(-360deg);} }
Финальная версия ... с шестеренками. Цепочка в настоящее время dotted dashed! FIDDLE body { background-color: white; } .rect { height: 120px; width: 401px; border-radius: 58px; position: relative; } .rect:before, .rect:after { content: ''; position: absolute; left: 40px; /*50-half width*/ height: 10px; width: 20px; background: transparent; box-shadow: 43px 0 0 0 gold, 86px 0 0 0 gold, 129px 0 0 0 gold, 172px 0 0 0 gold, 215px 0 0 0 gold, 258px 0 0 0 gold, 301px 0 0 0 gold, 344px 0 0 0 gold; /*keep adding 43 to x-axis*/ -webkit-animation: apple 0.6s linear infinite; -moz-animation: apple 0.6s linear infinite; animation: apple 0.6s linear infinite; overflow: hidden; } .rect:before { top: 0px; } .rect:after { bottom: 0px; -webkit-animation-direction: reverse; -moz-animation-direction: reverse; animation-direction: reverse; } @-webkit-keyframes apple { 0% {-webkit-transform: translatex(0px);} 100% {-webkit-transform: translateX(-43px);} } @-moz-keyframes apple { 0% {-moz-transform: translatex(0px);} 100% {-moz-transform: translateX(-43px);} } @keyframes apple { 0% {transform: translatex(0px);} 100% {transform: translateX(-43px);} } .left, .right { content: ''; position: relative; height: 100px; width: 100px; border-radius: 50px; -webkit-animation: mango 4.8s linear infinite; -moz-animation: mango 4.8s linear infinite; animation: mango 4.8s linear infinite; } .left { top: -110px; left: 0px; } .right { top: -210px; left: 344px; } .left:before, .left:after, .right:before, .right:after { height: 20px; width: 20px; content: ''; position: absolute; background-color: gold; } .left:before, .right:before { box-shadow: 50px 50px 0 0 gold, -50px 50px 0 0 gold, 0 100px 0 0 gold; top: -10px; left: 40px; } .left:after, .right:after { transform: rotate(45deg); top: 5px; left: 76px; box-shadow: 0px 100px 0 0 gold, 50px 50px 0 0 gold, -50px 50px 0 0 gold; } @-webkit-keyframes mango { 0% {-webkit-transform: rotate(0deg);} 100% {-webkit-transform: rotate(-360deg);} } @-moz-keyframes mango { 0% {-moz-transform: rotate(0deg);} 100% {-moz-transform: rotate(-360deg);} } @keyframes mango { 0% {transform: rotate(0deg);} 100% {transform: rotate(-360deg);} } .cover { height: 104px; width: 446px; border-radius: 50px; position: relative; background: rgba(255,255,255,1); top: -312px; left; -2px; } .gear, .gear2 { height: 100px; width: 100px; background: dimgray; border-radius: 50%; position: relative; -webkit-animation: gear 4.8s linear infinite; -moz-animation: gear 4.8s linear infinite; animation: gear 4.8s linear infinite; } .gear { top: -414px; } .gear2 { top: -514px; left: 345px; } .gear:before, .gear:after, .gear2:before, .gear2:after { height: 20px; width: 20px; content: ''; position: absolute; background-color: dimgray; } .gear:before, .gear2:before { box-shadow: 50px 50px 0 0 dimgray, -50px 50px 0 0 dimgray, 0 100px 0 0 dimgray; top: -10px; left: 40px; } .gear:after, .gear2:after { transform: rotate(45deg); top: 5px; left: 76px; box-shadow: 0px 100px 0 0 dimgray, 50px 50px 0 0 dimgray, -50px 50px 0 0 dimgray; } @-webkit-keyframes gear { 0% {-webkit-transform: rotate(22.5deg);} 100% {-webkit-transform: rotate(-337.5deg);} } @-moz-keyframes gear { 0% {-moz-transform: rotate(22.5deg);} 100% {-moz-transform: rotate(-337.5deg);} } @keyframes gear { 0% {transform: rotate(22.5deg);} 100% {transform: rotate(-337.5deg);} }
Финальная версия (закругленные зубья шестеренки) .rect { height: 120px; width: 401px; border-radius: 58px; position: relative; } .rect:before, .rect:after { content: ''; position: absolute; left: 40px; /*50-half width*/ height: 10px; width: 20px; box-shadow: 43px 0 0 0 gold, 86px 0 0 0 gold, 129px 0 0 0 gold, 172px 0 0 0 gold, 215px 0 0 0 gold, 258px 0 0 0 gold, 301px 0 0 0 gold, 344px 0 0 0 gold; /*keep adding 43 to x-axis*/ -webkit-animation: translate 0.6s linear infinite; -moz-animation: translate 0.6s linear infinite; animation: translate 0.6s linear infinite; overflow: hidden; } .rect:before {top: 0px;} .rect:after { bottom: 0px; -webkit-animation-direction: reverse; -moz-animation-direction: reverse; animation-direction: reverse; } @-webkit-keyframes translate { 0% {-webkit-transform: translatex(0px);} 100% {-webkit-transform: translateX(-43px);} } @-moz-keyframes translate { 0% {-moz-transform: translatex(0px);} 100% {-moz-transform: translateX(-43px);} } @keyframes translate { 0% {transform: translatex(0px);} 100% {transform: translateX(-43px);} } .left, .right { position: relative; height: 100px; width: 100px; border-radius: 50px; -webkit-animation: rotate 4.8s linear infinite; -moz-animation: rotate 4.8s linear infinite; animation: rotate 4.8s linear infinite; } .left { top: -110px; left: 0px; } .right { top: -210px; left: 344px; } .left:before, .left:after, .right:before, .right:after { height: 20px; width: 20px; content: ''; position: absolute; background: gold; } .left:before, .right:before { box-shadow: 50px 50px 0 0 gold, -50px 50px 0 0 gold, 0 100px 0 0 gold; top: -10px; left: 40px; } .left:after, .right:after { transform: rotate(45deg); top: 5px; left: 76px; box-shadow: 0px 100px 0 0 gold, 50px 50px 0 0 gold, -50px 50px 0 0 gold; } @-webkit-keyframes rotate { 0% {-webkit-transform: rotate(0deg);} 100% {-webkit-transform: rotate(-360deg);} } @-moz-keyframes rotate { 0% {-moz-transform: rotate(0deg);} 100% {-moz-transform: rotate(-360deg);} } @keyframes rotate { 0% {transform: rotate(0deg);} 100% {transform: rotate(-360deg);} } .cover { height: 104px; width: 446px; border-radius: 50px; position: relative; background: rgba(255,255,255,1); top: -312px; left; -2px; } .gear, .gear2, .gear3 { height: 100px; width: 100px; background: transparent; box-shadow: inset 0 0 0px 35px dimgray, inset 0 0 0px 40px #444; border-radius: 50%; position: relative; -webkit-animation: rotate 4.8s linear infinite; -moz-animation: rotate 4.8s linear infinite; animation: rotate 4.8s linear infinite; -webkit-animation-delay: 0.3s; -moz-animation-delay: 0.3s; animation-delay: 0.3s; } .gear {top: -414px;} .gear2 {top: -514px; left: 345px;} .gear:before, .gear:after, .gear2:before, .gear2:after, .gear3:before, .gear3:after { height: 20px; width: 20px; content: ''; border-radius: 20%; position: absolute; background: dimgray; } .gear:before, .gear2:before, .gear3:before { box-shadow: 50px 50px 0 0 dimgray, -50px 50px 0 0 dimgray, 0 100px 0 0 dimgray; top: -10px; left: 40px; } .gear:after, .gear2:after, .gear3:after { transform: rotate(45deg); top: 5px; left: 76px; box-shadow: 0px 100px 0 0 dimgray, 50px 50px 0 0 dimgray, -50px 50px 0 0 dimgray; } .gear3 { -webkit-animation-direction: reverse; -moz-animation-direction: reverse; animation-direction: reverse; top: -504px; -webkit-animation-delay: 0s; -moz-animation-delay: 0s; animation-delay: 0s; }
FIDDLE - ROUNDED TEETH ПРИМЕЧАНИЕ. Чтобы увеличить скорость анимации, вам просто нужно пропорционально уменьшить продолжительность анимации каждого элемента. Fiddle (fast) Перевод ответа: How to make a smooth dashed border rotation animation like 'marching ants'@The Pragmatick

Комментариев нет:

Отправить комментарий