Масштабирование кривых Безье с помощью анимации - PullRequest
0 голосов
/ 04 августа 2020

Я хочу создать анимацию, которая масштабирует 2 кривые Безье моего элемента холста Heart. Я попытался поставить значение перед всеми значениями кривой Безье, но он просто больше не рисовал кривую Безье. Как я могу масштабировать обе эти кривые, чтобы сделать их больше?

Heartdraw ()

    draw2(): void {

        crc2.beginPath();
        crc2.restore();
        crc2.moveTo(this.x, this.y); 
        crc2.bezierCurveTo(this.x + 82, this.y - 40, this.x, this.y - 80, this.x, this.y - 50);
        crc2.save();
        crc2.stroke();
        crc2.moveTo(this.x, this.y);
        crc2.bezierCurveTo(this.x - 82, this.y - 40, this.x, this.y - 80, this.x, this.y - 50);
        crc2.fillStyle = "Red";
        crc2.fill();
        crc2.restore();
        crc2.closePath();
        crc2.save();


    }

}

Для чего я пробовал:

    initScale: number = 1;
    scaleVal: number;


    animate(): void {

        if(this.scaleVal == 1){
        this.scaleVal += 2;
        }
        else if (this.scaleVal == 3) {
            this.scaleVal -= 2;
        }

    }




    draw2(): void {

        crc2.beginPath();

        crc2.restore();
        crc2.moveTo(this.x, this.y); 
        crc2.bezierCurveTo(this.scaleVal * this.x + 82, this.scaleVal * this.y - 40, this.scaleVal * this.x, this.scaleVal *  this.y - 80, this.scaleVal * this.x, this.scaleVal *  this.y - 50);
        crc2.save();
        crc2.stroke();
        crc2.moveTo(this.x, this.y);
        crc2.bezierCurveTo(this.x - 82, this.y - 40, this.x, this.y - 80, this.x, this.y - 50);
        crc2.fillStyle = "Red";
        crc2.fill();
        crc2.scale(this.xScale, this.yScale);
        crc2.restore();
        crc2.closePath();
        crc2.save();


    }

}

1 Ответ

0 голосов
/ 04 августа 2020

Преобразование визуализированного содержимого

Используйте преобразование холста для масштабирования визуализированного содержимого.

В приведенном ниже примере используется ctx.translate для размещения визуализации и ctx.scale для масштабирования.

Преобразование сбрасывается с помощью ctx.setTransform(1, 0, 0, 1, 0, 0), что намного быстрее, чем использование ctx.save и ctx.restore

Масштабировать траекторию, а не обводку

Чтобы lineWidth оставалось постоянным, преобразование сбрасывается после определения траектории Безье и до stroke Вызывается .

requestAnimationFrame(mainLoop);  // start animation
const ctx = canvas.getContext("2d");
const heart = {
    x: 100, y : 100, scale : 1,
    draw() {
        ctx.fillStyle = "Red";
        ctx.lineWidth = 4;

        ctx.translate(this.x, this.y);     // set origin 
        ctx.scale(this.scale, this.scale); // set scale

        ctx.beginPath();
        ctx.moveTo(0, 0); 
        ctx.bezierCurveTo(82, -40, 0, -80, 0, -50);
        ctx.bezierCurveTo(0, -80, -80, -40, 0, 0);
        
        // to keep the line width constant reset the transform after defining the path
        ctx.setTransform(1, 0, 0, 1, 0, 0);  // restore default transform
        ctx.stroke();
        ctx.fill();
    }
}

function mainLoop(time) {
    ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
    heart.scale = Math.sin(time / 100) * 0.2 + 1; // animate scale
    heart.draw();
    requestAnimationFrame(mainLoop);
}
<canvas id="canvas"></canvas>
...