Jump to content
Search Community

Leaderboard

Popular Content

Showing content with the highest reputation on 03/16/2018 in all areas

  1. Hi Tomsah and welcome to the GreenSock forums. The issue here lies in the fact that you're creating a new instance of the timeline each time you click on the toggle button. The real kicker is that, since the timeline is on a global scope, everytime the slideMenu method is called, GSAP says: "ok, so your calling a method that adds this instances to the timeline and since you're not specifying where you want them, I'll add them to the end". So everytime you click on the toggle button the timeline gets longer and longer and longer and longer and... you see where this is going right?? React has components lifecycle methods to help with this. You can create the timeline just once in the componentDidMount method and the timeline will be created and you can be sure that your elements are in the DOM when it happens. Just remove the call to slide menu in the toggle button click handler and add the component did mount call in your component: // add component did mount to the class componentDidMount(){ this.slideMenu(); } // remove the slide menu call in the toggle click handler toggleMenu = (e) => { e.preventDefault(); menuTl.reversed() ? menuTl.play() : menuTl.reverse(); this.setState({ menuActive: !this.state.menuActive }) } On a related note, the more purist React developers will consider using selectors like this a big NO-NO: var projects = document.getElementsByClassName('project'); React is all about doing things in a declarative way, so for getting dom nodes the so called "React way" is to use refs which in some cases can be really painful, specially if you're working with components that you didn't wrote, which makes generating and accessing the refs a bit tricky. I've been using React with GSAP for some time now and this is just my opinion, but in the case of elements that are permanently rendered on the DOM and are always there, there's no issue in doing it like you did. If that's no the case, the one thing you have to keep in mind is if a state or props change could un-mount the component being animated or elements contained in that component that could be animated, because the component could be unmounted and the GSAP instance could be still be active and you'll get an error. In that case you can use componentWillUnmount to kill the animation and prevent an error. Happy tweening!!
    5 points
  2. You can simply put repeat: -1 on the single tween within the timeline. If you want them to do something slightly different you could add a new tween to the end with new property values and repeat that one.
    4 points
  3. Hi @Zaperela Welcome to the forum. The reason your demo wasn't (kinda sorta) working was the onComplete was in the wrong spot and being called three times. It is a bit confusing, but for stagger tweens the onCompleteAll goes after the stagger number. So what you were seeing was the infinite circle repeat timeline starting before it should have which caused an overwrite. More info in the stagger docs: https://greensock.com/docs/TweenMax/static.staggerFrom() In addition to @Shaun Gorneau's demo or moving that onComplete call on the stagger, you could also move the onComplete to the vars of the cs timeline. Lots of options. Hopefully that helps. Happy tweening and welcome aboard.
    3 points
  4. @GreenSock - all joking aside, even after hanging around here for a few years, I'm still always impressed with the speed of improvements and bug fixes. I think that's one of those things people don't necessarily appreciate until they have a request or spot a little bug. We can all joke and whine about big companies like Adobe or Microsoft and trying to get their attention on something, but at GreenSock things get done quickly. It doesn't matter if it's a Club GreenSock Member or not, the request is given the same weight. Truly remarkable.
    3 points
  5. Hey Beau, I understand the frustration. The reality of things is that React works in a declarative way and the discourage to use string refs and find dom node has mostly to do with some specific issues and some excessively paternal approach by the React team. The paternal issue comes from the fact that the deprecation of string refs has to do with some edge cases and because of a few things that could go wrong the entire API is changed for everyone. Take GSAP for example, Jack does His best to ensure that GSAP serves as many scenarios as possible but never compromises performance, file size nor legacy support, and when those changes do come, believe me there is a lot of questions and samples going around before the decision is made. But that's how GSAP works and perhaps we've been a little spoiled by that, but that's how serious Jack and Carl are about how this works. IMHO there's nothing wrong with using string refs and fond dome node if you know what you're doing. At some point developers have to take responsibility for the code they write and not expect that the frameworks make all kind of loops and hoops to ensure that every blunder is supported. As I mentioned in another post yesterday this is some very specific issue, because you have to take in consideration the lifecycle of your app and it's components in order to make the best decision. There are some cases that you can safely reference the elements using the classic get element by id if, when you create the variable you're sure that the DOM node will be rendered in the app. In other cases if you're not sure is better to use refs. This simple codepen goes into the detail of how refs are accepted today: In the console you'll find an array with all the rendered elements that can be used with GSAP. This is the so called "React way" for referencing DOM nodes. Now the pain comes when you're using a third party component that doesn't expose the DOM node, like this case: import ThirdParty from "third-party"; const elements = ["label-1", "label-2", "label-3", "label-4"]; class MyApp extends Component{ constructor(){ super(); this.elements = []; } render(){ return <div> { elements.map( e => { <ThirdParty key={e} ref={ node => this.elements.push(node) } /> }) } </div>; } } In this case the array will have a collection of the four React components being rendered and not the nodes being added to the DOM. In this case find dom node comes in handy because it allows to reference the actual element in the screen. If the plan is indeed remove find dome node from ReactDOM then things will get more complicated, because developers will have to bake their own version of this component in order to expose the ref to the DOM node or the developers of third party components will have to come up with some way to find those references. One of the simple ways to do this could be for components to accept an id property in order to later reference that and get access to the DOM node. Finally don't get discouraged from using GSAP with React, there are ways to use it and the more is being used, the React team will become aware that to create complex animations and rich environments GSAP is the way to go and they'll have to come with some way to actually gain access to the dom elements. Right now we have to keep using this type of approaches with the hope that things will change and become simpler in the future. Also keep in mind that the article you mention was written when React was in version 15 and string refs and find dom node were not deprecated and that wasn't a long time ago, unfortunately this world moves way to fast and doesn't wait for anyone... Happy Tweening!!!
    3 points
  6. Aha! Found it. It was related to some code in ModifiersPlugin that'd run on the first render for each target instead of just once for the tween, thus if your tween had 500 targets (in one tween), it'd run 499 too many times at the very start, and set up some tasks to do during the tween as well. That's what led to all the extra CPU load when you were animating a bunch of stuff in one tween. This only affected ModifiersPlugin. Very glad you caught the performance difference, Sahil. It helped me identify and fix that issue. I updated that file on codepen, so you should be good-to-go after a cache refresh. Sorry about the confusion.
    3 points
  7. Slight clarification for anyone following along. I don't want to confuse anyone. On a regular tween the onCompleteAll goes after the stagger number. TweenMax.staggerFrom( targets:Array, duration:Number, vars:Object, stagger:Number, onCompleteAll:Function, onCompleteAllParams:Array, onCompleteAllScope:* ) For a timeline, the onCompleteAll goes after the stagger and position: .staggerFrom( targets:Array, duration:Number, vars:Object, stagger:Number, position:*, onCompleteAll:Function, onCompleteAllParams:Array, onCompleteScope:* ) Happy tweening.
    2 points
  8. Great note, Craig. Its worth repeating that all the hard work that you and the other moderators and contributors do makes it possible for Jack to improve the codebase. Its amazing that we have such great people around that go above and beyond.
    2 points
  9. Shaun, thank You so much! Didn't thought about this. You helped me a lot! Thanks
    2 points
  10. Try this .. I'm animating the the x property (vs css: { transform: 'translateX'}) and the rotation property (again, vs css:{ transform: 'rotate'}) and it seems to have much better results.
    2 points
  11. Thanks for sharing Shaun! Wanted to post that interview just now, good job Mine usage is pretty typical, so nothing special - just wanted to say huge THANKS, Jack, for starting this! P.S Always had the same problem with math, still, have - I prefer to watch it move
    2 points
  12. It's a little tricky because the current version isn't really built in ES6 modules, thus "gsap" actually points at TweenMax (which contains a bunch of stuff including TweenLite). If you really just want to import TweenLite, do so directly like: import TweenLite from "gsap/TweenLite"; But remember that if you're trying to animate anything DOM-related (typically CSS), you'll need to also load CSSPlugin ("gsap/CSSPlugin"). Also, the size you're seeing is probably uncompressed. TweenMax is under 40k minified and gzipped. Feel free to load it from a CDN instead of bundling it in your JS payload. That's a very popular option.
    2 points
  13. LOL --Great! I had a minor seizure... But I love it! This is kind of what I'm interested in doing. Thx so much for the help.
    2 points
  14. Yeah, that guy is obviously a total hack. What a slacker. I'll definitely have a chat with him and make him do 50 extra pushups.
    2 points
  15. Ha. I'm just glad you didn't make more improvements to my flicker version. I really like the changes you made to my first demo, but I was afraid we were getting into some kind of Zoolander style walk-off demo battle.
    2 points
  16. nice one craig. I deeply regret my lack of gif
    2 points
  17. And we enter in a new room in this dungeon of discovery... Although the initial battle with the loader has not gone as hoped, the one against the slider has not been too bad. Here is something I managed to whip up from this big project I am working on: The original one is a carousel - I am striping some bits out from it to make it simpler. Again, when I get some downtime I will work a bit more on this and report back. Same with the loader... I will eventually have to build an asset loader for the site anyway so, I'll adapt it to a more generic setup and post it here. We'll get there, folks!
    2 points
  18. So, last night I was listening to Jack's awesome interview with egghead.io (https://itunes.apple.com/us/podcast/egghead-io-instructor-chats/id1308497805#) and he started talking about all the unexpected uses of GSAP, and it got me thinking; what have I used GSAP for? And I realized the range is from pretty typical to not so typical! My line of work is for a few large clients. So I've used GSAP on many projects; some externally facing (marketing sites) ... some for "exclusive" groups (targeted marketing), and many internally facing (for very specific groups ... members and employees). So, for the typical stuff, it's Immersive content UI indicators and helpers UX sauce For the not so typical, it get's pretty varied pretty quick! But the one project that sticks out the most is GSAP as the heart of a frontend delivery system (backed by Drupal) that drives a community cable channel for a gated resort community in GA. The Drupal side allows content managers to create and place 3 types of media; image slideshows, video, and embedded (iframed) HTML. They have control over timings and transitions which map out to GSAP, background audio playlists and ducking (the ducking is tweened with GSAP ), and asset publish/unpublish dates. For the embedded HTML ... they are calling in external sites which are slideshows, but managed by another group for another purpose; a real estate listings slideshow of active properties within the community that is displayed on a large screen in their sales office which is ... you guessed it ... GSAP! It cycles through 280 properties (+/- a few) daily; transitioning in a property image, then a delayed detail and pricing overlay slides over a portion of the image. But back to the cable channel ... every asset and configuration managed on the Drupal side is fed through custom template files that generate all the GSAP Timelines and Tweens. It has been running for years and is rock solid! So, my not so typical uses are cable channel programming (in the sense of delivering programmed content), digital kiosks, and digital signage. So, I'm curious ... what have others used GSAP for that might be a little outside the norm?! Edit: I changed the title from "What have you done with GreenSock?" to "How have you used GreenSock?" Upon reading it back some time later ... it occured to me that the title could be implying that something is wrong with GreenSock Of course there isn't!
    1 point
  19. Of course I had to listen to the interview right away. So great to hear your story Jack and how you got this all going. I guess the most interesting thing I've done with GSAP so far is a single page microsite that runs as a full window design and uses GSAP to deliver everything to the viewer kind of like an app or a presentation instead of scrolling through content. Nothing revolutionary there many others have done similar but I can say that without GSAP I probably never would have had the confidence to attempt it.
    1 point
  20. Awesome! Thanks, Shaun! *Digital High Five* I was totally over thinking it. Working how I was hoping by just adding staggerTo to the end of the timeline and adding repeat: -1.
    1 point
  21. Hi @Mheetu Welcome to the GreenSock forum. What's happening is you're tweening to a label which isn't really the mouth pose you want. For example, you click 'frown' and then move the playhead to the 'frown' label. But that label is actually at the beginning of the timeline so you go past the frown pose and back to the neutral pose because that's what the mouth is doing at the beginning of the timeline. You could make some label changes and make this work, but in this case I'm not sure a master timeline would be the best choice. What I mean by that is what if you had 10 mouth positions and you were on position 10, but wanted to tween to position 1? You'd see all the poses as you tweened the playhead back to pose 1. See what I mean? I think just tweening in the button handling functions would be easier. Something like this: Hopefully that helps. Happy tweening and welcome aboard.
    1 point
  22. I tried forever tinkering with DRAWSvg. Thank you so much!
    1 point
  23. Hi @alfianridwan, no problem at all. I'll break down a few things that are happening here ... First and foremost ... I'm using jQuery to make some tasks much easier. If you're new to JS, you may or may not know the ins and outs of cross-browser compatibility. In short ... jQuery fights that battle for us. So your questions and my answers are addressing jQuery $('document').ready( function(){ Is just waiting for the DOM to be ready before we do anything. $('.blog-card img').each( function(){ So .each() is a jQuery method that allows us to iterate over the matched set ... in this case, all elements returned with the selector ".blog-card img". So what happens here is the DOM is scoured for all <img> within elements with the class ".blog-card". Now that that images are returned as a set, jQuery's .each() will iterate over each one to perform all the actions with the .each(){ }. In plain english, here is what is happening within that, Find the <img>'s nearest (up the DOM tree) enclosing element with the class "blog-card". This is the card that the image belongs to. Within that card, inject an element before all its children ... a new div using the current <img>'s (i.e. the <img> currently being referenced as we iterate with .each() ) src as the css background-image move the <h2> within the card to now be a child element of the new <div class="blog-card-background"> Add in a new div to represent the "close" X in the top of the expanded card. remove the <img> from this card (we no longer need it) Now, for the why to all the above We do this just to make a simple reference rather than asking jQuery to look up the tree many times. In this particular case, the hit is negligible. But it's good practice that if you are going to ask for something multiple times ... simply create a variable to hold it. For me, positioning and animating a div with a background image applied is much easier than positioning and animating the <img> itself. For example ... applying an image as a background with background-size: cover and background-position: 50% 50% tackles so many issues on its own when dealing with responsive images! Because the new <div class="blog-card-background"> is positioned relatively, it allows us to stick the (now) absolutely positioned <h2> to the bottom of the image (with padding) by using the CSS bottom property without any concern for how many lines the <h2> may be. We have to be able to close it! No use in keeping it in the DOM ... we are now using that image as a background for the <div class="blog-card-background"> You'll notice we did a lot of manipulation at this point with jQuery. But why? Why not just do all of this in the markup? Well, for several reasons. If javascript isn't available (or some other script causes it to fail), we want the user to have something that a. looks approriate and functions as expected (i.e. click a blog card and navigate go through to that blog post as a new web page) b. doesn't present interface elements that perform no action My basic rule ... if Javascript is required to interact, then Javascript is responsible for creating the element. So make sure it's usable without JS. $('#some-blog').on( 'click', '.blog-card.inactive', fucntion(){ ... This one is a bit nuanced, but I'll explain here. We want things to happen when something is clicked. Someting "A" when clicked in a "card" state and something "B" to happen when clicked in an open state. Now, I could have simply used ... $('.blog-card.inactive').click( function(){ ... Buuuuut, that does something a bit unexpected. A unique click handler get's bound to each matching element from that point forward .. regardless of losing the "inactive" class down the road. You might say, "that's OK, we're using a different element to close the open state.". And that's true ... but, clicking anywhere else anywhere within, in this example, the open blog post would still cause this handler to fire. We could do some detection to remove this handler while in an open state and rebind after. But it's so much easier to do $('someSharedParentElement').on( 'click' , 'target', function(){ ... because it creates a single handler for all matching elements AND allows the handler to be bound to dynamically created elements down the road! Think of a blog with infinite scroll, for example. And, when the "blog-card" has its class changed from "inactive" to "active", this event handler is no longer bound. When it goes back to "inactive" it is bound Noice!
    1 point
  24. I can't give you an exact date, but hopefully within 2-4 weeks I'd say. Got a few other things I want to do to the codebase first. You're welcome to use the beta version in the meantime.
    1 point
  25. @rodrigo Really, really helpful and interesting. The second example was j-u-u-st above my head without working through the code. But it's great motivation for me to skip out of work & start my weekend early Many thanks again for the helpful advice.!
    1 point
  26. I may be way off base here .. but couldn't you simply use a screen capture tool to record the animation to MP4?
    1 point
  27. Hi Unfortunately I ran out of time to get a proper answer, I'll get back to it later tonight. In the mean time take a look at this: https://reactjs.org/docs/refs-and-the-dom.html This: And this: Hopefully this is enough for now. Happy Tweening!!
    1 point
  28. I'm trying to pick this all apart ... there is a lot going on in the question, and even more going on in the code pen. Upfront confession ... I don't use React for anything. So my understanding of the question maybe because of that. I think the question is ... "With React, how do I target and tween specific set of DOM elements using GSAP?" Is that the question?
    1 point
  29. No need for extra pushups now, beta version performs slightly(by a frame or two) better than stable version. Thanks Jack.
    1 point
  30. @Rodrigo Thank you so much for the fast answer, it is making sense to me. I will try to implement your solution and get back to you with the result a bit later today. Happy tweening
    1 point
  31. You should probably have a chat with the guy that wrote the code for that ModifiersPlugin.
    1 point
  32. Had a bit of time this afternoon ... here is a quick crack at it. A few notes ... the HTML, CSS, and JS are setup to support progressive enhancement. If JS isn't available, you'd simply get a tile with a background image and an overlaid title. Clicking would push through the the target URL. jQuery does some restructuring to get better control from both a CSS and a Tweening perspective. I'm also using jQuery to handle the simple click events. I'm sure adjusting some timings (or even tween orders) would produce a better result ... I haven't gotten there yet Big note ... I wouldn't look it here in the embedded CodePen ... I would go out and view it in a narrower viewport.
    1 point
  33. This is great, Shaun! Thanks for starting the conversation and sharing some of the more unconventional uses you've found for GSAP. Hopefully others will weigh in as well. And thanks for listening to the interview. It was a fun one to do.
    1 point
  34. You know, this is something I've been thinking about doing ever since the App Store update ... I think it would be a great blog navigation element You've pushed me to do it I'll let you know how it goes!
    1 point
  35. Hi again @determin1st .. #1 We are helping you... #2 GSAP is already popular and does rule forever This isn't a GSAP algorithm thing . GSAP can only use what CSS property values are reported and computed by the browser, based on how you have your HTML and CSS setup. Like i said above this has to do with the CSS Spec on how height is calculated with box-sizing. As well as how the CSS box-model works. That is the nature of CSS, animating padding will affect height of its parent regardless if box-sizing is used or not Animating anything but transforms and opacity will cause jank (lost frames). Transforms and opacity do not cause a repaint and layout to be recalculated on every render tick frame. Transforms are also better for interface object, since they can animate on a sub-pixel level for silky smooth motion. Whereas padding and other non transform and opacity properties can only animate on a pixel level. And non transform or opacity CSS properties cant take advantage of hardware acceleration (the GPU) for smoother animation. You could take advantage of using transform scale instead of padding. We can only offer advise and solutions, but in the end its up to you. Happy Tweening!
    1 point
  36. It's not really a GSAP problem, when you animate elements using className, GSAP animates whatever the difference those class create. In your case, you have box-sizing as border-box, which when you change padding causes the height to change. So in order to animate class GSAP MUST animate height, which gives your parent element inline height. So when your child element animates, parent element has it's own height instead of auto height, so it won't animate along with the child element. When animation completes, GSAP like usual will remove inline styles set while animating class which causes the jump. If you put together many such different classes that affect each other or parent and child in MANY different ways then you will see such weird behavior and GSAP can't put logic in the place to address such out of control situations. What you can do is, 1. force height auto by using !important 2. First change padding of parent element and only then animate height of child element. 3. Manually animate height of parent and when animation completes, set height back to auto. 4. Use content box as @Jonathan suggested and as you are using flexbox you don't need to set width 100%, element will set itself to 100% inside the parent.
    1 point
  37. This isn't nearly as easy as it may seem due to a lot of performance optimizations and the flow of code. I'll look into it more though and see if there's a way I can do it efficiently, but no promises. I can do that copying of "scale" to "scaleX"/"scaleY" in the next release pretty easily, though, so that should resolve your issue @kreativzirkel. In the mean time, though, here's a way to use a simple function to reduce that code sample you provided: function scaleVars(vars) { vars.scaleX = vars.scaleY = vars.scale; delete vars.scale; return vars; } var tl = new TimelineMax() .from(".elem1", 1, { scale: 0, xPercent: 100, modifiers: scaleVars({ scale: function(value, target) { // some logic return newValue; }, xPercent: function(value, target) { // some logic return newValue; }) } }) .from(".elem2", 1, { scale: 0, xPercent: 100, modifiers: scaleVars({ scale: function(value, target) { // some logic return newValue; }, xPercent: function(value, target) { // some logic return newValue; }) } }) .from(".elem3", 1, { scale: 0, xPercent: 100, modifiers: scaleVars({ scale: function(value, target) { // some logic return newValue; }, xPercent: function(value, target) { // some logic return newValue; }) } }) .from(".elem4", 1, { scale: 0, xPercent: 100, modifiers: scaleVars({ scale: function(value, target) { // some logic return newValue; }, xPercent: function(value, target) { // some logic return newValue; }) } }) .from(".elem5", 1, { scale: 0, xPercent: 100, modifiers: scaleVars({ scale: function(value, target) { // some logic return newValue; }, xPercent: function(value, target) { // some logic return newValue; }) } }); Does that help?
    1 point
  38. ? naming my first kid after you. thank you!
    1 point
  39. You're a good man @Dipscom. May these brownie points motivate and nourish you on your noble quest. Safe travels my friend.
    1 point
  40. And for some cool fluid shader type stuff, check out all the links on these slides. You might find just what you're looking for in one of those. http://cake23.de/1c2/
    1 point
  41. Have you ever checked out Christmas Experiments? http://christmasexperiments.com/experiments Most of the stuff on there uses PixiJS or Three.js. Same with Chrome Experiments. https://experiments.withgoogle.com/chrome And of course the gallery page for each library. https://threejs.org http://www.pixijs.com/gallery And Twitter https://twitter.com/search?q=%23pixijs&src=typd https://twitter.com/search?q=%23threejs&src=tyah
    1 point
  42. It seems you have your work cut out for you with this one. I think your best bet is to explore the various Three.js demos on CodePen as there are many: https://codepen.io/search?q=three.js&limit=all&depth=everything&show_forks=false GSAP will run super fast with any of the top canvas-rendering libraries like Three.js or Pixi.js. When you start getting into collision detection and responding to mouse movement, most people would probably look for a physics library that would handle how elements react to walls, gravity, wind, resistance etc. A tweening engine like GSAP is much better suited for animations that have pre-determined start and end values, or that need precise sequencing with full playback controls (play, pause, reverse, speed up, slow down, etc). With the right amount ingenuity and the ModifiersPlugin you can get a GSAP tween to do pretty much whatever you want. Check out the demo from @OSUblake below Also check out the rest of the demos in his ModifiersPlugin collection as they show some very interesting (and somewhat unconventional) uses of GSAP to generate highly dynamic animations: https://codepen.io/collection/AWxOyk/
    1 point
  43. Hello IHeartGsap, Welcome to the GreenSock Forums. Here is a list of animatable CSS properties : https://developer.mo...ated_properties Here is another list of CSS properties that are animatable: http://oli.jp/2010/css-animatable-properties/ Keep in mind that GSAP can animate any object property, and even some CSS properties not in the list. Also that this list can change depending on if the specs change, and browser features are updated. Best to just use the above lists as a guideline, and test, test, test away!
    1 point
×
×
  • Create New...