第一步,圆形的 SVG shape - <circle>
- SVG 中基本的形状(basis shape)有 circle、ellipse、line、ploygon、polyline、rect,环形进度条的展示在这里使用的是 circle;
- SVG 使用 x, y, width, height 来定义自身在页面上的 viewport,配合 viewbox 属性,来对内部子元素的单位进行计算,以上面 circle 为例,( svg 的 viewport 中 width / viewbox 中的 width )等于 200 / 200 = 1,这里是故意设置,不等于 1 的情况比比皆是,而且需要明确这里 1 是不带单位,是一个计算出的比例值1;
- circle 元素上的
cx
、cy
属性分别指定 circle 的位置,r 代表 circle 的半径距离,例子中外层的 svg 的width
和height
都是 200,circle 的cx
和cy
都是 100 所以 circle 正好居中,同时r
半径为 80; stroke
和stroke-width
分别代表描边颜色和描边粗细,fill
代表 circle 整个的填充色, 例子中为无。
第二步,描边点状化
stroke-dasharray
属性,可以将图形的描边进行「点状化」,这里需要理解的是,「点状化」的「点」,其大小是可以设置的,并不真的就是那么一个「·」,可以变长或者变短。上面例子中的三个 circle 分别设置stroke-dasharray
为 10,50,100;- 所以如果 circle 的点的长度正好等于 circle 边长,那么「点」看上去就是 circle 的边。
第三步,动起来(使用 stroke-dashoffset 抵消一个长度很长的「点」)
stroke-dashoffset
可以使上一步中使用stroke-dasharray
生成的「点」沿着 path 移动;- 想象一个足够长的「点」+ 足够长的「offset」。比如
stroke-dashoffset
设置成 1000,元素的描边就不会显示,上面的例子中,三个 circle 的stroke-dasharray
分别为 100,500,1000,stroke-dashoffset 都是 1000,配合 animation 从 1000 运动到 0; - circle 描边的「起始位置」在 circle 在 3 点钟方向,使用
transform: rotate()
逆时针旋转 90 度使「起始位置」定位到 12 点方向。
第四步,根据半径计算周长
auto animation
control stroke-dashoffset using JavaScript
- 为了配合 CSS 中
transition
中的各种 easing 效果,不要直接在<circle>
元素上设置stroke-dasharray
和storke-dashoffset
,以 CSS 中对应的值代替。 - 同时 JavaScript 的控制的时候,应使用
el.style.storkeDash = val
的方式,而不是el.setAttribute()
,分别写作el.style.strokeDasharray
和el.style.strokeDashoffset
,array
的a
和offset
的o
都不需要大写。 - 同时由于 offset 值是通过 JavaScript 计算得到,考虑通过 JavaScript 设置元素的 transition 值,避免 page load 的过程中元素发生动画;或者 CSS 默认给一个绝对大的值。
- 第四部第二个根据
input[range]
来演示的例子中,input
的值从 0 到 100 变化,step 是 1,stroke-dashoffset
对应的变化的值的公式就是len - (range_value / 100) * len
。
参考、以及衍生阅读
更多参考:《SVG 快速入门 - 基本概念》 ↩︎
你们好,
2018 年初把小站从 Jekyll 迁移到 Hugo 的过程中,删除了评论区放的 Disqus 插件,考虑有二:首先无论评论、还是对笔记内容的进一步讨论,读者们更喜欢通过邮件、或者 Twitter 私信的方式来沟通;其次一年多以来
Disqus 后台能看到几乎都是垃圾留言(spam),所以这里直接贴一下邮件、以及 Twitter 账户 地址。
技术发展迭代很快,所以这些笔记内容也有类似新闻的时效性,不免有过时、或者错误的地方,欢迎指正 ^_^。
BEST
Lien(A.K.A 胡椒)
技术发展迭代很快,所以这些笔记内容也有类似新闻的时效性,不免有过时、或者错误的地方,欢迎指正 ^_^。
BEST
Lien(A.K.A 胡椒)