Within my HTML5 canvas, I have been experimenting with drawing lines and rotating them around the center point. My goal is to reset the canvas's transformation each time I draw, followed by re-translating/rotating the canvas. However, I have encountered an issue where the rotation does not seem to take effect as intended. In one version of my code, I managed to achieve the desired outcome by storing the previous rotation and only rotating based on the difference in angles.
To illustrate this problem, I have created two fiddles - the first version where the transform reset doesn't work properly and the second version where adjusting the angle difference works correctly. Both snippets are provided below. How can I modify the second version to replicate the functionality of the first?
First version (functional but undesired approach)
(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>
Second version (non-functional yet desired implementation)
(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>