SVG 线条旋转和动画
SVG line rotation and animation
我正在尝试在两点之间移动一条线。
为了只需要一个渐变,我使用 transform
.
旋转线条
详情见此:
现在,当我在线上应用动画时,它的行为很奇怪。
它不会靠近真正的目的地,我真的不明白发生了什么。
特别奇怪的是,如果我删除 rotate
转换,线条会转到正确的点(但显然它没有正确的渐变)。
<svg height="670.9" width="1920">
<defs>
<linearGradient y2="100%" x2="100%" y1="0%" x1="0%" id="linegradred">
<stop style="stop-color:#F70D1A;stop-opacity:0" offset="0%" />
<stop style="stop-color:#F70D1A;stop-opacity:0.3" offset="50%" />
<stop style="stop-color:#F70D1A;stop-opacity:0.8" offset="100%" />
</linearGradient>
</defs>
<circle cx="964" cy="426" r="4" stroke="black" fill="black" opacity="0.5" class="circle_loc"/>
<circle cx="924" cy="230" r="4" stroke="black" fill="black" opacity="0.5" class="circle_loc" />
<line class="svg_line_red" id="line_1442197044254" x1="964" y1="426" fill="url(#linegradred)" stroke="url(#linegradred)" x2="1030" y2="492" transform="rotate(-146.5346206536447 964 426)">
<animate attributeName="x1" attributeType="XML" to="924" fill="freeze" dur="1.1s" />
<animate attributeName="y1" attributeType="XML" to="230" fill="freeze" dur="1.1s" />
<animate attributeName="x2" attributeType="XML" to="924" fill="freeze" dur="1s" />
<animate attributeName="y2" attributeType="XML" to="230" fill="freeze" dur="1s" />
</line>
<circle cx="590" cy="344" r="4" stroke="black" fill="black" opacity="0.5" class="circle_loc" />
<circle cx="924" cy="230" r="4" stroke="black" fill="black" opacity="0.5" class="circle_loc" />
<line class="svg_line_red" id="line_1442197045251" x1="590" y1="344" fill="url(#linegradred)" stroke="url(#linegradred)" x2="707" y2="461" transform="rotate(-63.84566422168709 590 344)">
<animate attributeName="x1" attributeType="XML" to="924" fill="freeze" dur="1.1s" />
<animate attributeName="y1" attributeType="XML" to="230" fill="freeze" dur="1.1s" />
<animate attributeName="x2" attributeType="XML" to="924" fill="freeze" dur="1s" />
<animate attributeName="y2" attributeType="XML" to="230" fill="freeze" dur="1s" />
</line>
<circle cx="771" cy="363" r="4" stroke="black" fill="black" opacity="0.5" class="circle_loc" />
<circle cx="924" cy="230" r="4" stroke="black" fill="black" opacity="0.5" class="circle_loc" />
<line class="svg_line_red" id="line_1442197046253" x1="771" y1="363" fill="url(#linegradred)" stroke="url(#linegradred)" x2="838" y2="430" transform="rotate(-85.99981423948691 771 363)">
<animate attributeName="x1" attributeType="XML" to="924" fill="freeze" dur="1.1s" />
<animate attributeName="y1" attributeType="XML" to="230" fill="freeze" dur="1.1s" />
<animate attributeName="x2" attributeType="XML" to="924" fill="freeze" dur="1s" />
<animate attributeName="y2" attributeType="XML" to="230" fill="freeze" dur="1s" />
</line>
</svg>
这是一个 fiddle :https://jsfiddle.net/qj7z2hhr/
如果能帮助理解为什么会这样,我们将不胜感激。
在 SVG 文件中,层次结构中较低的任何内容都会受到其祖先元素中的内容的影响。因此,您动画中的所有坐标也会受到您应用于其父元素(直线)的旋转的影响。
如果要修复它,则必须在(即高于)旋转后应用平移动画。你可以做到这一点的一种方法是用一个组围绕这条线。对线应用旋转,对组应用 animateTransform
。
更新
其实我的建议是行不通的。我没有考虑到您正在为直线的起点和终点设置动画。
不过我还有一个建议。使每条线成为基于 (0,0) 的向量,并且长度与原始线匹配。即:
x1=0 y1=0
x2=(x2-x1) y2=(y2-y2)
然后您可以将所需的动画创建为三个动画组件的组合。
- 原始起点和终点之间的平移。
- 从 1 到 0 的尺度,使起点和终点收敛到一个点
- 一个固定的旋转变换使你的线条和渐变指向正确的方向
这是结果。我刚刚实现了其中两行来向您展示它是如何工作的。我将让您决定这是否比仅具有多个渐变更简单。
<svg viewBox="0 0 1920 670.9">
<defs>
<linearGradient y2="100%" x2="100%" y1="0%" x1="0%" id="linegradred">
<stop style="stop-color:#F70D1A;stop-opacity:0" offset="0%" />
<stop style="stop-color:#F70D1A;stop-opacity:0.3" offset="50%" />
<stop style="stop-color:#F70D1A;stop-opacity:0.8" offset="100%" />
</linearGradient>
</defs>
<circle cx="964" cy="426" r="4" stroke="black" fill="black" opacity="0.5" class="circle_loc"/>
<circle cx="924" cy="230" r="4" stroke="black" fill="black" opacity="0.5" class="circle_loc" />
<line class="svg_line_red" id="line_1442197044254"
x2="66" y2="66"
fill="url(#linegradred)" stroke="url(#linegradred)">
<animateTransform attributeName="transform" attributeType="XML"
type="translate" from="964 426" to="924 230" dur="1.1s"
additive="sum" fill="freeze" />
<animateTransform attributeName="transform" attributeType="XML"
type="scale" from="1" to="0" dur="1.1s"
additive="sum" fill="freeze" />
<animateTransform attributeName="transform" attributeType="XML"
type="rotate" from="-146.5" to="-146.5" dur="1.1s"
additive="sum" fill="freeze" />
</line>
<circle cx="590" cy="344" r="4" stroke="black" fill="black" opacity="0.5" class="circle_loc" />
<circle cx="924" cy="230" r="4" stroke="black" fill="black" opacity="0.5" class="circle_loc" />
<line class="svg_line_red" id="line_1442197045251"
x2="117" y2="116"
fill="url(#linegradred)" stroke="url(#linegradred)">
<animateTransform attributeName="transform" attributeType="XML"
type="translate" from="590 344" to="924 230" dur="1.1s"
additive="sum" fill="freeze" />
<animateTransform attributeName="transform" attributeType="XML"
type="scale" from="1" to="0" dur="1.1s"
additive="sum" fill="freeze" />
<animateTransform attributeName="transform" attributeType="XML"
type="rotate" from="-63.8" to="-63.8" dur="1.1s"
additive="sum" fill="freeze" />
</line>
</svg>
我正在尝试在两点之间移动一条线。
为了只需要一个渐变,我使用 transform
.
详情见此:
现在,当我在线上应用动画时,它的行为很奇怪。 它不会靠近真正的目的地,我真的不明白发生了什么。
特别奇怪的是,如果我删除 rotate
转换,线条会转到正确的点(但显然它没有正确的渐变)。
<svg height="670.9" width="1920">
<defs>
<linearGradient y2="100%" x2="100%" y1="0%" x1="0%" id="linegradred">
<stop style="stop-color:#F70D1A;stop-opacity:0" offset="0%" />
<stop style="stop-color:#F70D1A;stop-opacity:0.3" offset="50%" />
<stop style="stop-color:#F70D1A;stop-opacity:0.8" offset="100%" />
</linearGradient>
</defs>
<circle cx="964" cy="426" r="4" stroke="black" fill="black" opacity="0.5" class="circle_loc"/>
<circle cx="924" cy="230" r="4" stroke="black" fill="black" opacity="0.5" class="circle_loc" />
<line class="svg_line_red" id="line_1442197044254" x1="964" y1="426" fill="url(#linegradred)" stroke="url(#linegradred)" x2="1030" y2="492" transform="rotate(-146.5346206536447 964 426)">
<animate attributeName="x1" attributeType="XML" to="924" fill="freeze" dur="1.1s" />
<animate attributeName="y1" attributeType="XML" to="230" fill="freeze" dur="1.1s" />
<animate attributeName="x2" attributeType="XML" to="924" fill="freeze" dur="1s" />
<animate attributeName="y2" attributeType="XML" to="230" fill="freeze" dur="1s" />
</line>
<circle cx="590" cy="344" r="4" stroke="black" fill="black" opacity="0.5" class="circle_loc" />
<circle cx="924" cy="230" r="4" stroke="black" fill="black" opacity="0.5" class="circle_loc" />
<line class="svg_line_red" id="line_1442197045251" x1="590" y1="344" fill="url(#linegradred)" stroke="url(#linegradred)" x2="707" y2="461" transform="rotate(-63.84566422168709 590 344)">
<animate attributeName="x1" attributeType="XML" to="924" fill="freeze" dur="1.1s" />
<animate attributeName="y1" attributeType="XML" to="230" fill="freeze" dur="1.1s" />
<animate attributeName="x2" attributeType="XML" to="924" fill="freeze" dur="1s" />
<animate attributeName="y2" attributeType="XML" to="230" fill="freeze" dur="1s" />
</line>
<circle cx="771" cy="363" r="4" stroke="black" fill="black" opacity="0.5" class="circle_loc" />
<circle cx="924" cy="230" r="4" stroke="black" fill="black" opacity="0.5" class="circle_loc" />
<line class="svg_line_red" id="line_1442197046253" x1="771" y1="363" fill="url(#linegradred)" stroke="url(#linegradred)" x2="838" y2="430" transform="rotate(-85.99981423948691 771 363)">
<animate attributeName="x1" attributeType="XML" to="924" fill="freeze" dur="1.1s" />
<animate attributeName="y1" attributeType="XML" to="230" fill="freeze" dur="1.1s" />
<animate attributeName="x2" attributeType="XML" to="924" fill="freeze" dur="1s" />
<animate attributeName="y2" attributeType="XML" to="230" fill="freeze" dur="1s" />
</line>
</svg>
这是一个 fiddle :https://jsfiddle.net/qj7z2hhr/
如果能帮助理解为什么会这样,我们将不胜感激。
在 SVG 文件中,层次结构中较低的任何内容都会受到其祖先元素中的内容的影响。因此,您动画中的所有坐标也会受到您应用于其父元素(直线)的旋转的影响。
如果要修复它,则必须在(即高于)旋转后应用平移动画。你可以做到这一点的一种方法是用一个组围绕这条线。对线应用旋转,对组应用 animateTransform
。
更新
其实我的建议是行不通的。我没有考虑到您正在为直线的起点和终点设置动画。
不过我还有一个建议。使每条线成为基于 (0,0) 的向量,并且长度与原始线匹配。即:
x1=0 y1=0
x2=(x2-x1) y2=(y2-y2)
然后您可以将所需的动画创建为三个动画组件的组合。
- 原始起点和终点之间的平移。
- 从 1 到 0 的尺度,使起点和终点收敛到一个点
- 一个固定的旋转变换使你的线条和渐变指向正确的方向
这是结果。我刚刚实现了其中两行来向您展示它是如何工作的。我将让您决定这是否比仅具有多个渐变更简单。
<svg viewBox="0 0 1920 670.9">
<defs>
<linearGradient y2="100%" x2="100%" y1="0%" x1="0%" id="linegradred">
<stop style="stop-color:#F70D1A;stop-opacity:0" offset="0%" />
<stop style="stop-color:#F70D1A;stop-opacity:0.3" offset="50%" />
<stop style="stop-color:#F70D1A;stop-opacity:0.8" offset="100%" />
</linearGradient>
</defs>
<circle cx="964" cy="426" r="4" stroke="black" fill="black" opacity="0.5" class="circle_loc"/>
<circle cx="924" cy="230" r="4" stroke="black" fill="black" opacity="0.5" class="circle_loc" />
<line class="svg_line_red" id="line_1442197044254"
x2="66" y2="66"
fill="url(#linegradred)" stroke="url(#linegradred)">
<animateTransform attributeName="transform" attributeType="XML"
type="translate" from="964 426" to="924 230" dur="1.1s"
additive="sum" fill="freeze" />
<animateTransform attributeName="transform" attributeType="XML"
type="scale" from="1" to="0" dur="1.1s"
additive="sum" fill="freeze" />
<animateTransform attributeName="transform" attributeType="XML"
type="rotate" from="-146.5" to="-146.5" dur="1.1s"
additive="sum" fill="freeze" />
</line>
<circle cx="590" cy="344" r="4" stroke="black" fill="black" opacity="0.5" class="circle_loc" />
<circle cx="924" cy="230" r="4" stroke="black" fill="black" opacity="0.5" class="circle_loc" />
<line class="svg_line_red" id="line_1442197045251"
x2="117" y2="116"
fill="url(#linegradred)" stroke="url(#linegradred)">
<animateTransform attributeName="transform" attributeType="XML"
type="translate" from="590 344" to="924 230" dur="1.1s"
additive="sum" fill="freeze" />
<animateTransform attributeName="transform" attributeType="XML"
type="scale" from="1" to="0" dur="1.1s"
additive="sum" fill="freeze" />
<animateTransform attributeName="transform" attributeType="XML"
type="rotate" from="-63.8" to="-63.8" dur="1.1s"
additive="sum" fill="freeze" />
</line>
</svg>