【问题标题】:Rotate one wheel clockwise and another wheel anticlockwise in the same canvas在同一画布中顺时针旋转一个轮子,逆时针旋转另一个轮子
【发布时间】:2020-04-27 09:46:31
【问题描述】:

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

我想要这两件事:

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

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

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

【问题讨论】:

    标签: javascript html user-interface canvas html5-canvas


    【解决方案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>

    【讨论】:

    • 得到了大部分。但我想弄清楚如何在这段代码中提高旋转速度,旋转角度为 45 度。我打电话给 start(Math. PI/4) 并写了这个。 rotTarget += ang +1;这增加了速度,但也增加了角度。有没有办法在不增加角度的情况下提高速度?
    • @abhishekranjan 常量rotateCount 当前设置为 100 定义转动轮子所需的帧数(第 60 秒)。如果你把它改成60,轮子转1/4需要1秒,改成30,转个半秒。
    猜你喜欢
    • 1970-01-01
    • 2020-08-13
    • 1970-01-01
    • 2011-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多