我在单个画布中有多个 Path2D,我希望能够独立缩放和定位它们中的每一个,而不是调整 context.scale() 和 context.translate()。我正在使用 SVG 路径数据构建每个 path2D 对象,因为我希望能够修改笔划线和笔触长度。
似乎我可能无法使用 Path2D 实现这一目标,解决此问题的最佳方法是什么?
我正在考虑一些潜在的选择:
- 将 drawImage 方法与 svg 源一起使用
- 将 SVG 路径数据转换为画布路径弧(可能使用库)
- 调整实际的 svg 路径数据并为每个绘制重建 Path2D 对象
编辑:
我构建了这个代码笔,我试图在不改变 p2 位置的情况下将 p1 向 p2 移动。当我翻译上下文时,两个对象都会移动。仅调整 p1 位置的最佳方法是什么?
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var p1x = 0
var p1 = new Path2D("M1 0 h 100 v 50 h -100 Z");
var p2 = new Path2D("M200 0 h 50 v 25 h -50 Z");
setInterval(() => {
p1x = p1x + 1
ctx.translate(0, 0)
ctx.clearRect(0, 0, 300, 300)
ctx.translate(p1x, 0)
ctx.fill(p1)
ctx.fill(p2)
}, 1000)
http://codepen.io/jasonpearson/pen/reXyVG
可以将 addPath
方法与第二个转换参数结合使用来缩放路径......
const m = document.createElementNS("http://www.w3.org/2000/svg", "svg").createSVGMatrix()
const p = new Path2D()
const t = m.scale(0.5)
p.addPath(p1, t)
实现示例:
var canvas = document.getElementById("canvas")
var ctx = canvas.getContext("2d")
var p1x = 0
var p1 = new Path2D("M1 0 h 100 v 50 h -100 Z")
var p2 = new Path2D("M200 0 h 50 v 25 h -50 Z")
var m = document.createElementNS("http://www.w3.org/2000/svg", "svg").createSVGMatrix()
setInterval(() => {
p1x = p1x + 1
const p = new Path2D()
const t = m.translate(p1x, 0)
p.addPath(p1, t)
ctx.clearRect(0, 0, 300, 300)
ctx.fill(p)
ctx.fill(p2)
}, 1000)
canvas {
border: 1px solid blue;
height: 300px;
width: 300px;
}
<canvas id="canvas"></canvas>
更好的实施:
var canvas = document.getElementById("canvas")
var ctx = canvas.getContext("2d")
var p1 = new Path2D("M1 0 h 100 v 50 h -100 Z")
var p2 = new Path2D("M200 0 h 50 v 25 h -50 Z")
var m1 = document.createElementNS("http://www.w3.org/2000/svg", "svg").createSVGMatrix()
setInterval(() => {
let p = new Path2D()
m1 = m1.translate(1, 0)
p.addPath(p1, m1)
ctx.clearRect(0, 0, 300, 300)
ctx.fill(p)
ctx.fill(p2)
}, 1000)
canvas {
border: 1px solid blue;
height: 300px;
width: 300px;
}
<canvas id="canvas"></canvas>
只是一个小的辅助功能,以备将来使用:
function transformPath2D(path, matrix) {
const p = new Path2D()
p.addPath(path, matrix)
return p
}
您可以将翻译应用于第一个元素:
setInterval(() => {
p1x = p1x + 1;
ctx.clearRect(0, 0, 300, 300);
ctx.save();
ctx.translate(p1x, 0);
ctx.fill(p1);
ctx.restore();
ctx.fill(p2);
}, 1000);
由于 Chrome 不再像Path2D.addPath()
,如果您希望 Chrome 兼容而不需要实验标志,则需要在上下文上设置转换,我认为没有其他方法。
话虽如此,您可以在进行调整之前/之后save()
并restore()
上下文。从上面更新您的示例:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var p1x = 0
var p1 = new Path2D("M1 0 h 100 v 50 h -100 Z");
var p2 = new Path2D("M200 0 h 50 v 25 h -50 Z");
setInterval(() => {
p1x = p1x + 1
ctx.clearRect(0, 0, 300, 300);
ctx.save(); // Save the previous translation context
ctx.translate(p1x, 0); // Adjust context to where you want to draw p1
ctx.fill(p1);
ctx.restore(); // Restore the context before drawing p2
ctx.fill(p2)
}, 1000)
https://codepen.io/anon/pen/oMLNEz