我有一系列圆圈,边框由较小的圆圈组成,我称之为'圆点'。然后我用CSS3的transform
旋转它们来动画圆圈,每个旋转5或15度(交替),比起最后一个不旋转的中间圆圈开始。这种度数的交替是由于5deg
动画本身效果很好,但圆圈中每个点之间的偏移不一致。当动画完成时,这一点很明显,一些点跳回来。如果它们都是一致的数量,那么在我的计算中它将是一个错误,但是同一个圆圈周围的点会跳出不同的数量,这意味着它们会以不同的数量偏移开始。 Vals在他的答案结尾处的示例中也显示了偏移
中的这种不一致性以下是每个圆圈的设置方法。每个点之间的间距通过使用公式spacing = (radius × 2) × 3.14159265 ÷ numberOfCircles
确定。 .001
允许Chrome看到点
<circle cx="30" cy="30" r="radius" stroke-dasharray="0.001, spacing" stroke="color"/>
任何人都可以帮我解决这个SVG渲染偏移错误吗?
修改
vals和squeamish ossifrage都提供了奇妙的解决问题的替代解决方案。但是,如果可能的话,我仍然希望实际修复偏移/渲染问题答案 0 :(得分:5)
我认为您的设置中存在2个轻微错误。
第一个是点的间距是stroke-dash数组的2个参数的总和。由于第一个参数始终为0.001,因此第二个参数应为公式减去0.001的结果。
第二个是你在圆圈周围放置36个点。从点到点的角度给出10度。因此,你的动画应该特定10deg,20deg,30deg为系列,而不是15deg 30deg 45deg ......这会在每个周期结束时产生5度的跳跃。
我认为我或多或少都在工作
初始轮换也存在问题;我希望现在这就是你想要的。
而且,由于svg的小尺寸,还有一些圆形;将它设置为600平方的效果要好得多。
我还在10度处添加了一条线来检查点的正确对齐。
CSS
body {
background: black;
padding: 0;
margin: 0;
}
circle {
fill: none;
stroke-width: 10;
stroke-linecap: round;
}
circle { -webkit-transform-origin: center center; -moz-transform-origin: center center; transform-origin: center center;
-webkit-animation-duration: 3s;
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-iteration-count: infinite;}
circle:nth-child(2) { -webkit-animation-name:second;
-moz-animation:second 3s ease-in-out infinite;
animation:second 3s ease-in-out infinite;}
circle:nth-child(3) { -webkit-animation-name:third; -moz-animation:third 3s ease-in-out infinite; animation:third 3s ease-in-out infinite; }
circle:nth-child(4) { -webkit-animation-name:fourth; -moz-animation:fourth 3s ease-in-out infinite; animation:fourth 3s ease-in-out infinite; }
circle:nth-child(5) { -webkit-animation-name:fifth; -moz-animation:fifth 3s ease-in-out infinite; animation:fifth 3s ease-in-out infinite; }
circle:nth-child(6) { -webkit-animation-name:sixth; -moz-animation:sixth 3s ease-in-out infinite; animation:sixth 3s ease-in-out infinite; }
circle:nth-child(7) { -webkit-animation-name:seventh; -moz-animation:seventh 3s ease-in-out infinite; animation:seventh 3s ease-in-out infinite; }
circle:nth-child(8) { -webkit-animation-name:eighth; -moz-animation:eighth 3s ease-in-out infinite; animation:eighth 3s ease-in-out infinite; }
circle:nth-child(9) { -webkit-animation-name:ninth; -moz-animation:ninth 3s ease-in-out infinite; animation:ninth 3s ease-in-out infinite; }
circle:nth-child(10) {
-webkit-animation-name:tenth;
-moz-animation:tenth 3s ease-in-out infinite;
animation:tenth 3s ease-in-out infinite;
-webkit-transform: rotate(10deg);}
@-webkit-keyframes second { 0% { -webkit-transform:rotate(5deg) }
100% { -webkit-transform:rotate(15deg) } }
@-webkit-keyframes third { 100% { -webkit-transform:rotate(20deg) } }
@-webkit-keyframes fourth { 0% { -webkit-transform:rotate(5deg) }
100% { -webkit-transform:rotate(35deg) } }
@-webkit-keyframes fifth { 100% { -webkit-transform:rotate(40deg) } }
@-webkit-keyframes sixth { 0% { -webkit-transform:rotate(5deg) }
100% { -webkit-transform:rotate(55deg) } }
@-webkit-keyframes seventh {100% { -webkit-transform:rotate(60deg) } }
@-webkit-keyframes eighth { 0% { -webkit-transform:rotate(5deg) }
100% { -webkit-transform:rotate(75deg) } }
@-webkit-keyframes ninth { 0% { -webkit-transform:rotate(0deg) }
100% { -webkit-transform:rotate(80deg) } }
@-webkit-keyframes tenth { 0% { -webkit-transform:rotate(5deg) }
100% { -webkit-transform:rotate(95deg) } }
@-moz-keyframes second { 0% { -moz-transform:rotate(5deg) }
100% { -moz-transform:rotate(15deg) } }
@-moz-keyframes third { 100% { -moz-transform:rotate(20deg) } }
@-moz-keyframes fourth { 0% { -moz-transform:rotate(5deg) }
100% { -moz-transform:rotate(35deg) } }
@-moz-keyframes fifth { 100% { -moz-transform:rotate(40deg) } }
@-moz-keyframes sixth { 0% { -moz-transform:rotate(5deg) }
100% { -moz-transform:rotate(55deg) } }
@-moz-keyframes seventh { 100% { -moz-transform:rotate(60deg) } }
@-moz-keyframes eighth { 0% { -moz-transform:rotate(5deg) }
100% { -moz-transform:rotate(75deg) } }
@-moz-keyframes ninth { 100% { -moz-transform:rotate(80deg) } }
@-moz-keyframes tenth { 0% { -moz-transform:rotate(5deg) }
100% { -moz-transform:rotate(95deg) } }
line {
stroke-width: 1;
-webkit-transform-origin: left center;
-webkit-transform: rotate(-10deg);
}
还优化了一些风格
好吧,经过大量时间花在这个问题上,我几乎可以肯定某种舍入/精确度存在某种错误。
我完全改变了这个想法以避免这个问题。目标是在结束动画之前让圆圈成为圆圈,这样动画的开头和结尾始终是同步的。
由于这会产生巨大的关键帧样式,我想重用它;为了达到这个目的,我以嵌套的方式对圆圈进行了分组;并将动画应用于每个组:
HTML
<svg viewBox="0 0 60 60">
<g class="g">
<circle cx="30" cy="30" r="10" stroke-dasharray="0.001, 1.745" stroke="hsl(120, 100%, 50%)"/>
<g class="g">
<circle cx="30" cy="30" r="12" stroke-dasharray="0.001, 2.094" stroke="hsl(108, 100%, 50%)" class="c2"/>
<g class="g">
<circle cx="30" cy="30" r="14" stroke-dasharray="0.001, 2.443" stroke="hsl(96, 100%, 50%)"/>
<g class="g">
<circle cx="30" cy="30" r="16" stroke-dasharray="0.001, 2.793" stroke="hsl(84, 100%, 50%)" class="c2"/>
<g class="g">
<circle cx="30" cy="30" r="18" stroke-dasharray="0.001, 3.142" stroke="hsl(72, 100%, 50%)"/>
<g class="g">
<circle cx="30" cy="30" r="20" stroke-dasharray="0.001, 3.491" stroke="hsl(60, 100%, 50%)" class="c2"/>
<g class="g">
<circle cx="30" cy="30" r="22" stroke-dasharray="0.001, 3.840" stroke="hsl(48, 100%, 50%)"/>
<g class="g">
<circle cx="30" cy="30" r="24" stroke-dasharray="0.001, 4.189" stroke="hsl(36, 100%, 50%)" class="c2"/>
<g class="g">
<circle cx="30" cy="30" r="26" stroke-dasharray="0.001, 4.538" stroke="hsl(24, 100%, 50%)"/>
<g class="g">
<circle cx="30" cy="30" r="28" stroke-dasharray="0.001, 4.887" stroke="hsl(12, 100%, 50%)" class="c2"/>
</g></g></g></g></g></g></g></g></g></g>
</svg>
(是的,回到低分辨率!)
CSS
body {
background: black;
padding: 0;
margin: 0;
}
circle {
fill: none;
stroke-width: 1;
stroke-linecap: round;
}
.g {
-webkit-transform-origin: center center; -moz-transform-origin: center center; transform-origin: center center;
-webkit-animation-duration: 108s;
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-iteration-count: infinite;
-webkit-animation-name: anim;
-moz-animation:second 3s ease-in-out infinite;
animation:second 3s ease-in-out infinite;}
.c2 {
-webkit-transform-origin: center center;
-webkit-transform: rotate(5deg);
}
@-webkit-keyframes anim { 0% { -webkit-transform:rotate(0deg)}
2.778% { -webkit-transform:rotate(10deg)}
5.56% { -webkit-transform:rotate(20deg)}
8.33% { -webkit-transform:rotate(30deg)}
11.11% { -webkit-transform:rotate(40deg)}
13.89% { -webkit-transform:rotate(50deg)}
16.67% { -webkit-transform:rotate(60deg)}
19.44% { -webkit-transform:rotate(70deg)}
22.22% { -webkit-transform:rotate(80deg)}
25% { -webkit-transform:rotate(90deg)}
27.78% { -webkit-transform:rotate(100deg)}
30.56% { -webkit-transform:rotate(110deg)}
33.33% { -webkit-transform:rotate(120deg)}
36.11% { -webkit-transform:rotate(130deg)}
38.89% { -webkit-transform:rotate(140deg)}
41.67% { -webkit-transform:rotate(150deg)}
44.44% { -webkit-transform:rotate(160deg)}
47.22% { -webkit-transform:rotate(170deg)}
50% { -webkit-transform:rotate(180deg)}
52.78% { -webkit-transform:rotate(190deg)}
55.56% { -webkit-transform:rotate(200deg)}
58.33% { -webkit-transform:rotate(210deg)}
61.11% { -webkit-transform:rotate(220deg)}
63.89% { -webkit-transform:rotate(230deg)}
66.67% { -webkit-transform:rotate(240deg)}
69.44% { -webkit-transform:rotate(250deg)}
72.22% { -webkit-transform:rotate(260deg)}
75% { -webkit-transform:rotate(270deg)}
77.78% { -webkit-transform:rotate(280deg)}
80.56% { -webkit-transform:rotate(290deg)}
83.33% { -webkit-transform:rotate(300deg)}
86.11% { -webkit-transform:rotate(310deg)}
88.89% { -webkit-transform:rotate(320deg)}
91.67% { -webkit-transform:rotate(330deg)}
94.44% { -webkit-transform:rotate(340deg)}
97.22% { -webkit-transform:rotate(350deg)}
100% { -webkit-transform:rotate(360deg)}
}
new demo (抱歉,只有webkit)
这是我尝试调查错误。我改变了系统,而不是动画,我有两组圆圈,一组是彩色的,另一组是黑色的,旋转了10度。色圈不应该显示;偏移量是衡量误差的一个指标。 (可能需要滚动查看圆圈
答案 1 :(得分:2)
我认为这里的问题是虚线绘制算法使用线条长度的快速近似,而不是沿着每个线段实际积分路径长度,这可能会非常慢。
如果您将点绘制为单个圆而不是使用虚线,则此问题就会消失。以下PHP脚本将为您进行计算:
<svg viewBox="0 0 60 60">
<g transform="translate(30,30)">
<?php
define("PI",3.141592654);
for ($i=0; $i<10; $i++) {
$r = 10 + 2 * $i;
$hue = 120 - 12 * $i;
echo "<g id=\"ring_$i\">\n";
for ($th=0; $th<360; $th+=10) {
$theta = ($th + 5 * $i) * PI / 180;
$x = $r * sin($theta);
$y = $r * cos($theta);
printf(" <circle cx=\"%.5f\" cy=\"%.5f\" r=\"0.45\" fill=\"hsl(%d,100%%,50%%)\"/>\n",$x,$y,$hue);
}
echo "</g>\n";
}
?></g>
</svg>
这是CSS(为简洁省略了特定于供应商的规则):
body { background: black; padding: 0; margin: 0; }
g#ring_0 { transform:rotate(5deg); }
g#ring_1 { animation:second 3s ease-in-out infinite; }
g#ring_2 { animation:third 3s ease-in-out infinite; }
g#ring_3 { animation:fourth 3s ease-in-out infinite; }
g#ring_4 { animation:fifth 3s ease-in-out infinite; }
g#ring_5 { animation:sixth 3s ease-in-out infinite; }
g#ring_6 { animation:seventh 3s ease-in-out infinite; }
g#ring_7 { animation:eighth 3s ease-in-out infinite; }
g#ring_8 { animation:ninth 3s ease-in-out infinite; }
g#ring_9 { animation:tenth 3s ease-in-out infinite; }
keyframes second { 100% { transform:rotate(10deg) } }
keyframes third { 100% { transform:rotate(20deg) } }
keyframes fourth { 100% { transform:rotate(30deg) } }
keyframes fifth { 100% { transform:rotate(40deg) } }
keyframes sixth { 100% { transform:rotate(50deg) } }
keyframes seventh { 100% { transform:rotate(60deg) } }
keyframes eighth { 100% { transform:rotate(70deg) } }
keyframes ninth { 100% { transform:rotate(80deg) } }
keyframes tenth { 100% { transform:rotate(90deg) } }
您可以在此处看到它:JSFiddle