【问题标题】:Canvas not rotating after calling setTransform调用 setTransform 后画布不旋转
【发布时间】:2016-06-15 05:32:02
【问题描述】:

我有一个 HTML5 画布,我在其中画一条线并围绕中心旋转。我想在每次绘制时重置画布的转换,然后重新翻译/旋转画布,但它似乎没有旋转。我有一个工作示例,其中我存储了先前的旋转并且仅旋转角度差(显然,在此示例中,我不重置转换)但在此代码的未经处理的版本中,它没有提供足够的解决方法.

我创建了两个小提琴,the first version 在其中我重置了变换但它不能正常工作,the second version 我在其中存储角度差异并且它可以正常工作。下面复制的片段。 如何调整第二个版本以与第一个版本相同的方式运行?

第一个版本(功能性,不受欢迎的实现)

(function () {    
    // dynamic canvas
    var dynamic = document.getElementById("dynamic");
    var dynamicCtx = dynamic.getContext("2d");
    
    // animation status
    var FPS = 10;
    var INTERVAL = 1000 / FPS;
    
    dynamicCtx.translate(dynamic.width/2, dynamic.width/2);
    var previousRotation_rad = 0;
    var rotationCounter_deg = 0;

    var myDynamicObject = {
    		center: dynamic.width / 2,
        length: dynamic.width * 0.4,
        draw: function () {   // example of dynamic animation code
        		dynamicCtx.clearRect(-this.center, -this.center, 2*this.center, 2*this.center);
            
            // draw the current rotation angle
            dynamicCtx.textBaseline = 'middle';
            dynamicCtx.textAlign = 'center';
            dynamicCtx.fillText(rotationCounter_deg + '°', 0, -this.length);
            
            // draw a line from the center up
            dynamicCtx.beginPath();
            dynamicCtx.moveTo(0, 0);
            dynamicCtx.lineTo(0, -this.length + 20);
            dynamicCtx.stroke();
            
            // rotate the canvas
            var currentRotation_rad = rotationCounter_deg * Math.PI / 180;
            var rotationDifference_rad = currentRotation_rad - previousRotation_rad;
            previousRotation_rad = currentRotation_rad;
            console.log('rotating', rotationDifference_rad, 'radians');
            dynamicCtx.rotate(rotationDifference_rad);
          	++rotationCounter_deg;
        }
    };

    function drawDynamic() {        
        myDynamicObject.draw();
        // you can add more dynamic objects and draw here
    }

    function animate() {
        setInterval(function () {
            // only need to redraw dynamic objects
            drawDynamic();
        }, INTERVAL);
    }

    animate(); // entry point for animated (dynamic) objects
})();
#canvasesdiv {
    position:relative;
    width:400px;
    height:400px;
}
#dynamic {
    position: absolute;
    left: 0;
    top: 0;
    z-index: 1;
}
<div id="canvasesdiv">
    <canvas id="dynamic" width=400 height=400>This text is displayed if your browser does not support HTML5 Canvas</canvas>
</div>

第二个版本(非功能性,期望的实现)

(function () {    
    // dynamic canvas
    var dynamic = document.getElementById("dynamic");
    var dynamicCtx = dynamic.getContext("2d");
    
    // animation status
    var FPS = 10;
    var INTERVAL = 1000 / FPS;
    
    var rotationCounter_deg = 0;

    var myDynamicObject = {
    		center: dynamic.width / 2,
        length: dynamic.width * 0.4,
        draw: function () {   // example of dynamic animation code
        		dynamicCtx.setTransform(1, 0, 0, 1, 0, 0);
    				dynamicCtx.translate(dynamic.width/2, dynamic.width/2);
        		dynamicCtx.clearRect(-this.center, -this.center, 2*this.center, 2*this.center);
            
            // draw the current rotation angle
            dynamicCtx.textBaseline = 'middle';
            dynamicCtx.textAlign = 'center';
            dynamicCtx.fillText(rotationCounter_deg + '°', 0, -this.length);
            
            // draw a line from the center up
            dynamicCtx.beginPath();
            dynamicCtx.moveTo(0, 0);
            dynamicCtx.lineTo(0, -this.length + 20);
            dynamicCtx.stroke();
            
            // rotate the canvas
            var currentRotation_rad = rotationCounter_deg * Math.PI / 180;
            console.log('rotating', currentRotation_rad, 'radians');
            dynamicCtx.rotate(currentRotation_rad);
          	++rotationCounter_deg;
        }
    };

    function drawDynamic() {        
        myDynamicObject.draw();
        // you can add more dynamic objects and draw here
    }

    function animate() {
        setInterval(function () {
            // only need to redraw dynamic objects
            drawDynamic();
        }, INTERVAL);
    }

    animate(); // entry point for animated (dynamic) objects
})();
#canvasesdiv {
    position:relative;
    width:400px;
    height:400px;
}
#dynamic {
    position: absolute;
    left: 0;
    top: 0;
    z-index: 1;
}
<div id="canvasesdiv">
    <canvas id="dynamic" width=400 height=400>This text is displayed if your browser does not support HTML5 Canvas</canvas>
