vadbiz Posted January 31, 2021 Share Posted January 31, 2021 Good afternoon, colleagues! Please tell me, in the solution below, for some reason, sometimes there is a "twitching" of the line that moves. Moreover, in my project - it sometimes "jerks" (as if it starts anew every time, and does not continue) - uploaded to codepen.io - everything works stably, nothing jumps. With what it can be connected? How to make the RIGHT implementation? Sincerely. See the Pen XWNJaeK by alexverb_msk (@alexverb_msk) on CodePen Link to comment Share on other sites More sharing options...
GreenSock Posted February 1, 2021 Share Posted February 1, 2021 Are you saying that the CodePen works perfectly, but when you run the same code elsewhere it's glitchy? It's super difficult to troubleshoot when we can't see the issue If you've got it on a page where there are a lot of other things animating, perhaps the browser is having a hard time keeping up with the painting (graphics rendering). That's unrelated to GSAP. It's always best to keep the number of pixels that change on the screen to a minimum. When I look at your codepen, the "Development" line seems fine, but the "Design" line below it is sorta popping into existence and repeating. Is that intentional? Link to comment Share on other sites More sharing options...
vadbiz Posted February 1, 2021 Author Share Posted February 1, 2021 1 hour ago, GreenSock said: Are you saying that the CodePen works perfectly, but when you run the same code elsewhere it's glitchy? It's super difficult to troubleshoot when we can't see the issue If you've got it on a page where there are a lot of other things animating, perhaps the browser is having a hard time keeping up with the painting (graphics rendering). That's unrelated to GSAP. It's always best to keep the number of pixels that change on the screen to a minimum. When I look at your codepen, the "Development" line seems fine, but the "Design" line below it is sorta popping into existence and repeating. Is that intentional? Please tell me a similar implementation with functions: 1) it is obligatory to repeat the same word. 2) to be able to change the speed from the data tag. 3) to be able to change direction. 4) so that the line also moves "continuously". Perhaps by changing the code and solution - everything will work fine. All other animation except the creeping line - everything works well on the page. Perhaps the syntax is deprecated? Link to comment Share on other sites More sharing options...
vadbiz Posted February 1, 2021 Author Share Posted February 1, 2021 This is what happens to me: Link to comment Share on other sites More sharing options...
mikel Posted February 1, 2021 Share Posted February 1, 2021 Hey @vadbiz, Does this example help? See the Pen abmPjxz?editors=1010 by mikeK (@mikeK) on CodePen Happy tweening ... Mikel 1 Link to comment Share on other sites More sharing options...
ZachSaucier Posted February 1, 2021 Share Posted February 1, 2021 The issue is logical: You're appending words to the element in both cases but when it's going to the right you're not shifting the start position to the left to compensate. You should do that. Additionally we highly recommend upgrading to GSAP 3 syntax. Upgrading is easy! 1 Link to comment Share on other sites More sharing options...
Solution GreenSock Posted February 2, 2021 Solution Share Posted February 2, 2021 On 2/1/2021 at 12:16 AM, vadbiz said: Please tell me a similar implementation with functions: 1) it is obligatory to repeat the same word. 2) to be able to change the speed from the data tag. 3) to be able to change direction. 4) so that the line also moves "continuously". Perhaps by changing the code and solution - everything will work fine. We've had several people ask about this type of effect, so I just built a GSAP effect that makes this a lot simpler for you (or anyone). Here's a fork of your original CodePen with it in place: See the Pen oNYXzYB?editors=0010 by GreenSock (@GreenSock) on CodePen So you can just paste that gsap.registerEffect(...) code into your project, and then it's super simple to make anything have that effect: gsap.effects.ticker(".hero__ticker-init"); That's it! You can control the speed and direction with attributes like: <div data-speed="8" data-direction="right"></div> I noticed a problem with your original implementation - if the screen was resized, it didn't adjust, so there could be gaps that showed up. The effect here automatically listens for "resize" events on the window, and dynamically adjusts. Seems to work relatively well. I haven't done tons of testing on this, but hopefully it's at least a good starting point for you. Here's the raw effect (you don't really have to understand it all to use it): gsap.registerEffect({ name: "ticker", effect(targets, config) { buildTickers({ targets: targets, clone: config.clone || (el => { let clone = el.children[0].cloneNode(true); el.insertBefore(clone, el.children[0]); return clone; }) }); function buildTickers(config, originals) { let tickers; if (originals && originals.clones) { // on window resizes, we should delete the old clones and reset the widths originals.clones.forEach(el => el && el.parentNode && el.parentNode.removeChild(el)); originals.forEach((el, i) => originals.inlineWidths[i] ? (el.style.width = originals.inlineWidths[i]) : el.style.removeProperty("width")); tickers = originals; } else { tickers = config.targets; } const clones = tickers.clones = [], inlineWidths = tickers.inlineWidths = []; tickers.forEach((el, index) => { inlineWidths[index] = el.style.width; el.style.width = "10000px"; // to let the children grow as much as necessary (otherwise it'll often be cropped to the viewport width) el.children[0].style.display = "inline-block"; let width = el.children[0].offsetWidth, cloneCount = Math.ceil(window.innerWidth / width), right = el.dataset.direction === "right", i; el.style.width = width * (cloneCount + 1) + "px"; for (i = 0; i < cloneCount; i++) { clones.push(config.clone(el)); } gsap.fromTo(el, { x: right ? -width : 0 }, { x: right ? 0 : -width, duration: width / 100 / parseFloat(el.dataset.speed || 1), repeat: -1, overwrite: "auto", ease: "none" }); }); // rerun on window resizes, otherwise there could be gaps if the user makes the window bigger. originals || window.addEventListener("resize", () => buildTickers(config, tickers)); } } }); Hopefully that gives you something that you can work with, or at least analyze some of the logic. Enjoy! 4 Link to comment Share on other sites More sharing options...
vadbiz Posted February 7, 2021 Author Share Posted February 7, 2021 On 2/2/2021 at 10:42 AM, GreenSock said: We've had several people ask about this type of effect, so I just built a GSAP effect that makes this a lot simpler for you (or anyone). Here's a fork of your original CodePen with it in place: So you can just paste that gsap.registerEffect(...) code into your project, and then it's super simple to make anything have that effect: gsap.effects.ticker(".hero__ticker-init"); That's it! You can control the speed and direction with attributes like: <div data-speed="8" data-direction="right"></div> I noticed a problem with your original implementation - if the screen was resized, it didn't adjust, so there could be gaps that showed up. The effect here automatically listens for "resize" events on the window, and dynamically adjusts. Seems to work relatively well. I haven't done tons of testing on this, but hopefully it's at least a good starting point for you. Here's the raw effect (you don't really have to understand it all to use it): gsap.registerEffect({ name: "ticker", effect(targets, config) { buildTickers({ targets: targets, clone: config.clone || (el => { let clone = el.children[0].cloneNode(true); el.insertBefore(clone, el.children[0]); return clone; }) }); function buildTickers(config, originals) { let tickers; if (originals && originals.clones) { // on window resizes, we should delete the old clones and reset the widths originals.clones.forEach(el => el && el.parentNode && el.parentNode.removeChild(el)); originals.forEach((el, i) => originals.inlineWidths[i] ? (el.style.width = originals.inlineWidths[i]) : el.style.removeProperty("width")); tickers = originals; } else { tickers = config.targets; } const clones = tickers.clones = [], inlineWidths = tickers.inlineWidths = []; tickers.forEach((el, index) => { inlineWidths[index] = el.style.width; el.style.width = "10000px"; // to let the children grow as much as necessary (otherwise it'll often be cropped to the viewport width) el.children[0].style.display = "inline-block"; let width = el.children[0].offsetWidth, cloneCount = Math.ceil(window.innerWidth / width), right = el.dataset.direction === "right", i; el.style.width = width * (cloneCount + 1) + "px"; for (i = 0; i < cloneCount; i++) { clones.push(config.clone(el)); } gsap.fromTo(el, { x: right ? -width : 0 }, { x: right ? 0 : -width, duration: width / 100 / parseFloat(el.dataset.speed || 1), repeat: -1, overwrite: "auto", ease: "none" }); }); // rerun on window resizes, otherwise there could be gaps if the user makes the window bigger. originals || window.addEventListener("resize", () => buildTickers(config, tickers)); } } }); Hopefully that gives you something that you can work with, or at least analyze some of the logic. Enjoy! Thank you! 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