如何在单个 canvas 中为多个笔划创建公共阴影?
How to create a common shadow for multiple strokes in a single canvas?
我正在尝试在 canvas 上绘制多个笔触,我希望它们有一个共同的阴影。目前相互投射的阴影不是我想要的。
理想结果
我试过的
如果您需要每个笔划都是独立的(即它们都有自己的 strokeStyle 或 lineWidth),您将需要使用第二个分离的 canvas:
- 在这个分离的 canvas 上,你画的所有笔触都没有阴影
- 你
drawImage
分离 canvas 在可见的阴影上:
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
const detached = canvas.cloneNode();
const detachedCtx = detached.getContext("2d");
const colors = ["green", "blue", "yellow", "orange", "aqua"];
detachedCtx.lineWidth = 5;
for (let color of colors) {
// draw on the detached canvas
detachedCtx.beginPath();
for (let i = 0; i<5; i++) {
detachedCtx.lineTo(Math.random() * canvas.width, Math.random() * canvas.height);
}
detachedCtx.strokeStyle = color;
detachedCtx.lineWidth = Math.random() * 8 + 2;
detachedCtx.stroke();
}
// now draw all this with shadows on the visible canvas
ctx.shadowOffsetX = 3;
ctx.shadowOffsetY = 3;
ctx.shadowBlur = 3;
ctx.shadowColor = "red";
ctx.drawImage(detached, 0, 0);
<canvas></canvas>
但是要生成图像,您只需要在完成完整路径后调用 stroke()
一次:
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
ctx.fillStyle = "#0F0";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.lineWidth = 5;
ctx.shadowOffsetX = -3;
ctx.shadowOffsetY = -3;
ctx.shadowBlur = 3;
ctx.shadowColor = "red";
ctx.moveTo(10, 50);
ctx.lineTo(90, 50);
ctx.moveTo(50, 10);
ctx.lineTo(50, 90);
ctx.stroke(); // stroke only once, with the full path being traced
<canvas width=100 height=100></canvas>
您可以使用 Path2D
并将所有线段添加到一条路径,然后对该路径进行描边。
这是我推荐的使用 ctx.filter 的 jsfiddle。
const segments = [
[{x: 10, y: 50}, {x: 50, y: 50}],
[{x: 50, y: 10}, {x: 50, y: 50}],
[{x: 90, y: 50}, {x: 50, y: 50}],
[{x: 50, y: 90}, {x: 50, y: 50}],
]
let path = new Path2D()
segments.forEach(segment => {
path.moveTo(segment[0].x, segment[0].y)
path.lineTo(segment[1].x, segment[1].y)
})
const ctx = document.getElementById('my-canvas').getContext('2d')
ctx.lineWidth = 5
ctx.filter = 'drop-shadow(-3px -3px 3px #f00)';
ctx.strokeStyle = 'black'
ctx.stroke(path)
<canvas width="100" height="100" id="my-canvas" style="background: #00ff00"/>
您可以在此处阅读有关 Path2D
的更多信息:
https://developer.mozilla.org/en-US/docs/Web/API/Path2D/Path2D
我正在尝试在 canvas 上绘制多个笔触,我希望它们有一个共同的阴影。目前相互投射的阴影不是我想要的。
理想结果
我试过的
如果您需要每个笔划都是独立的(即它们都有自己的 strokeStyle 或 lineWidth),您将需要使用第二个分离的 canvas:
- 在这个分离的 canvas 上,你画的所有笔触都没有阴影
- 你
drawImage
分离 canvas 在可见的阴影上:
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
const detached = canvas.cloneNode();
const detachedCtx = detached.getContext("2d");
const colors = ["green", "blue", "yellow", "orange", "aqua"];
detachedCtx.lineWidth = 5;
for (let color of colors) {
// draw on the detached canvas
detachedCtx.beginPath();
for (let i = 0; i<5; i++) {
detachedCtx.lineTo(Math.random() * canvas.width, Math.random() * canvas.height);
}
detachedCtx.strokeStyle = color;
detachedCtx.lineWidth = Math.random() * 8 + 2;
detachedCtx.stroke();
}
// now draw all this with shadows on the visible canvas
ctx.shadowOffsetX = 3;
ctx.shadowOffsetY = 3;
ctx.shadowBlur = 3;
ctx.shadowColor = "red";
ctx.drawImage(detached, 0, 0);
<canvas></canvas>
但是要生成图像,您只需要在完成完整路径后调用 stroke()
一次:
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
ctx.fillStyle = "#0F0";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.lineWidth = 5;
ctx.shadowOffsetX = -3;
ctx.shadowOffsetY = -3;
ctx.shadowBlur = 3;
ctx.shadowColor = "red";
ctx.moveTo(10, 50);
ctx.lineTo(90, 50);
ctx.moveTo(50, 10);
ctx.lineTo(50, 90);
ctx.stroke(); // stroke only once, with the full path being traced
<canvas width=100 height=100></canvas>
您可以使用 Path2D
并将所有线段添加到一条路径,然后对该路径进行描边。
这是我推荐的使用 ctx.filter 的 jsfiddle。
const segments = [
[{x: 10, y: 50}, {x: 50, y: 50}],
[{x: 50, y: 10}, {x: 50, y: 50}],
[{x: 90, y: 50}, {x: 50, y: 50}],
[{x: 50, y: 90}, {x: 50, y: 50}],
]
let path = new Path2D()
segments.forEach(segment => {
path.moveTo(segment[0].x, segment[0].y)
path.lineTo(segment[1].x, segment[1].y)
})
const ctx = document.getElementById('my-canvas').getContext('2d')
ctx.lineWidth = 5
ctx.filter = 'drop-shadow(-3px -3px 3px #f00)';
ctx.strokeStyle = 'black'
ctx.stroke(path)
<canvas width="100" height="100" id="my-canvas" style="background: #00ff00"/>
您可以在此处阅读有关 Path2D
的更多信息:
https://developer.mozilla.org/en-US/docs/Web/API/Path2D/Path2D