Javascript - 变形/动画 svg 路径数据,无需 SMIL 或库

标签 javascript html css svg svg-morphing

我想在没有 SMIL 或库(jquery、Snap.svg、Velocity.js 等)的情况下对 svg 路径数据进行变形/动画处理,只需纯 JavaScript(如果可能的话,可以选择使用 css)。我想这样做是因为 Chrome 已弃用 SMIL,并且他们建议使用 css 或“Web 动画”制作动画 - 它们对 Web 动画意味着什么??-。例如,我想在下面的代码中将 id 为“rect1”的路径变形为 id 为“rect2”的路径:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>morph/animate svg path data WITHOUT SMIL or libraries (jquery, Snap.svg, Velocity.js etc.), just pure javascript</title>
</head>
<body>

<svg
	 xmlns="http://www.w3.org/2000/svg"
	 xmlns:xlink="http://www.w3.org/1999/xlink"
	 version="1.1"
	 width="500px" height="500px"
	 viewBox="0 0 500 500"
	 >
<g id="layer1">
  <path id="rect1" d="m25 7.3 61 12-6 57-71 6z" stroke="#f00" stroke-miterlimit="10" stroke-width="2" fill="none"/>
 </g>
 <g id="layer2">
  <path id="rect2" d="m9.3 34 59-27 26 41-54 42z" stroke="#f00" stroke-miterlimit="10" stroke-width="2" fill="none"/>
 </g>
</svg>

<script>

	// code for animating/morphing path with id "rect1" to path with id "rect 2"

</script>

</body>

</html>

最佳答案

要仅使用 JavaScript 对路径数据进行动画处理,我建议缓存两条路径的原始路径数据。然后使用计时器逐步完成动画过程。在每一步中,计算从起始路径数据平滑移动到结束路径数据的当前路径数据。

以下代码等待 1 秒,然后运行 ​​2 秒的动画...

<script>

(function() {

    var path1;
    var path2;
    var startPoints;
    var endPoints;
    var currentStep = 0;
    var maximumSteps = 100;
    var timeBeforeFirstStep = 1000;
    var timeBetweenSteps = 20;

    function animatePath() {
        if (currentStep < maximumSteps) {
            currentStep = currentStep + 1;
            for (var i = 0; i < path1.pathSegList.numberOfItems; i++) {
                var item = path1.pathSegList.getItem(i);
                if (item.pathSegType === SVGPathSeg.PATHSEG_MOVETO_REL || item.pathSegType === SVGPathSeg.PATHSEG_LINETO_REL) {
                    if (startPoints[i] && endPoints[i]) {
                        item.x = startPoints[i].x + (endPoints[i].x - startPoints[i].x) * (currentStep / maximumSteps);
                        item.y = startPoints[i].y + (endPoints[i].y - startPoints[i].y) * (currentStep / maximumSteps);
                    }
                }
            }
            setTimeout(animatePath, timeBetweenSteps);
        }
    }

    function window_load() {
        path1 = document.getElementById("rect1");
        path2 = document.getElementById("rect2");
        startPoints = [];
        for (var i = 0; i < path1.pathSegList.numberOfItems; i++) {
            var item = path1.pathSegList.getItem(i);
            if (item.pathSegType === SVGPathSeg.PATHSEG_MOVETO_REL || item.pathSegType === SVGPathSeg.PATHSEG_LINETO_REL) {
                startPoints.push({"x": item.x, "y": item.y});
            }
            else {
                startPoints.push(null);
            }
        }
        endPoints = [];
        for (var i = 0; i < path2.pathSegList.numberOfItems; i++) {
            var item = path2.pathSegList.getItem(i);
            if (item.pathSegType === SVGPathSeg.PATHSEG_MOVETO_REL || item.pathSegType === SVGPathSeg.PATHSEG_LINETO_REL) {
                endPoints.push({"x": item.x, "y": item.y});
            }
            else {
                endPoints.push(null);
            }
        }
        setTimeout(animatePath, timeBeforeFirstStep);
    }

    window.addEventListener("load", window_load);

}());

</script>

关于Javascript - 变形/动画 svg 路径数据,无需 SMIL 或库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33811183/

相关文章:

javascript - 在 Meteor 中实现 embed.ly Analytics

javascript - 如何创建并正确调度AudioBufferSource节点?

html - 将 Shiny 的应用程序嵌入到 Rmarkdown html 文档中

css - 图片没有居中对齐

javascript - contenteditable .execCommand() 没有触发?

html - 不要使用 VSCode 的自动格式化程序在 <head> 和 <body> 标签之前添加额外的换行符

html - 如何将大量类似的糟糕 html 页面转换为高质量的基于 css 的页面?

css - Page_Init vs Page_PreRender 与渲染 LI 和 CSS 冲突

jquery - 水平设置图像

javascript - 选择一个重叠的 div