Mira esto en Editar violín – JSFiddle:
var canvas = document.getElementById('mycanvas'),
ctx = canvas.getContext('2d'),
scene = [],
lastTime = 0, // Last seen timestamp.
drawFrame = function (timestamp) {
// Clear canvas. An efficient implementation
// will only clear as much as needed.
ctx.clearRect(0, 0, canvas.width, canvas.height); // Call update on all scene elements...
scene.forEach(function (elem) {
elem.update(timestamp - lastTime);
}); // ...then draw them.
scene.forEach(function (elem) {
elem.draw(ctx);
}); // Request to be called again.
lastTime = timestamp;
window.requestAnimationFrame(drawFrame);
}; // Kick off animation loop.
window.requestAnimationFrame(drawFrame); // Animated circle constructor.
var animatedCircle = function (starx, starty, color) {
var dir = 1, // movement direction
x = starx || canvas.width / 2,
y = starty || canvas.height / 2,
r = 50,
v = 0.1,
color = color || 'black'; return {
x: x, y: y, r: r, v: v, color: color,
update: function (deltaT) {
// Update location based on elapsed time.
this.x += this.v * deltaT * dir; // Clamp.
if (this.x + this.r > canvas.width) {
dir = -1;
}
else if (this.x - this.r < 0) {
dir = 1;
}
},
draw: function (ctx) {
// Draw element according to current property values.
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI);
ctx.fillStyle = this.color;
ctx.fill();
}
}
}; // Compose scene.
scene.push(animatedCircle(canvas.width * 0.33, null, 'red'));
scene.push(animatedCircle(null, canvas.height * 0.25, 'green'));
scene.push(animatedCircle(canvas.width * 0.66, canvas.height * 0.75, 'blue'));
var canvas = document.getElementById('mycanvas'),
ctx = canvas.getContext('2d'),
scene = [],
lastTime = 0, // Last seen timestamp.
drawFrame = function (timestamp) {
// Clear canvas. An efficient implementation
// will only clear as much as needed.
ctx.clearRect(0, 0, canvas.width, canvas.height); // Call update on all scene elements...
scene.forEach(function (elem) {
elem.update(timestamp - lastTime);
}); // ...then draw them.
scene.forEach(function (elem) {
elem.draw(ctx);
}); // Request to be called again.
lastTime = timestamp;
window.requestAnimationFrame(drawFrame);
}; // Kick off animation loop.
window.requestAnimationFrame(drawFrame); // Animated circle constructor.
var animatedCircle = function (starx, starty, color) {
var dir = 1, // movement direction
x = starx || canvas.width / 2,
y = starty || canvas.height / 2,
r = 50,
v = 0.1,
color = color || 'black'; return {
x: x, y: y, r: r, v: v, color: color,
update: function (deltaT) {
// Update location based on elapsed time.
this.x += this.v * deltaT * dir; // Clamp.
if (this.x + this.r > canvas.width) {
dir = -1;
}
else if (this.x - this.r < 0) {
dir = 1;
}
},
draw: function (ctx) {
// Draw element according to current property values.
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI);
ctx.fillStyle = this.color;
ctx.fill();
}
}
}; // Compose scene.
scene.push(animatedCircle(canvas.width * 0.33, null, 'red'));
scene.push(animatedCircle(null, canvas.height * 0.25, 'green'));
scene.push(animatedCircle(canvas.width * 0.66, canvas.height * 0.75, 'blue'));
var canvas = document.getElementById('mycanvas'),
ctx = canvas.getContext('2d'),
scene = [],
lastTime = 0, // Last seen timestamp.
drawFrame = function (timestamp) {
// Clear canvas. An efficient implementation
// will only clear as much as needed.
ctx.clearRect(0, 0, canvas.width, canvas.height); // Call update on all scene elements...
scene.forEach(function (elem) {
elem.update(timestamp - lastTime);
}); // ...then draw them.
scene.forEach(function (elem) {
elem.draw(ctx);
}); // Request to be called again.
lastTime = timestamp;
window.requestAnimationFrame(drawFrame);
}; // Kick off animation loop.
window.requestAnimationFrame(drawFrame); // Animated circle constructor.
var animatedCircle = function (starx, starty, color) {
var dir = 1, // movement direction
x = starx || canvas.width / 2,
y = starty || canvas.height / 2,
r = 50,
v = 0.1,
color = color || 'black'; return {
x: x, y: y, r: r, v: v, color: color,
update: function (deltaT) {
// Update location based on elapsed time.
this.x += this.v * deltaT * dir; // Clamp.
if (this.x + this.r > canvas.width) {
dir = -1;
}
else if (this.x - this.r < 0) {
dir = 1;
}
},
draw: function (ctx) {
// Draw element according to current property values.
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI);
ctx.fillStyle = this.color;
ctx.fill();
}
}
}; // Compose scene.
scene.push(animatedCircle(canvas.width * 0.33, null, 'red'));
scene.push(animatedCircle(null, canvas.height * 0.25, 'green'));
scene.push(animatedCircle(canvas.width * 0.66, canvas.height * 0.75, 'blue'));
- ¿Por qué Disney dejó de hacer dibujos animados en 2D y prefirió hacer películas animadas en 3D?
- ¿La animación se trata solo de la programación?
- ¿Cuáles son las mejores trilogías animadas de Hollywood?
- Cómo elegir entre Bode Animation o BreadnBeyond para videos explicativos
- ¿Dónde puedo encontrar un buen estudio de video explicativo de animación?
var canvas = document.getElementById('mycanvas'),
ctx = canvas.getContext('2d'),
scene = [],
lastTime = 0, // Last seen timestamp.
drawFrame = function (timestamp) {
// Clear canvas. An efficient implementation
// will only clear as much as needed.
ctx.clearRect(0, 0, canvas.width, canvas.height); // Call update on all scene elements...
scene.forEach(function (elem) {
elem.update(timestamp - lastTime);
}); // ...then draw them.
scene.forEach(function (elem) {
elem.draw(ctx);
}); // Request to be called again.
lastTime = timestamp;
window.requestAnimationFrame(drawFrame);
}; // Kick off animation loop.
window.requestAnimationFrame(drawFrame); // Animated circle constructor.
var animatedCircle = function (starx, starty, color) {
var dir = 1, // movement direction
x = starx || canvas.width / 2,
y = starty || canvas.height / 2,
r = 50,
v = 0.1,
color = color || 'black'; return {
x: x, y: y, r: r, v: v, color: color,
update: function (deltaT) {
// Update location based on elapsed time.
this.x += this.v * deltaT * dir; // Clamp.
if (this.x + this.r > canvas.width) {
dir = -1;
}
else if (this.x - this.r < 0) {
dir = 1;
}
},
draw: function (ctx) {
// Draw element according to current property values.
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI);
ctx.fillStyle = this.color;
ctx.fill();
}
}
}; // Compose scene.
scene.push(animatedCircle(canvas.width * 0.33, null, 'red'));
scene.push(animatedCircle(null, canvas.height * 0.25, 'green'));
scene.push(animatedCircle(canvas.width * 0.66, canvas.height * 0.75, 'blue'));
var canvas = document.getElementById('mycanvas'),
ctx = canvas.getContext('2d'),
scene = [],
lastTime = 0, // Last seen timestamp.
drawFrame = function (timestamp) {
// Clear canvas. An efficient implementation
// will only clear as much as needed.
ctx.clearRect(0, 0, canvas.width, canvas.height); // Call update on all scene elements...
scene.forEach(function (elem) {
elem.update(timestamp - lastTime);
}); // ...then draw them.
scene.forEach(function (elem) {
elem.draw(ctx);
}); // Request to be called again.
lastTime = timestamp;
window.requestAnimationFrame(drawFrame);
}; // Kick off animation loop.
window.requestAnimationFrame(drawFrame); // Animated circle constructor.
var animatedCircle = function (starx, starty, color) {
var dir = 1, // movement direction
x = starx || canvas.width / 2,
y = starty || canvas.height / 2,
r = 50,
v = 0.1,
color = color || 'black'; return {
x: x, y: y, r: r, v: v, color: color,
update: function (deltaT) {
// Update location based on elapsed time.
this.x += this.v * deltaT * dir; // Clamp.
if (this.x + this.r > canvas.width) {
dir = -1;
}
else if (this.x - this.r < 0) {
dir = 1;
}
},
draw: function (ctx) {
// Draw element according to current property values.
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI);
ctx.fillStyle = this.color;
ctx.fill();
}
}
}; // Compose scene.
scene.push(animatedCircle(canvas.width * 0.33, null, 'red'));
scene.push(animatedCircle(null, canvas.height * 0.25, 'green'));
scene.push(animatedCircle(canvas.width * 0.66, canvas.height * 0.75, 'blue'));
var canvas = document.getElementById('mycanvas'),
ctx = canvas.getContext('2d'),
scene = [],
lastTime = 0, // Last seen timestamp.
drawFrame = function (timestamp) {
// Clear canvas. An efficient implementation
// will only clear as much as needed.
ctx.clearRect(0, 0, canvas.width, canvas.height); // Call update on all scene elements...
scene.forEach(function (elem) {
elem.update(timestamp - lastTime);
}); // ...then draw them.
scene.forEach(function (elem) {
elem.draw(ctx);
}); // Request to be called again.
lastTime = timestamp;
window.requestAnimationFrame(drawFrame);
}; // Kick off animation loop.
window.requestAnimationFrame(drawFrame); // Animated circle constructor.
var animatedCircle = function (starx, starty, color) {
var dir = 1, // movement direction
x = starx || canvas.width / 2,
y = starty || canvas.height / 2,
r = 50,
v = 0.1,
color = color || 'black'; return {
x: x, y: y, r: r, v: v, color: color,
update: function (deltaT) {
// Update location based on elapsed time.
this.x += this.v * deltaT * dir; // Clamp.
if (this.x + this.r > canvas.width) {
dir = -1;
}
else if (this.x - this.r < 0) {
dir = 1;
}
},
draw: function (ctx) {
// Draw element according to current property values.
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI);
ctx.fillStyle = this.color;
ctx.fill();
}
}
}; // Compose scene.
scene.push(animatedCircle(canvas.width * 0.33, null, 'red'));
scene.push(animatedCircle(null, canvas.height * 0.25, 'green'));
scene.push(animatedCircle(canvas.width * 0.66, canvas.height * 0.75, 'blue'));
var canvas = document.getElementById('mycanvas'),
ctx = canvas.getContext('2d'),
scene = [],
lastTime = 0, // Last seen timestamp.
drawFrame = function (timestamp) {
// Clear canvas. An efficient implementation
// will only clear as much as needed.
ctx.clearRect(0, 0, canvas.width, canvas.height); // Call update on all scene elements...
scene.forEach(function (elem) {
elem.update(timestamp - lastTime);
}); // ...then draw them.
scene.forEach(function (elem) {
elem.draw(ctx);
}); // Request to be called again.
lastTime = timestamp;
window.requestAnimationFrame(drawFrame);
}; // Kick off animation loop.
window.requestAnimationFrame(drawFrame); // Animated circle constructor.
var animatedCircle = function (starx, starty, color) {
var dir = 1, // movement direction
x = starx || canvas.width / 2,
y = starty || canvas.height / 2,
r = 50,
v = 0.1,
color = color || 'black'; return {
x: x, y: y, r: r, v: v, color: color,
update: function (deltaT) {
// Update location based on elapsed time.
this.x += this.v * deltaT * dir; // Clamp.
if (this.x + this.r > canvas.width) {
dir = -1;
}
else if (this.x - this.r < 0) {
dir = 1;
}
},
draw: function (ctx) {
// Draw element according to current property values.
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI);
ctx.fillStyle = this.color;
ctx.fill();
}
}
}; // Compose scene.
scene.push(animatedCircle(canvas.width * 0.33, null, 'red'));
scene.push(animatedCircle(null, canvas.height * 0.25, 'green'));
scene.push(animatedCircle(canvas.width * 0.66, canvas.height * 0.75, 'blue'));
var canvas = document.getElementById('mycanvas'),
ctx = canvas.getContext('2d'),
scene = [],
lastTime = 0, // Last seen timestamp.
drawFrame = function (timestamp) {
// Clear canvas. An efficient implementation
// will only clear as much as needed.
ctx.clearRect(0, 0, canvas.width, canvas.height); // Call update on all scene elements...
scene.forEach(function (elem) {
elem.update(timestamp - lastTime);
}); // ...then draw them.
scene.forEach(function (elem) {
elem.draw(ctx);
}); // Request to be called again.
lastTime = timestamp;
window.requestAnimationFrame(drawFrame);
}; // Kick off animation loop.
window.requestAnimationFrame(drawFrame); // Animated circle constructor.
var animatedCircle = function (starx, starty, color) {
var dir = 1, // movement direction
x = starx || canvas.width / 2,
y = starty || canvas.height / 2,
r = 50,
v = 0.1,
color = color || 'black'; return {
x: x, y: y, r: r, v: v, color: color,
update: function (deltaT) {
// Update location based on elapsed time.
this.x += this.v * deltaT * dir; // Clamp.
if (this.x + this.r > canvas.width) {
dir = -1;
}
else if (this.x - this.r < 0) {
dir = 1;
}
},
draw: function (ctx) {
// Draw element according to current property values.
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI);
ctx.fillStyle = this.color;
ctx.fill();
}
}
}; // Compose scene.
scene.push(animatedCircle(canvas.width * 0.33, null, 'red'));
scene.push(animatedCircle(null, canvas.height * 0.25, 'green'));
scene.push(animatedCircle(canvas.width * 0.66, canvas.height * 0.75, 'blue'));
var canvas = document.getElementById('mycanvas'),
ctx = canvas.getContext('2d'),
scene = [],
lastTime = 0, // Last seen timestamp.
drawFrame = function (timestamp) {
// Clear canvas. An efficient implementation
// will only clear as much as needed.
ctx.clearRect(0, 0, canvas.width, canvas.height); // Call update on all scene elements...
scene.forEach(function (elem) {
elem.update(timestamp - lastTime);
}); // ...then draw them.
scene.forEach(function (elem) {
elem.draw(ctx);
}); // Request to be called again.
lastTime = timestamp;
window.requestAnimationFrame(drawFrame);
}; // Kick off animation loop.
window.requestAnimationFrame(drawFrame); // Animated circle constructor.
var animatedCircle = function (starx, starty, color) {
var dir = 1, // movement direction
x = starx || canvas.width / 2,
y = starty || canvas.height / 2,
r = 50,
v = 0.1,
color = color || 'black'; return {
x: x, y: y, r: r, v: v, color: color,
update: function (deltaT) {
// Update location based on elapsed time.
this.x += this.v * deltaT * dir; // Clamp.
if (this.x + this.r > canvas.width) {
dir = -1;
}
else if (this.x - this.r < 0) {
dir = 1;
}
},
draw: function (ctx) {
// Draw element according to current property values.
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI);
ctx.fillStyle = this.color;
ctx.fill();
}
}
}; // Compose scene.
scene.push(animatedCircle(canvas.width * 0.33, null, 'red'));
scene.push(animatedCircle(null, canvas.height * 0.25, 'green'));
scene.push(animatedCircle(canvas.width * 0.66, canvas.height * 0.75, 'blue'));
Para usted, TimelineLite proporcionará los métodos de update
: puede pasarle referencias a sus objetos JS y se encargará de mover sus propiedades, sean cuales sean. Por lo tanto, solo debe ocuparse de las llamadas de extracción, e incluso puede ignorar la marca de tiempo que obtiene de requestAnimationFrame
, ya que solo es necesario para los métodos de actualización. TimelineLite probablemente también use requestAnimationFrame
internamente, pero esto no es un problema (puede suscribirse tantas funciones como desee que se le notifique cuando el navegador comience a pintarse).
Por supuesto, cuide los detalles, como encontrar qué requestAnimationFrame
necesita llamar (prefijos de proveedor y setInterval
) y proporcionar un setInterval
basado en setInterval
para los navegadores que no tienen reqAnimFrame 🙂
Una última nota sobre el rendimiento: un bucle for
con una longitud en caché ( for (var i = 0, len = arr.length; i < len; i++)
) es mucho más rápido que forEach
, pero soy flojo.