如何为网球设置动画以从水平表面弹起 [英] How to animate a tennis ball to bounce off a horizontal surface

查看:123
本文介绍了如何为网球设置动画以从水平表面弹起的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个网球的图像:

有必要制作一个动画,使球掉下来,随后从固体表面反弹.

It is necessary to make an animation of a ball falling with subsequent bounces from a solid surface.

我得到了这种动画,但是看起来不现实:

I got this kind of animation, but it doesn't look realistic:

要开始播放动画,请单击图像:

<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 attributeName="transform" type="translate" dur="1s" begin="svg1.click" values="0,0;0,168;0" repeatCount="3" />
</image>
   <polyline points="5,190 190,190" stroke="silver" stroke-width="4" />
 
</svg>   

第一次反弹必须小于落球的高度,第二次反弹要小于第一次反弹的高度,第三次反弹要小于第二次反弹.

It is necessary that the first bounce was less than the height of the fall of the ball, the second bounce was less than the height of the first bounce, the third bounce was less than the second.

您如何实现这一目标?解决方案可能在SMIL SVG,CSS,JS上

How do you achieve this? Solution maybe on SMIL SVG, CSS, JS

首选SMIL SVG解决方案.

SMIL SVG solution is preferred.

推荐答案

最现实的方法是使用JS模拟物理.

The most realistic approach would be to simulate the physics with JS.

类似这样的东西:

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: 0, 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>

这篇关于如何为网球设置动画以从水平表面弹起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