在 canvas 2D API 中,我们可以首先使用一个上下文的转换定义一个子路径,然后只为fill()
orstroke()
调用更改该上下文的转换,这将对样式fillStyle
、likelineWidth
和其他可见属性产生影响,但会留下子路径。定义的路径。当我们想要放大矢量形状同时保持相同的笔划宽度时,这非常方便。
这是一个简单的示例,其中只有lineWidth
受可变缩放转换影响:
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
let zoom = 1;
let speed = 0.1;
requestAnimationFrame(update);
function update() {
if( zoom >= 10 || zoom <= 0.1 ) speed *= -1;
zoom += speed;
draw();
requestAnimationFrame(update);
}
function draw() {
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.clearRect(0,0,canvas.width,canvas.height);
// define the subpath at identity matrix
ctx.beginPath();
ctx.moveTo(10 ,80);
ctx.quadraticCurveTo(52.5,10,95,80);
ctx.quadraticCurveTo(137.5,150,180,80);
// stroke zoomed
ctx.setTransform(zoom, 0, 0, zoom, 0, 0);
ctx.stroke();
}
<canvas id="canvas"></canvas>
使用Path2D API,我们必须直接在ctx.fill(path)
orctx.stroke(path)
方法中传递这个子路径。
这意味着我们不能像以前那样将样式与子路径声明分开:
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
let zoom = 1;
let speed = 0.1;
requestAnimationFrame(update);
function update() {
if( zoom >= 10 || zoom <= 0.1 ) speed *= -1;
zoom += speed;
draw();
requestAnimationFrame(update);
}
function draw() {
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.clearRect(0,0,canvas.width,canvas.height);
// define the subpath at identity matrix
// (declared in 'draw' just for the example, would be the same anyway outside)
const path = new Path2D("M 10 80 Q 52.5 10, 95 80 T 180 80");
// stroke zoomed
ctx.setTransform(zoom, 0, 0, zoom, 0, 0);
ctx.stroke(path);
}
<canvas id="canvas"></canvas>
在使用这个原本方便的 Path2D API 时有没有办法做到这一点?