Javascript 如何在连续循环中放大和缩小画布图像?

Javascript 如何在连续循环中放大和缩小画布图像?,javascript,jquery,css,html,canvas,Javascript,Jquery,Css,Html,Canvas,我在画布上创建了一个云形状,我想知道如何在大小之间来回缩放该形状。就像我希望云变大,比变小,然后变大,然后变小,等等 我能够使用when-then方法上下移动一个单独的画布图像,但我认为通过增加画布大小,该方法不起作用,因为实际图像保持缩放 这是我的画布代码: <script> var canvas = document.getElementById('hardware-cloud'); var context = canvas.getContext('2d'); // begin

我在画布上创建了一个云形状,我想知道如何在大小之间来回缩放该形状。就像我希望云变大,比变小,然后变大,然后变小,等等

我能够使用when-then方法上下移动一个单独的画布图像,但我认为通过增加画布大小,该方法不起作用,因为实际图像保持缩放

这是我的画布代码:

<script>
var canvas = document.getElementById('hardware-cloud');
var context = canvas.getContext('2d');

// begin cloud shape-Hardware
context.beginPath();
context.moveTo(180, 80);
context.bezierCurveTo(150, 132, 143, 165, 203, 154);
context.bezierCurveTo(203, 154, 180, 200, 260, 175);
context.bezierCurveTo(297, 231, 352, 198, 344, 185);
context.bezierCurveTo(344, 185, 372, 215, 374, 175);
context.bezierCurveTo(473, 165, 462, 132, 429, 110);
context.bezierCurveTo(473, 44, 407, 33, 374, 55);
context.bezierCurveTo(352, 10, 275, 22, 275, 55);
context.bezierCurveTo(210, 20, 165, 22, 180, 80);

// complete cloud shape-Hardware
context.closePath();
context.lineWidth = 5;
context.strokeStyle = 'navy';
context.stroke();
context.fillStyle = 'white';
context.fill();

//font inside hardware cloud
context.beginPath();
context.font = 'bold 15pt Calibri';
context.textAlign = 'center';
context.fillStyle ="navy";  // <-- Text colour here
context.fillText('Why not the electronic store?', 300, 120);
context.lineWidth = 2;
context.strokeStyle = 'grey';
context.stroke();
context.closePath();

//top  hardware circle
context.beginPath();
context.arc(380, 220, 13, 0, Math.PI * 2, false);
context.lineWidth = 5;
context.strokeStyle = 'navy';
context.stroke();
context.fillStyle = 'white';
context.fill();
context.closePath();

//middle hardware circle
context.beginPath();
context.arc(398, 253, 10, 0, Math.PI * 2, false);
context.lineWidth = 5;
context.strokeStyle = 'navy';
context.stroke();
context.fillStyle = 'white';
context.fill();
context.closePath();

//bottom hardware circle
context.beginPath();
context.arc(425, 273, 7, 0, Math.PI * 2, false);
context.lineWidth = 5;
context.strokeStyle = 'navy';
context.stroke();
context.fillStyle = 'white';
context.fill();
context.closePath();
</script>

可以使用“缩放”和“平移”更改形状的大小

所有变换都适用于下一个绘制的形状,不会影响已绘制的形状

因此,要使其工作,您需要清除画布,变换,然后重新绘制形状

例如,重新计算代码的因子,以便调用
shape()
绘制云,然后:

  • 清除canvas
    ctx.clearRect(0,0,canvas.width,canvas.height)
  • 应用scale
    ctx.scale(scaleX,scaleY)
  • 可选择使用
    ctx.translate(deltaX,deltaY)平移形状
  • 重新绘制形状
    shape()
  • 在循环中重复使用例如
    requestAnimationFrame()
比例值为1=1:1,0.5=1/2等。请记住这些变换是累积的(您可以使用
setTransform()
每次设置绝对变换)

更新

这里有一种方法可以做到这一点:

var maxScale = 1,  // for demo, this represents "max"
    current = 0,   // angle (in radians) used to scale smoother
    step = 0.02,   // speed
    pi2 = Math.PI; // cached value

// main loop clears, transforms and redraws shape
function loop() {
    context.clearRect(0, 0, canvas.width, canvas.height);
    transform();
    drawShape();
    requestAnimationFrame(loop);
}
requestAnimationFrame(loop);

// set scale based on rotation
function transform() {
    current += step;
    current %= pi2;

    // just play around with different combinations here
    var s = (maxScale * Math.abs(Math.sin(current))) / maxScale + 0.5;

    // set absolute scale
    context.setTransform(s, 0, 0, s, 0, 0);
}

// wrap shape calls in a function so it can be reused
function drawShape() {
    // begin cloud shape-Hardware
    context.beginPath();
    ... rest goes here...
此外,可以使用
translate()
重新定位链接到旋转值的形状


希望这有帮助

啊,我被卡住了。你能帮我打个电话吗?我需要像这样重新绘制形状吗?函数redraw(){var canvas=document.getElementById(“硬件云”);var ctx=canvas.getContext(“2d”);ctx.scale(0.9,0.9);我通过以下方式调用整个画布:函数callshape(){@user3386635请设置一个小提琴,然后我们可以使用它作为基础。
var maxScale = 1,  // for demo, this represents "max"
    current = 0,   // angle (in radians) used to scale smoother
    step = 0.02,   // speed
    pi2 = Math.PI; // cached value

// main loop clears, transforms and redraws shape
function loop() {
    context.clearRect(0, 0, canvas.width, canvas.height);
    transform();
    drawShape();
    requestAnimationFrame(loop);
}
requestAnimationFrame(loop);

// set scale based on rotation
function transform() {
    current += step;
    current %= pi2;

    // just play around with different combinations here
    var s = (maxScale * Math.abs(Math.sin(current))) / maxScale + 0.5;

    // set absolute scale
    context.setTransform(s, 0, 0, s, 0, 0);
}

// wrap shape calls in a function so it can be reused
function drawShape() {
    // begin cloud shape-Hardware
    context.beginPath();
    ... rest goes here...