Jump to content
Search Community

stefanobartoletti

Members
  • Posts

    19
  • Joined

  • Last visited

Profile Information

  • Location
    Italy

Recent Profile Visitors

314 profile views

stefanobartoletti's Achievements

  1. Thanks. I will check these functions, probably matchMedia is what I need. A possible alternative (specific to Vue) that I'm also considering is useBreakpoints from the VueUse package (I'm reporting this here as a possible reference for other people too), but probably the two options that you gave me are covering my need. Thanks for your reply!
  2. I've tried to read the Draggable docs, but I haven't found an explicit reference to this. I've integrated a Draggable instance in one of my projects (It is based on Nuxt, but this does not seem to be relevant here), and the specific implementation should have the affected elements be draggable only on desktop viewports. Is it possible to natively enable Draggable only on certain breakpoints, or should I use a custom function before firing Draggable itself? Thanks
  3. This is not strictly a help request (my integration is working correctly), but more like a desire to understand how things work. And, it is probably also more generic and not related only to Draggable, but more generally even to other GSAP plugins. I've integrated Draggable into one Vue component, this is a schematic overview of my implementation: <template> <section> <!-- my component template --> </section> </template> <script setup> const items = ref([]) // Target items, full code omitted for brevity const { Draggable } = useGsap() // Import gsap from a dedicated composable onMounted(() => { Draggable.create(items.value, { // Draggable options }) }) onUnmounted(() => { Draggable.kill() }) </script> Everything is working correctly on the front-end, and also Draggable.kill() should be hooked correctly on the component lifecycle. I've also tried another implementation, similar to the one often suggested when using gsap.context, just like this: <script setup> const ctx = ref() const items = ref([]) // Target items, full code omitted for brevity const { Draggable } = useGsap() // Import gsap from a dedicated composable onMounted(() => { ctx.value = Draggable.create(items.value, { // Draggable options }) }) onUnmounted(() => { ctx.value.revert() }) </script> And it seems to work correctly, just like in the previous example. Since these two solutions are effectively working in the same way on the frontend, are there some reasons to prefer one over another? Under the hood, what are the differences between them? Thanks :-)
  4. Thanks for your reply! I really overlooked that part in the ScrollTrigger docs, I will check it. For ScrollSmoother I will try to see if I can find another way to implement a similar solution, but my priority was ScrollTrigger. Thanks again!
  5. I have a rather unusual layout, where the main content of the page is inside a "frame" that is exactly the size of the viewport. The body of the page itself basically never scrolls (it never gets higher than 100vh), and the scroll only happens inside .frame-content element (the blue-bordered one), that contains the main content of the page (as you can see, it contains many sections). I wish to integrate both ScrollTrigger and ScrollSmoother into this layout, by having them take effect (and do their calculations) only into the .frame-content element. But some intial trial-and-error (mostly error I would say, eheh) has given me: - ScrollTrigger does not work at all: I wish to animate elements inside the various sections when they appear on screen, but it looks like it listens to the scroll of the body, which never scrolls. So these elements do not animate at all. - ScrollSmoother, if set like this ScrollSmoother.create({ content: '.smooth-content' }), always break my layout and places this element out of the "frame" (I have not included both of them in the codepen, because I wanted to show the clean look of the original layout before applying anything to it). Is it possible to do these things, or am I only trying to force these tools to do something that they are not supposed to do? Thanks for any answer or insight about this!
  6. Thanks for your replies. From what I get, it should be called only once before all ScrollTriggers are set, am I wrong? And once set, all my subsequent scrolltriggers will automatically use it?
  7. Given my following animation import { gsap } from 'gsap'; import { ScrollTrigger } from 'gsap/ScrollTrigger'; gsap.registerPlugin(ScrollTrigger); const icons = document.querySelectorAll('.icon'); icons.forEach(icon => { gsap.to(icon, { rotate: 180, ease: 'linear', duration: 10, scrollTrigger: { trigger: icon.parentNode, start: 'top 100%', end: 'bottom 0%', scrub: 5, } }); }); I need to implement the normalizeScroll function on ScrollTrigger, but it is not very clear to me how to do it when using Scrolltrigger inside Gsap like in my example. Can somebody help me?
  8. Does it matter for Gsap where my ref="main" is located on the template?
  9. No, I don't have any image, I'm animating a plain text, and it doesn't have any particular css that could prevent its size being correctly displayed. It does not work even without applying any style at all.
  10. Thanks for the suggestion, I managed to get an inspiration by your solution by using the xPercent property instead of trying to access the element width directly. Now this code works: onMounted(() => { ctx.value = gsap.context((self) => { const scrollingText = self.selector('[gsap="scrolling-text"]') tl.value = gsap .timeline({ repeat: -1 }) .to(scrollingText, { xPercent: -100, duration: 20 * ((1 / 1920) * window.innerWidth), // Need to better define duration/speed ease: 'none', }) }, main.value) // <- Scope! }) I still need to tweak the duration to provide a consistent experience between various screensizes, but this is another matter. And of course I have not solved the main problem itself, directly accessing needed properties, but at least I have fixed this animation. Thanks for your help.
  11. Thanks for the insights. I do not really need or want to use a timeout, it is not a clean solution, I just tried to use it to better understand what was going on. Anyway, I tried putting console.logs along all the lifecycle of the component, and all of them fire in the expected order. I also tried assigning some extra properties (color and background color) from gsap, something like this: tl.value = gsap .timeline({ repeat: -1 }) .to(scrollingText, { x: -textWidth, duration: 20 * (textWidth / windowWidth), ease: 'none', color: '#976239', backgroundColor: '#456234', }) And they are applied also in changing routes, so I can also exclude gsap not correctly targeting the given element. The real problem lies in reading some of the targeted element properties, specifically the dimensions, since apparently some others are read without any issue (like innerHTML) I'd like to provide another minimal demo, but it seems that there is something going on related to the full configuration of my project (the same specific gsap instance is applied to the stackblitz that I provided and it works there). Are there some other information that I can gather to tr to get a better picture if this issue?
  12. Thanks for your answer, it is really appreciated Unfortunately nextTick isn't working either ? I don't exactly know what is causing the difference between my real project and the demo example on stackblitz. In my real project I have dynamic routes and data received from a CMS API, but this seems to be unrelated. Even by putting in fake static data (i.e. like I did on the example), the problem is still there, so I think that is is not caused by a micro delay in waiting the API (it wuld break the animation even on the first load I think). The only difference is the dynamic route, but even here, it does not really seem so related. At the moment, my only clue is that with the timeout set at a high value (1000ms) it works, if I lower it it stops working. So there should be some kind of issue o the lifecycle of the component. Do you think that in my code, the context is correctly destroyed at onUnmounted? could the problem be related to a previous instance of the animation not completely unloaded and causing problems with the new one?
  13. Also, I've tried to use a timeout, something like this onMounted(() => { ctx.value = gsap.context((self) => { const scrollingText = self.selector('[gsap="scrolling-text"]') setTimeout(() => { const textWidth = scrollingText[0].offsetWidth const textHTML = scrollingText[0].innerHTML const windowWidth = window.innerWidth console.log(scrollingText[0]) console.log(textWidth, textHTML) tl.value = gsap .timeline({ repeat: -1 }) .to(scrollingText, { x: -textWidth, duration: 20 * (textWidth / windowWidth), ease: 'none', }) }, '1000') }, main.value) // <- Scope! }) onUnmounted(() => { ctx.value.revert() // <- Easy Cleanup! }) And now it seems to work, but of course it is not a proper solution, the animation should not be delayed that much
  14. This is a basic fork of StackBlitz, to show what I'm trying to achieve. https://stackblitz.com/edit/nuxt-starter-hxrstv?file=pages%2Findex.vue It seems that on stackblitz is is working normally even on route changes, but in my actual setup I have dynamic routes accessed from pages/[...slug].vue instead of static routes. I still don't exactly know how to diagnose further this. Thanks for your help.
×
×
  • Create New...