在HTML Canvas中沿SVG路径插入图像



使用HTML5画布元素,我试图以特定(/任意)模式绘制灯光。

如果我有一个模式的SVG路径,是否有可能沿着路径重复步进固定的距离(基于总长度的一小部分或只是一个恒定的距离),并绘制一个元素(无论是预定义的图像或只是一个基本的画布形状)?

到目前为止,我所得到的一切都是基于沿着半径递减的弧线放置元素来产生圆锥形,但这不再与我需要产生的效果相匹配。

不幸的是,Path2D接口仍然没有getPointAtLength()getTotalLength()方法可用,所以我们必须使用SVGPathElement来为我们做这件事:

const pathData = `M20 20
s 20,80 40,80
Q 25,25 40,50
t 30,0 30,0 30,0 30,0 30,0
M10,30 A20,20 0,0,1 50,30 A20,20 0,0,1 90,30 Q90,60 50,90 Q10,60 10,30 z`;
// Create an <SVG:path> element to get the path length
// and the various points at a given distance
const pathEl = document.createElementNS("http://www.w3.org/2000/svg", "path");
pathEl.setAttribute("d", pathData);
const totalLength = pathEl.getTotalLength();
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
const path = new Path2D(pathData);
let duration = 5000;
const begin = performance.now();
const anim = (now) => {
const delta = ((now - begin) % duration) / duration;
const distance = delta * totalLength;
const pt = pathEl.getPointAtLength(distance);
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.stroke(path);
ctx.fillRect(pt.x - 5, pt.y - 5, 10, 10);
requestAnimationFrame(anim);
};
requestAnimationFrame(anim);
<canvas height=500></canvas>

但是这意味着你必须有访问DOM的权限,也就是说Worker中不支持。

否则,你可以尝试自己实现它,但老实说,这不是那么容易…
但我让你覆盖,因为这实际上是我想添加到我的path2d检查原型的功能的一部分,而其他人已经做了艰苦的工作。

所以使用我的这个原型,我们可以直接使用Path2D对象,这也应该适用于Worker:

const pathData = `M20 20
s 20,80 40,80
Q 25,25 40,50
t 30,0 30,0 30,0 30,0 30,0
M10,30 A20,20 0,0,1 50,30 A20,20 0,0,1 90,30 Q90,60 50,90 Q10,60 10,30 z`;
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
const path = new Path2D(pathData);
const totalLength = path.getTotalLength();
let duration = 5000;
const begin = performance.now();
const anim = (now) => {
const delta = ((now - begin) % duration) / duration;
const distance = delta * totalLength;
const pt = path.getPointAtLength(distance);
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.stroke(path);
ctx.fillRect(pt.x - 5, pt.y - 5, 10, 10);
requestAnimationFrame(anim);
};
requestAnimationFrame(anim);
<script src="https://cdn.jsdelivr.net/gh/Kaiido/path2D-inspection@master/build/path2D-inspection.min.js"></script>
<canvas height=500></canvas>

希望在不久的将来我们能够将这些方法直接添加到Path2D接口中。但是,规范所有这些并获得实现者的支持将是一场漫长的竞赛。

最新更新