javascript event too slow - javascript

Is there any way to improve the following html5 example, or is the browser
just to slow in handling mouse events?
Its a grid, and on the point you move the mouse to you see a red rectangle..
But this rectangle is a kind of lagging behind the mouse, so moving to slow to its position.
(if the mouse is moved pretty fast)
http://jsfiddle.net/191rmac8/
Here the code:
<body>
<canvas id="canvas" width="400" height="400">error or not supported.</canvas>
<script>
var lineSize = 10;
var rasterSize = 5;
var bx = 0;
var by = 0;
g2d = document.getElementById("canvas").getContext("2d");
g2d.setFillColor("rgb(10, 10, 10)");
g2d.fillRect(0, 0, g2d.canvas.width, g2d.canvas.height);
g2d.setStrokeColor("rgb(0, 0, 255)");
g2d.setLineWidth(lineSize);
function repaint(){
g2d.clearRect(0, 0, g2d.canvas.width, g2d.canvas.height);
g2d.beginPath();
for(i = 0; i < rasterSize + 1; i++){
g2d.moveTo(0, (lineSize / 2) + i * (g2d.canvas.height - lineSize) / (rasterSize));
g2d.lineTo(g2d.canvas.width, (lineSize / 2) + i * (g2d.canvas.height - lineSize) / (rasterSize));
g2d.moveTo((lineSize / 2) + i * (g2d.canvas.width - lineSize) / (rasterSize), 0);
g2d.lineTo((lineSize / 2) + i * (g2d.canvas.width - lineSize) / (rasterSize), g2d.canvas.height);
}
g2d.stroke();
g2d.setFillColor("red");
g2d.fillRect(bx - 5, by - 5, 11, 11);
}
repaint();
g2d.canvas.addEventListener("mousemove", function(e){
bx = e.offsetX;
by = e.offsetY;
repaint();
});
</script>
</body>
body {
margin: 0;
width: 100%;
height: 100%;
display: block;
background: black;
}
canvas {
margin: auto;
margin-top: 50px;
display: block;
}

You can separate the mouse events from the drawing to increase performance.
Create an array to hold mouse points
In mousemove, push the current mouse position into the array.
Depending on your design, you might use Aboca's idea of capping the capture rate of the points.
Create a loop using requestAnimationFrame.
In the loop, draw all points since the loop was last executed as 1 path.
The benefits are:
requestAnimationFrame is efficient at drawing.
You are drawing a polyline through a batch of points instead of 1 point at a time.
Changing context state is somewhat expensive, and this lets you change state only once.

