使用箭头键旋转 Canvas 形状
Issue Rotating Canvas Shape WIth Arrow Keys
我想要左右箭头键分别顺时针和逆时针旋转我的 canvas 形状。目前形状只能线性移动。
在漫长的 运行 中,我试图使用此 javascript 代码复制我的 ROS(机器人操作系统)TurtleSim 的运动,并且左右键在此旋转 turtlesim方法。 (我是 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();
}
没有"left rotation"和"right rotation"这样的东西,它们指的是同一个东西。你只需要一个旋转值,就是你画的当前角度。
我还假设您希望向上键朝您面向的任何方向移动而不是始终向上,因此您也可以将速度值也切换为一个值,即当前方向的速度。这基本上改变了您的坐标系 cartesian (x, y) to polar(角度和距离)。
要了解基于旋转和速度的移动在 X-Y 平面上的最终变化,您必须对 X 使用 speed * cos(angle)
,对 Y 使用 speed * sin(angle)
(基于三角学)。
rotate
需要在绘制矩形之前调用(它基本上是说 "everything that I will do next will need to be rotated by that amount")并且 save
和 restore
需要围绕所有这些调用,以绘制完旋转形状后取消旋转。
另一个注意事项:rotate
围绕原点 (0, 0) 旋转 canvas。要围绕元素的中心旋转,这可能是您想要做的,您需要先 translate
到该位置,然后不要忘记偏移绘制矩形的位置以考虑到初始翻译。
代码底部的潜在更新是:
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(粗略版)
我想要左右箭头键分别顺时针和逆时针旋转我的 canvas 形状。目前形状只能线性移动。
在漫长的 运行 中,我试图使用此 javascript 代码复制我的 ROS(机器人操作系统)TurtleSim 的运动,并且左右键在此旋转 turtlesim方法。 (我是 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();
}
没有"left rotation"和"right rotation"这样的东西,它们指的是同一个东西。你只需要一个旋转值,就是你画的当前角度。
我还假设您希望向上键朝您面向的任何方向移动而不是始终向上,因此您也可以将速度值也切换为一个值,即当前方向的速度。这基本上改变了您的坐标系 cartesian (x, y) to polar(角度和距离)。
要了解基于旋转和速度的移动在 X-Y 平面上的最终变化,您必须对 X 使用 speed * cos(angle)
,对 Y 使用 speed * sin(angle)
(基于三角学)。
rotate
需要在绘制矩形之前调用(它基本上是说 "everything that I will do next will need to be rotated by that amount")并且 save
和 restore
需要围绕所有这些调用,以绘制完旋转形状后取消旋转。
另一个注意事项:rotate
围绕原点 (0, 0) 旋转 canvas。要围绕元素的中心旋转,这可能是您想要做的,您需要先 translate
到该位置,然后不要忘记偏移绘制矩形的位置以考虑到初始翻译。
代码底部的潜在更新是:
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(粗略版)