SVG stroke-dasharray偏移不一致 [英] SVG stroke-dasharray offset not consistent

查看:438
本文介绍了SVG stroke-dasharray偏移不一致的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一系列的圆圈,边框由较小的圆圈组成,我将称为圆点。然后我使用CSS3的 transform 旋转它们,每个旋转5或15度(交替)多于最后一个开始,中间的圆圈不旋转。这种交替的度数是由于它们中的一半原始偏移 5deg

I have a series of circles with borders comprised of smaller circles which I will call 'dots'. I am then animating the circles by rotating them with CSS3's transform, each by either 5 or 15 degrees (alternating) more than the last starting with the middle circle not rotating at all. This alternating of degrees is due to the original offset of half of them of 5deg

动画本身工作得很好,但圆中每个点之间的偏移不一致。这是明显的,当动画完成,一些点跳回。如果他们都是一致的金额,那么这将是一个错误在我的计算,但在同一个圆周的点跳跃不同的金额,这意味着他们偏移不同的金额开始。 Vals,在他的回答的结尾他的例子,也显示这种偏差的不一致。

The animation itself works great, but the offset between each dot in a circle is not consistent. This is made obvious when the animation completes, some dots jump back. If they were all off by a consistent amount then it would be an error in my calculations, but dots around the same circle jump different amounts, meaning that they are offset different amounts to begin with. Vals, in his example at the end of his answer, also shows this inconsistency in offset

这里是如何设置每个圆。通过使用公式 spacing =(radius×2)×3.14159265÷numberOfCircles 确定每个点之间的间距。 .001 是允许Chrome查看点

Here is how each circle is set up. The spacing in between each dot was determined by using the formula spacing = (radius × 2) × 3.14159265 ÷ numberOfCircles. The .001 is to allow Chrome to see the dots

<circle cx="30" cy="30" r="radius" stroke-dasharray="0.001, spacing" stroke="color"/>

这里是演示jsFiddle

任何人都可以帮我修复这个SVG渲染偏移量错误?

Can anyone help me fix this SVG rendering offset bug?

EDIT

vals和squeamish ossifrage都为这个问题提供了奇妙的替代解决方案。但是,我仍然希望实际修复偏移/渲染问题,如果这样的事情是可能的

vals and squeamish ossifrage both provided wonderfully working alternative solutions to the problem. However, I'm still looking to actually fix the offset/rendering issue if such a thing is possible

推荐答案

第一个是点的间距是stroke-dash数组的2个参数的总和。由于第一个参数总是0.001,第二个参数应该是您的公式减去0.001的结果。

The first is that the spacing of your dots is the sum of the 2 parameters to the stroke-dash array. Since the first parameter is always 0.001, the second one should be the result of your formula minus 0.001.

第二个参数是您围绕圆放置36个点。从点到点的角度为10度。所以,你的动画应该明确10deg,20deg,30deg的系列,而不是15deg 30deg 45deg ...在每个周期结束时创建一个5度的跳跃。

The second one is that you are placing 36 dots around the circle. That gives 10 degrees for the angle from dot to dot. So, your animations should specificy 10deg, 20deg, 30deg for the series, and not 15deg 30deg 45deg ... That creates a jump of 5 deg at the end of every cycle.

我认为我有或多或少工作

I think that I have it more or less working

初始轮播也有问题;我希望现在它是你想要的。

There was also an issue with the initial rotation; I hope that now it is what you wanted.

还有,由于svg的小尺寸,有一些舍入;设置为600平方的工作好多了。

And also, there was some kind of round up due to the small size of the svg; setting it to 600 square works much better.

我也在10度处添加了一行,以检查圆点的正确对齐。

I have also added a line at 10 deg to check the correct alignment of the dots.

/ p>

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);
}

还优化了一些样式

好吧,在花了很多时间花在这个问题后,我几乎可以肯定在某种舍入/精度中有某种错误。

Well, after a lot of time spent with that issue, I am almost sure that there is some kind of bug in some kind of rounding / precision.

我完全改变了主意,以避免这个问题。目标将是在结束动画之前使圆圈成为完整的圆圈,以便动画的开始和结束始终保持同步。

I have changed the idea fully to avoid this issue. The target will be to have the circles make full circles before ending the animation, so that the beginning and the end of the animation are always in sync.

由于这会生成一个巨大的关键帧风格,我想重用它;为了实现这一点,我以嵌套方式分组了圆圈;并将动画应用到每个组:

Since that generates an huge keyframes style, I want to reuse it; to achieve this I have grouped the circles in a nested way; and applied the animation to every group:

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>

(是的,回到低分辨率!)

(yes, back to the low resolution !)

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)}
}

并且 新演示

这是我尝试调查错误。我改变了系统,而不是动画,我有2套圆,一个颜色,另一个在黑色,它旋转10度。色圈不应显示;偏移是一种测量误差。 (可能需要滚动才能查看圈子

This is my attempt to investigate the errors. I have changed the system, instead of animation, I have 2 sets of circles, one in color and another in black over it, and rotated 10 deg. The color circles shouldn't show; the offset is a measure off the error. (may be you need to scroll to see the circles

抵消演示

这篇关于SVG stroke-dasharray偏移不一致的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