You can cap the rate of the repaint like I did here:
http://jsfiddle.net/sh6o91g4/1/
Adjust as you see fit as it will fasten the perfomance but it will reduce the quality of the rendering too (skipping frames has it's drawbacks)
var now = new Date().getTime();
if(now - time > 10){
time = now;
bx = e.offsetX;
by = e.offsetY;
repaint();
}

Related

Generate a normal map with a color map in Three js

I started learning Three js and I was looking for a way to convert a color map into a normal map. What I want to do is to try and make the normal map based on this color map [image 1], by changing the pixels based on their color so it looks like this normal map [image 2]. I don't want to simply upload the files since I'm trying to minimize the weight of the project as much as possible. Here is what I already tried :
let img = new Image();
img.src = './texture/color.jpg';
img.onload = function () {
let canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
document.getElementById('body').appendChild(canvas)
const c = canvas.getContext('2d')
c.clearRect(0, 0, canvas.width, canvas.height);
c.fillStyle = '#EEEEEE';
c.fillRect(0,0,canvas.width, canvas.height);
//draw background image
c.drawImage(img, 0, 0);
//draw a box over the top
c.fillStyle = "rgba(200, 0, 0, 0)";
c.fillRect(0, 0, canvas.width, canvas.height);
draw(c, canvas);
};
function draw(c, canvas)
{
let img2 = c.getImageData(0, 0, canvas.width,canvas.height);
console.log(img2.data)
let d = img2.data;
for (let i=0; i<d.length; i+=4) {
let r = d[i];
let g = d[i+1];
let b = d[i+2];
v1 = r < 75 ? r / (50 - r) : r * (255 - r);
v2 = g > 75 ? g / (50 - g) : g * (255 - g);
v3 = b > 75 ? b / (50 - b) : b * (255 - b);
d[i] = v1;
d[i+1] = v2;
d[i+2] = v3;
}
console.log(img2.data)
c.putImageData(img2, 0, 0);
}
I can't say what Three.js can or can't do because all I really know of it is that it makes integrating 3d assets with canvases a breeze.
Aside from that, I wrote a pure javascript function that serves the purpose of generating normal maps from color maps quite effectively. Keep in mind, however, that this is a quick port to js of a function I wrote for C# winforms about 4 years ago, one that loops through all the pixels of a given image to extrapolate the data required for the conversion. It's slow. Seriously, painfully slow and it is so because getting nice, crisp, accurate normal maps from recursive algorithms is painfully slow.
But it does exactly what you want it to do; generate a very nice, clean, precise normal map from a given color map and it's simple enough to understand its functionality.
I've set this up as a live demo so you can see it / feel it in action.
There is, of course, a much faster solution involving making a single call for pixel data, iterating over its corresponding 1d array, saving calculated data back to that array then plopping the entire array, itself, down on the output canvas all at once but that involves some interesting virtual multi-dimensional trickery for Sobel but, for the sake of providing a clear, understandable example that works, I'm going with old-school nested recursion so you can see Sobel in action and how pixels are manipulated to arrive at normalization.
I did not implement any fancy asynchronous updates so you'll only know this is processing because, once initiated, the hand cursor used for the button won't return to the default arrow until map generation is complete.
I've also included 4 variations of your original image to play with, all in code with 3 of the 4 commented out. The app starts at 256x256 as the time it takes to generate a normal map from that with recursion is reasonable. Their sizes range from 128 to the original 1024, though I highly advise not engaging the full scale variant as your browser may whine about how long the operation takes.
As with the C# variant, you can implement a means by which client can control the intensity of the resulting normal calculations by adjusting the brightness parameters. Beyond the C# variant, this definitely can be a basis for generating normal maps to visualize in real-time as applied to geometry with Three.js. And by "real-time", I mean however long it takes to generate an x-scale map with nested recursion because the actual application of a completed map to geometry occurs in milliseconds.
Here's a screenshot of the results after processing the 256x256:
To accompany the live demo, here's the code:
normalize.htm
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Normalizer</title>
<link rel="stylesheet" href="css/normalize.css">
</head>
<body onload="startup()">
<canvas id="input" class="canvas"></canvas>
<canvas id="output" class="canvas"></canvas>
<div class="progress">
<input type="button" class="button" onclick="totallyNormal()" value="Normalize!" />
<span id="progress">Ready to rock and / or roll on your command!</span>
</div>
<script src="js/normalize.js"></script>
</body>
</html>
normalize.css
html {
margin: 0px;
padding: 0px;
width: 100vw;
height: 100vh;
}
body {
margin: 0px;
padding: 0px;
width: 100vw;
height: 100vh;
overflow: hidden;
font-family: "Arial Unicode MS";
background: linear-gradient(330deg, rgb(150, 150, 150), rgb(200, 200, 200));
background-color: rgb(200, 200, 200);
display: flex;
align-items: center;
justify-content: center;
}
.canvas {
outline: 1px solid hsla(0, 0%, 0%, 0.25);
}
.progress {
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 40px;
display: flex;
}
.progress span {
width: calc(100% - 160px);
height: 40px;
line-height: 40px;
color: hsl(0, 0%, 0%);
text-align: center;
}
input[type="button"] {
margin: 0px;
width: 120px;
height: 40px;
cursor: pointer;
display: inline;
}
normalize.js
// Javascript Normal Map Generator
// Copyright © Brian "BJS3D" Spencer 2022
// Incorporating W3C proposed algorithm to
// calculate pixel brightness in conjunction
// with the Sobel Operator.
var input, output, ctx_i, ctx_o, w, h;
function startup() {
var img;
input = document.getElementById("input");
ctx_i = input.getContext("2d");
ctx_i.clearRect(0, 0,input.width, input.height);
img = new Image();
img.crossOrigin = "Anonymous";
//img.src = "https://i.imgur.com/a4N2Aj4.jpg"; //128x128 - Tiny but fast.
img.src = "https://i.imgur.com/wFe4EG7.jpg"; //256x256 - Takes about a minute.
//img.src = "https://i.imgur.com/bm4pXrn.jpg"; //512x512 - May take 5 or 10 minutes.
//img.src = "https://i.imgur.com/aUIdxHH.jpg"; //original - Don't do it! It'll take hours.
img.onload = function () {
w = img.width - 1;
h = img.height - 1;
input.width = w + 1;
input.height = h + 1;
ctx_i.drawImage(img, 0, 0);
output = document.getElementById("output");
ctx_o = output.getContext("2d");
output.width = w + 1;
output.height = h + 1;
};
}
function totallyNormal() {
var pixel, x_vector, y_vector;
for (var y = 0; y < w + 1; y += 1) {
for (var x = 0; x < h + 1; x += 1) {
var data = [0, 0, 0, 0, x > 0, x < w, y > 1, y < h, x - 1, x + 1, x, x, y, y, y - 1, y + 1];
for (var z = 0; z < 4; z +=1) {
if (data[z + 4]) {
pixel = ctx_i.getImageData(data[z + 8], data[z + 12], 1, 1);
data[z] = ((0.299 * (pixel.data[0] / 100)) + (0.587 * (pixel.data[1] / 100)) + (0.114 * (pixel.data[2] / 100)) / 3);
} else {
pixel = ctx_i.getImageData(x, y, 1, 1);
data[z] = ((0.299 * (pixel.data[0] / 100)) + (0.587 * (pixel.data[1] / 100)) + (0.114 * (pixel.data[2] / 100)) / 3);
}
}
x_vector = parseFloat((Math.abs(data[0] - data[1]) + 1) * 0.5) * 255;
y_vector = parseFloat((Math.abs(data[2] - data[3]) + 1) * 0.5) * 255;
ctx_o.fillStyle = "rgba(" + x_vector + "," + y_vector + ",255,255)";
ctx_o.fillRect(x, y, 1, 1);
}
}
document.getElementById("progress").innerHTML = "Normal map generation complete.";
}

How can I improve the accuracy of Math.atan()?

I was trying to do some comparison between the angles of points, but quickly I ran into some strange results.
In this example I try rotate lines so that they point to the center, but the lines seem to angle more than they should quite quickly. Then, right above and below the center the lines start to point in all sorts of directions (These values are beyond the mathematical range of atan(x)).
How can I get accurate results from Math.atan()? Is there an alternative method to do this calculation?
I uploaded a 'working' version to this fiddle:
https://jsfiddle.net/0y2p6p3n/. I am working in Chrome.
html:
<div id="content">
</div>
javascript:
let points = [];
let amount = 1000;
let width = 300;
let height = 300;
for (let i = 0; i<amount;i++) {
let x = Math.random();
let y = Math.random();
let point = {x, y};
points.push(point);
points[i].tan = Math.atan(0.5 - points[i].y)/(0.5 - points[i].x);
points[i].error = Math.abs(points[i].tan) > 3.14/2 ? true : false;
}
for (let point of points) {
let line = document.createElement("div");
line.classList.add("line");
line.style.marginTop = point.y*height + "px";
line.style.marginLeft = point.x*width + "px";
line.style.transform = "rotateZ(" + ((point.tan*(180/Math.PI))) + "deg)";
point.error == true && line.classList.add("error");
document.getElementById("content").appendChild(line);
}
css:
#content {
position: relative;
}
.line {
position: absolute;
height: 1px;
width: 10px;
background-color: black;
}
.error {
background-color: red;
}
You are using
points[i].tan = Math.atan(0.5 - points[i].y)/(0.5 - points[i].x);
It should be
points[i].tan = Math.atan( (0.5 - points[i].y)/(0.5 - points[i].x) );
let points = [];
let amount = 1000;
let width = 300;
let height = 300;
for (let i = 0; i<amount;i++) {
let x = Math.random();
let y = Math.random();
let point = {x, y};
points.push(point);
points[i].tan = Math.atan( (0.5 - points[i].y)/(0.5 - points[i].x) );
points[i].error = Math.abs(points[i].tan) > 3.14/2 ? true : false;
}
for (let point of points) {
let line = document.createElement("div");
line.classList.add("line");
line.style.marginTop = point.y*height + "px";
line.style.marginLeft = point.x*width + "px";
line.style.transform = "rotateZ(" + ((point.tan*(180/Math.PI))) + "deg)";
point.error == true && line.classList.add("error");
document.getElementById("content").appendChild(line);
}
#content {
position: relative;
}
.line {
position: absolute;
height: 1px;
width: 10px;
background-color: black;
}
.error {
background-color: red;
}
<div id="content"></div>
As you mentioned, the exact asymptotes (i.e. pi/2 and -pi/2) are outside of the valid domain of atan, which makes taking the atan of those values impossible. You also may have to deal with the fact that atan always returns a reference angle, which may not be the quadrant you want your answer to be in. These are very well known issues, and most languages have a simple cure, called atan2. In the case of javascript, please see the MDN reference for atan2.
The change to your code is simple; simply change
points[i].tan = Math.atan(0.5 - points[i].y)/(0.5 - points[i].x);
to
points[i].tan = Math.atan2(0.5 - points[i].y, 0.5 - points[i].x);
If you check out the updated fiddle, you may see its behavior has improved considerably.
atan2 doesn't give you higher precision, but it does give you values over the complete range of [0..2pi], without you having to do all the extra work of figuring out which quadrant the answer should be in, as well as supporting pi/2 and -pi/2 within its range. It is helped in doing so by knowing whether the x or the y (or both) is negative, a fact which gets hidden if you do the division yourself.
It should be noted that the most significant change I made to your code was not atan2, however, it was changing around your use of parenthesis. While I'm an advocate for using atan2 any time you would normally use atan, your actual issue was misuse of parenthesis, making Oriol's answer the right one.

