Popular Content

Showing most liked content since 04/23/2018 in all areas

  1. 10 points
    Hey GreenSockers, This is my 2,000th post so I wanted to take a minute to commemorate the occasion. It’s so much fun to hang out with all of you. As I’ve said before, this is truly a unique place on the web. The community is so friendly and smart and I learn a ton by reading through different approaches to problems and reverse engineering all the clever answers and demos. Thank you all for sharing your knowledge. A special thanks to @GreenSock and @Carl for putting up with me for 2,000 posts. Shout-out to all the other mods @Jonathan, @OSUblake, @Dipscom, @Sahil, @Rodrigo, @Shaun Gorneau, @Acccent, @Visual-Q, @mikel. You are a terrific group of people (and one A.I.) and I’m inspired by all of you. I hope my little SVG tips & tricks have helped some community members save some time and prevent a few headaches. I’m looking forward to continuing this never-ending journey of learning with the entire GreenSock community. Happy tweening. - Craig
  2. 8 points
    Nice demo!!! I was working on a SVG module for PixiJS. Resolution independence!
  3. 7 points
    Hello everyone! I've finished* working on my personal website and thought I'd share it here, both because I think it's cool and also because feedback is always welcome and useful It's built with three.js but virtually all the animations are handled with GSAP. Feel free to poke around and ask me if you want to know how I approached things. https://robin-v.net *Obviously, it'll never be *truly* finished... I'm sure I'll start finding lots of stuff that needs fixing now that I've shared it, and regardless I'd like to integrate a Grav-powered blog in the future. But, you gotta show it at some point! Cheers
  4. 7 points
    Here is simple example. Trick is to animate scaleX so element looks like it transitions out and new element comes from left and changing transform origin of your element. Also animating scale instead of width gives you far better performance.
  5. 7 points
    Ah! what your code does at the moment, if I'm not mistaken, is create a new timeline for each scroll event – and there can be hundreds or thousands of scroll events per second when the user is scrolling! I assume you don't want thousands of identical timelines First of all, you should create your timeline outside of the scroll function. Just create it anywhere and make it paused, like you're doing now. By the way, instead of what you have, you can use this: docTimeline.to(".lightLogo", 1, { y: "200%" }) .to(".text", 1, { x: "0%" }); It's exactly the same thing, just saves you some typing. Inside your timeline, use addPause() to automatically pause it at certain points. Then, when the user scrolls, use resume() to unpause it To change the direction it's playing in (depending on whether the user is scrolling up or down), you can use reversed(). That should be enough. Lastly, have a look online at the concept of throttling and debouncing, to limit the amount of events that do get handled (there's no reason to have so many per second, you can ignore most of them without anyone noticing). Here's a recent post of mine about it: https://greensock.com/forums/topic/18197-gsap-slider-over-scroll/?tab=comments#comment-83832
  6. 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.
  7. 6 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.
  8. 6 points
    One more pen for the concept. I animated the size of the parent container so you can see how it works responsively without having to resize the window.
  9. 6 points
    It's probably not a good idea to keep asking for the size of something 60/second. jQuery .width() and .height() uses stuff from this list. https://gist.github.com/paulirish/5d52fb081b3570c81e3a Maybe something like this.
  10. 6 points
    Here’s another handy little SVG technique for the GS community. I was creating some infographics for a landscaping client and needed an interesting effect for a slider so I went with parallax viewBoxes. I hooked mine to a draggable, but you could tween on button clicks too. The trick is that you’re always showing the same size viewBox for each SVG, but the start point is offset for each one. In my demo, the SVG is 12,000 x 1,000 and the viewBox for each one is 2000 x 1000. The starting viewBox for each is (5000 0 2000 1000). That centers each one on the SVGs. At the extreme left position of the draggable the viewBoxes start at (foreground:0, middle:1500, background:3000). At the extreme right position of the draggable the viewBoxes end at (foreground:12000, middle: 10500, background: 9000). The math in the drag handler will be determined by your SVG size and the draggable min/max. If you want to try this, it’s best to plan how far you’ll be allowing each layer viewBox to travel while creating your artwork so you can line things up correctly. In my demo, the artwork on the foreground at x:0 will line up with the artwork at middle x:1500 and background x:3000. Adding guides in your vector software for those boundaries makes setup a breeze. Of course, you can make this work with any size SVG and the effect can be extreme or subtle depending on your needs. Happy tweening everyone.
  11. 6 points
    Nice question. I have had similar question but never bothered too much about it because it works. I will try to explain with what I know. JavaScript runs in a single thread so it will execute all statements before rendering/updating the page. So let's say on click event you are executing a function, JavaScript will execute all the statements before rendering the layout. In following demo you can see a there is a loop that executes 10 times it executes 20 statements of TweenMax and many more that you don't see from library. In console you can see that it takes about 2-8 miliseconds to execute the loop, it can vary depending from system to system. Once all statements are executed then browser will update the layout with any changes that occurred. Now for your animation to run at 60FPS browser must update any changes every 16 milliseconds so if you are doing a lot of animations that take more than 16ms, it will start degrading the performance by dropping the frames because JavaScript is busy executing other stuff. In demo, If you change the count to something like 5000, you will see that it takes browser about 1500ms to execute the loop. If you log the performance of the page using devtools you can see that for that time browser never rendered anything so no question of seeing jumps, just horrible user experience. Interestingly, just today a video was published about whole JavaScript event loop that talks in detail how JavaScript is executed, I haven't seen the video yet but it will be worth watching. You will find a lot more videos on that channel about everything in details. An article that talks about rendering and performance in details, https://developers.google.com/web/fundamentals/performance/rendering/ Another article worth reading that talks about how different scrolling methods affect the performance https://blogs.windows.com/msedgedev/2017/03/08/scrolling-on-the-web/#lvzozB8m1fZOWgTt.97 Another thing is how animating certain properties affects the layout, for example if you animate left, top, height or width it will trigger the layout and browser will have to recalculate entire page. While animating transforms won't cause layout trigger in most browsers. On following page you will find list of browsers and what property triggers what, so you want to avoid those triggers wherever possible for better performance. https://csstriggers.com/ About how animations work, at core GSAP just calculates over time with different easing formulas and set those values on the element. So basically you can animate numbers of any object, that's why it is very easy to use GSAP to animate different libraries like Three.js, PIXI js etc. GSAP uses the requestAnimationFrame function which makes sure everything animates at constant frame rate given that you don't animate too many pixels at once. Following is simple demo of how you can ease using simple Math, But of course GSAP does a lot more than simple easing, it makes sure that your animations execute at exact duration that you set and a lot of other work to work around different browser inconsistencies.
  12. 6 points
    Here is how you can animate element as you change it's parent. You can do that by recording element's old and new position using getBoundingClientRect and then animate the difference using from tween.
  13. 6 points
    It's hard to tell from a video. If everything else is the same as the CodePen then the only difference would be that you're using local files for TweenLite and the CSS plugin. I'd try loading both from the CDN and load the CSS plugin after TweenLite. <script src='https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.4/TweenLite.min.js'></script> <script src='https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.4/plugins/CSSPlugin.min.js'></script> // or just load TweenMax which includes the CSS plugin. <script src='https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.4/TweenMax.min.js'></script> CodePen also has an option for exporting the demo. (Check the lower right for the export button.) That way you can compare the version you know is working correctly against your local to spot any differences. Hopefully that helps. Happy tweening.
  14. 6 points
    One thought that comes to mind would be using two images and reveal the cracked version with a mask or clip-path that radiates from a central point. Maybe something like this? Of course that method involves more asset prep. I don't how many images you'll have or how big they may be, but it could work if you don't have too many. The other idea would be creating some vector art for the cracked glass pattern and using DrawSVG to animate the branches. Hopefully that gives you some ideas. Happy tweening.
  15. 6 points
    Hard to tell how you can build entire website, following are some of the threads with similar ideas or animation. It is just a lot of tiny steps and then putting them all together.
  16. 6 points
    This is definitely a Chrome issue... Adding will-change: transform to either the div or the span fixes the jitter, but makes the text become very blurry when it's finished scaling. One solution (not a very convenient one) is to immediately change the font-size of the text at the start of the animation, and scale it down to make it appear as if it was still at its initial size, and figure out the transform values so that the position is the same, and then animate back to scale: 1. After that, you can remove the will-change property. But yeah, it's cumbersome, especially if you don't know exactly where the text will be beforehand. (I've cleaned up a bit, btw)
  17. 6 points
    TIL you can animate innerHTML. Makes sense, just never thought about it. Here's that in a partial function. Passing in a negative number rounds to whole numbers.
  18. 6 points
    Without a state machine, but using the same principle. Works almost exactly like the CSS.
  19. 6 points
    HI @Eeliya You should also take a look at the .shiftChildren() method. https://greensock.com/docs/TimelineMax/shiftChildren() Happy tweening.
  20. 6 points
    Hi Eeliya, That's the expected behaviour. When you add a tween to a timeline, it's not like if you added it to the end of an array of tweens; you just added it at a specific time into an animation. So if you add a tween on the 3rd second of a timeline, it will play at that moment, regardless of what's before or after it. If you would like animations to shift, then maybe such an array is the way to go. Here's an example:
  21. 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.
  22. 5 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.
  23. 5 points
    https://thebirdthebear.com/ After months of learning, and hitting walls, and throwing phones, and punching laptops, I've finally launched one of the most ambitious sites I've ever done. I learned SO much! And my Javascript skills have improved and evolved immensely. I'd love to hear your thoughts. Just about everything on this site is animated, and if it isn't text or photography, it's an SVG. If you see things that can be improved in any way, I'm open to hear about it. Special thanks to those that have responded to my posts and questions here in the forum: @OSUblake Big ups for your help with the dynamic ID thing! @Sahil, @Carl, @GreenSock You all have helped along the way too! Thanks a ton.
  24. 5 points
    Hi @gaggo With the scrollTo plugin, you can scroll to an element ID, but the snap is going to need a number. If all the elements are the same size, it would be pretty easy to use a function and snap to a value, but I'm assuming the elements won't be the same size. I think a fairly easy approach would be to loop through your elements and get their offsetTop distance and create your snap array from those values. Maybe something like this? Others may have additional suggestions, but that's the first thing that came to my mind. Happy tweening.
  25. 5 points
    Here's a quick demo you can tinker with to get some ideas. It's the weekend so it's nothing fancy. Happy tweening
  26. 5 points
    It's kinda tough to troubleshoot blind, but from what I can tell it seems like you're constantly reusing and populating the same "tl" (which I assume is a TimelineLite or TimelineMax). That's probably not a good idea, at least the way you're doing it. Remember, the playhead will keep moving forward in that timeline until it reaches the end, and then it'll stop. It looks like you're hard-coding positions where you're inserting tweens on hover/out, so what happens if the playhead is at 1.5 seconds and you insert a new tween at a time of 1? See the problem? It'll instantly set that new tween as if it was at 0.5 seconds. I'm not entirely sure what effect you're going for, but you could either: Just create your timeline initially paused (but populated with the tweens), and then on hover play() it, and on hoverOff reverse() it. Or recreate a new timeline instance each time you hover/out. Don't worry, the instances will automatically garbage collect. And GSAP is very fast, so you shouldn't have to worry about some huge cost to instantiating a new instance. If you're still having trouble, it'd be great to see a reduced test case in codepen so that we can see what's going on. Happy tweening!
  27. 5 points
    o.k. - I managed to break it in CodePen. If you remove or comment out this line in iOS, the clip-path works correctly. <base href="https://devsaver.com/"> I'm not sure why, but that is the problem child. Try it for yourself here.
  28. 5 points
    Here's a second run at this with @OSUblake's invaluable assistance moving the resize calculations into an event handler outside of the modifiers. I realized, dufus that I am, that the original had a whole bunch of extra calculations of the object's size that were unnecessary all you had to do was calculate the parent's size. So here's my revised effort for Responsive Transforms Based on Parent ( in this case the Window). Note I added in the divide by 100 in the function to allow for the tween x and y to treat 100 as 100% percent of the parent/window size. Otherwise 1 would represent 100%. It can certainly be removed to reduce the calculations if you want to work with values of 0-1 instead of 0-100.
  29. 5 points
    That's actually not a bug. And it demonstrates why we strongly recommend that you always apply transforms via GSAP instead of trying to mix CSS and GSAP... The browser always reports the calculated values as matrix() or matrix3d() which are inherently ambiguous when it comes to rotational data in particular. A scaleX(-1) results in exactly the same matrix as a scaleY(-1) rotate(180deg) or rotateY(180deg) or rotateY(-180deg) or many other options. GSAP must pick one. Your particular scenario is interpreted as scaleY:-1, rotation:180. Again, that's not a bug - it's a perfectly valid parsing of the matrix that the browser provides. If you set the value via GSAP, it always knows EXACTLY what you meant. Plus it is more performant (it can skip the parsing of the computed value on subsequent animations). More accuracy, better performance, and total reliability. It's fine if you set things in CSS if you want (to avoid an initial flash of unstyled content), but immediately set() them with GSAP too. Like: TweenMax.set(element, {scaleX:-1}); Make sense?
  30. 5 points
    Easiest way would be to change your click handler to header so your map card won't listen to click event.
  31. 5 points
    The simplest solution is probably to apply a scaleX and scaleY accordingly and set vector-effect: non-scaling-stroke on that element so that the stroke doesn't scale with it. Very little code, totally effective. If you really need to adjust all the coordinates in the path itself, here's a fork with a different technique that leverages MorphSVGPlugin's pathDataToRawBezier() functionality: I also dropped in a function at the bottom that'll take any path and spit back the transforms as a matrix array, just in case you want to essentially take the transforms and bake them into all the coordinates of a <path>. The solution I'm providing above doesn't have the limitations that the Stack Overflow one did. Good luck!
  32. 5 points
    Hello @Hugh Nivers For more on SVG export One extra tip if you want to export the WHOLE artboard with different layers etc you can export it by https://gyazo.com/e12f38bb3e754b715972acad4f4988a5 Also using Presentation attributes will save you a lot of headaches 1) 2) 3) Happy tweening
  33. 5 points
    I'm not sure I'm understanding all this completely, but it seems like you are referring to blended or additive animation. Check out the demo from @OSUblake below If you want to learn more about what he is doing there, and can afford to go down a rabbit hole for a few hours, check out the post below. I'd recommend packing a light lunch As for your performance concerns earlier, I can assure you that TweenMax.to() is not nearly as troublesome as you suspect. In fact everything is extremely optimized. I suspect GreenSock will provide some more specifics.
  34. 5 points
    Hello @Hugh Nivers and Welcome to the GreenSock Forum! What browser and browser version do you see this difference of behavior? Also keep in mind that when you run your code in codepen edit mode, that it renders inside an iframe. You would have to view your codepen in debug mode so codepen renders without being in an iframe. So in your codepen URL you would change /pen/ to /debug/ If you still see the behavior difference than you can at least narrow down your issue isnt that your code is being run through an iframe. Which can cause render and functional problems sometimes when viewing in codepen.
  35. 5 points
    My GSAP story for the day. I was integrating some found code to add a peek-a-boo menu to a site update, the kind where the menu slides away as you scroll down but slides back in as you scroll up. It used css transitions but since they did what was intended I went with it. After spending awhile getiing it all plugged into Wordpress it worked fine in Safari and Chrome but Firefox was a disaster. Failed to work half the time. When it did work content mysteriously dissapeared huge ArrRRRGH! Now i could have spent ages trying to refactor my html, or css, or try to rewrite the triggering system in javascript or spend two hours investigating firefox bugs on forums... However 5 minutes to swap out css transitions for gsap and it works like a charm. So much for css transitions/animations.
  36. 5 points
    You can check that using tl.reversed() method.
  37. 5 points
    Uh-oh! If Jack is playing then @Sahil and I get to be on the same team. We should probably grab the rest of the mods for our team too.
  38. 5 points
    Yep, all these solutions are good. Here's one more: var tl = new TimelineLite(); tl.staggerTo(".box", .6, {x:100, opacity: 1, ease: Back.easeOut}, 0.2); var children = tl.getChildren(); children.pop().duration(1.8); //last children.pop().duration(1.8); //2nd to last This is fun.
  39. 5 points
    new video above. i removed 20 seconds of dead space and a cough;)
  40. 5 points
    Great demo! I think it will be helpful to step back and just discuss how invalidate() works on a single tween. Its a tricky method that probably doesn't do exactly what you (or anyone else) expects it to do in all situations. I did a quick video for you as it was much easier than trying to type it all out. Hopefully it helps you see where invalidate() is good and where it might cause unexpected results. the TL;DR is that TweenLite.invalidate() is not really The Solution for responsive stuff
  41. 5 points
    Green is the top level tier @Sahil, not diamond... And then, inside the Green spectrum, you have other levels... Light Green, Pale Green, Vivid Green, Deep Green... Up to the Level of Green Sock - This one, is unattainable. One can only hope to achieve the mark of Sock Green.
  42. 5 points
    Hi @radutrs Welcome to the forum. That's a pretty neat website. They have quite a bit going on there and most of it is happening on canvas. From what I can tell, they are are using GSAP and three.js for most of the heavy lifting. three.js is what creates the displacement on the pictures. They've also got some Vray reflection maps in there to really make it shine. The effect that you asked about isn't too difficult. You could make it work with canvas or SVG. You might be able to do it with regular DOM elements too. I made a little demo to show one way you could do it. I've used a SVG. However you design it, the basic mechanics will be the same. You'll probably have two images and a mask. The full color image will be hidden until the end. A mask will reveal the line art version of the picture and its size can be increased by holding down the mouse button. I just made a timeline for the mask expansion animation and play/reverse it on mousedown/mouseup. Once that timeline hits 100%, the onComplete fires which fades in the full color version of the image. Here's some more info about three.js. https://threejs.org/ You can also take a look at Pixi for a canvas option. http://www.pixijs.com/ Pixi has an impressive variety of filters that can create some neat effects http://pixijs.io/pixi-filters/tools/demo/ Hopefully that gets you started. Happy tweening and welcome aboard.
  43. 5 points
    Sorry, but SplitText doesn't currently support "lines" on nested elements. However, I whipped together a utility function that should give you what you need: function nestedLinesSplit(target, vars) { var split = new SplitText(target, vars), words = (vars.type.indexOf("words") !== -1), chars = (vars.type.indexOf("chars") !== -1), insertAt = function(a, b, i) { //insert the elements of array "b" into array "a" at index "i" var l = b.length, j; for (j = 0; j < l; j++) { a.splice(i++, 0, b[j]); } return l; }, children, child, i; if (typeof(target) === "string") { target = document.querySelectorAll(target); } if (target.length > 1) { for (i = 0; i < target.length; i++) { split.lines = split.lines.concat(nestedLinesSplit(target[i], vars).lines); } return split; } //mark all the words and character <div> elements as _protected so that we can identify the non-split stuff. children = (words ? split.words : []).concat(chars ? split.chars : []); for (i = 0; i < children.length; i++) { children[i]._protect = true; } children = split.lines; for (i = 0; i < children.length; i++) { child = children[i].firstChild; //if the first child isn't protected and it's not a text node, we found a nested element that we must bust up into lines. if (!child._protect && child.nodeType !== 3) { children[i].parentNode.insertBefore(child, children[i]); children[i].parentNode.removeChild(children[i]); children.splice(i, 1); i += insertAt(children, nestedLinesSplit(child, vars).lines, i) - 1; } } return split; } Then, all you've gotta do is use that function in place of "new SplitText()", like: var mySplitText = nestedLinesSplit(assetTexts, {type:"lines"}); Does that help? Here's a fork:
  44. 5 points
    Hi @JMgreen, welcome to GreenSock You are very close ... `repeat` can be set just like `y` and `rotation` inside the vars object of the tween, in the vars object of the timeline (which will produce a different result), or with the repeat method on the timeline (which will produce the same result as the vars object of the timeline). Here are demonstrations of those options. *Note TimelineLite doesn't accept the repeat parameter ... so I used TimelineMax for that. Stagger does accept the repeat parameter, so we could place it directly on the tween within a TimelineLite. Happy Tweening!
  45. 5 points
    Ah, ok. Here is simple pen showing how to tie the progress value of a timeline to the value of an HTML5 progress element.
  46. 5 points
    Those might be guesses about how far to animate the background, which I wouldn't recommend. That is, don't guess the distance, and don't animate the background position. Animate the position using transforms i.e. x and y. Perhaps a related issue about animating clouds. Keep in mind that HTML was not designed to handle a ton of animations. Judging by some of the keywords you use like clouds, sea, ship, alps, flame, a canavs/WebGL solution might be better. You might want to check out PixiJS. http://pixijs.io/examples/#/basics/basic.js http://pixijs.io/pixi-filters/tools/demo/ https://greensock.com/docs/Plugins/PixiPlugin
  47. 5 points
  48. 5 points
    Love the demo, Craig! Your animations are not just a visual thrill but they tell wonderful stories as well. Congrats on your huge accomplishment.
  49. 5 points
  50. 5 points
    It is going to be little complex but doable. In following demo I am playing an animation by detecting which section is active and calling animation for it. Its not enough though. You will need to create an array of animations so you are able to use index and call different animations for particular section, somewhat similar concept but not exactly as in following thread. So, Step 1, determine which section is active. Step 2, call animation for that section by determining index and use that index to play animation from an array. But that's not enough to reverse animation, so Step 3, Use onReverseComplete callback to trigger the change of section. See if that helps. I won't be able to post complete demo at the moment. But I might work on something similar in couple of days so I will post a simple demo for you.