// Content-Type: application/javascript // 定义 isTouchDevice 函数 window.isTouchDevice = function() { return 'ontouchstart' in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0; }; // 定义 dg 构造函数 function dg() { if (!window.isTouchDevice()) { this.run(document); } } dg.prototype.run = function(e) { var self = this; var elements = e.querySelectorAll("[data-hover-animation]"); elements.forEach(function(element) { var target = element.querySelector("[data-hover-animation-target]"); if (target) { self.setupAnimation(target, element); } }); }; dg.prototype.setupAnimation = function(target, element) { var self = this; gsap.set(target, { display: "inline-flex", position: "relative", overflow: "hidden", lineHeight: 1.3 }); if (!element.getAttribute("aria-label")) { element.setAttribute("aria-label", target.textContent); } var content = target.innerHTML; target.innerHTML = ""; var firstSpan = this.createSpan(content, "data-hover-animation-first-el"); var secondSpan = this.createSpan(content, "data-hover-animation-second-el"); target.appendChild(firstSpan); target.appendChild(secondSpan); var transformValue = element.getAttribute("data-move-horizontal") ? "translateX(-150%)" : "translateY(150%)"; gsap.set(secondSpan, { position: "absolute", top: 0, left: 0, transform: transformValue }); element.addEventListener("mouseenter", function() { self.hover_animation(element); }); element.addEventListener("touchstart", function() { self.hover_animation(element); }); }; dg.prototype.createSpan = function(content, attribute) { var span = document.createElement("span"); span.setAttribute(attribute, ""); span.setAttribute("aria-hidden", "true"); span.innerHTML = content; return span; }; dg.prototype.hover_animation = function(element) { var firstElements = element.querySelectorAll("[data-hover-animation-first-el]"); var secondElements = element.querySelectorAll("[data-hover-animation-second-el]"); var isHorizontal = element.getAttribute("data-move-horizontal"); var animationProps = isHorizontal ? { x: "0%", opacity: 1 } : { y: "0%", opacity: 1 }; var animationToProps = isHorizontal ? { x: "-105%", opacity: 0 } : { y: "-105%", opacity: 0 }; var secondAnimationProps = isHorizontal ? { x: "105%" } : { y: "105%" }; var secondAnimationToProps = isHorizontal ? { x: "0%" } : { y: "0%" }; gsap.fromTo(firstElements, animationProps, Object.assign({}, animationToProps, { duration: 0.4, ease: "expo.inout" })); gsap.fromTo(secondElements, secondAnimationProps, Object.assign({}, secondAnimationToProps, { duration: 0.4, ease: "linkhover" })); }; // 实例化 dg 类 document.addEventListener("DOMContentLoaded", () => { new dg(); }); /* *************** * 检查元素是否存在 * @param selector : 选择器 * 如果有则返回 true *************** */ $.exists = function(selector) { return $(selector).length > 0; } /* Text Effect Animation */ function initTextEffectAnimation() { const animatedElements = document.querySelectorAll(".text-anime"); animatedElements.forEach(element => { const staggerAmount = element.getAttribute("data-stagger") || 0.05; const translateXValue = element.getAttribute("data-translateX") || 20; const translateYValue = element.getAttribute("data-translateY") || false; const onScrollValue = element.getAttribute("data-on-scroll") || 1; const delayValue = element.getAttribute("data-delay") || 0.5; const easeType = element.getAttribute("data-ease") || "power2.out"; const splitText = new SplitType(element, { type: "chars, words" }); const animationProps = { duration: 1, delay: delayValue, autoAlpha: 0, stagger: staggerAmount, ease: easeType }; if (onScrollValue == 1) { animationProps.scrollTrigger = { trigger: element, start: "top 85%" }; } if (translateXValue && !translateYValue) { animationProps.x = translateXValue; } else if (translateYValue && !translateXValue) { animationProps.y = translateYValue; } else if (translateXValue && translateYValue) { animationProps.x = translateXValue; animationProps.y = translateYValue; animationProps.duration = 3; } else { animationProps.x = 50; } gsap.from(splitText.chars, animationProps); }); } if ($('.text-anime').length) { initTextEffectAnimation(); } if ($('[text-split]').length && typeof ScrollTrigger !== 'undefined') { gsap.registerPlugin(ScrollTrigger); window.addEventListener("DOMContentLoaded", (event) => { // Split text into spans let typeSplit = new SplitType("[text-split]", { types: "words, chars", tagName: "span" }); // Link timelines to scroll position function createScrollTrigger(triggerElement, timeline) { // Reset tl when scroll out of view past bottom of screen ScrollTrigger.create({ trigger: triggerElement, start: "top bottom", onLeaveBack: () => { timeline.progress(0); timeline.pause(); } }); // Play tl when scrolled into view (60% from top of screen) ScrollTrigger.create({ trigger: triggerElement, start: "top 60%", onEnter: () => timeline.play() }); } $("[words-slide-up]").each(function (index) { let tl = gsap.timeline({ paused: true }); tl.from($(this).find(".word"), { opacity: 0, yPercent: 100, duration: 0.6, ease: "back.out(2)", stagger: { amount: 0.5 } }); createScrollTrigger($(this), tl); }); $("[letters-fade-in]").each(function (index) { let tl = gsap.timeline({ paused: true }); tl.from($(this).find(".char"), { opacity: 0, duration: 0.5, ease: "power1.out", stagger: { amount: 0.8 } }); createScrollTrigger($(this), tl); }); $("[words-slide-from-right]").each(function (index) { let tl = gsap.timeline({ paused: true }); tl.from($(this).find(".word"), { opacity: 0, x: "1em", duration: 0.8, ease: "power2.out", stagger: { amount: 0.2 } }); createScrollTrigger($(this), tl); }); $("[letters-slide-up]").each(function (index) { let tl = gsap.timeline({ paused: true }); tl.from($(this).find(".char"), { opacity: 0, yPercent: 100, duration: 0.2, ease: "power1.out", stagger: { amount: 0.6 } }); createScrollTrigger($(this), tl); }); $("[letters-fade-in-random]").each(function (index) { let tl = gsap.timeline({ paused: true }); tl.from($(this).find(".char"), { opacity: 0, duration: 0.05, ease: "power1.out", stagger: { amount: 0.4, from: "random" } }); createScrollTrigger($(this), tl); }); $("[scrub-each-word]").each(function (index) { let tl = gsap.timeline({ scrollTrigger: { trigger: $(this), start: "top 90%", end: "top center", scrub: true } }); tl.from($(this).find(".char"), { opacity: "0.1", duration: 0.2, ease: "power1.out", stagger: { each: 0.4 } }); }); // Avoid flash of unstyled content gsap.set("[text-split]", { opacity: 1 }); }); } function TextWave() { this.texts = document.querySelectorAll( "[animation-wave], [animation-wave-child]" ); if (this.texts === null || this.texts === undefined) return; gsap.registerPlugin(SplitText); this.splittedTexts = []; this.setup(); this.bind(); } TextWave.prototype.setup = function() { var _this = this; this.texts.forEach(function(el) { var text = { split: new SplitText(el, { type: "chars,words,lines" }), progress: false }; text.tl = gsap.timeline({ paused: true, yoyo: true, onComplete: function() { text.progress = false; } }); text.tl .addLabel("start") .to( text.split.chars, { yPercent: -30, duration: 0.3, stagger: 0.1, ease: "power1.inOut" }, "start" ) .to( text.split.chars, { yPercent: 0, duration: 0.3, stagger: 0.1, ease: "power1.inOut" }, "start+=0.3" ); text.tl.timeScale(1.2); _this.splittedTexts.push(text); }); }; TextWave.prototype.bind = function() { var _this = this; this.texts.forEach(function(el, i) { var trigger = el; if (el.hasAttribute("animation-wave-child")) { trigger = el.closest("[animation-wave-trigger]"); } trigger.addEventListener("mouseenter", function() { if (_this.splittedTexts[i].progress) return; _this.splittedTexts[i].progress = true; _this.splittedTexts[i].tl.play(0); }); trigger.addEventListener("mouseleave", function() { if (!_this.splittedTexts[i].progress) return; _this.splittedTexts[i].progress = false; _this.splittedTexts[i].tl.progress(0); _this.splittedTexts[i].tl.pause(); }); }); }; $(document).ready(function () { // 确保DOM加载完成后实例化 new TextWave(); }); if ($('.text_effect').length) { $(".text_effect").each(function (index, ele) { var ly = $(ele).data("delay"); if (ly === undefined) { ly = 20; } var text = $(ele).find(".appoint").text(); var html = ""; for (var i = 0; i < text.length; i++) { html += '