填充由 path2d 对象定义的自定义对象
fill a custom object defined by a path2d object
我正在尝试填充 HTML5 canvas.context 的 path2d 对象。
我根据这个网站画了一条自定义路径,是一条贝塞尔曲线:
https://javascript.info/bezier-curve
但无法用纯色填充。
这是 jsfiddle 中的一些代码来说明我的问题。如果我取消注释 //this.ctx.stroke(this.p2d);
行,则会绘制贝塞尔曲线的轮廓,但我似乎无法填充完整的路径。
constructor () {
this.canv = document.getElementById('canv');
this.ctx = this.canv.getContext('2d');
this.ctx.beginPath();
this.ctx.moveTo(160,350);
this.ctx.restore();
this.p2d = new Path2D();
this.t = 0;
this.currentPoint = [160,350];
this.to = setInterval(() => this.plot(), 10, this.to);
}
plot(intid) {
const p1x = 160;
const p2x = 20;
const p3x = 320;
const p4x = 160;
const p1y = 350;
const p2y = 50;
const p3y = 50;
const p4y = 350;
let t = this.t;
let x = (((1 - t)*(1 - t)*(1 - t)) * p1x) + ((3 * ((1 - t) * (1 -t))) * (t * p2x)) + ((3 * ((1 - t) * (1 -t))) * (t * p3x)) + ((t * t * t) * p4x);
let y = (((1 - t)*(1 - t)*(1 - t)) * p1y) + ((3 * ((1 - t) * (1 -t))) * (t * p2y)) + ((3 * ((1 - t) * (1 -t))) * (t * p3y)) + ((t * t * t) * p4y);
this.t = t + 0.01;
if (t <= 1.01) {
//this.p2d.fillStyle = "#1000ff";
this.p2d.moveTo(this.currentPoint[0], this.currentPoint[1]);
this.p2d.lineTo(x, y);
this.currentPoint[0] = x;
this.currentPoint[1] = y;
console.log(x + " " + y + " " + t)
}
else
{
//this.p2d.closePath();
this.ctx.lineWidth = 2;
this.ctx.strokeStyle = "blue";
this.ctx.fillStyle = "blue";
//this.ctx.stroke(this.p2d);
this.ctx.fill(this.p2d, "evenodd");
clearInterval(this.to);
}
}
}
Window.cl = new clazz();
https://jsfiddle.net/9oL4xw1b/2/
ps。这对我来说是高等数学,所以虽然我计算 x 和 y 的公式是正确的,但可能没有正确优化。
每次移动都不会填满...
你最后画的都是用那种技术画的线,看看下面代码的区别。
canv = document.getElementById('canv');
ctx = canv.getContext('2d');
ctx.fillStyle = "blue";
ctx.moveTo(10, 10);
ctx.lineTo(20, 40);
ctx.lineTo(99, 40);
ctx.lineTo(90, 30);
ctx.fill();
ctx.stroke();
ctx.moveTo(100, 10);
ctx.lineTo(120, 40);
ctx.moveTo(120, 40);
ctx.lineTo(200, 40);
ctx.moveTo(200, 40);
ctx.lineTo(190, 30);
ctx.fill();
ctx.stroke();
<canvas id="canv" width="500px" height="100px"></canvas>
所以在您的代码中,只需注释 this.p2d.moveTo
就可以了
class clazz {
constructor() {
this.canv = document.getElementById('canv');
this.ctx = this.canv.getContext('2d');
this.ctx.moveTo(160, 350);
this.p2d = new Path2D();
this.t = 0;
this.currentPoint = [160, 350];
this.to = setInterval(() => this.plot(), 5, this.to);
}
plot(intid) {
const p1x = 160; const p2x = 20;
const p3x = 320; const p4x = 160;
const p1y = 350; const p2y = 50;
const p3y = 50; const p4y = 350;
let t = this.t;
let x = (((1 - t) * (1 - t) * (1 - t)) * p1x) + ((3 * ((1 - t) * (1 - t))) * (t * p2x)) + ((3 * ((1 - t) * (1 - t))) * (t * p3x)) + ((t * t * t) * p4x);
let y = (((1 - t) * (1 - t) * (1 - t)) * p1y) + ((3 * ((1 - t) * (1 - t))) * (t * p2y)) + ((3 * ((1 - t) * (1 - t))) * (t * p3y)) + ((t * t * t) * p4y);
this.t = t + 0.01;
if (t <= 1.01) {
//this.p2d.moveTo(this.currentPoint[0], this.currentPoint[1]);
this.p2d.lineTo(x, y);
this.ctx.stroke(this.p2d);
} else {
this.ctx.lineWidth = 2;
this.ctx.strokeStyle = "blue";
this.ctx.fillStyle = "blue";
this.ctx.fill(this.p2d, "evenodd");
clearInterval(this.to);
}
}
}
Window.cl = new clazz();
<canvas id="canv" width="500px" height="500px"></canvas>
我正在尝试填充 HTML5 canvas.context 的 path2d 对象。
我根据这个网站画了一条自定义路径,是一条贝塞尔曲线: https://javascript.info/bezier-curve
但无法用纯色填充。
这是 jsfiddle 中的一些代码来说明我的问题。如果我取消注释 //this.ctx.stroke(this.p2d);
行,则会绘制贝塞尔曲线的轮廓,但我似乎无法填充完整的路径。
constructor () {
this.canv = document.getElementById('canv');
this.ctx = this.canv.getContext('2d');
this.ctx.beginPath();
this.ctx.moveTo(160,350);
this.ctx.restore();
this.p2d = new Path2D();
this.t = 0;
this.currentPoint = [160,350];
this.to = setInterval(() => this.plot(), 10, this.to);
}
plot(intid) {
const p1x = 160;
const p2x = 20;
const p3x = 320;
const p4x = 160;
const p1y = 350;
const p2y = 50;
const p3y = 50;
const p4y = 350;
let t = this.t;
let x = (((1 - t)*(1 - t)*(1 - t)) * p1x) + ((3 * ((1 - t) * (1 -t))) * (t * p2x)) + ((3 * ((1 - t) * (1 -t))) * (t * p3x)) + ((t * t * t) * p4x);
let y = (((1 - t)*(1 - t)*(1 - t)) * p1y) + ((3 * ((1 - t) * (1 -t))) * (t * p2y)) + ((3 * ((1 - t) * (1 -t))) * (t * p3y)) + ((t * t * t) * p4y);
this.t = t + 0.01;
if (t <= 1.01) {
//this.p2d.fillStyle = "#1000ff";
this.p2d.moveTo(this.currentPoint[0], this.currentPoint[1]);
this.p2d.lineTo(x, y);
this.currentPoint[0] = x;
this.currentPoint[1] = y;
console.log(x + " " + y + " " + t)
}
else
{
//this.p2d.closePath();
this.ctx.lineWidth = 2;
this.ctx.strokeStyle = "blue";
this.ctx.fillStyle = "blue";
//this.ctx.stroke(this.p2d);
this.ctx.fill(this.p2d, "evenodd");
clearInterval(this.to);
}
}
}
Window.cl = new clazz();
https://jsfiddle.net/9oL4xw1b/2/
ps。这对我来说是高等数学,所以虽然我计算 x 和 y 的公式是正确的,但可能没有正确优化。
每次移动都不会填满...
你最后画的都是用那种技术画的线,看看下面代码的区别。
canv = document.getElementById('canv');
ctx = canv.getContext('2d');
ctx.fillStyle = "blue";
ctx.moveTo(10, 10);
ctx.lineTo(20, 40);
ctx.lineTo(99, 40);
ctx.lineTo(90, 30);
ctx.fill();
ctx.stroke();
ctx.moveTo(100, 10);
ctx.lineTo(120, 40);
ctx.moveTo(120, 40);
ctx.lineTo(200, 40);
ctx.moveTo(200, 40);
ctx.lineTo(190, 30);
ctx.fill();
ctx.stroke();
<canvas id="canv" width="500px" height="100px"></canvas>
所以在您的代码中,只需注释 this.p2d.moveTo
就可以了
class clazz {
constructor() {
this.canv = document.getElementById('canv');
this.ctx = this.canv.getContext('2d');
this.ctx.moveTo(160, 350);
this.p2d = new Path2D();
this.t = 0;
this.currentPoint = [160, 350];
this.to = setInterval(() => this.plot(), 5, this.to);
}
plot(intid) {
const p1x = 160; const p2x = 20;
const p3x = 320; const p4x = 160;
const p1y = 350; const p2y = 50;
const p3y = 50; const p4y = 350;
let t = this.t;
let x = (((1 - t) * (1 - t) * (1 - t)) * p1x) + ((3 * ((1 - t) * (1 - t))) * (t * p2x)) + ((3 * ((1 - t) * (1 - t))) * (t * p3x)) + ((t * t * t) * p4x);
let y = (((1 - t) * (1 - t) * (1 - t)) * p1y) + ((3 * ((1 - t) * (1 - t))) * (t * p2y)) + ((3 * ((1 - t) * (1 - t))) * (t * p3y)) + ((t * t * t) * p4y);
this.t = t + 0.01;
if (t <= 1.01) {
//this.p2d.moveTo(this.currentPoint[0], this.currentPoint[1]);
this.p2d.lineTo(x, y);
this.ctx.stroke(this.p2d);
} else {
this.ctx.lineWidth = 2;
this.ctx.strokeStyle = "blue";
this.ctx.fillStyle = "blue";
this.ctx.fill(this.p2d, "evenodd");
clearInterval(this.to);
}
}
}
Window.cl = new clazz();
<canvas id="canv" width="500px" height="500px"></canvas>