﻿ H5在Canvas中实现自定义路径动画 - 鸿网互联

# H5在Canvas中实现自定义路径动画

```const path = 'M0,0 C8,33.90861 25.90861,16 48,16 C70.09139,16 88,33.90861 88,56 C88,78.09139 105.90861,92 128,92 C150.09139,92 160,72 160,56 C160,40 148,24 128,24 C108,24 96,40 96,56 C96,72 105.90861,92 128,92 C154,93 168,78 168,56 C168,33.90861 185.90861,16 208,16 C230.09139,16 248,33.90861 248,56 C248,78.09139 230.09139,96 208,96 L48,96 C25.90861,96 8,78.09139 8,56 Z';
const pathElement = document.createElementNS('http://www.w3.org/2000/svg',"path");
pathElement.setAttributeNS(null, 'd', path);```

getTotalLength与getPointAtLength

SVGPathElement提供的这两个api很关键，可以说它是实现路径动画的最为核心的地方（在svg内实现自定义路径动画一般也是通过这两个api去解决）详情请戳：SVGPathElement MDN

getTotalLength方法可以获取SVGPathElement的总长度

getPointAtLength方法，传入一个长度x，将返回距离SVGPathElement起点的长度为x的终点坐标。

```const length = pathElement.getTotalLength();
const duration = 1000; // 动画总时长
const interval = length / duration;
const canvas = document.querySelector('canvas');
const context = canvas.getContext('2d');
let time = 0, step = 0;
const timer = setInterval(function() {
if (time <= duration) {
const x = parseInt(pathElement.getPointAtLength(step).x);
const y = parseInt(pathElement.getPointAtLength(step).y);
move(x, y);  // 更新canvas所绘制图形的坐标
step++;
} else {
clearInterval(timer)
}
}, interval);
function move(x, y) {
context.clearRect(0, 0, canvas.width, canvas.height);
context.beginPath();
context.arc(x, y, 25, 0, Math.PI*2, true);
context.fillStyle = '#f0f';
context.fill();
context.closePath();
}```

```function customizePath(path, func) {
const pathElement = document.createElementNS('http://www.w3.org/2000/svg',"path");
pathElement.setAttributeNS(null, 'd', path);
const length = pathElement.getTotalLength();
const duration = 1000;
const interval = length / duration;
let time = 0, step = 0;

const timer = setInterval(function() {
if (time <= duration) {
const x = parseInt(pathElement.getPointAtLength(step).x);
const y = parseInt(pathElement.getPointAtLength(step).y);
func(x, y);
step++;
} else {
clearInterval(timer)
}
}, interval);
}
const path = 'M0,0 C8,33.90861 25.90861,16 48,16 C70.09139,16 88,33.90861 88,56 C88,78.09139 105.90861,92 128,92 C150.09139,92 160,72 160,56 C160,40 148,24 128,24 C108,24 96,40 96,56 C96,72 105.90861,92 128,92 C154,93 168,78 168,56 C168,33.90861 185.90861,16 208,16 C230.09139,16 248,33.90861 248,56 C248,78.09139 230.09139,96 208,96 L48,96 C25.90861,96 8,78.09139 8,56 Z';
const canvas = document.querySelector('canvas');
const context = canvas.getContext('2d');
function move(x, y) {
context.clearRect(0, 0, canvas.width, canvas.height);
context.beginPath();
context.arc(x, y, 25, 0, Math.PI*2, true);
context.fillStyle = '#f0f';
context.fill();
context.closePath();
}
customizePath(path, move);```

H5的Drag与Drop详解

<