如何使一个光滑的虚线边框旋转animation,如“行军ant”

我正在使用“齿轮和链”的cssanimation,但无法创build“平滑”的边框旋转序列。

你可以看到这个小提琴如何(当前)我正在使用一个伪元素来产生“旋转”的效果。 这是通过在白色虚线和虚线金色边框之间“切换”来完成的,使得它看起来像是“边框正在旋转”。

我拥有的

#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; } } 
 <svg id="one" style="width:50px" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 100 100"> <defs> <circle id="c" cx="50" cy="50" r="30" stroke="#808080" fill="none" stroke-width="25"/> <path id="d" stroke="#808080" stroke-width="16" d="M50 0, V15 M50 100, V85 M0 50, H15 M100 50, H85"/> </defs> <use xlink:href="#c"/> <use xlink:href="#d"/> <use xlink:href="#d" transform="rotate(45, 50, 50)"/> </svg> <svg id="two" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 100 100"> <use xlink:href="#one"/> </svg> <div class="chain"></div> 

所以,在代码片段的下半部分,你可以看到我是如何通过使用关键帧来产生“旋转链效应”的。


我想要什么

我的总体愿望是产生像这样的东西:

想想一下传送带的横截面,以及“最终传动带的传动方式”。 我试图重现这一点。 (即虚线边缘的黄金位应在齿轮的槽内,并由其“拉”)

 #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); } } 
 <svg id="one" style="width:50px" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 100 100"> <defs> <circle id="c" cx="50" cy="50" r="30" stroke="#808080" fill="none" stroke-width="25"/> <path id="d" stroke="#808080" stroke-width="16" d="M50 0, V15 M50 100, V85 M0 50, H15 M100 50, H85"/> </defs> <use xlink:href="#c"/> <use xlink:href="#d"/> <use xlink:href="#d" transform="rotate(45, 50, 50)"/> </svg> 

但金色的破折号适合在齿轮的槽内,以及80%的屏幕宽度(如果这是有道理的)。

最后,我想生成像这样的图像描绘:

在这里输入图像说明

看看我想如何链“旋转”?


我目前的问题

  • 由于animation是通过使用伪元素“黑客”,我发现很难实际上同步这个“链”的旋转。
  • 我仍然在学习关键帧animation,所以我相信这不是最好的方法
  • 同样,对于我来说,svg是一个新的概念,所以忍受我不愿意使用它(因此为什么我使用css作为'链')
  • 最后,我想“让它看起来像”齿轮正在转动链条,但现在他们看起来像完全(而且做得不好)单独的元素animation

齿轮和连锁animation:

我总共重构了代码( CSSHTML ),现在是:

  • 较短(尤其是css)
  • 简单
  • 更现实:纠正了链条和齿轮之间的同步问题,并在右侧添加了一个缺失齿轮,因为链条似乎漂浮在空中:

DEMO

方法是一样的,animation的齿轮的旋转angular度和链条path的dash-offset 。 我调整了两个animation之间的时间间隔,使它看起来好像是齿轮拉链。

浏览器支持:

由于IE 不支持 svg animate元素,我还使用snap.svg库(也支持IE9及以上版本(在IE9中使用crossbrowsertesting进行testing))制作此版本的animation。

与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%; } 
 <script src="http://thisisa.simple-url.com/js/snapsvg.js"></script> <svg id="svg" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 100 30"> <defs> <circle id="c" cx="20" cy="20" r="4" stroke="#808080" fill="none" stroke-width="4" /> <path id="d" stroke="#808080" stroke-width="2" d="M20 13 V16 M27 20 H24 M20 27 V24 M13 20 H16" /> <g id="cog_acw"> <use xlink:href="#c" /><use xlink:href="#d" /> <use xlink:href="#d" transform="rotate(45 20 20)" /> </g> <g id="cog_cw"> <use xlink:href="#c" /><use xlink:href="#d" /> <use xlink:href="#d" transform="rotate(45 20 20)" /> </g> </defs> <path id="chain" stroke-width="1" stroke="#000" fill="transparent" d="M21.3 13.5 H20 C11.4 13.5 11.4 26.5 20 26.5 H80 C89.4 26.5 89.4 13.5 80.8 13.5z" /> <use xlink:href="#cog_acw" /> <use transform="translate(60.5 0), rotate(19,20,20)" xlink:href="#cog_acw" /> <use transform="translate(-4.5 -4.5),scale(.8), rotate(0,20,20)" xlink:href="#cog_cw" /> </svg> 

