如何在Angular TypeScript中实现回调?动画结束后执行指定函数
Hey there! Let's tackle this problem step by step. Since your roulette animation library doesn't provide a built-in way to detect when it finishes, but you know the approximate duration and expected outcome, here are a few practical approaches you can use:
1. Delay based on known animation duration (simplest and fastest)
Since you mentioned the animation takes around 5 seconds, the quickest fix is to use setTimeout to trigger alertResult() right after the animation should end. Add a small buffer time to account for minor performance differences across devices:
function startRoulette() { roulette_animation(); // Launch the animation setTimeout(alertResult, 5200); // Trigger alert 5.2s later, adding 200ms for error tolerance }
Pros: Extremely easy to implement.
Cons: Might be slightly out of sync if the animation duration varies (e.g., on slower devices). Works great if strict sync isn't critical.
2. Listen for visual animation end events (most accurate)
If your animation uses CSS transitions or keyframes, you can listen directly to the browser's built-in animation end events:
- For CSS animations: Listen to the
animationendevent - For CSS transitions: Listen to the
transitionendevent
First, target the DOM element the animation applies to (e.g., your roulette wheel container), then bind the event:
function startRoulette() { const rouletteWheel = document.getElementById('your-roulette-element-id'); // Remove existing listeners first to avoid duplicate triggers rouletteWheel.removeEventListener('animationend', alertResult); rouletteWheel.addEventListener('animationend', alertResult); roulette_animation(); // Start the animation }
If the animation is JS-driven (e.g., using requestAnimationFrame), you can poll for the wheel's final state (like rotation angle or position) to detect completion:
function waitForAnimationFinish() { const rouletteWheel = document.getElementById('your-roulette-element-id'); // Replace with your actual expected end state (e.g., 10 full rotations = 3600deg) const finalRotation = 3600; const checkState = () => { const currentRotation = parseInt(getComputedStyle(rouletteWheel).transform.split(',')[4]) || 0; if (currentRotation >= finalRotation) { alertResult(); } else { requestAnimationFrame(checkState); } }; requestAnimationFrame(checkState); } function startRoulette() { roulette_animation(); waitForAnimationFinish(); }
Pros: Perfectly syncs the alert with the animation's actual end.
Cons: Requires knowing the animation's final visual state (like rotation value) to check against.
3. Wrap the animation function as a Promise (cleanest async workflow)
If you can modify or wrap the roulette_animation function, turn it into a Promise to make asynchronous logic more readable:
// Wrap the animation into a Promise function rouletteAnimationPromise() { return new Promise((resolve) => { roulette_animation(); // Start the animation // Use either the timeout or state-check method above to trigger resolve() setTimeout(resolve, 5200); // Or use the state polling logic here, calling resolve() when done }); } // Use async/await for clean execution flow async function startRoulette() { await rouletteAnimationPromise(); alertResult(); }
Pros: Makes asynchronous code easier to read and extend for future features.
Cons: Requires a small amount of wrapper code to handle the Promise logic.
内容的提问来源于stack exchange,提问作者Monkey

