Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

303
Vistas
adding animation to canvas wheel using javascript, spinning wheel animation

I'm trying to make a simple animation for a wheel, and I'm not sure how to define the animation function of it.

index.html, can be found below, trying to keep the body clean... (no real reson).

<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
  </body>
</html>

javascript, can be found below or using the jsfiddle link. I have compose the wheel from 2 main canvas, one is the outterWheel and the other one is the innerWheel which is filled to cover the lines of outterWheel, give the impression of a mechanical wheel.

let buttonDOM = document.createElement('canvas');
buttonDOM.id = 'outterWheel';
buttonDOM.width = 80;
buttonDOM.height = 60;
document.body.appendChild(buttonDOM);
ctx = document.getElementById('outterWheel').getContext('2d');
ctx.lineWidth = 2;
ctx.beginPath();
const smallLines = [ 0, 22.5, 45, 67.5, 90, 112.5, 135, 157.5, 180, 202.5, 225, 247.5, 270, 292.5, 315, 337.5 ];
ctx.fillStyle = "#76D7C4";
ctx.fillRect(0, 0, 80, 60);
ctx.arc(40, 30, 15, 0, 2 * Math.PI);
for (var angle of smallLines){
    ctx.moveTo(40, 30);
    ctx.lineTo(40 + 17 * Math.cos(angle * Math.PI * 2 / 360), 30 + 17 * Math.sin(angle * Math.PI * 2 / 360));
}
ctx.stroke();
buttonDOM = document.createElement('canvas');
buttonDOM.id = 'innerWheel';
buttonDOM.width = 80;
buttonDOM.height = 60;
document.body.appendChild(buttonDOM);
ctx = document.getElementById('innerWheel').getContext('2d');
ctx.lineWidth = 2;
ctx.beginPath();
ctx.fillStyle = "#76D7C4";
ctx.clearRect(0, 0, 80, 60);
ctx.arc(40, 30, 15, 0, 2 * Math.PI);
ctx.fillStyle = "#76D7C4";
ctx.fill();
for (var angle of smallLines){
    ctx.moveTo(40, 30);
    ctx.lineTo(40 + 18 * Math.cos((angle + 11.25) * Math.PI * 2 / 360), 30 + 18 * Math.sin((angle + 11.25) * Math.PI * 2 / 360));
}
ctx.stroke();

https://jsfiddle.net/nh63c28w/2/

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

At the moment you're using two <canvas> elements to draw your wheels. I'd recommend using a single instance for creating each wheel initially. With the help of the canvas.toDataURL() you can store a snapshot of your canvas' content to a element and re-use the two images to compose your final animation on the canvas.

To actually draw the animation we can utilize a combination of the translate(), rotate() and drawImage() methods. translate will move the context to a specific x & y position, rotate will rotate the canvas by a certain amount given in radians and drawImage will finally draw the given image at the context's current position.

To change the animation over time - like rotating the wheels - we need to re-trigger the animation function. This is done by the requestAnimationFrame() function which calls a given callBack function at the refreshrate of your monitor e.g. 60 times per second on a 60hz display.

For example:

let buttonDOM = document.createElement('canvas');
buttonDOM.id = 'outerWheel';
buttonDOM.width = 80;
buttonDOM.height = 60;
document.body.appendChild(buttonDOM);
ctx = document.getElementById('outerWheel').getContext('2d');
ctx.lineWidth = 2;
ctx.beginPath();
const smallLines = [0, 22.5, 45, 67.5, 90, 112.5, 135, 157.5, 180, 202.5, 225, 247.5, 270, 292.5, 315, 337.5];
ctx.fillStyle = "#76D7C4";
ctx.fillRect(0, 0, 80, 60);
ctx.arc(40, 30, 15, 0, 2 * Math.PI);
for (var angle of smallLines) {
  ctx.moveTo(40, 30);
  ctx.lineTo(40 + 17 * Math.cos(angle * Math.PI * 2 / 360), 30 + 17 * Math.sin(angle * Math.PI * 2 / 360));
}
ctx.stroke();
ctx.closePath();
let outerWheel = new Image();
outerWheel.src = buttonDOM.toDataURL();

ctx.lineWidth = 2;
ctx.beginPath();
ctx.clearRect(0, 0, 80, 60);
ctx.arc(40, 30, 15, 0, 2 * Math.PI);
ctx.fill();
for (var angle of smallLines) {
  ctx.moveTo(40, 30);
  ctx.lineTo(40 + 18 * Math.cos((angle + 11.25) * Math.PI * 2 / 360), 30 + 18 * Math.sin((angle + 11.25) * Math.PI * 2 / 360));
}
ctx.stroke();
ctx.closePath();
let innerWheel = new Image();
innerWheel.src = buttonDOM.toDataURL();
let innerWheelProperties = {
  x: 75,
  y: 100,
  rotation: 0
};
let outerWheelProperties = {
  x: 250,
  y: 100,
  rotation: 0
};
buttonDOM.width = 300;
buttonDOM.height = 200;

function animation() {
  ctx.clearRect(0, 0, buttonDOM.width, buttonDOM.height);
  ctx.save();
  ctx.translate(innerWheelProperties.x, innerWheelProperties.y);
  ctx.rotate(innerWheelProperties.rotation * Math.PI / 180);
  ctx.drawImage(innerWheel, 0 - innerWheel.width / 2, 0 - innerWheel.height / 2);
  ctx.restore();
  ctx.save();
  ctx.translate(outerWheelProperties.x, outerWheelProperties.y);
  ctx.rotate(outerWheelProperties.rotation * Math.PI / 180);
  ctx.drawImage(outerWheel, 0 - outerWheel.width / 2, 0 - outerWheel.height / 2);
  ctx.restore();
  outerWheelProperties.rotation++;
  innerWheelProperties.rotation -= 0.5;
  requestAnimationFrame(animation);

}
requestAnimationFrame(animation);

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda