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

我有一张网球的图像:

http://img2.mukewang.com/64b8e50300019d5501010102.jpg

有必要制作一个球下落并随后从固体表面弹起的动画。


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


要启动动画,请单击图像:


<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 解决方案是首选。


忽然笑
浏览 123回答 2
2回答

临摹微笑

最现实的方法是用 JS 模拟物理。像这样的东西:let ballElem = document.getElementById("ball");let GRAVITY = 40;&nbsp; &nbsp; &nbsp; &nbsp; // Acceleration due to gravity (pixels / sec /sec)let FLOOR_Y = 200 - 25;&nbsp; // Y coord of floor. The 25 here is because ball.y is the top of the ball.let BOUNCINESS = 0.8;&nbsp; &nbsp; // Velocity retained after a bouncelet LIMIT = 0.1;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Minimum velocity required to keep animation runninglet ball = {};let lastFrameTime = null;ballElem.addEventListener("click", startAnim);function startAnim(){&nbsp; ball = {x: 82, y: 0, dx: 0, dy: 0};&nbsp; lastFrameTime = null;&nbsp; requestAnimationFrame(animStep);}function animStep(timestamp){&nbsp; if (lastFrameTime === null)&nbsp; &nbsp; lastFrameTime = timestamp;&nbsp; // Milliseconds elapsed since last step&nbsp; const elapsed = timestamp - lastFrameTime;&nbsp; lastFrameTime = timestamp;&nbsp;&nbsp;&nbsp; ball.dy += GRAVITY * elapsed / 1000;&nbsp; ball.y += ball.dy;&nbsp; ball.x += ball.dx;&nbsp; &nbsp;// not really used in this example&nbsp; if (ball.y > FLOOR_Y) {&nbsp; &nbsp; // Step has taken us below the floor, so we need to rebound the ball.&nbsp; &nbsp; ball.y -= (ball.y - FLOOR_Y);&nbsp; &nbsp; ball.dy = -ball.dy * BOUNCINESS;&nbsp; }&nbsp;&nbsp;&nbsp; // Update the <image> element x and y&nbsp; ballElem.x.baseVal.value = ball.x;&nbsp; ballElem.y.baseVal.value = ball.y;&nbsp;&nbsp;&nbsp; // Request another animation step&nbsp; if (Math.abs(ball.y - FLOOR_Y) > LIMIT ||&nbsp; // Not on ground&nbsp; &nbsp; &nbsp; Math.abs(ball.dy) > LIMIT ||&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// or still moving&nbsp; &nbsp; &nbsp; Math.abs(ball.dx) > LIMIT) {&nbsp; &nbsp; requestAnimationFrame(animStep);&nbsp; }}<svg id="svg1"&nbsp;&nbsp; &nbsp; &nbsp;width="200" height="200" viewBox="0 0 200 200" preserveAspectRatio="xMinYMin meet" style="border:1px solid" >&nbsp;&nbsp;&nbsp;&nbsp; <image id="ball" xlink:href="https://i.stack.imgur.com/hXyA5.png" x="82" width="25px" height="25px"/>&nbsp;</svg>

吃鸡游戏

