小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
实现步骤
-
引入svg.js(一个使用
js写svg的库),绘制一个折线图
<!DOCTYPE html> <html> <head> <title>SVG.js</title> <script src="https://cdn.jsdelivr.net/npm/@svgdotjs/svg.js@3.0/dist/svg.min.js"></script> <style> #drawing { width: 1000px; height: 500px; background: #399979; margin-left: 100px; margin-top: 100px; } </style> </head> <body> <div id="drawing"></div> </body> </html> <script> let draw = SVG().addTo('#drawing').size('100%', '100%') draw.viewbox('0 0 100 100') let path = draw.path('M10 10 L40 10 40 20 80 20').fill('none').attr({stroke: '#cfcfcf', 'stroke-width': 0.3}) </script> -
使用
stroke-dasharray属性,值分别为2、6效果// js path.attr({'stroke-dasharray': 2})// js path.attr({'stroke-dasharray': 6}) -
获取
path长度,如果stroke-dasharray不断增加,直到刚好等于path长度,整个图形被这一段虚线覆盖,效果相当于初始化图形一样。但是实际上只是虚线的一段。此时再结合stroke-dashoffset属性配合CSS动画,即可添加动画效果- 这里
stroke-dashoffset的意义是:dash模式到路径开始的距离。初始化值如果大于0,可以理解为以绘制好的dash模式的path包括可见和不可见部分为参照,路径往右移动了一定距离(所以,此时添加keyframe,值从大于0变为0时,路径就像自我描绘一样的动画效果)。如果stroke-dashoffset小于0,路径往左移动了一定距离。这个决定了动画效果的运动轨迹方向。
<style> .path { animation: drawPath 3s infinite; } </style> <script> path.addClass("path") let pathLength = path.length() path.attr({'stroke-dasharray': pathLength, 'stroke-dashoffset': pathLength}) var keyFrames = `@keyframes drawPath { 0% { stroke-dashoffset: ${pathLength} } 100% { stroke-dashoffset: 0; } }` createKeyframes(keyFrames) // 动态添加style方法 const getStyleElement = () => { let style = document.querySelector('style#dynamic-keyframes') if (!style) { style = document.createElement('style') style.id = 'dynamic-keyframes' style.type = 'text/css' document.getElementsByTagName('head')[0].appendChild(style) } return style } const createKeyframes = (keyframeString) => { let style = getStyleElement() style.insertAdjacentHTML('beforeend', keyframeString) } </scritp> - 这里
总结
- 可以直接使用现成的
svg和css实现类似动画效果。使用js是为了可以精确计算path的长度,动态设置stroke-dashoffset和stroke-dasharray的值,因为实际场景中,path长度不固定 stroke-dashoffset的运动轨迹的方向由初始值决定- 路径动画实际上是
path的dash模式下,偏移量offset的运动过程