我正在处理使用&#c; cogs和chain'的css动画,但我无法创建一个平滑的'边界旋转序列。
您可以在此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; }
}

<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>
&#13;
因此,在该片段的下半部分,您可以看到我是如何产生旋转链效应的&#39;通过使用关键帧。
我想要什么
我的总体愿望是产生类似的东西:
想象一下传送带的横截面,以及最后的齿轮如何驱动传送带&#39;。我试图重现这一点。 (即虚线边框的金色钻头应位于齿轮的波谷内,并由它拉动)
#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); }
}
&#13;
<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>
&#13;
但是金色的破折号适合在齿轮的槽内,并且屏幕宽度为80%(如果有意义的话)。
最后,我想生成像这样的图像描绘:
了解我希望链条如何旋转&#39;?
我当前的问题
答案 0 :(得分:77)
我完全重构了代码( CSS 和 HTML ),现在是:
<强> DEMO 强>
方法是相同的,为齿轮的旋转角度设置动画,为链路设置dash-offset
。我调整了两个动画之间的时间,使它看起来好像是齿轮拉链。
作为IE doesn't support svg animate元素,我还使用snap.svg库创建了此版本的动画,该库也支持IE9及以上版本(在IE9中使用crossbrowsertesting进行测试)。
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);
&#13;
svg {
width:100%;
}
&#13;
<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>
&#13;
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; }
}
&#13;
<svg id="one" 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">
<use xlink:href="#c"/>
<use xlink:href="#d"/>
<use xlink:href="#d" transform="rotate(45 20 20)"/>
</g>
</defs>
<g transform="translate(0,-7), scale(0.8), rotate(22.5 8 8)">
<use xlink:href="#cog">
<animateTransform attributeType="xml" attributeName="transform" type="rotate" from="-22.5 20 20" to="337.5 20 20" dur="8s" repeatCount="indefinite"/>
</use>
</g>
<path id="chain_st" stroke-width="1" stroke="#000" fill="transparent" stroke-dasharray="2.6 2.45" d="M21.3 13.5 H20 C11.4 13.5 11.4 26.5 20 26.5 H80 C89 26.5 89 13.5 80.8 13.5z" />
<use class="rot" xlink:href="#cog">
<animateTransform attributeType="xml" attributeName="transform" type="rotate"from="22.5 20 20" to="-337.5 20 20" dur="8s" repeatCount="indefinite"/>
</use>
<g transform="translate(60.3 0)">
<use class="" xlink:href="#cog">
<animateTransform attributeType="xml" attributeName="transform" type="rotate" from="22.5 20 20" to="-337.5 20 20" dur="8s" repeatCount="indefinite"/>
</use>
</g>
</svg>
&#13;
原始回答:
您可以使用其他svg虚线路径,并使用关键帧动画为dash-offset属性设置动画。
这可以而且应该被简化/调整为现实世界&#34;使用:
<svg>
标记中(这样可以使其更简单,并且cogs + chain可以一起调整大小)
#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;
}
}
&#13;
<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>
<svg id="chain" xmlns="http://www.w3.org/2000/svg" viewbox="0 0 70 10">
<path class="chain_st" stroke-width="0.5" stroke="#000" fill="transparent" d="M60 1 Q65 1 65 5 Q65 9 60 9 H6 Q1 9 1 5 Q1 1 6 1z" />
</svg>
&#13;
答案 1 :(得分:29)
这种做法怎么样?我在齿轮和输送机上都使用SVG。齿轮按照您的示例旋转,但我使用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; }
}
&#13;
<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>
&#13;
答案 2 :(得分:18)
注意:我在box-shadow中重新制作了整个动画,因为使用虚线边框并非在所有浏览器上都有一致的输出。
..并且跨浏览器工作。
FF 5 +,GC 4 +,IE9 +,Safari 4 +,Opera 12.1 +
您可以使用box-shadow尝试此操作:
要制作齿轮齿,请使用负展开半径的箱形阴影。例如,我的设备大小为50px
,因此要使用box-shadow
绕d=8px
,我使用-46px
作为展开半径。
我使用坐标geo定位牙齿,仅使用8颗牙齿来简化。
现在对于直线输送机,我们需要知道牙齿之间的距离。我们通过以下方式得到:
2*pi*(gear radius) / no. of teeth
= (pi * r) / 4
我的 = (55 * 3.1415) / 4 = 43
(约)
我将半径设为55,因为齿的半径为4px,距齿轮周长1px。
为了对齐顶部和底部直线输送机,它们需要按其距离的任意倍数进行平移。对于我的装备,我将它们翻译为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);}
}
&#13;
<div class="rect"></div>
<div class="left"></div>
<div class="right"></div>
&#13;
...带齿轮。链条目前点缀虚线!
<强> 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);}
}
&#13;
<div class="rect"></div>
<div class="left"></div>
<div class="right"></div>
<div class="cover"></div>
<div class="gear"></div>
<div class="gear2"></div>
&#13;
.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;
}
&#13;
<div class="rect"></div>
<div class="left"></div>
<div class="right"></div>
<div class="cover"></div>
<div class="gear"></div>
<div class="gear2"></div>
<div class="gear3"></div>
&#13;
<强> FIDDLE - ROUNDED TEETH 强>
注意:要提高动画的速度,您只需减少每个元素的动画持续时间按比例。
答案 3 :(得分:15)
这是关于如何使用CSS实现cog动画的不同方法。此方法已在IE11,IE10,Firefox,Chrome,Opera和Safari中进行了测试。
box-shadow
的齿轮/齿轮的两个圆形元件,以产生内圆。牙齿是由围绕轴线旋转的子元素(正常+伪)产生的。
.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>
奖励:这是带有开/关开关的整个动画:)单击(拉)链柄以打开或关闭动画。
.container {
position: relative;
}
.chain {
margin: 45px 100px;
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;
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 .spokes:after,
.belt-after .spokes,
.belt-after .spokes:before,
.belt-after .spokes:after {
content: '';
}
.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 {
position: absolute;
top: 5px;
height: 90px;
width: 90px;
border-radius: 100%;
-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, inset 0px 0px 0px 40px white, inset 0px 0px 0px 50px tomato;
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 {
position: absolute;
left: -91px;
top: -20px;
height: 50px;
width: 50px;
border-radius: 50%;
-webkit-animation: borderAnim 8s 0.4s infinite linear;
-moz-animation: borderAnim 6s infinite linear;
animation: borderAnim 6s infinite linear;
-webkit-animation-direction: reverse;
-moz-animation-direction: reverse;
animation-direction: 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;
}
}
#pull-switch {
display: none;
/* no need to display checkbox */
}
#switch {
position: absolute;
left: 77px;
top: 50px;
border-right: 2px dotted tomato;
height: 200px;
width: 15px;
-webkit-transition: height 0.5s;
-moz-transition: height 0.5s;
transition: height 0.5s;
z-index: 10;
}
#handle {
display: block;
position: absolute;
/* left: width of chain div (15px) + half of border (1px) - radius of handle (8px)*/
left: 8px;
bottom: 0%;
background-color: tomato;
width: 16px;
height: 16px;
border-radius: 50%;
cursor: pointer
}
#pull-switch:checked + #switch > #handle {
background-color: seagreen;
}
#pull-switch:checked + #switch {
height: 225px;
border-color: seagreen;
}
#pull-switch ~ .chain .gear-small,
#pull-switch ~ .chain .belt,
#pull-switch ~ .chain .belt-after,
#pull-switch ~ .chain .gear,
#pull-switch ~ .chain {
-webkit-animation-play-state: paused;
-moz-animation-play-state: paused;
animation-play-state: paused;
}
#pull-switch:checked ~ .chain .gear-small,
#pull-switch:checked ~ .chain .belt,
#pull-switch:checked ~ .chain .belt-after,
#pull-switch:checked ~ .chain .gear,
#pull-switch:checked ~ .chain {
-webkit-animation-play-state: running;
-moz-animation-play-state: running;
animation-play-state: running;
}
#pull-switch:checked ~ .chain .belt + .gear,
#pull-switch:checked ~ .chain .belt-after + .gear {
box-shadow: inset 0px 0px 0px 30px gray, inset 0px 0px 0px 40px white, inset 0px 0px 0px 50px seagreen;
}
<div class="container">
<input type="checkbox" id="pull-switch" />
<div id="switch">
<label for="pull-switch" id="handle"></label>
</div>
<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>
</div>
原始答案:(由于虚线边框错误而无法在Firefox上运行,并且破折号在IE中更接近使其看起来很丑陋)。
您可以使用以下组合来实现边框旋转动画:
border-radius: 50%
),两边都有虚线边框,以形成边框的弯曲部分。linear-gradient
进行模仿。该元素的背景(顶部和底部的渐变除外)是纯色,这是一种缺点。这种纯色用于隐藏两侧的圆形元素的一半。background-position
。box-shadow
生成。齿轮旋转的方式是链条的边界始终位于齿轮的边界之间。
.chain {
margin: 45px auto;
height: 100px;
width: 300px;
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: 30px 5px;
background-repeat: repeat-x;
background-position: 0px 0px, 5px 95px;
-webkit-animation: bgPos 4s infinite linear;
-moz-animation: bgPos 4s infinite linear;
animation: bgPos 4s infinite linear;
}
.chain .before,
.chain .after {
position: absolute;
content: '';
height: 90px;
width: 90px;
top: 0px;
border-radius: 50%;
border: 5px dashed gold;
-webkit-animation: borderAnim 2s infinite linear;
-moz-animation: borderAnim 2s infinite linear;
animation: borderAnim 2s infinite linear;
z-index: -2;
}
.chain .before {
left: -45px;
}
.chain .after {
right: -45px;
}
.chain .gear {
content: '';
position: absolute;
top: 0px;
height: 90px;
width: 90px;
border-radius: 50%;
border: 5px dashed gray;
-webkit-transform: rotate(16deg);
-moz-transform: rotate(16deg);
transform: rotate(16deg);
-webkit-animation: gearAnim 2s infinite linear;
-moz-animation: gearAnim 2s infinite linear;
animation: gearAnim 2s infinite linear;
box-shadow: inset 0px 0px 0px 30px gray;
z-index: 4;
}
.chain .before + .gear {
left: -45px;
}
.chain .after + .gear {
right: -45px;
}
.gear-small {
content: '';
position: absolute;
left: -95px;
top: -23px;
height: 60px;
width: 60px;
border-radius: 50%;
border: 3px dashed gray;
-webkit-transform: rotate(16deg);
-moz-transform: rotate(16deg);
transform: rotate(16deg);
-webkit-animation: gearAnim 6s infinite linear reverse;
-moz-animation: gearAnim 6s infinite linear reverse;
animation: gearAnim 6s infinite linear reverse;
box-shadow: inset 0px 0px 0px 20px gray;
z-index: -2;
}
@-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: 610px 0px, 0px 95px;
}
100% {
background-position: 0px 0px, 600px 95px;
}
}
@-moz-keyframes bgPos {
0% {
background-position: 610px 0px, 0px 95px;
}
100% {
background-position: 0px 0px, 600px 95px;
}
}
@keyframes bgPos {
0% {
background-position: 610px 0px, 0px 95px;
}
100% {
background-position: 0px 0px, 600px 95px;
}
}
@-webkit-keyframes gearAnim {
0% {
-webkit-transform: rotate(376deg);
}
100% {
-webkit-transform: rotate(16deg);
}
}
@-moz-keyframes gearrAnim {
0% {
-moz-transform: rotate(376deg);
}
100% {
-moz-transform: rotate(16deg);
}
}
@keyframes gearAnim {
0% {
transform: rotate(376deg);
}
100% {
transform: rotate(16deg);
}
}
<div class="chain">
<div class="gear-small"></div>
<div class="before"></div>
<div class="gear"></div>
<div class="after"></div>
<div class="gear"></div>
</div>
最后但并非最不重要的是,我仍然建议使用SVG方法,因为超过某一点,这样的CSS动画会变得非常混乱:)
答案 4 :(得分:4)
您可以尝试编辑cog,以便更好地适应而不是调整div边界以落在cog上。它比css更容易操作图形。
从那里可能会分为三个或四个部分的分割链动画,以使其更加健壮。
然后你可以调整齿轮和链条的速度来匹配,隐藏一半的链条,加上它只有顶部和底部边框div,并做同样但另一端相反。 (使用cliping,position和z-index)。
这样的事情:
至少在理论上,这将是我的方法(更不用说我会使用JS而不是这个工作流程。)
答案 5 :(得分:3)
形状(齿轮和链条)和行进蚂蚁动画效果(虚线边框)也可以通过使用Canvas绘图来实现。浏览器对Canvas的支持是quite good。
虽然Canvas的缺点是基于光栅(与基于形状的SVG相反),但只要画布没有缩放太大,它就不是一个大问题。在处理大量对象和实时动画时,画布应该会更好。 Here是MSDN上有关何时使用Canvas或SVG的有趣文章。
以下是此动画中涉及的关键部分/形状:
链:通过绘制两条水平线(使用lineTo
命令)创建链,这两条水线在两端连接半圆(使用arc
命令绘制) 。通过对笔划使用setLineDash
方法来实现虚线边框效果。 setLineDash
方法有两个参数,第一个表示短划线的长度,第二个表示短划线之间的间隙。
下面的代码段显示了创建链所需的最少代码:
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>
Cogs :所有三个齿轮(左,右和上)都是使用相同的命令实现的,唯一的区别是它们在屏幕上的定位(以及顶部的半径)。
齿轮的辐条或齿是使用arc
命令创建的(就像链的半圆一样),并使用相同的半径。调整它们的lineDashoffset
,使它们占据链条破折号之间留下的确切空间。
齿轮的主体由两个圆圈组成,外圈的半径大于内圈。 evenodd
fill参数用于仅在外圆上设置背景颜色(此示例中为tan
),并使内部颜色保持透明。
下面的代码段显示了创建cogs所需的最少代码:
window.onload = function() {
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var cog = {
paint: function(x, y, r, offset) {
ctx.beginPath();
ctx.arc(x, y, r, 0, Math.PI * 2, true);
ctx.closePath();
ctx.lineWidth = 5;
ctx.setLineDash([12, 14.16]);
ctx.lineDashOffset = offset;
ctx.strokeStyle = 'tan';
ctx.stroke();
ctx.beginPath();
ctx.arc(x, y, (r - 2), 0, Math.PI * 2, true);
ctx.arc(x, y, (r / 2.5), 0, Math.PI * 2, true);
ctx.closePath();
ctx.fillStyle = 'tan';
ctx.fill('evenodd');
}
};
function paint() {
var cog_radius = 50;
var cog_t_x = 30,
cog_t_y = 40,
cog_t_offset = 20.5,
cog_l_x = 75,
cog_l_y = 100,
cog_l_offset = 24.25,
cog_r_x = 533,
cog_r_offset = 11.25;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.save();
cog.paint(cog_t_x, cog_t_y, (cog_radius / 2), cog_t_offset);
ctx.restore();
ctx.save();
cog.paint(cog_l_x, cog_l_y, cog_radius, cog_l_offset);
ctx.restore();
ctx.save();
cog.paint(cog_r_x, cog_l_y, cog_radius, cog_r_offset);
ctx.restore();
}
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>
通过在动画的每一帧中移动笔画的lineDashOffset
来实现动画。动画本身是使用window.requestAnimationFrame
方法触发的,该方法定期调用绘制函数(作为参数传递)。回调率通常为每秒60次(引用MDN)。在画布的每次重绘过程中移动偏移都会使其外观呈现动画效果。
可以通过调用cancelAnimationFrame
方法随时停止动画。这可以基于某些用户交互(例如点击,悬停等)或基于超时来完成。
window.onload = function() {
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var anim, onState = false,
counter = 0;
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();
}
};
function paint(type) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
chain.offset += (6.54 / 10);
ctx.save();
chain.paint();
ctx.restore();
if (type) {
anim = window.requestAnimationFrame(function() {
paint(type);
})
}
}
paint(true);
}
/* 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>
将所有部分放在一起,下面的代码片段提供链和齿轮的完整图片以及动画:
window.onload = function() {
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var anim, onState = false,
counter = 0;
var cog_radius = 50;
var cog_t_x = 30,
cog_t_y = 40,
cog_t_offset = 20.5,
cog_l_x = 75,
cog_l_y = 100,
cog_l_offset = 24.25,
cog_r_x = 533,
cog_r_offset = 11.25;
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();
}
};
var cog = {
paint: function(x, y, r, offset) {
ctx.beginPath();
ctx.arc(x, y, r, 0, Math.PI * 2, true);
ctx.closePath();
ctx.lineWidth = 5;
ctx.setLineDash([12, 14.16]);
ctx.lineDashOffset = offset;
ctx.strokeStyle = 'tan';
ctx.stroke();
ctx.beginPath();
ctx.arc(x, y, (r - 2), 0, Math.PI * 2, true);
ctx.arc(x, y, (r / 2.5), 0, Math.PI * 2, true);
ctx.closePath();
ctx.fillStyle = 'tan';
ctx.fill('evenodd');
}
};
function paint(type) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
chain.offset += (6.54 / 10);
cog_l_offset -= (6.54 / 10);
cog_r_offset -= (6.54 / 10);
cog_t_offset += (6.54 / 10);
ctx.save();
cog.paint(cog_t_x, cog_t_y, (cog_radius / 2), cog_t_offset);
ctx.restore();
ctx.save();
chain.paint();
ctx.restore();
ctx.save();
cog.paint(cog_l_x, cog_l_y, cog_radius, cog_l_offset);
ctx.restore();
ctx.save();
cog.paint(cog_r_x, cog_l_y, cog_radius, cog_r_offset);
ctx.restore();
if (type) {
anim = window.requestAnimationFrame(function() {
paint(type);
})
}
}
paint(true);
}
/* 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>
如前所述,还可以使用事件侦听器(addEventListener
)添加用户交互。如果需要通过用户对画布的特定形状或部分的操作触发操作,则可以使用pointInPath
方法来验证该点是否在画布的必需部分内。
Here是CodePen演示的链接,它还添加了这些用户交互(以及其他一些额外的东西)。
注意:有关如何添加用户交互等的说明超出了此特定答案的范围。但是,如果您需要任何帮助,可以在this chat room。
找到我