The question was initiated by a topic
In that question, the bounces were vertical
<svg id="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" viewBox="0 0 200 200" preserveAspectRatio="xMinYMin meet" style="border:1px solid" > <image xlink:href="https://i.stack.imgur.com/hXyA5.png" x="82" width="25px" height="25px" > <animateTransform id="anT" attributeName="transform" type="translate" dur="3s" begin="svg1.click+0.5s;anT.end+1s" values=" 0,0; 0,168; 0,84; 0,168; 0,126; 0,168; 0,148; 0,168; 0,158; 0,168; 0,163; 0,168; 0,166; 0,168; " keyTimes="0;0.066;0.13;0.198;0.264;0.33;0.396;0.462;0.528;0.594;0.66;0.726;0.792;1" repeatCount="1" fill="freeze" restart="whenNotActive" /> </image> <polyline points="5,193 194,193" stroke="silver" stroke-width="4" /> </svg>
This question concerns bounces with different amounts of offset in height and length
But it is difficult to realize the unevenness of movement and speed.
How to implement realistic parabolic ball movement?
Any idea and solution would be appreciated.
Advertisement
Answer
I allowed for this behaviour in my previous answer (in the linked question). Just set dx
to a non-zero value.
ball = {x: 82, y: 0, dx: 1, dy: 0};
x
andy
are the starting position of the balldx
anddy
are the initial velocity of the ball
let ballElem = document.getElementById("ball"); let GRAVITY = 40; // Acceleration due to gravity (pixels / sec /sec) let FLOOR_Y = 200 - 25; // Y coord of floor. The 25 here is because ball.y is the top of the ball. let BOUNCINESS = 0.8; // Velocity retained after a bounce let LIMIT = 0.1; // Minimum velocity required to keep animation running let ball = {}; let lastFrameTime = null; ballElem.addEventListener("click", startAnim); function startAnim() { ball = {x: 82, y: 0, dx: 1, dy: 0}; lastFrameTime = null; requestAnimationFrame(animStep); } function animStep(timestamp) { if (lastFrameTime === null) lastFrameTime = timestamp; // Milliseconds elapsed since last step const elapsed = timestamp - lastFrameTime; lastFrameTime = timestamp; ball.dy += GRAVITY * elapsed / 1000; ball.y += ball.dy; ball.x += ball.dx; // not really used in this example if (ball.y > FLOOR_Y) { // Step has taken us below the floor, so we need to rebound the ball. ball.y -= (ball.y - FLOOR_Y); ball.dy = -ball.dy * BOUNCINESS; } // Update the <image> element x and y ballElem.x.baseVal.value = ball.x; ballElem.y.baseVal.value = ball.y; // Request another animation step if (Math.abs(ball.y - FLOOR_Y) > LIMIT || // Not on ground Math.abs(ball.dy) > LIMIT || // or still moving Math.abs(ball.dx) > LIMIT) { requestAnimationFrame(animStep); } }
<svg id="svg1" width="200" height="200" viewBox="0 0 200 200" preserveAspectRatio="xMinYMin meet" style="border:1px solid" > <image id="ball" xlink:href="https://i.stack.imgur.com/hXyA5.png" x="82" width="25px" height="25px"/> </svg>