醉美水芙蓉 发表于 2026-8-13 21:44:04

马黑黑《SVG动态模拟示波图》


<style>
    .artBox { margin: 20px auto; font: normal 18px/26px sans-serif; }
    .artBox p { margin: 10px 0; }
</style>

<div class="artBox">
    <p>实现原理:JS 动态生成 SVG path 元素 d 属性值,由 setTimeout、setInterval 定时器或 requestAnimationFrame(请求关键帧动画)或其它机制不断重绘 path 路径。下例 path 元素 d 属性值仅用到 M、H、L 三个绘图指令,代码有详尽说明,支持在线预览:</p>
    <div class="hEdiv" data-prev="1"><pre class="hEpre">
&lt;h1&gt;点击页面任意地方运行/暂停动画&lt;/h1&gt;
&lt;svg id="msvg" widt="800" height="400" viewBox="0 0 400 200" xmlns="http://www.w3.org/2000/svg"&gt;
    &lt;path id="p1" d="M0 100 H400" fill="none" stroke="green" stroke-width="4" stroke-dasharray="4" /&gt;
&lt;/svg&gt;

&lt;script&gt;
    var timeID, go = false; // timeID : 定时器标识、go : 动画开关

    // 页面点击事件
    document.onclick = () =&gt; {
      go = !go; // go开关取反
      draw(); // 执行draw 函数
    };
      
    function draw() {
      var tt = 15;// 路径节点总数
      var str = ''; // 路径字符串
      // 遍历节点、生成动态路径
      Array.from({length: tt}).forEach((_,k) =&gt; {
            var x = (k + 1) * (360 / tt); // 节点X坐标(360取值依据是viewBox宽度去头尾)
            // 节点Y坐标 :节点序列号被2整除定在Y轴中心,否则按viewBox高度值取随机值
            var y = k % 2 === 0 ? 100 : Math.floor(Math.random() * 200);
            // 拼接路径字串 :开始时是M指令,其余L指令
            str += k === 0 ? `M0 100 H${x}` : ` L${x} ${y}`;
      });
      var path = `${str}L400 100`; // 路径终点
      p1.setAttribute('d', path);// 给path d属性赋值
      // setTimeout定时器递归调用本函数 :根据 go 开关运行或取消动画
      go ? timeID = setTimeout(draw, 200) : cancelTimeout(timeID);
    }
&lt;/script&gt;
    </pre></div>
    <p>核心在于路径各个节点的算法及其路径字符串的拼接。上例仅是演示,可根据需求做相应调整。</p>
</div>

<script type="module">
    import hl from 'https://638183.freep.cn/638183/web/js/hl.js';
    const divs = document.querySelectorAll('.hEdiv');
    const pres = document.querySelectorAll('.hEpre');
    divs.forEach((div,idx) => hl.hl(div, pres));
</script>

klxf 发表于 7 天前

实用的教程,谢谢分享
页: [1]
查看完整版本: 马黑黑《SVG动态模拟示波图》