2024-12-04
前端开发
00

目录

规则
代码

💡实现

GSAP动画的封装,实现页面元素自动瀑布流切入切出且可以自定义切入切出方向及动画时间延时

规则

  • paused 时间线开始不自动执行
  • ease 动画规则 "power4.in", // 先慢后快 "power2.inOut", // 先快后慢
  • opacity 不透明度
  • duration 所需时间
  • , "<0.5" 后缀添加意义为上一动画后0.5秒运行
  • , "<" 后缀添加意义为与上一动画同时运行

代码

//面板动画 - 切出 gsap.registerEffect({ name: "panelEffectOut", effect: (targets, config) => { // 定义一个时间线来串联两个动画 let tl = gsap.timeline(); if (config.mode == "in") { if (config.direction == "left" || config.direction == "right") { //默认左方向 let x1 = 100; let x2 = 0 if (config.direction == "right") { //右方向 x1 = -100; x2 = 0 } // 第一步动画 tl.to(targets, { x: x1, opacity: 0.5, duration: 0.8 }); // 第二步动画 tl.to(targets, { x: x2, opacity: 1, duration: 1 }); } else { //默认上方向 let y1 = 100; let y2 = 0 if (config.direction == "bottom") { //右方向 y1 = -100; y2 = 0 } // // 第一步动画 // tl.to(targets, { // y: y1, // opacity: 0.5, // duration: 0.5 // }); // 第二步动画 tl.to(targets, { y: y2, opacity: 1, duration: 0.8 }); } } else { if (config.direction == "left" || config.direction == "right") { //默认左方向 let x1 = 100; let x2 = -700 if (config.direction == "right") { //右方向 x1 = -100; x2 = 700 } // 第一步动画 tl.to(targets, { x: x1, opacity: 0.5, duration: 0.4 }); // 第二步动画 tl.to(targets, { x: x2, opacity: 0, duration: 1 }); } else { //默认上方向 let y1 = 100; let y2 = -700 if (config.direction == "bottom") { //右方向 y1 = -100; y2 = 700 } // 第一步动画 tl.to(targets, { y: y1, opacity: 0.5, duration: 0.4 }); // 第二步动画 tl.to(targets, { y: y2, opacity: 0, duration: 1 }); } } return tl; }, extendTimeline: true // 允许在 GSAP 时间线上直接调用这个效果 }); //元素动画 -元素切入 gsap.registerEffect({ name: "elementsEffect", effect: (targets, config) => { // console.log("🚀元素切入 ~ targets, config:", targets, config) // 创建时间线以添加延迟 let tl = gsap.timeline(); // 使用 .forEach 遍历每个目标元素 targets.forEach(target => { let delay = 0; let direction = ""; // 从类名中提取延迟时间 const classList = target.classList; classList.forEach(className => { const match = className.match(/hl-effect-(left|right|top|bottom)-(\d+)/); if (match != null) { direction = match[1] delay = parseInt(match[2], 10) / 1000; // 将毫秒转换为秒 } }); // 根据方向设置初始位置 if (direction === "left") { gsap.set(target, { x: -300, opacity: 0 }); } else if (direction === "right") { gsap.set(target, { x: 300, opacity: 0 }); } else if (direction === "bottom") { gsap.set(target, { y: 300, opacity: 0 }); } else if (direction === "top") { gsap.set(target, { y: -300, opacity: 0 }); } // 添加动画到时间线 if (direction === "left" || direction === "right") { tl.to(target, { x: 0, opacity: 1, duration: 0.6, }, "<" + delay) } else if (direction === "top" || direction === "bottom") { tl.to(target, { y: 0, opacity: 1, duration: 0.6, }, "<" + delay); } }); return tl; }, extendTimeline: true // 允许在 GSAP 时间线上直接调用这个效果 }); //隐藏传入元素 const hiddenelement = (element, direction = "x", px = 300) => { if (direction == "x") { gsap.set(element, { x: px, opacity: 0, }); } if (direction == "y") { gsap.set(element, { y: px, opacity: 0, }); } } //切出动画 export const cutOut = () => { // 创建一个时间线 const tl1 = gsap.timeline({ paused: true, ease: "power4.in", // 先慢后快 }); // 创建一个时间线 const tl2 = gsap.timeline({ paused: true, ease: "power4.in", // 先慢后快 }); // 创建一个时间线 面板3 const tl3 = gsap.timeline({ paused: true, ease: "power2.inOut", // 先快后慢 }); // 创建一个时间线 面板4 const tl4 = gsap.timeline({ paused: true, ease: "power2.inOut", // 先快后慢 }); // 创建一个时间线 图例 const tl5 = gsap.timeline({ paused: true, ease: "power2.inOut", // 先快后慢 }); // 创建一个时间线 顶部 const tl6 = gsap.timeline({ paused: true, ease: "power2.inOut", // 先快后慢 }); tl1.panelEffectOut("#main-box1", { direction: "left", mode: "out" }) tl2.panelEffectOut("#main-box2", { direction: "right", mode: "out" }) // var el1 = '.header-left'; // var el2 = '.header-right'; // var el3 = '.header-box'; // var el4 = '.masklayer-main'; // tl6.to(el4, { // x: 0, // opacity: 0, // duration: 0.4 // }).to(el1, { // x: 100, // opacity: 0.5, // duration: 0.4 // }, "<").to(el2, { // x: -100, // opacity: 0.5, // duration: 0.4 // }, "<").to(el1, { // x: -300, // opacity: 0, // duration: 0.4 // }, "<0.4").to(el2, { // x: 300, // opacity: 0, // duration: 0.4 // }, "<").to(el3, { // y: -300, // opacity: 0, // duration: 0.6 // }, "<0.4"); tl1.play(); tl2.play(); // tl4.play(); // tl6.play(); // gsap.delayedCall(0.4, () => { // tl2.play() // tl3.play() // } // ); // gsap.delayedCall(0.8, () => { // tl5.play() // } // ); } //切入动画 export const cutIn = (e) => { // 创建一个时间线 面板1 const tl1 = gsap.timeline({ paused: true, ease: "power2.inOut", // 先快后慢 }); // 创建一个时间线 面板3 const tl3 = gsap.timeline({ paused: true, ease: "power2.inOut", // 先快后慢 }); // 创建一个时间线 面板4 const tl4 = gsap.timeline({ paused: true, ease: "power2.inOut", // 先快后慢 }); // 创建一个时间线 面板4 const tl5 = gsap.timeline({ paused: true, ease: "power2.inOut", // 先快后慢 }); // 创建一个时间线 顶部 const tl6 = gsap.timeline({ paused: true, ease: "power2.inOut", // 先快后慢 }); tl1.panelEffectOut("#main-box1", { direction: "left", mode: "in" }) const elemetlist1 = document.getElementById('main-box1').querySelectorAll('[class*="hl-effect-"]'); tl1.elementsEffect(elemetlist1, {}, "<0.2") tl4.panelEffectOut("#main-box2", { direction: "right", mode: "in" }) const elemetlist4 = document.getElementById('main-box2').querySelectorAll('[class*="hl-effect-"]'); tl4.elementsEffect(elemetlist4, {}, "<0.2") if(e==0){ tl3.panelEffectOut("#main-box4", { direction: "right", mode: "in" }) tl5.panelEffectOut("#main-box5", { direction: "bottom", mode: "in" }) } // var el1 = '.header-left'; // var el2 = '.header-right'; // var el3 = '.header-box'; // var el4 = '.masklayer-main'; // tl6.to(el4, { // x: 0, // opacity: 1, // duration: 0.4 // }).to(el3, { // y: -300, // opacity: 0, // duration: 0.2 // }, "<").to(el3, { // y: 0, // opacity: 1, // duration: 0.6 // }, "<0.2").to(el1, { // x: 100, // opacity: 0.5, // duration: 0.6 // }, "<0.6").to(el2, { // x: -100, // opacity: 0.5, // duration: 0.6 // }, "<").to(el1, { // x: 0, // opacity: 1, // duration: 0.6 // }, "<0.6").to(el2, { // x: 0, // opacity: 1, // duration: 0.6 // }, "<") tl1.play(); tl4.play(); tl6.play(); if(e==0){ gsap.delayedCall(1.5, () => { tl5.play(); tl3.play(); }) } } export const hideBox = () => { hiddenelement("#main-box1", 'x', -300) hiddenelement("#main-box2", 'x', -300) hiddenelement("#main-box4", 'x', -300) hiddenelement("#main-box5", 'y', 100) } export const hideBox1 = () => { hiddenelement("#main-box1", 'x', -300) hiddenelement("#main-box2", 'x', -300) }
如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:烈焰大火龙

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 © 烈焰大火龙 许可协议。转载请注明出处!