简体   繁体   English

沿矩形路径平滑移动 SVG 线

[英]Smoothly move an SVG line along a rectangular path

I am trying to recreate the following animation:我正在尝试重新创建以下动画:

在此处输入图片说明

I am having trouble with getting a line to properly animate around corners.我在获得一条线以正确地在拐角处设置动画时遇到了麻烦。 I've tried using an animateMotion-element like so:我试过使用 animateMotion 元素,如下所示:

<line class="testLine" x1="10" y1="10" x2="100" y2="10" stroke="white"> 
        <animateMotion dur="1.6s" repeatCount="indefinite" 
            path="M 10 10 L 390 10
             M 390 10 L 390 290
             M 390 290 L 10 290
             M 10 290 L 10 10"> 
        </animateMotion>
</line> 

But the line is not smoothly rounding corners.但线条不是圆滑的圆角。 Any idea on how to get it to make it move smoothly around corners as shown in the GIF?关于如何让它在拐角处平滑移动的任何想法,如 GIF 所示?

You will need to create a path with srtoke-dasharray = 1/2 of the side of the rect and animate the stroke-dashoffset of the path to 0您将需要使用 srtoke-dasharray = 1/2 矩形边的路径创建路径,并将路径的 stroke-dashoffset 设置为 0

Please read the comments in the code:请阅读代码中的注释:

 const SVG_NS = "http://www.w3.org/2000/svg"; let sz = 50;//initial size 1/2 rect side //the array of the paths. Inside the array uou have a first object for the path #p let sqRy = [{ s: sz, d: "", l: p.getTotalLength(), el: p }]; //create several paths and rotate those paths accordingly for (let i = 1; i < 8; i++) { let o = {}; let size = sqRy[i - 1].s / 2; os = Math.sqrt(2 * size * size); //the value od the d attribute of the new path od = `M-${os},-${os}L${os},-${os} ${os},${os} -${os},${os} -${os},-${os}z`; o.el = document.createElementNS(SVG_NS, "path"); o.el.setAttribute("d", od);//set the d attribute o.el.setAttribute("transform", `rotate(${45 * i})`);//set the rotation svg.appendChild(o.el);//append the new path to the svg element ol = o.el.getTotalLength();//calculate the total length of the new path //push the object for the path to the array sqRy.push(o); } //for every element in the array set the stroke-dasharray and the stroke-dashoffset. sqRy.map((sq) => { sq.el.setAttribute("style", `stroke-dasharray:${sq.s};stroke-dashoffset:${sq.l}`); });
 svg{fill:none;stroke:black;} path{ animation: dash 16s linear infinite; } @keyframes dash { to { stroke-dashoffset: 0; } }
 <svg width="300" viewBox="-60 -60 120 120" id="svg"> <path id="p" d="M-50,-50L50,-50 50,50 -50,50 -50,-50z" /> </svg>

Same thing just scale rotate and square's diaginal multiplier - sqrt(2)同样的事情只是缩放旋转和平方的对数乘数 - sqrt(2)

 document.querySelector('svg').innerHTML = [...Array(11)] .map((_, i) => Math.pow(2, i/2)) .map((s, i) => ` <path transform="scale(${s})rotate(${i*45})" stroke-width="${2/s}" d="m5,5h-10v-10h10z"></path> `).join(',');
 path { stroke-dasharray: 5 5; fill: none; stroke: black; animation: shift 3s infinite linear; } @keyframes shift { 100% {stroke-dashoffset: -20} }
 <svg viewBox='-200,-200,400,400' width="90vw" height="90vh"></svg>

Not a calculated one but by aligning svg rectangle(prefer svg path) using svg attribute transform and making use of css stroke-dasharray and stroke-offset for animating, the result can be obtained不是计算出来的,而是通过使用 svg 属性变换对齐 svg 矩形(首选 svg 路径)并利用 css stroke-dasharray 和 stroke-offset 进行动画处理,可以获得结果

if js is not an option then you can just add and align the rectangles you need如果 js 不是一个选项,那么你可以添加和对齐你需要的矩形

CODE代码

 svg>rect { stroke-dasharray: 100; -webkit-animation: draw 5s infinite linear; /* Chrome, Safari, Opera */ animation: draw 5s infinite linear; } @keyframes draw { to { stroke-dashoffset: 1000; } } @-moz-keyframes draw { to { stroke-dashoffset: 1000; } } @-webkit-keyframes draw { to { stroke-dashoffset: 1000; } }
 <svg width="500" height="500"> <rect width="300" height="300" style="fill:none;stroke-width:2;stroke:black" /> <rect width="210" height="210" transform='translate(150 1) rotate(45)' style="fill:none;stroke-width:2;stroke:black" /> <rect width="150" height="150" transform='translate(75 75)' style="fill:none;stroke-width:2;stroke:black" /> </svg>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM