Jump to content
Search Community

Asored

Business
  • Posts

    23
  • Joined

  • Last visited

Everything posted by Asored

  1. Many, many thanks @Rodrigo! Your post helped me to find a sensible and creative solution! 👍 Because all the users' tweens are stored in the database, I was able to recreate the timelines simply by grabbing the animation data via tween.vars and other objects. So each new DOM element will create and run a new timeline on loaded. Everything works as expected. Very cool. 🤓
  2. Hey everyone! First of all, and sorry for the Offtopic: this new gsap website is just amazing. Great work! Now about the problem I'm currently fighting with. I've created a minimal demo to understandable reproduce the issue. Demo description in short: When new items with the same class are coming to the DOM, only the old ones are animated. Detailled version: When a timeline is created, targets are saved, which are DOM nodes in the end. If I've researched this correctly, the function uses `querySelectorAll()`. That's good so far, but I'm currently encountering a problem. I have a context where data is dynamically loaded on a page (a facet filter system, where different data are pulled from the server but always have the same class). I want to animate the reloading of these contents by restarting the GSAP timeline with .restart() after the server request. Unfortunately, the timeline does not recognize the new elements, which is understandable up to this point, as it only saved those that were in the DOM at the time the timeline was created. My question: is it somehow possible to update the timeline instance so that it also includes the new elements present in the DOM? Of course, the sensible approach here would be to simply create a new timeline. However, in my case, this is not possible because it's a UI platform where users create the timeline that they can restart in different situations. So, it's a prerequisite that the same timeline is used. Is this somehow possible? I would be very grateful for any help!
  3. Hi! I try to understand an issue which currently occurs for a pinned animation in combination with SplitText and display: flex parent containers. As you can see in the pen, SplitText seems not to render this string correctly when the text element (in this case h1) has a parent element with display: flex (in this case .container). It splits the text into two lines. Changing the parent to display: block, the rendering is fine and the headline remains one line. This would be the expected (or desired) behavior. This error only appears while the PIN functionality is activated. Is there a common way to handle with such situations?
  4. Hi all! I understand the principal logic of immediateRender. Setting this value to true may be definitely needed for .from and .fromTo methods, where we need the initial properties very fast. But I'm on a situation where I need to set immediateRender to false. As you can see in the Codepen, some basic staggered splittext animations are not working as I expect. Seems that the animation starts without setting the initial properties for each char element. Is there a way to force gsap to wait for the initial value while setting immediateRender to false? By the way, I need this for a backend UI where the user can change the progress of a timeline with a dragger. Also wenn the .progress is setting manually to position 0, the element never gets the initial properties. You can see this example in my pen in the setTimeout function, where I set the timeline to the position 0 after three seconds. I really appreciate your help!
  5. Hi there! First of all, sorry for always coming up with such tricky questions here. In my application, the user can create timelines via a UI. I store all created timelines in a variable and can access them later to play them as needed. Now I had the case that every item of a navigation should be animated on mouseenter. Here it became a challenge for me to find the right timeline for the right item. I added comments to my codepen code and I tried to create my project as simple as possible minimized. Simply asked, do I have the ability to get a reference in the timeline object to the elements it will animate? If so, I could just query that. Or is there a better solution for my use case?
  6. Oh, understood! Thank you! In my case I have no possibilities to add extra containers. My users can create some animation stuff with an UI. The DOM is always another and I don't know it. So this solution would not work for me. Is there any way with gsap.context() ?
  7. Hi there! I'm trying to create some very basic timelines which I can use on different places on the website / page, adding a class to an element. For example: Each element with the class .animate-me should animate y: -100 when entering the viewport. I have a problem with the scrollTrigger start and end values. When checking my attached CodePen, you will see that the animation for all .animation2 elements is triggering when the first element with the class .animation hits the center of the viewport. I think that is the expected behavior. But how could I make the trigger relative to the element which enters the viewport? In the CodePen, the second headline "Another headline" should start to animate when the second a.animation hits the center of the viewport. When iterating the triggers, I could choose the trigger selector to animate exactly this element. This works (.animation) But what if I want to animate other selectors in this timeline? (.animation2 in my example) Is there a best practice to handle such situations? I hope that I could describe my problem understandable. If not, please ask me
  8. Hi @Carl Thanks so much! Works like a charm!
  9. Hi everyone! I have a question which is very simple to ask, but where I currently do not know what to do. To make it clear, I've created a codepen on which I tried to reproduce my project as simple as possible. Basically, if I change a tween within a timeline, how do I make all the other tweens change with it? For example I could update the duration of a tween..and depending on the duration for a tween, the next tween in the timeline should change the startTime. Or do I understand something wrong? If my timeline has two tweens, both with the duration of 1 second. The structure will look like that: First Tween: Duration: 1, Start Time: 0 Second Tween: Duration: 1, Start Time: 1 When changing now the duration for the first tween to 5, for my understanding it should be: First Tween: Duration: 5, Start Time: 0 Second Tween: Duration: 1, Start Time: 5 But the start time remains to: 1. Please check my CodePen example. There you'll find some comments about this. The context is that I'm creating a timeline visualization. I need to change the values in real time. The UI is located in a different place than where the timeline creation is located. Therefore I have to work with a parent variable that stores the timelines globally. I think that should be fine. The user can change the duration of each tween inside an Input field. As result, the duration of the timeline changes successfully. But all other tweens ignores the change of this one tween. Do you have an idea how to achieve what I need? I hope that I was able to explain this understandably enough.
  10. Hi @GreenSock, understood. Thanks for the clarification! And yes, I think that would be the expected behavior – at least at the first thought. I think that would really make sense, also regarding the `start` and `end` arguments. Lets say the user defines a very small path. It is almost impossible to grab the end of the path to change it afterwards, because the animation is looping around the path. As workaround he can increase the duration to have the chance to grab the path dot. As solution we could just say: `end: 0.8` and as result, the end of the path will always be free for mouse interactions. Just to talk about a possible use case. Is there a workaround for me to force the arguments to have an effect – also for existing paths?
  11. Hi GreenSock! I've simplified the example removing the astronaut https://codepen.io/asored/pen/yLjpEwW But in general I talk about the following lines: MotionPathHelper.create(".astronaut", { path: "#path", pathWidth: 5, pathColor: "red", pathOpacity: 0.6, selected: true, start: 0.1, end: 0.5, duration: 5, ease: "power2.inOut" }); The documentation says: `You can optionally pass in a vars parameter to further configure the motion path helper. It's an object and can include any of the following properties:`. I've used the properties above and expect the following: - The width of the displayed path should be 5 - The path color should be not blue, but red - The path opacity should be 0.6 - The object should end on the half of the path - ..... and so on But all passed arguments seem to not have an affect. Just the basic blue path appears. Do I missunderstand something here? Are the arguments perhaps doing something different than I understand?
  12. @GreenSock @mvaneijgen Thanks so much for your feedback! I've got it to work calculating the viewBox dynamically depending on the path: // Calculate Viewbox let clientRect = document.querySelector(pathElementClass).getBBox(); let viewBox = clientRect.x+' '+clientRect.y+' '+clientRect.width+' '+clientRect.height; document.querySelector(pathElementClass).closest('svg').setAttribute('viewBox', viewBox); It works like a charm. GreenSock, great concept to recalculate also the motion values. But I think this will be too much. Its okay for me to have the new calculated viewBox on page reload. If I need this at some point, I will return to this post.
  13. Hi! As the documentation says, we can pass arguments to the `MotionPathHelper.create()` function. But all arguments are getting ignored for some reason. I've tried it also in your official example from the documentation page. Are there any breaking changes in the new MotionPathHelper version that require me to pass the arguments differently than what the documentation says?
  14. Hi GreenSock! Thanks for your feedback! Good hint with the `mouseenter`. I've completely overseen this. As you recommended, I've included some console.log() to my code to be sure that the code only runs once. Its important in this case that we have to separate the frontend output from the broken backend output where to code does not work as expected. Console – Frontend Output Creating timeline Set timeline settings Create Timeline animations Wait for event trigger Mouseenter event triggered Mouseleave event triggered Mouseenter event triggered Mouseleave event triggered Here everything seems to be okay, the way I would judge it. Console – Backend (where the DOM is loaded twice) JQMIGRATE: Migrate is installed, version 3.3.2 JQMIGRATE: Migrate is installed, version 3.3.2 Creating timeline Set timeline settings Create Timeline animations Wait for event trigger Creating timeline Set timeline settings Create Timeline animations Wait for event trigger Creating timeline Set timeline settings Create Timeline animations Wait for event trigger (3) Mouseenter event triggered (3) Mouseleave event triggered As you can see, in this case the DOM is rendered not twice, but three times! I hope they will fix the bug soon. But for now, I have to find a workaround for my application. ? By the way: man thanks to you and your great community. This forum is just an enrichment! ? --EDIT-- I've found a temporary workaround by saving the timeline into a variable and checking if is active or not: flip.addEventListener("mouseleave", event => { if (tl.isActive()) { return; } tl.reverse(); }); May really not be the best solution, but I think in this case I can play with the weird DOM loading.
  15. I'm just playing with the incredible MotionPath plugin. The MotionPathHelper extension is very helpful for my users to build easily custom paths without struggling in Illustrator. But I already know. There will come questions like: "Why this is not responsive? We cannot use this in production if so". Is there a way to make such a scenario responsive and limit it to the viewport? https://codepen.io/asored/pen/jOxadKJ I don't think if we can play with nested SVG and if its a best practice to do so, but what if the user want to create a MotionPath from another element type like an image? In general I don't know what I get. The user can choose any HTML code and create paths for it. Have any of you thought about this specifically, how to solve something like this?
  16. Hey Cassie! Thanks very much! You're right. I've created a codepen with my code and simplified it removing the switch case blocks to focus on the relevant parts. In general this is what I try to do. A very simple flip box. As you can see, the code works. Also in my WordPress environment in frontend. But exactly the same code does not work correctly in backend when viewing trough the builder which loads it as iframe. The reverse finishes not on 100%, but pauses on 80-90%. Because of a current bug, the builder loads the DOM twice. I thought that this causes the error, because with a workaround for the builder which loads the DOM once, the animation works again, also in the builder. What do you think? https://codepen.io/asored/pen/bGMYaVw
  17. Thanks so much for your words! And also you, Rodrigo! Awesome people here in the forum! Regarding the problem I have, I badly cannot provide a codepen demo, because this plays inside a WordPress installation with a Page Builder. The Page Builder itself currently has a bug which loads the DOM content twice. (iframe). In the frontend view, where the DOM content is loading once, the reverse animation works well. But in the backend (builder) view, where the DOM is loaded twice, I get this strange behavior. As workaround I tried to force the javascript function where the animation was created only to load on the first DOM load..and yea, the reverse works then also in the builder view. This shows me: it really has anything to do with the double DOM loading. Very strange. I'll post the code from my javascript function. Maybe this helps. By the way. I see its a good practice to create the timeline outside of the for loop. In this case its not possible because I need to integrate date from the looped items. Or do you have a better idea? Here the code: async function gsapExample() { gsap.utils.toArray('.elem-flip-wrapper').forEach(flip => { let wrapper = flip; let box = wrapper.querySelector(".elem-flip-box"); let front = wrapper.querySelector('.elem-flip-front'); let back = wrapper.querySelector('.elem-flip-back'); let animationType = flip.getAttribute('data-type'); let duration = flip.getAttribute('data-duration'); let delay = flip.getAttribute('data-delay'); let trigger = flip.getAttribute('data-trigger'); let onComplete = flip.getAttribute('data-oncomplete'); let onStart = flip.getAttribute('data-onstart'); let onReverseComplete = flip.getAttribute('data-onreversecomplete'); animationType = animationType ? animationType : 'flip'; duration = duration ? duration : 1; delay = delay ? delay : 0; trigger = trigger ? trigger : 'hover'; onComplete = onComplete ? new Function (onComplete) : ''; onStart = onStart ? new Function (onStart) : ''; onReverseComplete = onReverseComplete ? new Function (onReverseComplete) : ''; const tl = gsap.timeline({ paused: true, onStart: function() { typeof onStart == 'function' ? onStart() : ''; }, onComplete: function() { typeof onComplete == 'function' ? onComplete() : ''; }, onReverseComplete: function() { typeof onReverseComplete == 'function' ? onReverseComplete() : ''; } }); gsap.set(wrapper, { transformStyle: "preserve-3d", transformPerspective: 1000 }); gsap.set(box, { transformStyle: "preserve-3d", transformOrigin: "50% 50%", }); gsap.set(back, { rotationY: 180, rotationZ: 180 }); switch (animationType) { case 'flip': tl.to(front, { rotationX: 180, duration: duration }, delay); tl.to(back, { rotationX: 180, duration: duration }, delay); break; case 'fade': gsap.set(back, { rotationX: 180 }); tl.to(front, { opacity: 0, duration: duration }, delay); tl.to(back, { opacity: 1, duration: duration }, delay); break; case 'fadeShrink': wrapper.style.overflow = 'hidden'; gsap.set(back, { rotationX: 180 }); tl.to(front, { scale: .8, opacity: 0, duration: duration/2 }, delay); tl.to(back, { opacity: 1, duration: duration }, delay); break; case 'fadeUp': wrapper.style.overflow = 'hidden'; gsap.set(back, { rotationX: 180, translateY: 500, opacity: 0 }); tl.to(front, { opacity: 1, rotationX: 180, duration: duration }, delay); tl.to(back, { translateY: 0, opacity: 1, duration: duration }, delay); break; case 'overlay': wrapper.style.overflow = 'hidden'; gsap.set(back, { rotationX: 180, translateY: 500, zIndex: 1 }); tl.to(back, { translateY: 0, duration: duration }, delay); break; case 'overlayShrink': wrapper.style.overflow = 'hidden'; gsap.set(back, { rotationX: 180, translateY: 500, zIndex: 1, scale: .9 }); tl.to(back, { translateY: 0, duration: duration }, delay); break; default: break; } switch (trigger) { case 'hover': flip.addEventListener("mouseover", event => { tl.play(); }); flip.addEventListener("mouseleave", event => { tl.reverse(); }); break; case 'click': flip.addEventListener("click", event => { if (flip.classList.contains('active')) { tl.reverse(); flip.classList.remove('active'); } else { flip.classList.add('active'); tl.play(); } }); default: break; } }) }
  18. I refer to the following post: In order to keep the forum clear, I created a new thread because the last question of the thread is about a different issue. That way others looking for it can find the solution faster. The issue is the following: In the environment I need to integrate a gsap animation currently is a small bug. The DomContentLoaded eventListener fires twice. I can't change this behavior and I need to play with it. This seems to be a problem for the tl.reverse(). The reverse animation stops until finishing. To make it more clear: I animate a translateX from 180 to 0..and the reverse() stops for example on 15. I think this is because there is triggered a second reverse() until the first is finished. Is there a way to say: "Hey! Please ignore other requests and animate only once"? Something like a force function to definitely finish the reverse animation. Or how could I handle a such scenario?
  19. Great, thanks very mich, Rodrigo! I really appreciate your help. It works well animating only the children. There is just another issue. In the system I need to integrate this animation currently is a small bug. The DomContentLoaded eventListener fires three times. I can't change this behavior and I need to play with it. Firering the page three times seems to be a problem for the tl.reverse(). The reverse animation stops until finishing. Is there a way to say: "Hey! Please ignore other requests and animate only once"?
  20. Hi guys! I'm really in love with Gsap and want to use it for my future projects. I'm sure I'll join the Business Membership. Awesome work. Since I'm still in the getting-to-know phase, I may have a question that I'm sure seems obvious to you. I try to animate a typical Flip Card with a gsap timeline. Works like a charm! But: When more then one elements / cards are on the page and I create a loop (in my case with the gsap util toArray.forEach), the animation seems to be broken. No error messages in the console, each element can be found by gsap. So I don't know where is the problem here. For some reason the back of the card is going to be white. When realizing that without foreach and directly with one element, everything works. What's the error here? Did I misunderstood some important concepts? Wish you a great weekend!
  21. This absolutely helped me as well! Many thanks!
  22. Hi :) I'm new with GSAP and I like it very much! Thanks for your great work! Just a beginner question: I try to animate the following simple thing: https://codepen.io/Asored/pen/PoGYyOg In my project I trigger the window scroll position instead of waiting for a click event. How could I create the animation from current relative position to a fixed position on bottom right? This is my try: ScrollTrigger.create({ start: 'top 20%', trigger: '#contact--btn', markers: false, scrub: true, onEnter: () => { var windowWidth = $(window).width(); var windowHeight = $(window).height(); var buttonWidth = $("#contact--btn").width(); var buttonHeight = $("#contact--btn").height(); var buttonOffsetLeft = $('#contact--btn').offset().left; var buttonOffsetTop = $('#contact--btn').offset().left; gsap.to('#contact--btn', { x: (windowWidth - buttonOffsetLeft) - buttonWidth - 250, y: (windowHeight - buttonOffsetTop) - buttonHeight - 250 }) setTimeout(function () { $("#contact--btn").css("position", "fixed"); }, 10) }, }) This is not really elegant. Also the animation is not smooth because of the small break from the setTimeout function. Is there a better way to create animations like this with GSAP? Thanks in advance for your help! :) Best regards
×
×
  • Create New...