JavaScript SVGLine 连接移动元素动画
JavaScript SVGLine connecting moving elements animation
我有两个 SVG 矩形;它们的两个角由 SVGLine 连接,我正在尝试为整体制作动画。
现在使用 Element.animate()
函数将矩形移动到一个新位置(新位置必须在运行时计算,所以我认为只有在 JS 中使用 animate()
函数才有可能? ).
在那之前一切正常,但是当我尝试为线条设置动画以使其在动画期间仍然连接角时,它不会移动。
有什么方法可以使线条移动到新位置的动画吗? (我不能只将属性设置到新位置)。
如果我必须使用 <path>
或 <polyline>
之类的东西,那么快速解释一下我应该如何做会很好,因为 path.animate([{points:...},{points:...}],{...})
也没有移动我想要的路径。
这是一个快速代码示例,我认为它应该可以工作,但该行不会移动。
let svg = document.querySelector("#theSVG");
const SVGNS = "http://www.w3.org/2000/svg";
function drawing() {
let rect = document.createElementNS(SVGNS, "rect");
rect.setAttribute("x", 100);
rect.setAttribute("y", 100);
rect.setAttribute("width", 100);
rect.setAttribute("height", 100);
rect.setAttribute("stroke", "black");
svg.appendChild(rect);
let rect2 = document.createElementNS(SVGNS, "rect");
rect2.setAttribute("x", 10);
rect2.setAttribute("y", 10);
rect2.setAttribute("width", 50);
rect2.setAttribute("height", 25);
rect2.setAttribute("stroke", "black");
svg.appendChild(rect2);
let line = document.createElementNS(SVGNS, "line");
line.setAttribute("x1", rect.x.baseVal.value);
line.setAttribute("x2", rect2.x.baseVal.value);
line.setAttribute("y1", rect.y.baseVal.value);
line.setAttribute("y2", rect2.y.baseVal.value);
line.setAttribute("stroke", "darkgray");
svg.appendChild(line);
rect.animate([{
x: rect.x.baseVal.value
}, {
x: '200px'
}], {
duration: 5000,
iterations: 1
});
rect2.animate([{
y: rect2.y.baseVal.value
}, {
y: '300px'
}], {
duration: 5000,
iterations: 1
});
line.animate([{
x1: line.x1.baseVal.value,
y2: line.y2.baseVal.value
}, {
x1: '200px',
y2: '300px'
}], {
duration: 5000,
iterations: 1
});
}
drawing();
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 700 360" id="theSVG">
</svg>
您只能 animate()
CSS 个属性。在 SVG 中,只有 presentational attributes 映射到 CSS。 <line>
的 x1
、x2
、y1
和 y2
(奇怪地)不在该列表中...
不过,您应该能够用 <path>
替换此元素,为其 d
属性设置动画。
let svg = document.querySelector("#theSVG");
const SVGNS = "http://www.w3.org/2000/svg";
function drawing() {
let rect = document.createElementNS(SVGNS, "rect");
rect.setAttribute("x", 100);
rect.setAttribute("y", 100);
rect.setAttribute("width", 100);
rect.setAttribute("height", 100);
rect.setAttribute("stroke", "black");
svg.appendChild(rect);
let rect2 = document.createElementNS(SVGNS, "rect");
rect2.setAttribute("x", 10);
rect2.setAttribute("y", 10);
rect2.setAttribute("width", 50);
rect2.setAttribute("height", 25);
rect2.setAttribute("stroke", "black");
svg.appendChild(rect2);
let line = document.createElementNS(SVGNS, "path");
line.setAttribute("d", `
M${ rect.x.baseVal.value } ${ rect.y.baseVal.value }
L${ rect2.x.baseVal.value } ${ rect2.y.baseVal.value }
`);
line.setAttribute("stroke", "darkgray");
svg.appendChild(line);
rect.animate([{
x: '200px'
}], {
duration: 5000,
iterations: 1
});
rect2.animate([{
y: '300px'
}], {
duration: 5000,
iterations: 1
});
line.animate([{
d: `path("M200 ${ rect.y.baseVal.value }L${ rect2.x.baseVal.value } 300")`
}], {
duration: 5000,
iterations: 1
});
}
drawing();
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 700 360" id="theSVG">
</svg>
但只有基于 Chromium 的浏览器支持 CSS path()
d
属性...
所以您可能不得不改用 SMIL animations:
let svg = document.querySelector("#theSVG");
const SVGNS = "http://www.w3.org/2000/svg";
function drawing() {
const rect = document.createElementNS(SVGNS, "rect");
rect.setAttribute("x", 100);
rect.setAttribute("y", 100);
rect.setAttribute("width", 100);
rect.setAttribute("height", 100);
rect.setAttribute("stroke", "black");
svg.appendChild(rect);
const rectAnimateX = document.createElementNS(SVGNS, "animate");
rectAnimateX.setAttribute("attributeName", "x");
rectAnimateX.setAttribute("values", "100;200");
rectAnimateX.setAttribute("dur", "5s");
rect.append(rectAnimateX);
let rect2 = document.createElementNS(SVGNS, "rect");
rect2.setAttribute("x", 10);
rect2.setAttribute("y", 10);
rect2.setAttribute("width", 50);
rect2.setAttribute("height", 25);
rect2.setAttribute("stroke", "black");
svg.appendChild(rect2);
const rectAnimateY = document.createElementNS(SVGNS, "animate");
rectAnimateY.setAttribute("attributeName", "y");
rectAnimateY.setAttribute("values", "10;300");
rectAnimateY.setAttribute("dur", "5s");
rect2.append(rectAnimateY);
const line = document.createElementNS(SVGNS, "line");
line.setAttribute("x1", rect.x.baseVal.value);
line.setAttribute("y1", rect.y.baseVal.value);
line.setAttribute("x2", rect2.x.baseVal.value);
line.setAttribute("y2", rect2.y.baseVal.value);
line.setAttribute("stroke", "darkgray");
svg.appendChild(line);
const lineAnimateX1 = document.createElementNS(SVGNS, "animate");
lineAnimateX1.setAttribute("attributeName", "x1");
lineAnimateX1.setAttribute("values", `${rect.x.baseVal.value};200`);
lineAnimateX1.setAttribute("dur", "5s");
line.append(lineAnimateX1);
const lineAnimateY2 = document.createElementNS(SVGNS, "animate");
lineAnimateY2.setAttribute("attributeName", "y2");
lineAnimateY2.setAttribute("values", `${rect2.y.baseVal.value};300`);
lineAnimateY2.setAttribute("dur", "5s");
line.append(lineAnimateY2);
}
drawing();
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 700 360" id="theSVG">
</svg>
我有两个 SVG 矩形;它们的两个角由 SVGLine 连接,我正在尝试为整体制作动画。
现在使用 Element.animate()
函数将矩形移动到一个新位置(新位置必须在运行时计算,所以我认为只有在 JS 中使用 animate()
函数才有可能? ).
在那之前一切正常,但是当我尝试为线条设置动画以使其在动画期间仍然连接角时,它不会移动。
有什么方法可以使线条移动到新位置的动画吗? (我不能只将属性设置到新位置)。
如果我必须使用 <path>
或 <polyline>
之类的东西,那么快速解释一下我应该如何做会很好,因为 path.animate([{points:...},{points:...}],{...})
也没有移动我想要的路径。
这是一个快速代码示例,我认为它应该可以工作,但该行不会移动。
let svg = document.querySelector("#theSVG");
const SVGNS = "http://www.w3.org/2000/svg";
function drawing() {
let rect = document.createElementNS(SVGNS, "rect");
rect.setAttribute("x", 100);
rect.setAttribute("y", 100);
rect.setAttribute("width", 100);
rect.setAttribute("height", 100);
rect.setAttribute("stroke", "black");
svg.appendChild(rect);
let rect2 = document.createElementNS(SVGNS, "rect");
rect2.setAttribute("x", 10);
rect2.setAttribute("y", 10);
rect2.setAttribute("width", 50);
rect2.setAttribute("height", 25);
rect2.setAttribute("stroke", "black");
svg.appendChild(rect2);
let line = document.createElementNS(SVGNS, "line");
line.setAttribute("x1", rect.x.baseVal.value);
line.setAttribute("x2", rect2.x.baseVal.value);
line.setAttribute("y1", rect.y.baseVal.value);
line.setAttribute("y2", rect2.y.baseVal.value);
line.setAttribute("stroke", "darkgray");
svg.appendChild(line);
rect.animate([{
x: rect.x.baseVal.value
}, {
x: '200px'
}], {
duration: 5000,
iterations: 1
});
rect2.animate([{
y: rect2.y.baseVal.value
}, {
y: '300px'
}], {
duration: 5000,
iterations: 1
});
line.animate([{
x1: line.x1.baseVal.value,
y2: line.y2.baseVal.value
}, {
x1: '200px',
y2: '300px'
}], {
duration: 5000,
iterations: 1
});
}
drawing();
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 700 360" id="theSVG">
</svg>
您只能 animate()
CSS 个属性。在 SVG 中,只有 presentational attributes 映射到 CSS。 <line>
的 x1
、x2
、y1
和 y2
(奇怪地)不在该列表中...
不过,您应该能够用 <path>
替换此元素,为其 d
属性设置动画。
let svg = document.querySelector("#theSVG");
const SVGNS = "http://www.w3.org/2000/svg";
function drawing() {
let rect = document.createElementNS(SVGNS, "rect");
rect.setAttribute("x", 100);
rect.setAttribute("y", 100);
rect.setAttribute("width", 100);
rect.setAttribute("height", 100);
rect.setAttribute("stroke", "black");
svg.appendChild(rect);
let rect2 = document.createElementNS(SVGNS, "rect");
rect2.setAttribute("x", 10);
rect2.setAttribute("y", 10);
rect2.setAttribute("width", 50);
rect2.setAttribute("height", 25);
rect2.setAttribute("stroke", "black");
svg.appendChild(rect2);
let line = document.createElementNS(SVGNS, "path");
line.setAttribute("d", `
M${ rect.x.baseVal.value } ${ rect.y.baseVal.value }
L${ rect2.x.baseVal.value } ${ rect2.y.baseVal.value }
`);
line.setAttribute("stroke", "darkgray");
svg.appendChild(line);
rect.animate([{
x: '200px'
}], {
duration: 5000,
iterations: 1
});
rect2.animate([{
y: '300px'
}], {
duration: 5000,
iterations: 1
});
line.animate([{
d: `path("M200 ${ rect.y.baseVal.value }L${ rect2.x.baseVal.value } 300")`
}], {
duration: 5000,
iterations: 1
});
}
drawing();
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 700 360" id="theSVG">
</svg>
但只有基于 Chromium 的浏览器支持 CSS path()
d
属性...
所以您可能不得不改用 SMIL animations:
let svg = document.querySelector("#theSVG");
const SVGNS = "http://www.w3.org/2000/svg";
function drawing() {
const rect = document.createElementNS(SVGNS, "rect");
rect.setAttribute("x", 100);
rect.setAttribute("y", 100);
rect.setAttribute("width", 100);
rect.setAttribute("height", 100);
rect.setAttribute("stroke", "black");
svg.appendChild(rect);
const rectAnimateX = document.createElementNS(SVGNS, "animate");
rectAnimateX.setAttribute("attributeName", "x");
rectAnimateX.setAttribute("values", "100;200");
rectAnimateX.setAttribute("dur", "5s");
rect.append(rectAnimateX);
let rect2 = document.createElementNS(SVGNS, "rect");
rect2.setAttribute("x", 10);
rect2.setAttribute("y", 10);
rect2.setAttribute("width", 50);
rect2.setAttribute("height", 25);
rect2.setAttribute("stroke", "black");
svg.appendChild(rect2);
const rectAnimateY = document.createElementNS(SVGNS, "animate");
rectAnimateY.setAttribute("attributeName", "y");
rectAnimateY.setAttribute("values", "10;300");
rectAnimateY.setAttribute("dur", "5s");
rect2.append(rectAnimateY);
const line = document.createElementNS(SVGNS, "line");
line.setAttribute("x1", rect.x.baseVal.value);
line.setAttribute("y1", rect.y.baseVal.value);
line.setAttribute("x2", rect2.x.baseVal.value);
line.setAttribute("y2", rect2.y.baseVal.value);
line.setAttribute("stroke", "darkgray");
svg.appendChild(line);
const lineAnimateX1 = document.createElementNS(SVGNS, "animate");
lineAnimateX1.setAttribute("attributeName", "x1");
lineAnimateX1.setAttribute("values", `${rect.x.baseVal.value};200`);
lineAnimateX1.setAttribute("dur", "5s");
line.append(lineAnimateX1);
const lineAnimateY2 = document.createElementNS(SVGNS, "animate");
lineAnimateY2.setAttribute("attributeName", "y2");
lineAnimateY2.setAttribute("values", `${rect2.y.baseVal.value};300`);
lineAnimateY2.setAttribute("dur", "5s");
line.append(lineAnimateY2);
}
drawing();
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 700 360" id="theSVG">
</svg>