I'm trying to make a canvas move towards another canvas - JAVASCRIPT

I wrote this code to try to get the myCanvas to move towards myCanvas1. I tried doing this using the Math.atan2() method. However it doesn't work. Any ideas?
Please don't use any JQuery.
HTML:
<canvas id="myCanvas"></canvas>
<canvas id="myCanvas1"></canvas>
JS:
var follower = document.getElementById('myCanvas');
var flw = follower.getContext('2d');
var runner = document.getElementById('myCanvas1');
var rnr = runner.getContext('2d');
document.addEventListener('keydown', moveShot);
//Cordinates of sPositions 1 and two
var sPosition0 = [700, 700];
var sPosition1 = [400, 400];
var xPosition0 = sPosition0[0], yPosition0 = sPosition0[1];
var xPosition1 = sPosition1[0], yPosition1 = sPosition1[1];
//This should be the arctan between sPosition0 and sPosition1
var angleRadians0 = Math.atan2(sPosition0[0] - sPosition1[0], sPosition0[1] - Position1[1]);
/*The speed of the object is 4. To get it to move diagonally towards sPosition1 I need to divide dy with the angle arctan between the two objects */
var dx = 4;
var dy = 4 / angleRadians0;
function moveShot(){
// Deleting the "old" square
flw.clearRect(0, 0, 700, 700);
//Drawing the square at its appropriate position
flw.fillRect(xPosition0, yPosition0, 100, 100);
//Adding the movement after every frame
xPosition0 += dx;
yPosition0 += dy;
setTimeout(moveShot, 20);
}
CSS:
#myCanvas1{
height: 100px;
width: 100px;
background-color: '#ff0000';
}
Thanks!
EDIT:
As to what actually happens, I'm very confused. Nothing happens at all, I didn't say that because it's 3am and I thought someone would point out some very obvious mistake I've made and everything would make sence. So, what happens is well, nothing, I cannot understand why. Then again though, its 3am and I might have screwed up somewhere but I don't see where.
Here's a fiddle https://jsfiddle.net/Snubben/15tf0svd/3/
Well, the reason NOTHING happens, is that your canvas is using the default size. 300x150;
Your initial position is drawing the square OUTSIDE the canvas, and then your dx and dy variables are adding to x and y, making it move even further away (down and to the right).
See the following for an example of keeping it within the container and moving the square up and to the left.
var follower = document.getElementById('myCanvas');
var flw = follower.getContext('2d');
var runner = document.getElementById('myCanvas1');
var rnr = runner.getContext('2d');
document.addEventListener('keydown', moveShot);
//Cordinates of sPositions 1 and two
var sPosition0 = [70, 70]; //within the canvas
var sPosition1 = [40, 40]; //within the canvas
var xPosition0 = sPosition0[0],
yPosition0 = sPosition0[1];
var xPosition1 = sPosition1[0],
yPosition1 = sPosition1[1];
//This should be the arctan between sPosition0 and sPosition1
var angleRadians0 = Math.atan2(sPosition0[0] - sPosition1[0], sPosition0[1] - sPosition1[1]);
/*The speed of the object is 4. To get it to move diagonally towards sPosition1 I need to divide dy with the angle arctan between the two objects */
var dx = 4;
var dy = 4 / angleRadians0;
function moveShot() {
if(yPosition0 < 10) return;
// Deleting the "old" square
flw.fillStyle = "green";
flw.clearRect(0, 0, 700, 700);
//Drawing the square at its appropriate position
flw.fillRect(xPosition0, yPosition0, 10, 10);
//Adding the movement after every frame
xPosition0 -= dx; //move left
yPosition0 -= dy; //move up.
setTimeout(moveShot, 20);
}
#myCanvas1 {
height: 100px;
width: 100px;
background-color: #ff0000;
}
#myCanvas {
width: 300px;
height: 300px;
background-color: blue;
}
<canvas id="myCanvas" height="300" width="300"></canvas>
<canvas id="myCanvas1" height="100" width="100"></canvas>
press a key to make it work.

