0

嘿,我在画布上有两个圆形图像

我想要这两件事:

  1. 当我们单击按钮 wheel1 时,我想将左轮顺时针旋转 45 度并停止。
  2. 当我们单击按钮 wheel2 时,我想将右轮逆时针旋转 45 度并停止。

我已经能够实现第一个。但是我今天已经尝试了一整天,我无法弄清楚我怎样才能达到第二点。当我单击第二个按钮时,左轮停止旋转,右轮在整个画布中旋转。

如何将右轮逆时针旋转到 45 度?还有其他有效的方法来实现我已经实现的问题中的部分吗?

4

1 回答 1

1
  • 只加载一次图像。每次需要绘制图像时都无需加载图像。两个轮子也是相同的图像,因此您只需要一个图像副本。

  • 用于requestAnimationFrame为画布内容设置动画。

  • 只获取一次画布上下文。无需每帧都获取它。

  • 避免在不需要时更改画布大小,例如设置画布宽度或高度,即使相同的值会重置整个 2D 上下文状态。

  • 不要重复相同的代码。除了位置和旋转外,车轮几乎相同。定义一个描述轮子的对象并为两个轮子创建该对象,仅设置使它们唯一的属性。

  • 你真的需要 jQuery 吗?只是膨胀会减慢您的页面速度,并且对于您加载的所有这些额外的 javascript 行,您只调用了两次。使用 jQuery 不再重要,现代浏览器 API 更快、更强大。不要落后。

例子

使用上述要点编写代码的示例。

const wheelImg = new Image;
wheelImg.src = "https://www.freeiconspng.com/uploads/car-wheel-png-image-free-download--car-wheel-png-image-free--11.png";
canvas.width = innerWidth - 30;
canvas.height = innerHeight - 40;
const ctx = canvas.getContext("2d");
const wheelScale = 0.4;  // scales the wheels
const rotateCount = 100; // frames (@60 per second)
var activeWheelCount = 0; // to track if any wheels are active

// when the image has loaded set up click events and draw the first frame
wheelImg.addEventListener("load",() => { 
    requestAnimationFrame(mainLoop)
    clockwiseBtn.addEventListener("click",() => wheels[0].start(Math.PI / 2));
    antiClockwiseBtn.addEventListener("click",() => wheels[1].start(-Math.PI / 2));
    }
    ,{once:true}
);

// defines a single wheel
const wheel = (x,y,rot) => ({
    x,y,rot,
    rotTarget: rot,
    counter: 0,
    start(ang) {   // command a wheel to turn 
      if (!this.counter ) {  // make sure not already turning
          this.counter = rotateCount;
          this.rotTarget += ang;
          if (!activeWheelCount) { requestAnimationFrame(mainLoop) } // start the
                                                                     // animation is no wheel
                                                                     // is active
          activeWheelCount ++;
      }
    },
    update() {  // update the wheel animation counter
        this.counter += this.counter > 0 ? -1 : 0;
        if (this.counter === 0) {  this.rot = this.rotTarget }
        else { activeWheelCount += 1 } // count this wheel as an active wheel
    },
    draw() { // draw the wheel
        const r = (1 - (this.counter / rotateCount))  * (this.rotTarget - this.rot) + this.rot;
        ctx.setTransform(wheelScale, 0, 0, wheelScale, this.x, this.y);
        ctx.rotate(r);
        ctx.drawImage(wheelImg, -wheelImg.width / 2, -wheelImg.height / 2);

    }
});
const wheels = [wheel(90,80, 0), wheel(350,80,0)]; // create two wheels
 
function mainLoop() {  // animates wheels
    activeWheelCount = 0;
    ctx.setTransform(1, 0, 0, 1, 0, 0);
    ctx.clearRect(0,0,ctx.canvas.width, ctx.canvas.height);
    wheels.forEach(wheel => wheel.update());
    wheels.forEach(wheel => wheel.draw());
    if (activeWheelCount) {
        requestAnimationFrame(mainLoop);
    }
}
#canvas {
  border:solid 1px black;
  position:absolute;
  top:30px;
  left:0px;
}
  <canvas id="canvas"></canvas>
  <button id='clockwiseBtn'>Wheel1</button>
  <button id='antiClockwiseBtn'>Wheel2</button>

于 2020-01-10T00:37:59.140 回答