为了账号安全,请及时绑定邮箱和手机立即绑定

如何制作网球从水平表面弹起的动画

如何制作网球从水平表面弹起的动画

忽然笑 2023-07-20 15:40:21
我有一张网球的图像:有必要制作一个球下落并随后从固体表面弹起的动画。我得到了这种动画,但它看起来不现实:要启动动画,请单击图像:<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>   第一次弹跳必须小于球下落的高度,第二次弹跳小于第一次弹跳的高度,第三次弹跳小于第二次弹跳的高度。你如何实现这一目标?解决方案可能在 SMIL SVG、CSS、JS 上SMIL SVG 解决方案是首选。
查看完整描述

2 回答

?
临摹微笑

TA贡献1982条经验 获得超2个赞

最现实的方法是用 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>


查看完整回答
反对 回复 2023-07-20
?
吃鸡游戏

TA贡献1829条经验 获得超7个赞

SVG SMILE 解决方案


values = ""球弹跳的可变量可以在动画命令的属性中设置animateTransform。


可以使用属性值来控制每个时间段的球速keyTimes。


restart = "whenNotActive"- 防止重新启动动画直到它完全完成。


单击后将开始动画


<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"

     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>

循环动画示例

为此,在动画开始条件中写入以下条件:
begin = "svg1.click; anT.end + 1s",其中

svg1.click- 单击后动画的第一次开始
anT.end + 1s- 在 id = "anT" 的动画结束后 1 秒内重新启动动画

<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>


查看完整回答
反对 回复 2023-07-20
  • 2 回答
  • 0 关注
  • 122 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信