Track mouse speed even when cursor is at edge of screen

I wrote a little Javascript app to track and display the x- and y- components of the mouse's velocity. It subtracts the cursor's previous position from its current position, and divides by time. Pretty simply stuff. Here is the complete working source:
<!DOCTYPE html5>
<html>
<head>
<meta charset="UTF-8">
<style>
* {
background-color:#000000;
}
html {
width:100%;
height:100%;
}
#readout {
background-color:#FFFFFF;
border: 8px solid #34a1ff;
width: 162px;
height: 100px;
position:absolute;
top:0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
padding: 16px;
}
.text {
background-color:#FFFFFF;
}
</style>
</head>
<body>
<div id="readout">
<span id="xLabel" class="text">X: </span>
<span id="xValue" class="text"></span>
<br>
<span id="yLabel" class="text">Y: </span>
<span id="yValue" class="text"></span>
</div>
<script>
// Where the speed will be displayed
window.xDisplay = document.getElementById("xValue");
window.yDisplay = document.getElementById("yValue");
// Keep track of last time mouse was moved
window.lastTime = new Date().getTime();
window.lastDeltaTime = 0;
window.lastMouseX = 0;
window.lastMouseY = 0;
window.lastVX = 0; // for smoothing
window.lastVY = 0;
// Listen for mouse move event
document.addEventListener('mousemove', function(e){
// Get current mouse position
var currentX = e.clientX || e.pageX;
var currentY = e.clientY || e.pageY;
// Get distance travelled from last mouse position
var deltaX = currentX - lastMouseX;
var deltaY = currentY - lastMouseY;
// Update mouse position
lastMouseX = currentX;
lastMouseY = currentY;
// Get current time
var currentTime = new Date().getTime();
// Get time elapsed since last mouse event
var deltaTime = currentTime - lastTime;
// Update last time
lastTime = currentTime;
// Get velocity components
var xSpeed = deltaX / deltaTime;
var ySpeed = deltaY / deltaTime;
// Smooth out velocity
var xSmooth = (xSpeed*2 + lastVX)/3;
var ySmooth = (ySpeed*2 + lastVY)/3;
// Update previous components
lastVX = xSpeed;
lastVY = ySpeed;
// Display velocity
xDisplay.innerHTML = xSmooth.toFixed(3);
yDisplay.innerHTML = ySmooth.toFixed(3);
}, false);
</script>
</body>
</html>
This will be used in an app that is intended to run in fullscreen mode. The problem I encounter is when the cursor ends up all the way at an edge of the screen, and the user keeps moving the mouse in that direction. (Example: the cursor is all the way at the right edge of the screen, but the user keeps moving their mouse toward the right).
In the above scenario, the app displays a velocity of zero, since the cursor position is not being updated. However, I am in need to a solution that continues to display the actual mouse velocity even after the cursor has reached the edge (none of the similar questions on this site address this issue).
This is important since the use case will be in a WebGL context in which the mouse is used to control rotation from a first person view. The user needs to be able to keep on rotating their view around as many times as they want where rotation velocity is based on mouse velocity (not position!) and this simply doesn't work by calculating mouse speed from cursor position.
This may require some creativity but I'm sure it can be done. Thanks in advance for any solutions!
Found the solution, in case anyone ever stumbles upon this later.
The Pointer Lock API does exactly what I needed.

