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

285
Vistas
reverse gravity : how to reset the values to their default values?

I try to create reverse gravity, and I have an issue after I click several times on the button "physics" : it is supposed to restart with the default values, but after 10 times, the balls go too fast and I don't understand why. The function works fine the first time, but then it starts to accelerate each time you click on "physics".

https://codepen.io/Arthur222/pen/QWOgMXq

let isOn = 0;
let canvas = document.getElementById("canvas");
if (canvas.getContext('2d') == null ) alert("erreur javascript");
let ctx = canvas.getContext('2d');
let velocity=1, force=1, mass = 1, radius=30;
let lastTs;

//FCN


window.addEventListener('load', ()=>{
    resize();
    window.addEventListener('resize', resize);
    createBalls();
    drawBalls();
});

// PHYSICS


let balls = [];
function createBalls(){
  for ( let i=0; i<6; i++){
    let x = radius+(i*radius*2);
    if (i>0) x = radius+(i*(radius+10)*2);
    let vel = Math.random();
    let ball = {x:x, y:250, xBase:x, yBase:250, velocity:vel, velocityBase:vel, radius:30, active:true}
    balls.push(ball);
  }
}


function startPhy1(){

  if (isOn == 1){
    console.log("canvas.width, canvas.height : "+canvas.width, canvas.height);
    ctx.clearRect(0,0,canvas.width, canvas.height);
    balls.forEach(element => {
      element.y = element.yBase;
      element.active = true;
      element.velocity = element.velocityBase;
    });
  }

  isOn = 1;
  lastTs = getTimestamp();
  runPhy();
  draw();
} 

function runPhy(){
  let t = (getTimestamp() - lastTs)/1000;

  balls.forEach(element => {
    if ( element.active ){ //still below
      element.y -= element.velocity * t;
      element.velocity += ( force / mass ) * t;
      if ( element.y <= element.radius+10 ){//already on top
        element.active = false;
        element.y = element.radius;//stay on top
      }
    }
  });
  requestAnimationFrame(runPhy);
  
}

function getTimestamp() {
  return new Date().getTime();
}
// DRAW 

function draw(){
  drawBalls();
  requestAnimationFrame(draw);
}

function drawBalls(){
  ctx.clearRect(0,0,canvas.width, canvas.height);
  for (let i=0; i< balls.length; i++){

    
    ctx.beginPath();
    ctx.arc(balls[i].x, balls[i].y, balls[i].radius, 0, 2 * Math.PI, false);
    ctx.strokeStyle = "green";
    ctx.lineWidth = 2;
    ctx.stroke();
  }
  
}


function resize(){
  ctx.canvas.width = window.innerWidth*0.7;
  ctx.canvas.height = window.innerHeight*0.9;
}
about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

I think the problem with your code is that you are requesting the animation frame every time that the button is clicked.

I tried fixing your code without success, that's why I coded this one. Try it:

const canvas = document.getElementById('root')
const btn = document.getElementById('btn')
const ctx = canvas.getContext('2d')
const circleImage = new Image()
      
circleImage.src = 'https://i.stack.imgur.com/CdziF.png'

var piece = {
  image: circleImage,
  x: 100,
  y: 250,
  width: 50
}
     
var speed = 0    
var max = 10   
    
function gameLoop(){ 
  ctx.clearRect(0, 0, canvas.width, canvas.height) 
  ctx.drawImage(piece.image, piece.x, piece.y)    
  
  speed < max ? speed += 0.1 : null
  
  if(piece.y > 0){
    piece.y -= speed
    piece.y < 0 ? piece.y = 0 : null // Position correction
  }
  window.requestAnimationFrame(gameLoop)   // Needed to keep looping
}

function start(){
  if(btn.value === 'start'){
    btn.value = 'restart'   
    circleImage.onload = window.requestAnimationFrame(gameLoop)  // Start gameLoop()
  }
  if(btn.value === 'restart'){
    speed = 0  
    piece.y = 250
  }
}

btn.addEventListener('click', start) // When btn is clicked execute start()
<input id="btn" type="button" value="start" />
<p>
<canvas id="root" height="300" width="300" style="border:1px solid grey">

And see here what happens when the request animation frame is requested everytime the a button is clicked:

const canvas = document.getElementById('root')
const btn = document.getElementById('btn')
const ctx = canvas.getContext('2d')
const circleImage = new Image()
      
circleImage.src = 'https://i.stack.imgur.com/CdziF.png'

var piece = {
  image: circleImage,
  x: 100,
  y: 250,
  width: 50
}
     
var speed = 0    
var max = 10   
    
function gameLoop(){ 
  ctx.clearRect(0, 0, canvas.width, canvas.height) 
  ctx.drawImage(piece.image, piece.x, piece.y)    
  
  speed < max ? speed += 0.1 : null
  
  if(piece.y > 0){
    piece.y -= speed
    piece.y < 0 ? piece.y = 0 : null // Position correction
  }
  window.requestAnimationFrame(gameLoop)   // Needed to keep looping
}

function start(){
  if(btn.value === 'start'){
    speed = 0  
    piece.y = 250
    circleImage.onload = window.requestAnimationFrame(gameLoop)  // Start gameLoop()
  }
}

btn.addEventListener('click', start) // When btn is clicked execute start()
<input id="btn" type="button" value="start" />
<p>
<canvas id="root" height="300" width="300" style="border:1px solid grey">

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