I am trying to fill a path2d object of the HTML5 canvas.context.
I have drawn a custom path that is a bezier curve according to this site: https://javascript.info/bezier-curve
but am unable to get it to fill with a solid colour.
Here is some code in a jsfiddle to illustrate my problem. If I uncomment the line //this.ctx.stroke(this.p2d);
then the outline of the bezier curve will be drawn, but I can't seem to fill the completed path.
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. this is advanced math for me, so although my formula for calculating x and y is correct, it may not be optimised properly.
Every time you move there will be nothing to fill...
All you are drawing at the end is lines with that technique, see the difference in the code below.
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>
So in your code just commenting the this.p2d.moveTo
does it
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>