ScrollMagic多视口触发冲突求助:分端控制动画触发逻辑
Hey there! I’ve run into similar ScrollMagic responsive animation conflicts before, so let’s break this down and fix that duplicate animation issue for good.
Core Problem & Solution
The root issue is loading both sets of ScrollMagic scenes at once—we need to dynamically create only the relevant scenes based on viewport size, and clean up old scenes when the window resizes. This way, desktop and mobile animations never run simultaneously.
Step-by-Step Implementation
First, let’s structure our code to handle scene initialization, destruction, and responsive updates:
// Define your Tween animations (make these accessible globally or within scope) const entire = TweenMax.to('.your-entire-element', 0.6, { /* Desktop animation props */ }); const row1 = TweenMax.to('.row-1', 0.6, { /* Mobile row 1 props */ }); const row2 = TweenMax.to('.row-2', 0.6, { /* Mobile row 2 props */ }); const row3 = TweenMax.to('.row-3', 0.6, { /* Mobile row 3 props */ }); const mainController = new ScrollMagic.Controller(); let currentScenes = []; // Track active scenes to destroy later function initScrollMagicScenes() { // 1. Clean up existing scenes to prevent duplicates currentScenes.forEach(scene => scene.remove()); currentScenes = []; // 2. Check viewport size and create matching scenes const isDesktop = window.innerWidth >= 768; // Adjust breakpoint to your project's needs if (isDesktop) { // Desktop: Trigger full animation set const sceneEntire = new ScrollMagic.Scene({ triggerElement: "#triggerall", reverse: false }) .setTween(entire) .addIndicators({ name: "Desktop: Full Animation" }) .addTo(mainController); currentScenes.push(sceneEntire); } else { // Mobile: Trigger row animations individually const scene1 = new ScrollMagic.Scene({ triggerElement: "#trigger1", reverse: false }) .setTween(row1) .addIndicators({ name: "Mobile: Row 1" }) .addTo(mainController); const scene2 = new ScrollMagic.Scene({ triggerElement: "#trigger2", reverse: false }) .setTween(row2) .addIndicators({ name: "Mobile: Row 2" }) .addTo(mainController); const scene3 = new ScrollMagic.Scene({ triggerElement: "#trigger3", reverse: false }) .setTween(row3) .addIndicators({ name: "Mobile: Row 3" }) .addTo(mainController); currentScenes.push(scene1, scene2, scene3); } } // Initialize scenes on page load initScrollMagicScenes(); // Handle window resize with debounce to avoid performance hits let resizeTimeout; window.addEventListener('resize', () => { clearTimeout(resizeTimeout); resizeTimeout = setTimeout(initScrollMagicScenes, 250); // Adjust debounce delay as needed });
Key Notes for Polish
- Breakpoint Adjustment: Change
768to match your project’s official desktop/mobile breakpoint (e.g., 992px for larger tablets/desktops). - Animation Reset: If elements get stuck in an animated state when switching viewports, add a reset step at the start of
initScrollMagicScenes:// Reset all animated elements to their initial state TweenMax.set(['.your-entire-element', '.row-1', '.row-2', '.row-3'], { opacity: 0, // Match your initial animation state y: 20 }); - Performance: The debounce function ensures we don’t reinitialize scenes every pixel during resizing, which keeps things smooth.
This setup will give you the responsive animation flow you’re aiming for—desktop gets the full batch animation, mobile gets per-row triggers, no duplicate animations.
内容的提问来源于stack exchange,提问作者Thomas

