GSAP滑块文本进出动画实现求助(附完整代码)
实现GSAP滑块文本的退出与进入动画
你需要在幻灯片切换时为文本添加独立的动画效果,以下是修改后的代码及关键说明:
核心修改点
- 初始化文本入场动画:在
init函数中为第一张幻灯片的文本添加初始入场动画,提升内容层次感。 - 切换时的文本动画:在
slideAnimation函数中同步处理当前幻灯片文本的退出动画与新幻灯片文本的进入动画,和幻灯片位移动画配合执行。 - 状态重置:每次切换前重置所有文本元素的动画属性,避免属性累积导致异常。
修改后的完整代码
JavaScript部分
console.clear(); // Just for codepen clear the console between refreshes // gsap.registerPlugin(SplitText, Draggable); document.querySelectorAll(".slider").forEach((container) => { // Setup variables const items = container.querySelectorAll(".slider__wrraper"), itemsMax = items.length - 1; const next = container.querySelector(".next"), prev = container.querySelector(".prev"), dots = container.querySelector(".slider_dots"); let index = 0; const move = 100; const timer = 5000; const duration = 0.5; // let autoplay; //--------------------------------// // 💾 Inital setup //--------------------------------// function init() { // Create 🟣 Dots items.forEach((item, index) => { const dot = document.createElement("li"); if (index === 0) dot.classList.add("active"); // Set the first dot to active // Allow clicking the dots dot.addEventListener("click", () => { slideLogic(false, index); }); if (dots) dots.appendChild(dot); }); // Animate the first element in gsap.set(items, { autoAlpha: 0 }); gsap.set([".slider", items[index]], { autoAlpha: 1 }); // 为第一张幻灯片的文本添加入场动画 gsap.from([items[index], items[index].querySelector('.slider__context')], { autoAlpha: 0, x: move, y: 30, stagger: 0.1, duration: duration }); // autoplay = window.setTimeout(slideLogic, timer); } // Run inital setup init(); // END 💾 Inital setup --------------// //--------------------------------// // ☝️ Touch //--------------------------------// if (window.Draggable) { Draggable.create(items, { type: "x", // Drag only on the X axis zIndexBoost: false, onDragStart: function () { // window.clearTimeout(autoplay); // disable autoplay slideLogic(this.getDirection() === "right" ? true : false); } }); } // END ☝️ Touch --------------// //--------------------------------// // Set active 🟣 dot //--------------------------------// function dotActive(index) { const dotsAll = dots.querySelectorAll("li"); dotsAll.forEach((dot) => { dot.classList.remove("active"); }); dotsAll[index].classList.add("active"); } // END Set active 🟣 dot --------------// //--------------------------------// // 🖼️ Slide animation //--------------------------------// function slideAnimation(index, moveIn, outIn) { // Reset the properties you are animating below // Otherwise they animate from that position (probably not visible) gsap.set(items, { xPercent: 0, scale: 1 }); gsap.set(items[moveIn], { autoAlpha: 1 }); // 重置所有文本元素的状态 gsap.set([...items.map(item => item.querySelector('.slider__context'))], { y: 0, autoAlpha: 1 }); // 获取当前和新幻灯片的文本元素 const currentText = items[index].querySelector('.slider__context'); const newText = items[moveIn].querySelector('.slider__context'); // The animation const tl = gsap.timeline({ defaults: { duration: duration }, onStart: animationStart, onComplete: animationDone, }); // 当前幻灯片退出:文本先淡出上移,同步幻灯片位移 tl.to([items[index], currentText], { xPercent: outIn[0], y: -30, autoAlpha: 0, stagger: 0.1 }); // 新幻灯片进入:幻灯片位移同步文本淡入下移 tl.from([items[moveIn], newText], { xPercent: outIn[1], y: 30, autoAlpha: 0, stagger: 0.1 }, "<"); // Hide moved out slide tl.set(items[index], { autoAlpha: 0, y: 0 }); } function animationStart() { container.classList.add("running"); } function animationDone() { toggleButtons(); // autoplay = window.setTimeout(slideLogic, timer); container.classList.remove("running"); gsap.set(items, { x: 0 }); } // END 🖼️ Slide animation --------------// //--------------------------------// // Slider 🎛️ logic //--------------------------------// function slideLogic(prev, customMoveIn) { toggleButtons(); // Disable buttons // window.clearTimeout(autoplay); // disable autoplay let outIn = [-move, move]; if (prev) outIn.reverse(); let moveIn; // Check if moveIn is passed with the function if (typeof customMoveIn === "undefined") { if (prev) { moveIn = index === 0 ? itemsMax : index - 1; } else { moveIn = index === itemsMax ? 0 : index + 1; } } else { moveIn = customMoveIn; } if (dots) dotActive(moveIn); // Set active dot slideAnimation(index, moveIn, outIn); // Animation function // Changing the next index if (typeof customMoveIn === "undefined") { if (prev) { index === 0 ? (index = itemsMax) : index--; } else { index === itemsMax ? (index = 0) : index++; } } else { index === itemsMax ? (index = 0) : (index = customMoveIn); } } // END Slider 🎛️ logic --------------// //--------------------------------// // Button 🎛️ control //--------------------------------// function toggleButtons() { if (next) next.disabled = !next.disabled; if (prev) prev.disabled = !prev.disabled; } if (next) next.addEventListener("click", () => slideLogic()); if (prev) prev.addEventListener("click", () => slideLogic(true)); // END Button 🎛️ control --------------// });
CSS和HTML部分保持不变
动画说明
- 退出动画:当前幻灯片文本伴随幻灯片位移,同时向上移动30px并淡出,形成连贯退场效果。
- 进入动画:新幻灯片文本伴随幻灯片位移,同时从下方30px位置淡入,增强内容层次感。
- Stagger效果:使用
stagger: 0.1让幻灯片与文本动画产生0.1秒延迟,使动画更自然流畅。
你可根据需求调整动画参数(如y轴偏移量、stagger延迟时间、动画时长等),匹配自身设计风格。
内容的提问来源于stack exchange,提问作者Adesh
相关产品推荐
相关产品推荐

