如何去除重叠笔画
How to remove overlapping stroke
我正在尝试绘制一组圆圈,这些圆圈应该打断一组直线。
如果圆圈彼此远离,一切看起来都很好,但如果圆圈重叠 - 下面会出现笔画。
关于如何在圆圈重叠时删除此笔画的任何提示?
这就是我要说的:
这是我的代码:
let canvas = document.getElementById('myCanvas')
let ctx = canvas.getContext('2d');
document.body.style.backgroundColor = "#121212";
ctx.lineWidth = 1;
ctx.fillStyle = '#121212';
ctx.strokeStyle = '#9f9999';
ctx.lineCap = "round";
let width = canvas.width;
let height = canvas.height;
let lines = new Array(height);
let singleLine = new Array(width);
let step = 30;
for (let y = step; y < height; y += step) {
ctx.beginPath();
for (let x = step; x < width; x += step) {
if (Math.random() < 0.85) {
ctx.lineTo(x, y);
} else {
drawCircle(y, x);
}
}
ctx.stroke();
ctx.fill();
}
function drawCircle(x, y) {
ctx.arc(y, x, 20, Math.PI, 0, false);
}
<canvas id="myCanvas"></canvas>
发生这种情况是因为您通过 fill()
覆盖交点的方式将覆盖 仅 填充区域边界上的一半描边。这是圆形部分的 okay-ish,但两个圆弧之间的底部(隐式)lineTo
的下半部分仍然可见:
const ctx = document.querySelector("canvas").getContext("2d");
ctx.fillStyle = "rgba(255, 0, 0, 0.25)";
ctx.lineTo(30, 50);
ctx.lineTo(60, 50);
ctx.arc(90, 50, 20, Math.PI, 0);
ctx.arc(120, 50, 20, Math.PI, 0);
ctx.lineTo(150, 50);
ctx.lineTo(180, 50);
ctx.stroke();
ctx.fill();
// a zoomed in version in case it's not visible enough
const zoom = document.querySelectorAll("canvas")[1].getContext("2d");
zoom.scale(4, 4);
zoom.imageSmoothingEnabled = false;
zoom.drawImage(ctx.canvas, -70, -20);
canvas{ vertical-align: middle }
<canvas width=200></canvas>zoomed in: <canvas></canvas>
我最初的想法是在每个重叠的凹凸部分上绘制矩形,但更好的方法是 :在描边后稍微向下扩展填充,然后用背景颜色填充路径。这确保重叠线的底部笔划也被填充。
const canvas = document.querySelector("canvas")
const ctx = canvas.getContext("2d");
document.body.style.backgroundColor = "#121212";
ctx.lineWidth = 1;
ctx.fillStyle = "#121212";
ctx.strokeStyle = "#9f9999";
ctx.lineCap = "round";
const {width, height} = canvas;
const step = 30;
for (let y = step; y < height; y += step) {
ctx.beginPath();
for (let x = step; x < width; x += step) {
if (Math.random() < 0.55) {
ctx.lineTo(x, y);
}
else {
ctx.arc(x, y, 20, Math.PI, 0, false);
}
}
ctx.stroke();
ctx.lineTo(width - step, y + 1);
ctx.lineTo(step, y + 1);
//ctx.fillStyle = "red"; // to debug
ctx.fill();
}
<canvas></canvas>
我正在尝试绘制一组圆圈,这些圆圈应该打断一组直线。 如果圆圈彼此远离,一切看起来都很好,但如果圆圈重叠 - 下面会出现笔画。
关于如何在圆圈重叠时删除此笔画的任何提示? 这就是我要说的:
这是我的代码:
let canvas = document.getElementById('myCanvas')
let ctx = canvas.getContext('2d');
document.body.style.backgroundColor = "#121212";
ctx.lineWidth = 1;
ctx.fillStyle = '#121212';
ctx.strokeStyle = '#9f9999';
ctx.lineCap = "round";
let width = canvas.width;
let height = canvas.height;
let lines = new Array(height);
let singleLine = new Array(width);
let step = 30;
for (let y = step; y < height; y += step) {
ctx.beginPath();
for (let x = step; x < width; x += step) {
if (Math.random() < 0.85) {
ctx.lineTo(x, y);
} else {
drawCircle(y, x);
}
}
ctx.stroke();
ctx.fill();
}
function drawCircle(x, y) {
ctx.arc(y, x, 20, Math.PI, 0, false);
}
<canvas id="myCanvas"></canvas>
发生这种情况是因为您通过 fill()
覆盖交点的方式将覆盖 仅 填充区域边界上的一半描边。这是圆形部分的 okay-ish,但两个圆弧之间的底部(隐式)lineTo
的下半部分仍然可见:
const ctx = document.querySelector("canvas").getContext("2d");
ctx.fillStyle = "rgba(255, 0, 0, 0.25)";
ctx.lineTo(30, 50);
ctx.lineTo(60, 50);
ctx.arc(90, 50, 20, Math.PI, 0);
ctx.arc(120, 50, 20, Math.PI, 0);
ctx.lineTo(150, 50);
ctx.lineTo(180, 50);
ctx.stroke();
ctx.fill();
// a zoomed in version in case it's not visible enough
const zoom = document.querySelectorAll("canvas")[1].getContext("2d");
zoom.scale(4, 4);
zoom.imageSmoothingEnabled = false;
zoom.drawImage(ctx.canvas, -70, -20);
canvas{ vertical-align: middle }
<canvas width=200></canvas>zoomed in: <canvas></canvas>
我最初的想法是在每个重叠的凹凸部分上绘制矩形,但更好的方法是
const canvas = document.querySelector("canvas")
const ctx = canvas.getContext("2d");
document.body.style.backgroundColor = "#121212";
ctx.lineWidth = 1;
ctx.fillStyle = "#121212";
ctx.strokeStyle = "#9f9999";
ctx.lineCap = "round";
const {width, height} = canvas;
const step = 30;
for (let y = step; y < height; y += step) {
ctx.beginPath();
for (let x = step; x < width; x += step) {
if (Math.random() < 0.55) {
ctx.lineTo(x, y);
}
else {
ctx.arc(x, y, 20, Math.PI, 0, false);
}
}
ctx.stroke();
ctx.lineTo(width - step, y + 1);
ctx.lineTo(step, y + 1);
//ctx.fillStyle = "red"; // to debug
ctx.fill();
}
<canvas></canvas>