Reputation: 31
I'm trying to make a rectangle follow the angle between it and the mouse. Basically if the angle between the mouse and the current angle of the rectangle is higher than the current angle of the rectangle, it adds 1 and will continue until condition is false. The opposite happens when the angle between the two is lower than the current angle of the rectangle. My problem here is the angle between the mouse and rectangle, after 180 degrees it goes becomes -180. This causes the rectangle to go around again instead of going to 181 degrees. I've tried figuring out a way around this but I somehow always ended up in the same problem. Thanks in advance, here is my code:
<body>
<canvas id="ctx" width="500" height="500" style="border:1px solid #000000;"></canvas>
</body>
<script>
var canvas = document.getElementById("ctx"),
ctx = canvas.getContext("2d"),
width = canvas.width = window.innerWidth,
height = canvas.height = window.innerHeight,
mouse,
angle = 0;
function test() {
"use strict";
var dX = mouse.X - 200,
dY = mouse.Y - 200,
rad = (Math.atan2(dY, dX)),
deg = (rad * (180 / Math.PI)),
player = {
x : 200,
y : 200,
width : 40,
height : 10,
angle : 0,
dAngle : 0
};
//Test
if (deg > angle) {
angle += 1;
} else if (deg) {
angle -= 1;
}
ctx.clearRect(0, 0, width, height);
ctx.translate(player.x, player.y);
ctx.rotate((angle * Math.PI / 180));
ctx.fillRect(0, -player.height / 2, player.width, player.height);
//console.log("deg :" + deg + "angle : " + angle);
ctx.setTransform(1, 0, 0, 1, 0, 0);
}
window.onmousemove = function (mm) {
"use strict";
mouse = {
X : mm.clientX - document.getElementById('ctx').getBoundingClientRect().left,
Y : mm.clientY - document.getElementById('ctx').getBoundingClientRect().top
};
};
setInterval(test, 40);
</script>
Upvotes: 0
Views: 117
Reputation: 1271
you can notice that angle flip flops within 1.0 of deg by printing (deg-angle). Just make it stop if it's in that range. (and dont use plain > or == when dealing with floats)
Of course there's nothing special about 1.0, here I replaced it with spd:
<body>
<canvas id="ctx" width="500" height="500" style="border:1px solid #000000;"></canvas>
</body>
<script>
var canvas = document.getElementById("ctx"),
ctx = canvas.getContext("2d"),
width = canvas.width = window.innerWidth,
height = canvas.height = window.innerHeight,
mouse = {X:0.0, Y:0.0},
angle = 0;
function test() {
"use strict";
var dX = mouse.X - 200,
dY = mouse.Y - 200,
rad = (Math.atan2(dY, dX)),
deg = (rad * (180 / Math.PI)),
player = {
x : 200,
y : 200,
width : 40,
height : 10,
angle : 0,
dAngle : 0
};
//Test
var spd = 5.0;
if (Math.abs(deg - angle) - spd > 0.0000001)
angle += Math.sign(deg - angle)*spd;
ctx.clearRect(0, 0, width, height);
ctx.translate(player.x, player.y);
ctx.rotate((angle * Math.PI / 180));
ctx.fillRect(0, -player.height / 2, player.width, player.height);
//console.log("deg :" + deg + "angle : " + angle);
ctx.setTransform(1, 0, 0, 1, 0, 0);
}
window.onmousemove = function (mm) {
"use strict";
mouse = {
X : mm.clientX - document.getElementById('ctx').getBoundingClientRect().left,
Y : mm.clientY - document.getElementById('ctx').getBoundingClientRect().top
};
};
setInterval(test, 40);
</script>
Upvotes: 0
Reputation: 4630
The Math.atan2() method returns a numeric value between -π and π representing the angle theta of an (x, y) point as mentioned in https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atan2
So you need just a convert value from [-180;180] to [0;360]. You can do it, let say, in this manner degrees = (degrees + 360) % 360;
Upvotes: 1
Reputation: 1076
<body>
<canvas id="ctx" width="500" height="500" style="border:1px solid #000000;"></canvas>
</body>
<script>
var canvas = document.getElementById("ctx"),
ctx = canvas.getContext("2d"),
width = canvas.width = window.innerWidth,
height = canvas.height = window.innerHeight,
//Initialize with dummy values
mouse={X:0,Y:0},
angle = 0;
function test() {
"use strict";
var dX = mouse.X - 200,
dY = mouse.Y - 200,
rad = (Math.atan2(dY, dX)),
deg = (rad * (180 / Math.PI)),
player = {
x : 200,
y : 200,
width : 40,
height : 10,
angle : 0,
dAngle : 0
};
//Test
if (deg > angle) {
angle += 1;
} else if (deg) {
angle -= 1;
}
ctx.clearRect(0, 0, width, height);
ctx.translate(player.x, player.y);
ctx.rotate((angle * Math.PI / 180));
ctx.fillRect(0, -player.height / 2, player.width, player.height);
//console.log("deg :" + deg + "angle : " + angle);
ctx.setTransform(1, 0, 0, 1, 0, 0);
}
window.onmousemove = function (mm) {
"use strict";
mouse = {
X : mm.clientX - document.getElementById('ctx').getBoundingClientRect().left,
Y : mm.clientY - document.getElementById('ctx').getBoundingClientRect().top
};
};
setInterval(test, 40);
</script>
Upvotes: 0