SVG SMILE 解决方案values = ""球弹跳的可变量可以在动画命令的属性中设置animateTransform。可以使用属性值来控制每个时间段的球速keyTimes。restart = "whenNotActive"- 防止重新启动动画直到它完全完成。单击后将开始动画<svg id="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg"&nbsp;&nbsp; &nbsp; xmlns:xlink="http://www.w3.org/1999/xlink"&nbsp; &nbsp; &nbsp; &nbsp;width="200" height="200" viewBox="0 0 200 200" preserveAspectRatio="xMinYMin meet" style="border:1px solid" >&nbsp;&nbsp;&nbsp;<image xlink:href="https://i.stack.imgur.com/hXyA5.png" x="82" width="25px" height="25px" >&nbsp; &nbsp;<animateTransform id="anT"&nbsp; &nbsp; &nbsp;attributeName="transform"&nbsp; &nbsp; &nbsp;type="translate"&nbsp; &nbsp; &nbsp;dur="3s"&nbsp; &nbsp; &nbsp;begin="svg1.click+0.5s"&nbsp; &nbsp; &nbsp;values="&nbsp; &nbsp; &nbsp; 0,0;&nbsp; &nbsp; &nbsp; &nbsp; 0,168;&nbsp; &nbsp; &nbsp; &nbsp; 0,84;&nbsp; &nbsp; &nbsp; &nbsp; 0,168;&nbsp; &nbsp; &nbsp; &nbsp; 0,126;&nbsp; &nbsp; &nbsp; &nbsp; 0,168;&nbsp; &nbsp; &nbsp; &nbsp; 0,148;&nbsp; &nbsp; &nbsp; &nbsp; 0,168;&nbsp; &nbsp; &nbsp; &nbsp; 0,158;&nbsp; &nbsp; &nbsp; &nbsp; 0,168;&nbsp; &nbsp; &nbsp; &nbsp; 0,163;&nbsp; &nbsp; &nbsp; &nbsp; 0,168;&nbsp; &nbsp; &nbsp; &nbsp; 0,166;&nbsp; &nbsp; &nbsp; &nbsp; 0,168;"&nbsp; &nbsp; 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"&nbsp; &nbsp; &nbsp; &nbsp; repeatCount="1"&nbsp; &nbsp; &nbsp; &nbsp; fill="freeze"&nbsp; &nbsp; &nbsp; &nbsp; restart="whenNotActive" /></image>&nbsp; &nbsp;<polyline points="5,193 194,193" stroke="silver" stroke-width="4" />&nbsp;</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"&nbsp;&nbsp; &nbsp; xmlns:xlink="http://www.w3.org/1999/xlink"&nbsp; &nbsp; &nbsp; &nbsp;width="200" height="200" viewBox="0 0 200 200" preserveAspectRatio="xMinYMin meet" style="border:1px solid" >&nbsp;&nbsp;&nbsp;<image xlink:href="https://i.stack.imgur.com/hXyA5.png" x="82" width="25px" height="25px" >&nbsp; &nbsp;<animateTransform id="anT"&nbsp; &nbsp; &nbsp;attributeName="transform"&nbsp; &nbsp; &nbsp;type="translate"&nbsp; &nbsp; &nbsp;dur="3s"&nbsp; &nbsp; &nbsp;begin="svg1.click+0.5s;anT.end+1s"&nbsp; &nbsp; &nbsp;values="&nbsp; &nbsp; &nbsp; &nbsp; 0,0;&nbsp; &nbsp; &nbsp; &nbsp; 0,168;&nbsp; &nbsp; &nbsp; &nbsp; 0,84;&nbsp; &nbsp; &nbsp; &nbsp; 0,168;&nbsp; &nbsp; &nbsp; &nbsp; 0,126;&nbsp; &nbsp; &nbsp; &nbsp; 0,168;&nbsp; &nbsp; &nbsp; &nbsp; 0,148;&nbsp; &nbsp; &nbsp; &nbsp; 0,168;&nbsp; &nbsp; &nbsp; &nbsp; 0,158;&nbsp; &nbsp; &nbsp; &nbsp; 0,168;&nbsp; &nbsp; &nbsp; &nbsp; 0,163;&nbsp; &nbsp; &nbsp; &nbsp; 0,168;&nbsp; &nbsp; &nbsp; &nbsp; 0,166;&nbsp; &nbsp; &nbsp; &nbsp; 0,168;&nbsp; &nbsp; &nbsp; &nbsp; "&nbsp; &nbsp; &nbsp; &nbsp; 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"&nbsp; &nbsp; &nbsp; &nbsp; repeatCount="1"&nbsp; &nbsp; &nbsp; &nbsp; fill="freeze"&nbsp; &nbsp; &nbsp; &nbsp; restart="whenNotActive" /></image>&nbsp; &nbsp;<polyline points="5,193 194,193" stroke="silver" stroke-width="4" />&nbsp;</svg>
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript