通过 CSS 过渡动画 SVG 直线
Animate SVG straight line by CSS transition
我想以同样的方式移动直线和圆圈,并用 CSS 设置动画过渡。
对圆起作用,对线不起作用
怎么了?
const state = {
x: 75,
y: 75
};
const line = document.getElementsByTagName('line')[0];
const circle = document.getElementsByTagName('circle')[0];
setInterval(() => {
state.x = Math.floor(Math.random() * 150);
state.y = Math.floor(Math.random() * 150);
line.setAttribute("x2", state.x);
line.setAttribute("y2", state.y);
circle.setAttribute("transform", `translate(${state.x} ${state.y})`);
}, 2000)
circle,
line {
transition: all 1s ease;
}
<svg height="150" width="150" style="border: 1px solid black">
<line
x1="0"
y1="0"
x2="75"
y2="75"
stroke="red"
>
</line>
<circle
r="10"
transform="translate(75 75)"
fill="none"
stroke="blue"
>
</circle>
</svg>
您可以使用 Path 元素代替 Line 元素,如下所示:
const state = {
x: 75,
y: 75
};
const line = document.getElementsByClassName('line')[0];
setInterval(() => {
state.x = Math.floor(Math.random() * 150);
state.y = Math.floor(Math.random() * 150);
line.setAttribute("d", `M 0 0 l ${state.x} ${state.y}`);
}, 2000)
path {
transition: all 1s ease;
}
<svg height="150" width="150" style="border: 1px solid black">
<path
class="line"
d="M 0 0 L 75 75"
stroke="red"
fill="none"
/>
</svg>
使圆和线同步动画的最简单方法是将圆用作 marker。
在这种情况下,圆圈将始终附加到直线上并随之移动。
const state = {
x: 75,
y: 75
};
const line = document.getElementsByTagName('line')[0];
const circle = document.getElementsByTagName('circle')[0];
setInterval(() => {
state.x = Math.floor(Math.random() * 150);
state.y = Math.floor(Math.random() * 150);
line.setAttribute("x2", state.x);
line.setAttribute("y2", state.y);
}, 2000)
<svg height="160" width="160" style="border: 1px solid black">
<defs>
<marker id="markEnd" viewBox="0 0 22 22" refX="10" refY="10" markerUnits="userSpaceOnUse" markerWidth="22" markerHeight="22">
<circle r="10" cx="10" cy="10" fill="none" stroke="blue" />
</marker>
</defs>
<line
x1="0"
y1="0"
x2="75"
y2="75"
stroke="red"
marker-end="url(#markEnd)"
>
</line>
</svg>
更新
选项@AOD 用路径和标记替换行
const state = {
x: 75,
y: 75
};
const line = document.getElementsByClassName('line')[0];
setInterval(() => {
state.x = Math.floor(Math.random() * 150);
state.y = Math.floor(Math.random() * 150);
line.setAttribute("d", `M 0 0 L ${state.x} ${state.y}`);
}, 2000)
path {
transition: all 1s ease;
}
<svg height="160" width="160" style="border: 1px solid black">
<defs>
<marker id="markEnd" viewBox="0 0 22 22" refX="10" refY="10" markerUnits="userSpaceOnUse" markerWidth="22" markerHeight="22">
<circle r="10" cx="10" cy="10" fill="none" stroke="blue" />
</marker>
</defs>
<path
class="line"
d="M 0 0 L 75 75"
stroke="red"
fill="none"
marker-end="url(#markEnd)"
/>
</svg>
我想以同样的方式移动直线和圆圈,并用 CSS 设置动画过渡。
对圆起作用,对线不起作用
怎么了?
const state = {
x: 75,
y: 75
};
const line = document.getElementsByTagName('line')[0];
const circle = document.getElementsByTagName('circle')[0];
setInterval(() => {
state.x = Math.floor(Math.random() * 150);
state.y = Math.floor(Math.random() * 150);
line.setAttribute("x2", state.x);
line.setAttribute("y2", state.y);
circle.setAttribute("transform", `translate(${state.x} ${state.y})`);
}, 2000)
circle,
line {
transition: all 1s ease;
}
<svg height="150" width="150" style="border: 1px solid black">
<line
x1="0"
y1="0"
x2="75"
y2="75"
stroke="red"
>
</line>
<circle
r="10"
transform="translate(75 75)"
fill="none"
stroke="blue"
>
</circle>
</svg>
您可以使用 Path 元素代替 Line 元素,如下所示:
const state = {
x: 75,
y: 75
};
const line = document.getElementsByClassName('line')[0];
setInterval(() => {
state.x = Math.floor(Math.random() * 150);
state.y = Math.floor(Math.random() * 150);
line.setAttribute("d", `M 0 0 l ${state.x} ${state.y}`);
}, 2000)
path {
transition: all 1s ease;
}
<svg height="150" width="150" style="border: 1px solid black">
<path
class="line"
d="M 0 0 L 75 75"
stroke="red"
fill="none"
/>
</svg>
使圆和线同步动画的最简单方法是将圆用作 marker。
在这种情况下,圆圈将始终附加到直线上并随之移动。
const state = {
x: 75,
y: 75
};
const line = document.getElementsByTagName('line')[0];
const circle = document.getElementsByTagName('circle')[0];
setInterval(() => {
state.x = Math.floor(Math.random() * 150);
state.y = Math.floor(Math.random() * 150);
line.setAttribute("x2", state.x);
line.setAttribute("y2", state.y);
}, 2000)
<svg height="160" width="160" style="border: 1px solid black">
<defs>
<marker id="markEnd" viewBox="0 0 22 22" refX="10" refY="10" markerUnits="userSpaceOnUse" markerWidth="22" markerHeight="22">
<circle r="10" cx="10" cy="10" fill="none" stroke="blue" />
</marker>
</defs>
<line
x1="0"
y1="0"
x2="75"
y2="75"
stroke="red"
marker-end="url(#markEnd)"
>
</line>
</svg>
更新
选项@AOD 用路径和标记替换行
const state = {
x: 75,
y: 75
};
const line = document.getElementsByClassName('line')[0];
setInterval(() => {
state.x = Math.floor(Math.random() * 150);
state.y = Math.floor(Math.random() * 150);
line.setAttribute("d", `M 0 0 L ${state.x} ${state.y}`);
}, 2000)
path {
transition: all 1s ease;
}
<svg height="160" width="160" style="border: 1px solid black">
<defs>
<marker id="markEnd" viewBox="0 0 22 22" refX="10" refY="10" markerUnits="userSpaceOnUse" markerWidth="22" markerHeight="22">
<circle r="10" cx="10" cy="10" fill="none" stroke="blue" />
</marker>
</defs>
<path
class="line"
d="M 0 0 L 75 75"
stroke="red"
fill="none"
marker-end="url(#markEnd)"
/>
</svg>