fonveton Posted March 14, 2023 Share Posted March 14, 2023 gsap.utils.toArray(".text-hover-effect").forEach(element => { let text = element.textContent; element.innerHTML = '<span class="actual -translate-y-[50%] [&_.split-chars]:overflow-hidden absolute left-0 top-[50%] w-[100%]">' + text + '</span><span class="placeholder [&_.split-chars]:overflow-hidden">' + text + '</span>'; let placeholder = new SplitText(element.querySelector(".placeholder"), { type: "chars, words, lines", charsClass: 'split-chars', wordsClass: 'split-words', linesClass: 'split-lines' }); let actual = new SplitText(element.querySelector(".actual"), { type: "chars, words, lines", charsClass: 'split-chars', wordsClass: 'split-words', linesClass: 'split-lines' }); let textHoverTL = gsap.timeline({ paused: true }); gsap.set(actual.chars, { y: '50%', opacity: 0, }); textHoverTL.to(placeholder.chars, { duration: 0.25, y: '-50%', opacity: 0, stagger: 0.001 }) .to(actual.chars, { delay: 0.025, duration: 0.25, y: '0%', opacity: 1, stagger: 0.001 }, 0); element.addEventListener("mouseenter", () => { textHoverTL.play() }, false); element.addEventListener("mouseleave", () => { textHoverTL.reverse() }, false); }); I wrote a short code for text animation and I'm using this class on multiple object on page. The problem I'm having is if there are too many element it becomes a performance issue. I takes 1-2 seconds to load with over 50+ '.text-hover-effect' classes. I know the problem is I'm doing a lot of things before page load and that is what creates performance issues. What I don't know, how to solve this. I tried making all codes start working on hover but that way with multiple classes it's not working how it supposed to be and breaks you you move your cursor swiftly between objects. const textAnim = { in: { duration: 0.15, y: '-25%', opacity: 0, stagger: 0.001 }, out: { delay: 0.015, duration: 0.15, y: '0%', opacity: 1, stagger: 0.001 } }; gsap.utils.toArray(".fx-text-hover-with-child").forEach(el => { el.setAttribute('data-fx', el.querySelector(".fx-child").textContent); el.addEventListener("mouseenter", () => { let child = el.querySelector(".fx-child"); if (el.getAttribute('data-fx') != 'used') { let text = el.getAttribute('data-fx'); el.setAttribute('data-fx', 'used'); child.innerHTML = '<div class="actual -translate-x-[50%] -translate-y-[50%] absolute left-[50%] top-[50%] w-[100%]">' + text + '</div><div class="placeholder">' + text + '</div>'; new SplitText(el.querySelector(".placeholder"), { type: "chars, words, lines", charsClass: 'split-chars', wordsClass: 'split-words', linesClass: 'split-lines' }); new SplitText(el.querySelector(".actual"), { type: "chars, words, lines", charsClass: 'split-chars', wordsClass: 'split-words', linesClass: 'split-lines' }); } textTL.add(gsap.set(child.querySelectorAll('.actual .split-chars'), { y: '25%', opacity: 0, })); textTL.add(gsap.to(child.querySelectorAll('.placeholder .split-chars'), textAnim.in)) textTL.add(gsap.to(child.querySelectorAll('.actual .split-chars'), textAnim.out, 0)) textTL.play(); }, false); el.addEventListener("mouseleave", () => { textTL.reverse(); }, false); }); See the Pen xxaWYeG by manidar (@manidar) on CodePen Link to comment Share on other sites More sharing options...
GSAP Helper Posted March 14, 2023 Share Posted March 14, 2023 Hi there - would you be able to pop this in situ for us? Here's a starter CodePen that loads all the plugins. Just click "fork" at the bottom right and make your minimal demo: See the Pen aYYOdN by GreenSock (@GreenSock) on CodePen Link to comment Share on other sites More sharing options...
Cassie Posted March 14, 2023 Share Posted March 14, 2023 It's hard to advise as I can't see how this all fits together on a page and how much text is being split, but you could potentially use scrollTrigger to check if they're in view and split the text only for the ones in view? Link to comment Share on other sites More sharing options...
fonveton Posted March 14, 2023 Author Share Posted March 14, 2023 I didn't create a codepen because my issue is performance related using same effect multiple times. In my latest project I used this effect on 210 objects and even chrome lags a lot. It adds extra 2-3 seconds to website load time. I would like to know if there is a gsap approach to solve this issue. Link to comment Share on other sites More sharing options...
Cassie Posted March 14, 2023 Share Posted March 14, 2023 Sure thing - and we'd like to see what the effect is doing and what your markup and CSS looks like - meet us halfway! Thanks. Link to comment Share on other sites More sharing options...
fonveton Posted March 14, 2023 Author Share Posted March 14, 2023 added codepen to main topic: Link to comment Share on other sites More sharing options...
Cassie Posted March 14, 2023 Share Posted March 14, 2023 Ok, thanks! This doesn't really look representative of your actual project though. There's no styling. I'll just assume you don't have any filters or blurs that could affect things there. It seems pretty odd that it's adding 2-3 seconds load time. That's a lot. But yeah - I'll stick to what I said before - split the ones in view and then split the others as and when they come into the viewport. You could use batch for that - https://greensock.com/docs/v3/Plugins/ScrollTrigger/static.batch() Link to comment Share on other sites More sharing options...
Cassie Posted March 14, 2023 Share Posted March 14, 2023 Two more things that could help - adding the span in to the HTML up front instead of with JS, and only getting splitText to split into chars instead of chars, lines and words - you're not using them so they're unnecessary. Same with the class that's being added, this should be all you need. new SplitText(element.querySelector(".actual"), { type: "chars" }); 2 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now