How to cut off the start of a jquery animation?

狂风中的少年 提交于 2020-01-21 09:08:16

问题


Don't be hard on me, it's my first time posting.

I'm currently working on a wheel of fortune, which is synchronized to each connected device via node.js and websockets. However I want to cut off the start of the animation, when a user joins while the wheel is spinning already, so it would only show the last seconds of the animation without changing it's easing.

The jquery animation is made of a simple step animation, which rotates the wheel around. I already tried to change the parameters of the step's 'fx' object like fx.start or fx.pos. While fx.start only being the variable at which point the animation started, for example 180 degrees and fx.pos is only a sort of output parameter to change something to a given time in the animation, like a text color or something. However the fx.pos value can't be changed nor changes the position the animation is currently set in. I created a function to rotate the wheel of fortune two times and then it stops at a given degree.

Also I tried to change the easing, so it would be 50% linear, 50% swing, but this makes the animation look trashy, since at first it's spins at a constant speed and suddenly it spins faster than slower.

function spinRoulette(deg, duration = 10000) {
  deg = Math.round(deg);
  $("img.roulette").animate(
      { now: '+='+(720+deg-getRotation()) }, {
      duration: duration,
      ...
      step: function(now, fx) {
        if(now >= 360)
          now -= 360;
        $(this).css("transform", "rotate("+now+"deg)");
      }
    });
}

If the duration would be less then 10 seconds the start of the animation would be cut off. So, if the server spun the wheel about 5 seconds ago the first 5 seconds of my animation should be cut off.


回答1:


Catch-up an easing animation rotation at any point in time

  • Animate linearly t from 0 to 1, or from 0.N to 1.0 ( 0.6 if a player joined at the 6th second out of 10 max) $({t: t}).animate({t: 1},
  • Ease! At any given "now"-point-in-time, convert the current 0.0-1.0 time range (t_now value) to the respective easing e_now value using a custom easing function
  • Multiply the easing e_now result by the desired end-degrees number

Instead of using "swing" use "linear" and let's take control over the easing and timing with a custom easing function (you can find many easing snippets online). Say we like the easeInOutSine:

const easeInOutSine = t => -(Math.cos(Math.PI * t) - 1) / 2;

Example

Example with 4 persons, one spinning the wheel, and other joining the show at 2, 4.5 and 8.7 seconds after the initial spin started:

const easeInOutSine = t => -(Math.cos(Math.PI * t) - 1) / 2;

function spinRoulette(sel, deg, duration = 10000) {
  const $el = $(sel);
  const maxDuration = 10000;
  const deg_end = 720 + Math.round(deg);  // 2 revolutions + server-generated degrees
  const time = maxDuration - duration;    // Start time in ms
  const t = time / maxDuration;           // Start time to 0.0-1.0 range 

  $({t: t}).animate({t: 1}, {             // Custom jQuery anim. from 0.N to 1.0
    duration: duration,
    easing: "linear",                     // We need a linear 0.0 to 1.0
    step: function(t_now) {
      const e_now = easeInOutSine(t_now); // Current easing
      const deg_now = e_now * deg_end;    // Current degrees
      $el.css({transform: `rotate(${ deg_now }deg)`});
    }
  });
}

// Person 1 spins!
spinRoulette("#r1", 45);
// Person 2 joins the room after 2s
setTimeout(() => spinRoulette('#r2', 45, 10000 - 2000), 2000);
// Person 3 joins the room after 4.5s
setTimeout(() => spinRoulette('#r3', 45, 10000 - 4500), 4500);
// Person 4 joins the room after 8.7s
setTimeout(() => spinRoulette('#r4', 45, 10000 - 8700), 8700);
img {height: 120px; display: inline-block;}
<img id="r1" src="https://i.stack.imgur.com/bScK3.png">
<img id="r2" src="https://i.stack.imgur.com/bScK3.png">
<img id="r3" src="https://i.stack.imgur.com/bScK3.png">
<img id="r4" src="https://i.stack.imgur.com/bScK3.png">

<script src="//code.jquery.com/jquery-3.4.1.min.js"></script>

In the example above, finally, you can notice (besides some weird optical illusion) that the wheels catch-up at any point in time with the correct rotation state, velocity, and all finish at the same time with the same easing, at the exact predefined deg_end degree.



来源:https://stackoverflow.com/questions/58794004/how-to-cut-off-the-start-of-a-jquery-animation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!