调用setTransform

时间:2016-06-14 21:13:33

标签: javascript canvas

我有一个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>

2 个答案:

答案 0 :(得分:2)

与示例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);

答案 1 :(得分:1)

绘制内容后,您正在旋转画布。首先旋转,它工作正常。