这个方法怎么样? 我正在使用SVG的齿轮和传送带。 齿轮按照您的示例进行旋转,但是我正在使用stroke-dasharray和animationstroke-dash-offset stroke-dasharray stroke-dash-offset来使传送带移动。

需要花费一点时间才能得到输送带的长度和冲刺时间,如果你改变齿轮尺寸或者输送带的长度,你需要重新调整。

 #one{ -webkit-animation: rotateClockwiseAnimation 4s linear infinite; /* Safari 4+ */ -moz-animation: rotateClockwiseAnimation 4s linear infinite; /* Fx 5+ */ -o-animation: rotateClockwiseAnimation 4s linear infinite; /* Opera 12+ */ animation: rotateClockwiseAnimation 4s linear infinite; /* IE 10+, Fx 29+ */ } #two{ -webkit-animation: rotateAntiClockwiseAnimation 4s linear infinite; /* Safari 4+ */ -moz-animation: rotateAntiClockwiseAnimation 4s linear infinite; /* Fx 5+ */ -o-animation: rotateAntiClockwiseAnimation 4s linear infinite; /* Opera 12+ */ animation: rotateAntiClockwiseAnimation 4s 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 { -webkit-animation: conveyor 0.5s linear infinite; /* Safari 4+ */ -moz-animation: conveyor 0.5s linear infinite; /* Fx 5+ */ -o-animation: conveyor 0.5s linear infinite; /* Opera 12+ */ animation: conveyor 0.5s linear infinite; /* IE 10+, Fx 29+ */ } @-webkit-keyframes conveyor { 0% { stroke-dashoffset: -9; } 100% { stroke-dashoffset: 20.06; } } @-moz-keyframes conveyor { 0% { stroke-dashoffset: -9; } 100% { stroke-dashoffset: 20.06; } } @-o-keyframes conveyor { 0% { stroke-dashoffset: -9; } 100% { stroke-dashoffset: 20.06; } } @keyframes conveyor { 0% { stroke-dashoffset: -9; } 100% { stroke-dashoffset: 20.06; } } 
 <svg width="100%" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 800 100"> <defs> <circle id="c" cx="0" cy="0" r="30" stroke="#808080" fill="none" stroke-width="25"/> <path id="d" stroke="#808080" stroke-width="16" d="M0,-50 v15 M0,50 v-15 M-50,0 h15 M50,0 h-15"/> <g id="gear"> <use xlink:href="#c"/> <use xlink:href="#d"/> <use xlink:href="#d" transform="rotate(45)"/> </g> </defs> <rect id="chain2" x="43" y="23" width="598" height="74" rx="37" stroke="gold" stroke-width="2" fill="none"/> <g transform="translate(27,27) scale(0.5)"> <g id="one"> <use xlink:href="#gear"/> </g> </g> <g transform="translate(80,60) scale(0.8)"> <g id="two"> <use xlink:href="#gear"/> </g> </g> <rect id="chain" x="43" y="23" width="598" height="74" rx="37" stroke="gold" stroke-width="5" fill="none" stroke-dasharray="14 15.06"/> </svg> 

注意:我已经在box-shadow中重新制作了整个animation,因为使用虚线边框在所有浏览器上都没有一致的输出。

加工

..和Works跨浏览器。
FF 5+,GC 4+,IE9 +,Safari 4+,Opera 12.1+

你可以用box-shadow来试试这个:

  • 要制作齿轮齿,请使用散布半径为负的阴影。 例如,我的装备的大小是50px ,所以为了得到d=8px box-shadow ,我使用了-46px作为扩展半径。

  • 我使用坐标geo来定位牙齿,只用8颗牙齿来简化。

  • 现在对于直线输送机,我们需要知道牙齿之间的距离。 我们通过以下方式获得:

  • 2*pi*(gear radius) / no. of teeth 2*pi*(gear radius) / no. of teeth = (pi * r) / 4
    = (55 * 3.1415) / 4 = 43 (大约)
    我把半径设为55,因为这些齿的半径是4px,并且离齿轮圆周1px。

  • 为了alignment顶部和底部直线输送机,他们需要翻译他们的任何倍数的距离。 对于我的装备,我翻译了43px。

脚手架