</div>

【问题讨论】:

    标签: javascript canvas


    【解决方案1】:

    与例如 CSS 不同,画布上下文呈现中间状态,因此必须在绘制任何内容之前应用所有变换

    在绘制到画布和声明之前,只需将旋转变换向上移动即可:

    (function() {
      // dynamic canvas
      var dynamic = document.getElementById("dynamic");
      var dynamicCtx = dynamic.getContext("2d");
    
      // animation status
      var FPS = 10;
      var INTERVAL = 1000 / FPS;
    
      var rotationCounter_deg = 0;
    
      var myDynamicObject = {
        center: dynamic.width / 2,
        length: dynamic.width * 0.4,
        draw: function() { // example of dynamic animation code
          var currentRotation_rad = rotationCounter_deg * Math.PI / 180;
    
          dynamicCtx.setTransform(1, 0, 0, 1, 0, 0);
          dynamicCtx.translate(dynamic.width / 2, dynamic.width / 2);
          dynamicCtx.clearRect(-this.center, -this.center, 2 * this.center, 2 * this.center);
          dynamicCtx.rotate(currentRotation_rad);
    
          // draw the current rotation angle
          dynamicCtx.textBaseline = 'middle';
          dynamicCtx.textAlign = 'center';
          dynamicCtx.fillText(rotationCounter_deg + '°', 0, -this.length);
    
          // draw a line from the center up
          dynamicCtx.beginPath();
          dynamicCtx.moveTo(0, 0);
          dynamicCtx.lineTo(0, -this.length + 20);
          dynamicCtx.stroke();
    
          // rotate the canvas
          console.log('rotating', currentRotation_rad, 'radians');
          ++rotationCounter_deg;
        }
      };
    
      function drawDynamic() {
        myDynamicObject.draw();
        // you can add more dynamic objects and draw here
      }
    
      function animate() {
        setInterval(function() {
          // only need to redraw dynamic objects
          drawDynamic();
        }, INTERVAL);
      }
    
      animate(); // entry point for animated (dynamic) objects
    })();
    #canvasesdiv {
      position: relative;
      width: 400px;
      height: 400px;
    }
    #dynamic {
      position: absolute;
      left: 0;
      top: 0;
      z-index: 1;
    }
    <div id="canvasesdiv">
      <canvas id="dynamic" width=400 height=400>This text is displayed if your browser does not support HTML5 Canvas</canvas>
    </div>

    额外提示:您还可以合并setTransform() 和第一个translate()

    dynamicCtx.setTransform(1, 0, 0, 1, 0, 0);
    dynamicCtx.translate(dynamic.width / 2, dynamic.width / 2);
    

    到:

    dynamicCtx.setTransform(1, 0, 0, 1, dynamic.width * 0.5, dynamic.width * 0.5);
    

    【讨论】:

    • 我想我被抛出了一些过去的经历。这现在看起来很明显,谢谢!
    【解决方案2】:

    您在绘制内容后正在旋转画布。先旋转一下就可以了。

    【讨论】:

    • 你能用一些示例代码扩展你的答案吗?
    猜你喜欢
    • 1970-01-01
    • 2015-10-01
    • 2014-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-23
    • 2012-03-16
    相关资源
    最近更新 更多