The idea:
Hi, this is my first experiment with canvas animation. I'm not sure if this concept already exists but I've dubbed my version "two-state animation". The idea is this: A map is created with three sub-maps for each object on-screen. One of the sub-map holds the current state properties (of an animating object), the second holds the final destination (of an animating object), and the third for divided increments to ensure the object (on-screen) reaches its final destination in the number of frames set in `framesForChange.
The problem:
Notice, as the animation progresses, the objects are gradually pushed down to the bottom right but the numbers for x and y axis continue to grow. I'm aware that I'm generating random number to confine it within the width (x) and height (y) of the viewport. Why is this happening? How can I fix it?
The code:
If you have any suggestions for how I could make this more efficient (or, more primarily, fix the problem [mentioned above]), please mention it in your answer or in the comments. Thank you.
window.addEventListener('load', initializeCanvasTwo());
function initializeCanvasTwo() {
var canvas, c, map = {},
framesForChange = 360;
initializeCanvas();
resizeCanvas();
initializeMapping();
draw();
window.addEventListener('resize', function() {
resizeCanvas();
});
function initializeCanvas() {
canvas = document.getElementById('canvasTwo');
c = canvas.getContext('2d');
}
function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
c.width = window.innerWidth;
c.height = window.innerHeight;
}
function initializeMapping() {
var n = Math.floor(window.innerWidth * window.innerHeight / 20000);
for (var i = 0; i < n; i++) {
map[i] = {
current: {
startX: getRandomX(),
startY: getRandomY(),
endX: getRandomX(),
endY: getRandomY()
},
final: {
startX: getRandomX(),
startY: getRandomY(),
endX: getRandomX(),
endY: getRandomY()
},
increment: {
}
};
map[i].increment.startXIncrement = (map[i].final.startX - map[i].current.startX) / framesForChange;
map[i].increment.startYIncrement = (map[i].final.startY - map[i].current.startY) / framesForChange;
map[i].increment.endXIncrement = (map[i].final.endX - map[i].current.endX) / framesForChange;
map[i].increment.endYIncrement = (map[i].final.endY - map[i].current.endY) / framesForChange;
}
}
function getRandomX() {
return Math.floor(Math.random() * window.innerWidth);
}
function getRandomY() {
return Math.floor(Math.random() * window.innerHeight);
}
function updateMap() {
var n = Object.keys(map).length;
for (var i = 0; i < n; i++) {
if (map[i].final.startX - map[i].current.startX < map[i].increment.startXIncrement) {
//startX transition complete: set new destination...
map[i].final.startX = getRandomX();
map[i].increment.startXIncrement = (map[i].final.startX - map[i].current.startX) / framesForChange;
} else {
map[i].current.startX += map[i].increment.startXIncrement;
}
if (map[i].final.startY - map[i].current.startY < map[i].increment.startYIncrement) {
//startY transition complete: set new destination...
map[i].final.startY = getRandomY();
map[i].increment.startYIncrement = (map[i].final.startY - map[i].current.startY) / framesForChange;
} else {
map[i].current.startY += map[i].increment.startYIncrement;
}
if (map[i].final.endX - map[i].current.endX < map[i].increment.endXIncrement) {
//endX transition complete: set new destination...
map[i].final.endX = getRandomX();
map[i].increment.endXIncrement = (map[i].final.endX - map[i].current.endX) / framesForChange;
} else {
map[i].current.endX += map[i].increment.endXIncrement;
}
if (map[i].final.endY - map[i].current.endY < map[i].increment.endYIncrement) {
//endY transition complete: set new destination...
map[i].final.endY = getRandomY();
map[i].increment.endYIncrement = (map[i].final.endY - map[i].current.endY) / framesForChange;
} else {
map[i].current.endY += map[i].increment.endYIncrement;
}
}
}
function draw() {
c.clearRect(0, 0, window.innerWidth, window.innerHeight);
c.strokeStyle = 'blue';
var n = Object.keys(map).length;
for (var i = 0; i < n; i++) {
c.beginPath();
c.moveTo(map[i].current.startX, map[i].current.startY);
c.lineTo(map[i].current.endX, map[i].current.endY);
c.stroke();
c.closePath();
}
updateMap();
requestAnimationFrame(draw);
}
}
html,
body {
margin: 0;
padding: 0;
}
canvas {
width: 100%;
height: 100%;
margin-bottom: -4px;
}
<canvas id="canvasTwo"></canvas>