小提琴

 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);} } 
 <div class="rect"></div> <div class="left"></div> <div class="right"></div> 

下面是如何使用CSS实现齿轮animation的另一种方法。 这个方法已经在IE11,IE10,Firefox,Chrome,Opera和Safari中testing过了。

  • 两个圆形元素的齿轮/齿轮embeddedbox-shadow产生的内圈。 牙齿由围绕轴旋转的子元素(正常+伪)产生。
  • 带的弯曲部分使用与齿轮的辐条相同的技术来实现,并且定位成使得它们总是位于齿之间。
  • 一个矩形容器元素,其顶部和底部边界使用线性梯度模拟。 这个元素的背景(除了顶部和底部的渐变)是一种纯色,这是一个缺点。 这种纯色用于隐藏任何一侧的一半圆形元素。
  • animation是通过两种方式实现的:(a)不断旋转两个圆形元素;(b)不断地改变渐变背景的背景位置。
 .chain { margin: 45px auto; height: 100px; width: 310px; position: relative; background: -webkit-linear-gradient(0deg, gold 50%, transparent 50%), -webkit-linear-gradient(0deg, gold 50%, transparent 50%), white; background: -moz-linear-gradient(90deg, gold 50%, transparent 50%), -moz-linear-gradient(90deg, gold 50%, transparent 50%), white; background: linear-gradient(90deg, gold 50%, transparent 50%), linear-gradient(90deg, gold 50%, transparent 50%), white; background-size: 41px 5px; background-repeat: repeat-x; background-position: 20px 0px, 20px 95px; -webkit-animation: bgPos 1s infinite linear; -moz-animation: bgPos 1s infinite linear; animation: bgPos 1s infinite linear; } .belt, .belt-after, .belt .spokes, .belt .spokes:before, .belt .spokes:after, .belt-after .spokes, .belt-after .spokes:before, .belt-after .spokes:after { position: absolute; content:''; height: 90px; width:15px; top: 0px; border-top: 5px solid gold; border-bottom: 5px solid gold; z-index: -1; } .belt, .belt-after { -webkit-animation: borderAnim 8s infinite linear; -moz-animation: borderAnim 8s infinite linear; animation: borderAnim 8s infinite linear; } .belt .spokes, .belt-after .spokes { top: -5px; -webkit-transform: rotate(45deg); -moz-transform: rotate(45deg); transform: rotate(45deg); } .belt .spokes:before, .belt-after .spokes:before { top: -5px; -webkit-transform: rotate(90deg); -moz-transform: rotate(90deg); transform: rotate(90deg); } .belt .spokes:after, .belt-after .spokes:after { top: -5px; -webkit-transform: rotate(45deg); -moz-transform: rotate(45deg); transform: rotate(45deg); } .belt { left: -16px; } .belt-after { right: -16px; } .gear { content:''; position: absolute; top: 5px; height: 90px; width: 90px; border-radius: 50%; -webkit-animation: borderAnim 8s infinite linear; -moz-animation: borderAnim 8s infinite linear; animation: borderAnim 8s infinite linear; box-shadow: inset 0px 0px 0px 30px gray; z-index: 4; } .gear:before, .gear .spokes, .gear .spokes:before, .gear .spokes:after { position: absolute; content:''; height: 88px; width:15px; top: -5px; border-top: 6px solid gray; border-bottom: 6px solid gray; } .gear:before { left: 37px; -webkit-transform: rotate(22.5deg); -moz-transform: rotate(22.5deg); transform: rotate(22.5deg); } .gear .spokes { left: 37px; -webkit-transform: rotate(67.5deg); -moz-transform: rotate(67.5deg); transform: rotate(67.5deg); } .gear .spokes:before { top: -6px; -webkit-transform: rotate(45deg); -moz-transform: rotate(45deg); transform: rotate(45deg); } .gear .spokes:after { -webkit-transform: rotate(90deg); -moz-transform: rotate(90deg); transform: rotate(90deg); } .chain .belt + .gear { left:-52px; } .chain .belt-after + .gear { right: -52.5px; } .gear-small { content:''; position: absolute; left: -92px; top: -20px; height: 50px; width: 50px; border-radius: 50%; -webkit-animation: borderAnim 6s infinite linear reverse; -moz-animation: borderAnim 6s infinite linear reverse; animation: borderAnim 6s infinite linear reverse; box-shadow: inset 0px 0px 0px 20px gray; z-index: -2; } .gear-small:before { position: absolute; content:''; left: 21px; top: -3px; height: 48px; width: 10px; border-top:4px solid gray; border-bottom: 4px solid gray; } .gear-small .spokes, .gear-small .spokes:before, .gear-small .spokes:after { position: absolute; content:''; left: 21px; top: -3px; height: 48px; width: 10px; border-top:4px solid gray; border-bottom: 4px solid gray; } .gear-small .spokes { -webkit-transform: rotate(45deg); -moz-transform: rotate(45deg); transform: rotate(45deg); } .gear-small .spokes:before { left: 0px; -webkit-transform: rotate(90deg); -moz-transform: rotate(90deg); transform: rotate(90deg); } .gear-small .spokes:after { left: 0px; -webkit-transform: rotate(45deg); -moz-transform: rotate(45deg); transform: rotate(45deg); } @-webkit-keyframes borderAnim { 0% { -webkit-transform: rotate(360deg); } 100% { -webkit-transform: rotate(0deg); } } @-moz-keyframes borderAnim { 0% { -moz-transform: rotate(360deg); } 100% { -moz-transform: rotate(0deg); } } @keyframes borderAnim { 0% { transform: rotate(360deg); } 100% { transform: rotate(0deg); } } @-webkit-keyframes bgPos { 0% { background-position: 20px 0px, -20px 95px; } 100% { background-position: -20px 0px, 20px 95px; } } @-moz-keyframes bgPos { 0% { background-position: 20px 0px, -20px 95px; } 100% { background-position: -20px 0px, 20px 95px; } } @keyframes bgPos { 0% { background-position: 20px 0px, -20px 95px; } 100% { background-position: -20px 0px, 20px 95px; } } 
 <div class="chain"> <div class="gear-small"> <div class="spokes"></div> </div> <div class="belt"> <div class="spokes"></div> </div> <div class="gear"> <div class="spokes"></div> </div> <div class="belt-after"> <div class="spokes"></div> </div> <div class="gear"> <div class="spokes"></div> </div> </div> 