Dynamic Animations?

So I'm trying to make this div animation a little more realistic by implementing a "physics engine" that slightly resembles how it would actually accelerate and decelerate... kinda...
<!DOCTYPE html>
<html>
<head>
<title>Gio is Fay</title>
<link rel="stylesheet" href="sliding.css"/>
</head>
<body>
<div id="button">
<h5>Click me!</h5>
<h4>HARDER!</h4>
</div>
<div id="moving"></div>
<script type="text/javascript">
var sliding = document.getElementById("moving");
var margin = sliding.style.marginTop | 100;
var speeds = [0.5, 1, 3, 6, 8, 9, 10, 10, 10, 10, 10, 10, 9, 8, 5, 3, 1];
var length = speeds.length;
sliding.onclick = move;
function move() {
window.log("Herro!");
for (i = 0; i < length; i++) {
var x = speeds[i];
margin += x * 5;
sliding.style.marginTop = margin + "px";
}
}
</script>
</body>
</html>
When I click on the div, unsurprisingly, nothing happens. I put in an alert box to tell me whether the function was being triggered, and apparently it wasn't. Or at least the alert never showed up. Not sure why. No errors in the console. Help?
I tried your code, and everything but window.log() "worked", so I'm not sure why you weren't getting any results at all.
This really isn't the best method to animate. You should use requestAnimationFrame(), which works a lot like a setTimeout() but is optimized for animation. When I got your code working, you don't see an animation at all because you have only 17 frames, and those 17 passes through the for loop happen SUPER fast. So look into requestAnimationFrame() for animating with js. Here is what your code would look like implementing that change:
var sliding = document.getElementById("moving");
var margin = sliding.style.marginTop | 10;
var speeds = [0.5, 1, 3, 6, 8, 9, 10, 10, 10, 10, 10, 10, 9, 8, 5, 3, 1];
var length = speeds.length;
var frame = 0;
sliding.onclick = function () {
frame = 0;
requestAnimationFrame(move);
}
function move() {
var x = speeds[frame];
margin += x;
sliding.style.marginTop = margin + "px";
if (frame < length)
requestAnimationFrame(move);
frame++;
}
You should also reconsider your method for changing the rate. I would use trig functions. That way you could easily change the duration and distance that the div moves. Here is an example of that, feel free to use it. You can run this snippet to see what it looks like.
var sliding = document.getElementById("moving");
var margin = sliding.style.marginTop | 10;
// a few settings for our animation
var theta = 0.0; //in radians
var distance = 100; //in pixels
var duration = 1; //in seconds
var frameRate = 60; //fps
var down = false; //a switch so we can move up and down, we are starting in the up position
sliding.onclick = function () {
if (down)
//if we need to go up, we start at 1 (cos(PI) = -1)
theta = Math.PI;
else
//otherwise we start at 0
theta = 0.0;
//flip it
down = !down;
//and away we go
requestAnimationFrame(move);
}
function move() {
//the margin is determined with cos
margin = (-1 * Math.cos(theta) + 1) * distance + 10;
//and set
sliding.style.marginTop = margin + "px";
//our theta advances
theta += (Math.PI) / frameRate / duration;
//and we continue if we are not at either end
if ((down && theta <= Math.PI) || (!down && theta <= Math.PI * 2))
requestAnimationFrame(move);
}
#moving {
margin-top: 10px;
padding: 10px;
background: #047;
color: #bbb;
border-radius: 5px;
width: 80px;
text-align: center;
}
<div id="moving">DIV</div>
And finally, jQuery has this stuff built in so you don't have to worry about reinventing the wheel, so look in to that. I hope this helps!
first of all, as mentioned. window.log isnt a function. I do get that error in the console. You will also need to set the position of your moving div to be relative to see it move.
Here is a fiddle of your code (with my modifications)
http://jsfiddle.net/404xk2fo/
when I click on the red div it will instantly disappear off the screen because it's moving quite a bit. Lower the multiplication factor, and it will stay on the screen but still instantly move. The problem is you are trying to animate in this loop without any kind of timer. Executing this code in a loop is so fast that your animation is going to happen instantly.
check out this webpage for some examples on how to do smooth animations in javascript. the key is using requestAnimationFrame
http://creativejs.com/resources/requestanimationframe/
I added a really simple example of requestAnimationFrame http://jsfiddle.net/j4x9dctq/
I'm using a little jquery to select the div. I just prefer jquery syntax. you can use native javascript if you prefer.

Categories

Resources