Reputation: 19
I would like the left and right arrow keys to rotate my canvas shape clockwise and anticlockwise, respectively. Currently the shape moves only linearly.
In the long run, I am trying to replicate the movement of my ROS (Robot Operating System) TurtleSim using this javascript code, and the left & right keys rotate the turtlesim in this way. (I am fairly new to javascript.)
<script>
function Parent(){
//diffColor = false;
mainCanvas.load();
tracker = new track(30, 50, "white", 30, 120); //create object that will move with keys;
click();
//touch();
//animate();
//mapCanvas.load();
}
function click(){
window.addEventListener("click", getClickPosition, false);
function getClickPosition(e){
tracker.distanceX = e.clientX - (tracker.width / 2); //move tracker to near center of tracker; clientX gets horizontal coordinate of cursor
tracker.distanceY = e.clientY - (tracker.height / 2);
}
}
var mainCanvas = {
canvas : document.createElement("canvas"),
load: function(){
this.canvas.width = (window.innerWidth)/2;
this.canvas.height = window.innerHeight;
this.ctx1 = this.canvas.getContext("2d");
document.body.insertBefore(this.canvas, document.body.childNodes[0]);
this.interval = setInterval(moveTracker, 20);
window.addEventListener ("keydown", function(e){
console.log(e.keyCode);
mainCanvas.key = e.keyCode; //execute movement when key pressed
});
window.addEventListener ("keyup", function(e){
mainCanvas.key = false; //stop movement once key is released
});
},
clear: function(){
this.ctx1.clearRect(0, 0, this.canvas.width, this.canvas.height);
}
}
function track(width, height, color, distanceX, distanceY, theSquare){
this.width = width;
this.height = height;
this.speedX = 0;
this.speedY = 0;
this.distanceX = distanceX;
this.distanceY = distanceY;
this.rotationSpeedRight = 0;
this.rotationSpeedLeft= 0;
this.rotationLeft = rotationLeft;
this.rotationRight = rotationRight;
console.log("inside track()");
this.update = function(theSquare){
ctx = mainCanvas.ctx1;
ctx.fillStyle = color;
ctx.fillRect(this.distanceX, this.distanceY, this.width, this.height, this.rotationLeft, this.rotationRight);
ctx.rotate(45*Math.PI/180);
ctx.save();
ctx.restore();
}
this.newPosition = function(){
this.rotation += this.rotationSpeed;
this.distanceX += this.speed * Math.cos(this.rotation);
this.distanceY += this.speed * Math.sin(this.rotation);
}
}
function moveTracker(){ //recognize keys from keyboard
mainCanvas.clear();
tracker.speedX = 0;
tracker.speedY = 0;
tracker.rotationSpeedRight = 0;
tracker.rotationSpeedLeft = 0;
if (mainCanvas.key && mainCanvas.key == 37) //left key; should move anticlockwise
tracker.rotationSpeedLeft = -1;
if (mainCanvas.key && mainCanvas.key == 38) //down key
tracker.speedY = -1;
if (mainCanvas.key && mainCanvas.key == 39) //right key; should move clockwise;
tracker.rotationSpeedRight = 1;
if (mainCanvas.key && mainCanvas.key == 40) //up key
tracker.speedY=1;
tracker.newPosition();
tracker.update();
}
Upvotes: 0
Views: 221
Reputation: 3408
There is no such thing as a "left rotation" and a "right rotation", they both refer to the same thing. You only need one rotation value, it is the current angle of your drawing.
I also assume you want your up key to go in whichever direction you are facing rather than always up, so you can switch the speed values to only one value as well, the speed in the current direction. This basically changes your coordinate system from cartesian (x, y) to polar (angle and distance).
To know the final change on the X-Y plane of a move based on rotation and speed, you have to use speed * cos(angle)
for X and speed * sin(angle)
for Y (based on trigonometry).
rotate
needs to be called before you draw your rectangle (it's basically saying "everything that I will do next will need to be rotated by that amount") and save
and restore
need to be called around all that, to cancel the rotation once you are done drawing your rotated shape.
Another note: rotate
rotates the canvas around the origin (0, 0). To rotate around the center of your element, which is probably what you want to do, you will need to first translate
to the position, then not forget to offset the position at which you draw the rectangle to take into account that initial translation.
A potential update of the bottom part of your code would be:
function track(width, height, color, distanceX, distanceY, rotation){
this.width = width;
this.height = height;
this.distanceX = distanceX || 0;
this.distanceY = distanceY || 0;
this.speed = 0;
this.rotation = rotation || 0;
this.rotationSpeed = 0;
this.update = function(){
ctx = mainCanvas.ctx1;
ctx.fillStyle = color;
ctx.save();
ctx.translate(this.distanceX, this.distanceY);
ctx.rotate(this.rotation);
ctx.fillRect(-this.width / 2, -this.height / 2, this.width, this.height);
ctx.restore();
}
this.newPosition = function(){
this.rotation += this.rotationSpeed;
this.distanceX += this.speed * Math.cos(this.rotation);
this.distanceY += this.speed * Math.sin(this.rotation);
}
}
function moveTracker(){ //recognize keys from keyboard
mainCanvas.clear();
tracker.speed = 0;
tracker.rotationSpeed = 0;
// Adjust the values as you need here
if (mainCanvas.key == 37) //left key
tracker.rotationSpeed = -0.5 / Math.PI;
if (mainCanvas.key == 38) //up key
tracker.speed = 3;
if (mainCanvas.key == 39) //right key
tracker.rotationSpeed = 0.5 / Math.PI;
if (mainCanvas.key == 40) //down key
tracker.speed = -3;
tracker.newPosition();
tracker.update();
}
JSFiddle (rough version)
Upvotes: 1