You could try and edit cog so it fits better instead of tweaking div border to fall into place on cog. Its easier to manipulate graphics than css.

And from there maybe to split chain animation in three or four parts to make it more robust.

Then you could tweak speeds of cog and chain to match, hide a half of chain, add onto it div only with top and bottom border and do the same but opposite on other end. (using cliping, position and z-index).

像这样的东西:

xhtml

In theory at least, that would be my approach (not to mention that I would use JS instead of this workflow).

Using Canvas

The shapes (cog and chain) and the marching ants animation effect (dashed border) can also be achieved by using a Canvas drawing. The browser support for Canvas is quite good .

While Canvas has the disadvantage of being raster based (as opposed to SVG, which is shape based), it is not a big problem as long as the canvas is not scaled too much. Canvas is expected to be better when handling a large number of objects and real-time animations. Here is an interesting article from the MSDN on when to use Canvas or SVG.


Construction of Shapes

The following are the key parts/shapes involved in this animation:

  • Left Cog
  • Right Cog
  • Top Cog

Chain : The chain is created by drawing two horizontal lines (using the lineTo commands) that are connected at either end by semicircles (drawn using the arc command). The dashed border effect is achieved by using setLineDash method for the stroke. setLineDash method takes two parameters where the first represents the length of the dash and the second represents the gap between dashes.

Below snippet shows the minimal code required to create the chain:

 window.onload = function() { var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); var chain = { offset: 0, paint: function() { ctx.beginPath(); ctx.moveTo(75, 50); ctx.lineTo(533, 50); ctx.arc(533, 100, 50, (Math.PI * 1.5), (Math.PI * 0.5), false); ctx.lineTo(75, 150); ctx.arc(75, 100, 50, (Math.PI * 0.5), (Math.PI * 1.5), false); ctx.lineWidth = 5; ctx.fillStyle = 'transparent'; ctx.setLineDash([12, 14.16]); ctx.lineDashOffset = this.offset; ctx.fill(); ctx.stroke(); } }; chain.paint(); } 
 /* CSS needed only for demo */ body { background-image: radial-gradient(circle, #3F9CBA 0%, #153346 100%); } canvas { margin: 50px auto; } 
 <canvas id='canvas' width='650' height='300'></canvas>