How to cut off the start of a jquery animation?

后端 未结 1 484
醉话见心
醉话见心 2021-01-06 21:49

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 webso

相关标签:
1条回答
  • 2021-01-06 22:17

    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.

    0 讨论(0)
提交回复
热议问题