Popular Content

Showing most liked content since 05/16/2018 in all areas

  1. 6 points
    Yes, I'm responsible for that. I never finished the demo I was working on, but morphing into different shapes is what I actually designed it to do. I totally forgot all about making that, so thanks for reminding me. Now I just need to find time to finish it.
  2. 5 points
    Concerning your first question about library overlap, look at what I wrote about ScrollMagic in my previous post. I have always claimed that ScrollMagic isn't needed, and it isn't. You can do the same exact thing by specifying the scroll position for an animation's time/duration. Nothing magical.
  3. 5 points
    There is no passing of commands between GSAP and ScrollMagic. GSAP has no concept of ScrollMagic. It doesn't exist as far as GSAP is concerned. And Lottie is just a fancy flip book animation. Tell it what frame to display, and it displays that frame. Maybe it's best to take a step back, and first understand how some of this stuff works conceptually. Please watch these 3 videos. It will only take like 10 minutes, and is key to understanding how a lot animation works. Normalization - https://www.youtube.com/watch?v=hJqRcExiBk0 Linear interpolation - https://www.youtube.com/watch?v=mAi2-LTC2CA Map - https://www.youtube.com/watch?v=FxAEXHGZSPA All GSAP animations have a start and end value. It changes the value using interpolation. The norm value is time. The normalized time value is the same thing as the progress value. https://greensock.com/docs/TweenLite/progress() ScrollMagic does the same thing as GSAP, but instead of using time for the norm value, it uses the scroll position. So scroll position can also be considered a progress value. So here's the connection. ScrollMagic can change the progress of a GSAP animation. A GSAP animation can change a frame value. Lottie can be controlled by specifying a frame number. GSAP can't control the frame value of a Lottie animation directly, but you can animate a frame value on a generic object. Every time GSAP updates that object, you take the frame value, round it, and pass it into Lottie. See how it works on it's own. You shouldn't be calling .play() on your Lottie animation inside an onUpdate callback as it will constantly call it. The reason your animation isn't working like it should is because you omitted the most important part. You can't animate something if it doesn't exist. You have to wait for .json file to download and processed by the player. Look at the onDOMLoaded function in that video. That's kind of important.
  4. 5 points
    Thanks for the demo. The site looks nice too. I have to say I was a bit suprised when I saw the source for the SVG. The artwork could probably be constructed of a dozen or so rectangles and simple paths yet the svg is extremely complex with over 1000 lines of code. I noticed you are doing drawSVG and opacity tweens on every element with a class of "st4"and saw that almost every line in the svg has that class. I ran some code to see how many elements have st4 as class. console.log(document.querySelectorAll(".st4").length) That returns 780. For each path the browser has calculate the length of the path and the update the stroke-dash-array and change opacity at 60 times per seconds while other things are going on. Unfortunately, SVGs do not at all benefit from GPU hardware acceleration. My guess is that IE11 is simply not up to the task. My first recommendation is to recreate the artwork with simpler shapes (even if this requires re-building it from scratch) Second, be sure that you are only animating the lines you need to. You can do this by applying a unique class to only the lines you want to animate.
  5. 5 points
    It looks like you've taken parts of my demo, but reverted back to your original way of adding to the timeline on each mouse wheel event that calls that slide animation function. If you look at what I made for you, you'll see that all the timelines are created outside of the mouse wheel animation function. All we're doing in that handler is changing the slide number, reversing one timeline and then playing the new one. In answer to your question about the position parameter of 0, no that doesn't really fix it. It seems to, but what's happening is you are adding more and more child tweens to the timeline. They all start at 0 and all do the same thing, but the number of children keeps going up. Drop this into your function to see what I mean. console.log(home.getChildren().length) Use that on any of your timelines and you'll see the array of children for each timeline keeps growing as you scroll through the slides. I'm not clear on why you've gone back to adding and removing an active class and using multiple if/else statements to check slide classes. The way you have it structured again will only work with three slides. The demo I created for you works for 3 or 300. You can add as many as you like. (Except for the slide number indicator which has a limit of 5 for the purposes of illustration). As I mentioned in my demo comments, you can manually create the timelines and push them into the array rather than making them in a loop like I did. Here's what that would look like in your case. var home = new TimelineMax({onComplete: onComplete, paused: true, onReverseComplete: newAnim}); var about = new TimelineMax({onComplete: onComplete, paused: true, onReverseComplete: newAnim}); var cases = new TimelineMax({onComplete: onComplete, paused: true, onReverseComplete: newAnim}); var timelines = []; home.to(".home h1", 0.5, {x:200}); about.to(".about h1", 0.5, {x:50}); cases.to(".cases h1", 0.5, {x:100}); timelines.push(home, about, cases); Whatever you do, you need to create the timelines outside of the mouse wheel handler or you'll end up with a greater duration and/or loads of duplicate child tweens. Hopefully that helps. Happy tweening.
  6. 4 points
    Look at the page @Sahil linked to. You need to find the closest point on the path. NONE of the pens you have made do that. They all do linear progression.
  7. 4 points
    SVG filters can be very processor intensive which can yield sub-optimal animation results. If your logos are all the same size (or aspect ratio), you might do better with a bitmap (png) shadow and place it underneath each logo. I'm not exactly sure what the best performing alternative would be here.
  8. 4 points
    That's just because you've got an error in your JS code that's referencing a non-existent object (progress): progress.html(tl.progress().toFixed(2)); If you look at the console, you'll see a bunch of errors getting spit out. Once you remove that line, it looks like it all works perfectly Let us know if you've got any other questions.
  9. 4 points
    All it means is that a new timeline will be created every time you trigger the click event and it will not be held in memory. So, unless you're passing in new parameters every time, there's no particular reason to do so. You can create the timeline once and only replay it on click. Having said that, there's nothing really bad or wrong by creating a " throwaway" timeline like that. Performance-wise.... Unless you are triggering thousands upon thousand of clicks or looping and creating thousands upon thousands of calculations on that one click, there's no real perceivable difference in performance.
  10. 4 points
    Your punishment: minus 50 likes, and you must rebuild that entire animation using only CSS. Good luck.
  11. 4 points
    Hi @Johanna Your animation ran fine for me in IE11 with one exception. The only problem I saw was the orange lines. That's a weird IE11 bug when you have stroke-linecap: round. If you also set stroke-linejoin:round on your .st7 class, you should be good to go. You can also check out this thread: Happy tweening.
  12. 4 points
    That demo is from this thread: I'd recommend reading through that information. After that, you can search the forum for particles and you'll find quite a few threads where Blake works his canvas magic.
  13. 4 points
    Also, for parameterized wiggles and bounces, be sure to check out the eases CustomWiggle and CustomBounce: https://greensock.com/wiggle-bounce As a Club GreenSock member you have access to these powerful tools. I think you will enjoy them.
  14. 4 points
    We don't really have "built-in" effects, but the engine is very flexible and excels at allowing you to create your own re-usable effects. I would strongly recommend reading this article and watching the videos if you need help with the concept of "creating functions that return animations". https://css-tricks.com/writing-smarter-animation-code/ The general idea is that you can build a timeline consisting of animations that are created via parameterized functions. Below is a very basic implementation of this idea with 2 effects "bounceScale" and "spinAndThenFadeOut" Notice how each box bounces and scales with unique parameters (scale amount, duration) and then each box spins and fades out with unique rotations and speed. //effect function animates an element and returns the tween function bounceScale(element, endScale, duration) { var tween = TweenLite.to(element, duration, {scale:endScale, ease:Bounce.easeOut}); return tween; } //effect function animates an element and returns the timeline function spinAndThenFadeOut(element, spinSpeed, spinAmount){ var tl = new TimelineLite() tl.to(element, spinSpeed, {rotation:spinAmount}) .to(element, 0.5, {opacity:0}); return tl; } // build timeline using multiple effects on multiple elements with unique parameters var tl = new TimelineMax(); tl.add(bounceScale(box1, 3, 1)) .add(bounceScale(box2, 0.5, 2)) .add(bounceScale(box3, 0.2, 1)) .add(spinAndThenFadeOut(box3, 2, 720), "+=0.5") .add(spinAndThenFadeOut(box2, 0.5, 180)) .add(spinAndThenFadeOut(box1, 3, 360))
  15. 4 points
    It looks exactly as I would expect. The position of your appended divs has nothing to do with SplitText. To see what I mean, try commenting out your tltour timeline (lines 23-25) and just look at the layout. Do you want all the text to be at the top of the div? If that's the case, you'd just change your CSS .TeaserText { font-size: 4rem; color: #000; position: absolute; } Does that help? Happy tweening.
  16. 4 points
    Here's your matrix. Then just transform the points like I showed above. const cos = Math.cos(rotation); const sin = Math.sin(rotation); matrix.a = cos * scaleX; matrix.b = sin * scaleX; matrix.c = -sin * scaleY; matrix.d = cos * scaleY; matrix.e = x - matrix.a + matrix.c; matrix.f = y - matrix.b + matrix.d;
  17. 4 points
    I'm not sure if Shaun will be online again today so I'll jump back in. It looks like you're using GSAP to set() a new class name on click, but that class is a CSS transition? That may cause problems as mixing the two will many times result in a fight for control of the element. I don't think we understood you wanted to do this with multiple elements in a jQuery each() loop. Here's a basic demo of creating a timeline for each() jQuery element and checking a global variable to see if a click should allow the timeline to play. Hopefully that helps. Happy tweening.
  18. 3 points
    Thanks for the demo. SplitText isn't removing any spaces. This is just normal browser behavior. Only 1 space in your code will be honored. If you remove all the JavaScript you will see that there is only 1 space that gets recognized I don't think there is a SplitText solution for this. Someone else may have some suggestions. You may need to inject your own divs or spans with single spaces.
  19. 3 points
    Hey GSAP, Sorry for the late response. I tried hard to reproduce the problem in codepen but it wasn't possible. Anyway, I found what was the problem. The SVG renders in heavy dom documents looks to be blocked... (probably for the sake of performance) although there is no documentation anywhere regarding this! As proof of this assumption is the solution that I found... that is not really a hack. The solution is... LAYERS! Forcing the browser to create an internal layer for the animation container, improves the performance (but note that this is not cheap and should be used sparingly). A nice description for this can be found here: https://aerotwist.com/blog/on-translate3d-and-layer-creation-hacks/
  20. 3 points
    First of all, welcome to the forums, @closerlook. Thanks for being a Club member. Short answer: Set the autoKillThreshold to a lower value (default is 7): ScrollToPlugin.autoKillThreshold = 3; And make sure you're using the latest version - the codepen you posted is using a very outdated one. I know, it's counter-intuitive because it's pointing to the "/latest/" directory on the CDN, but unfortunately CDNJS stopped supporting that years ago and they refuse to update files there. We begged...they denied. So just point to /1.20.4/ instead, and you'll be golden. Explanation: autoKill is enabled by default which means that ScrollToPlugin will automatically check to see if the value that it set on the scroll value last has been changed. If so, that means something else (typically user interaction) made it change, thus the tween should be killed (well, that part of the tween at least). The problem is that some browsers (like iOS safari) are pretty sloppy with those values, so even if (for example) ScrollToPlugin sets it to 112, Safari might alter that slightly (without any user interaction), so we had to build in a tolerance. That's where the autoKillThreshold comes in. Does that solve things for you?
  21. 3 points
    If I understand correctly you could run a loop that tweens every box I suspect at some point the number of elements will impact performance. Hopefully this sparks some ideas. Good luck on your project
  22. 3 points
    There's some SVG magic going on there. Not really, people just think SVG is all based on attributes, but there's objects to work with. This line of code is getting actual point objects from the SVG. var point = star.points.getItem(i); Changing a point automatically updates the element. I show how some of that works in this post. And to get the transform values, GSAP puts an object on the element called _gsTransform. OBJECT is the key word there. That means we can scope a function to that object i.e. moveAction. var tl = new TimelineMax({ onUpdate: moveAction, callbackScope: handle._gsTransform }); // Draggable and the timeline can share this function function moveAction() { point.x = this.x; point.y = this.y; }
  23. 3 points
    Was typing this when @PointC replied Beat me to it. You could do it programmatically using the getBBox() method of SVG elements to calculate the center and feed that into the svgOrigin. I noticed that circle has a class of .st10 (and it's the only thing with that), so it'd be: var bounds = document.querySelector(".st10").getBBox(), originX = bounds.x + (bounds.width / 2), originY = bounds.y + (bounds.height / 2); TweenLite.set(arm, {svgOrigin: originX + " " + originY}); Here's a fork: Note that once you set an svgOrigin or transformOrigin, you don't have to keep setting it in every tween for that same element. GSAP remembers Does that help?
  24. 3 points
    Hi @puffywuffer Please try this on line 34: .to(arm, 1, {rotation: 30, svgOrigin: '225.6 300.1'}, '-=1') Then remove the arm transformOrigin on lines 40 and 50 as you 'll only have to set it in that first tween. More info about svgOrigin: https://greensock.com/gsap-1-16 Happy tweening.
  25. 3 points
    You will need to animate multiple tspan elements.
  26. 3 points
    The updateTo method only works with generic objects and not dom objects. In docs you can also see that you can get unexpected behavior for reversing tweens. https://greensock.com/docs/TweenMax/updateTo() What you are trying to do can be achieved using invalidate method. In following demo, onRepeat I am updating the values in vars object and then invalidating the tween. You can repeat the same logic for resize event so you won't see any odd behavior.
  27. 3 points
    You mean like this?: Should be as easy as sprinkling in some conditional logic and populating a timeline (or just regular tweens...either way). Hope that helps.
  28. 3 points
    I read your question a few times and I can't quite understand what's not working or what "syncing of click events" means in your context. Are you saying that after you click the button and the animation starts, you want to force the user to watch the whole animation before they're allowed to click on the button again to animate them off the screen?
  29. 3 points
    Hi @anotheruser Please try adding this to your CSS #text div { text-decoration: underline; } Hopefully that helps. Happy tweening.
  30. 3 points
    I think you can fix that with this: array.push(379 - ((379 / 10) * i).toFixed()); Happy tweening.
  31. 3 points
    Understanding how matrices work probably isn't too important. I would focus on how and when to use them. Using an SVG Matrix. The trick is doing stuff in the correct order. matrix = svg.createSVGMatrix() .translate(X, Y) .rotate(R) .scaleNonUniform(SX, SY);
  32. 3 points
    Great demo, Craig. I love how little code there is and how you take the time to make these so nicely responsive too
  33. 3 points
    I can appreciate the difficulty and the amount of support it would involve, but it still has a lot of neat features. The spinning dot wheel demo you made with that tool is really cool. You should make that into a coding challenge. I'd like to see how many people could actually do that.
  34. 3 points
    This was a fun little challenge. Here's another technique that uses what I call a "chopped ease" (it's a fork of Craig's): Normally an ease goes from 0 to 1 of the course of the tween, but here I'm creating a new ease for each tween that basically scales that value down. That way, you use a normal tween as if it's going along the whole path, but since the ease is chopped (well, scaled I guess), it'll go only partially to the end of the path (according to however much we chop). Probably more performant this way and more concise. Nice job @Carl and @PointC. Hope you don't mind me offering an alternate solution.
  35. 2 points
    Or just a simple <span> with a margin, like: <div id="blueBox">hi<span style="margin-left:5em"></span>greensock</div>
  36. 2 points
    Hello! I have managed to spend a bit of time on this. Diaco's original pen is quite useful and a rather neat trick he's got there. The catch is making sure you are using the same type of curve for the Bezier and the SVG you are drawing. In this case, it's "Cubic". It will be wise to read the following pages to get yourself familiar with the Path attribute in SVG and GSAP's BezierPlugin: https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths https://greensock.com/docs/Plugins/BezierPlugin Now you can just drag the knob sideways to get it to slide along the path nicely. I also feel this fixes your continuity issue, where you were saying the knob wasn't sitting exactly where you expected it to be. Here's my fork of Diaco's pen: Now if you want the dragging not to be just a straight line, you know it will be a rather complex set of logic for you to achieve that. And I don't think I'll have enough spare time to write the logic for you.
  37. 2 points
    Hi and welcome to the GreenSock forums. I removed the fill and filter from each logo. See if this runs any better. What type of iPhone / iPad are you using (version, iOS)
  38. 2 points
    Hi there! I am reading this thread but finding it very hard to picture what it is that you mean by " continuity" . What in Diaco's example does not fulfil your needs? Another question: When you stated that you wanted the mouse pointer should be "in sync" with the draggable knob, do you mean you want to lock the mouse pointer to the location of the draggable object? If that is what you want, you will not be able to achieve it. You cannot take over the mouse pointer. The best you can do is fake it by hiding the mouse cursor and then adding a fake cursor on top of the draggable object, locking that fake one onto the position you desire.
  39. 2 points
    Welcome to the forums, @TomerBrosh. Sorry, but I'm pretty lost in terms of exactly what you're asking here. Can you be a little more specific? I don't know what "rotate and move correctly" means in this case. Are you saying you want that thick part of the line to look like it's following the thinner line that it's sitting on? If so, that's probably easiest with DrawSVGPlugin (though you could do it as a rotation instead, but that'd require figuring out the svgOrigin or transformOrigin accordingly). As for moving things inside of the half-circle, you'd probably need to write a function that'll return randomized points inside that area and feed that into a recursive tween (one with an onComplete that calls the same function that does the same thing again). Not exactly simple, but doable. I hope that helps. Happy tweening!
  40. 2 points
    @Sahil is totally right, but there may be a simpler solution. Part of the problem had to do with some limitations of <polygon> and <polyline> points, so try converting those to <path> elements instead which are much more flexible. Don't worry - MorphSVGPlugin makes it SUPER easy: MorphSVGPlugin.convertToPath("polygon, polyline"); Just run that first. Here's a fork: When working with <path> elements, MorphSVGPlugin will automatically select the shapeIndex that results in the points traveling the least distance overall (which is generally the most intuitive one). Does that help?
  41. 2 points
    Here ya go: Is that what you're looking for?
  42. 2 points
    I don't know why it keeps throwing an error, but it's supposed to throw an error if the target doesn't exists. If it failed silently, then it would be hard to debug. Error handling is just part of development, and no, you shouldn't wrap all your code up in try... catch statements. Elements don't magically add and remove themselves from your app. Whenever something changes, you should update your code to reflect those changes. There is no easy answer on how to do that as it depends on what you're doing. A simple way to prevent a null target error is to test for a truthy value. https://developer.mozilla.org/en-US/docs/Glossary/Truthy Any object will be true. if (foo) { tl.fromTo(foo, 1, { x: 100 }, { x: 0 }); }
  43. 2 points
    I personally wouldn't code it like that because making any changes would be really hard, for example if you change number of panels then you will have to adjust everything else. Take a look at following similar thread.
  44. 2 points
    Here's a good article on hand coding SVGs. https://webdesign.tutsplus.com/tutorials/how-to-hand-code-svg--cms-30368 I wrote a little post about better exports from AI. You may find some of the info helpful. I also have this one about DrawSVG and MorphSVG start points. Happy tweening.
  45. 2 points
    I feel obligated to advocate for the user and say "please, please don't do that" Just my opinion about UX. I can't stand it when apps force me to sit through an animation, especially for a menu. It feels really weird (bug-like) to not have the UI respond to my clicks (as if I'm locked out). So are you saying that you want to queue the animations so that if the user clicks the menu (to open it) and then clicks it again very quickly (to close it), you want the whole "open" animation to run, and then run the "close" animation after that? And what happens if the user clicks 5 times really fast? Do you want it to queue up all those animations back-to-back? [cringe] Basically it just boils down to adding conditional logic in your click functions accordingly. Kinda like:
  46. 2 points
    Welcome to the forums! I'm not very familiar with Bodymovin' or ScrollMagic so I may not be able to help much but I can tell you with confidence that what you're attempting is totally doable. The problem I noticed in your code is that you've got "animationControl" as a local variable tucked inside of that function you're feeding to $.each(), thus it's not available outside that function. It's a scope issue. What's confusing to me is that it looks like you've got it set up to accommodate MULTIPLE #animationWindow instances (which of course can't happen because IDs by their very nature are unique), so why do you have things inside of an $.each() at all? It doesn't even look like you're referencing the #animationWindow element at all inside that loop, so couldn't you just delete the whole $('#animationWindow').each(function(){ ... }) wrapper? Oh, and you don't need to sign up for Codepen Pro to do a codepen example. It's free to create anonymous pens. See Good luck with the project & happy tweening!
  47. 2 points
    Hello! Videos can't autoplay with sound on. Set your video's muted property to true and it should work as you have it. Video with sound can only play if the user interact with it in a meaningful way. A click or a tap. Mouse hover are not classed as intentional interaction as one can easily hide nefarious code to play annoying sounds in such interaction without the user wanting it.
  48. 2 points
    We completely rewrote CustomEase from the ground up for the JavaScript version. It's much more powerful and accurate now. There isn't really a direct conversion tool, but I whipped together some code that should (in theory at least) replicate that ease: CustomEase.create("custom", "M0,0,C0,0,0.106,0.053,0.165,0.095,0.225,0.138,0.26,0.169,0.315,0.223,0.479,0.387,0.576,0.482,0.73,0.657,0.841,0.783,1,1,1,1"); And here's a codepen that does all the work of estimating that conversion: If it doesn't look/act like what you expected, let me know. Does that help?
  49. 2 points
    Hi and welcome to the GreenSock forums, I added code similar to yours to a fork of one of @PointC's demos. It appears to work just fine snapping to increments of 50px Please do your best to provide a very basic example of what you are doing in an online, editable environment like CodePen, jsFiddle, plunkr, etc. To edit the demo above: click "Run Pen" click "edit on CodePen click "fork" replace code in demo above with the least amount of code possible to illustrate the issue. if you can replicate the problem without Angular that would be fantastic. save demo send us the link Hopefully once we can see your demo in an online environment that allows us to easily, view, test and share we will be able to provide some more assistance.
  50. 2 points
    Hi @puffywuffer Welcome to the forum and thanks for joining Club GreenSock. Looks like I'm a bit slow so @Carl has whooped me and already given you the answer. I did see your question earlier and was tinkering with a demo, but got sidetracked until now. It's pretty much the same idea as Carl's demo, but it might be helpful so I'll throw it out here for you. Happy tweening and welcome aboard.