问题
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
from0
to1
, or from0.N
to1.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 easinge_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