заполнить пользовательский объект, определенный объектом path2d - PullRequest
1 голос
/ 24 марта 2020

Я пытаюсь заполнить объект path2d HTML5 canvas.context.

Я нарисовал пользовательский путь, который является кривой Безье согласно этому сайту: https://javascript.info/bezier-curve

, но я не могу заставить его заполниться цветом solid.

Вот некоторый код в 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/

пс. для меня это сложная математика, поэтому, хотя моя формула для вычисления x и y верна, она не может быть оптимизирована должным образом.

1 Ответ

0 голосов
/ 24 марта 2020

Каждый раз, когда вы двигаетесь, заполнять нечего ...
Все, что вы рисуете в конце, это линии с этой техникой, см. Разницу в коде ниже.

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>
...