Popular Content

Showing most liked content since 12/23/2017 in Posts

  1. 8 points
    Hi alessio, Just use transformOrigin. TweenMax.fromTo('.test', 0.6, {scale: 1}, {scale: 1.1, repeat: -1, repeatDelay:0, yoyo: true, transformOrigin: 'center center'});
  2. 7 points
    Hi @Raistlin That's a nice effect. Are you asking if that website uses GSAP or just how to make something like it in general? As far as I can tell, they're using CSS transitions. This would normally fall outside the scope of GSAP support, but coincidentally I'm in the middle of creating something quite similar for some interactive infographics so I'll show you what I'm doing. I'm using SVGs in my project, but you can do it with some plain old divs too. The secret is setting the origin point for the divs so they go around the circle correctly. That website is using a pretty big parent circle (3000px) so they set the origin point of the divs to the center of that circle (1500px) and then rotate them. The fade at the top and bottom is accomplished with an additional div over the top of everything with a gradient background image that's transparent in the middle. Here's a basic example of what you could do: I'm manually setting the start rotation of each box with a set() tween, but if you had a lot of elements, you could get them to their starting positions with a loop too. To get the infinite part to work, I simply set() the rotation of each box back to the beginning as it drops down out of view. I just use a simple counter to pick which box is set back to the beginning and when the counter reaches 1, I reset it back to 6. Again, the fade-out at the top and bottom is created with a gradient div over the top of everything. There would be other ways to approach this, but this is how I'd do it. Hopefully it gives you a starting point. Happy tweening and good luck with your project.
  3. 7 points
    I'd definitely echo @GreenSock's advice and convert that to a path. I've fought with many circle animations and that is the easiest approach. (You can also convert it to a path before exporting from your vector software if you like.) I started a thread last year about SVG circle fun in the various browsers. It may be of interest to you. Happy tweening.
  4. 7 points
    Hi and welcome to the GreenSock forums. The way I normally attack this situation is using React's lifecycle methods, most specific the componentDidMount method. With that you know for sure that all the child have been rendered before making the animation. This is a sample that uses a code similar to that. Unfortunately I don't have any samples around with the specific behavior you need but hopefully you'll get the gist of it: Basically when creating each child (which in this case come as a hardcoded array, but getting the data via props shouldn't be much different) you give it a unique ref attribute to each which then you can use to loop and create the timeline or the stagger instance if you like (to create a stagger instance just reach to the array in the props and that should do it), then create the timeline and finally play it. I'll try to whip something during the afternoon that matches what you need. This is another sample but it uses a different approach, since it uses Transition Group since the elements are mounted and unmounted depending on the user interaction. It doesn't use a timeline or stagger, just a simple delay. This relies in the fact that the code is executed very fast (for larger apps you could consider server side rendering or perhaps another approach, once all the elements are rendered, perhaps pagination to render a small chunk of elements) and that the components are rendered in the sequence they exist in the app's data (again hardcoded in an array). But considering the fact that in a real app React will render all those child components at once so we can rely on that delay to create the stagger effect. Pay no attention to the code that's commented out, that's there in case someone needs to use CSS Transitions. The only catch is that the duration const used in the <Transition> component has to be the same that the one used in the GSAP instance, otherwise the component mount/unmount will be out of sync with the animation. https://codesandbox.io/s/7Lp1Q8WBA Hope this helps. Happy Tweening!!!
  5. 7 points
    Hello dear friends, Kind regards Mikel
  6. 7 points
    I think I see what the problem is - GSAP doesn't natively interpolate "vw" or "vh" units (though it likely will when 2.0.0 is released, but that won't be for a few months most likely). It can set() them directly, but interpolating is different. In this case, the inbetween values are converted to px. So here's a solution that gives you the same result but just does the conversion for you at the right time: Is that what you're after?
  7. 6 points
    Hello @DD77 You could try and use a SVG displacement map (feTurbulence). Here is an example using it with GSAP Happy Tweening!
  8. 6 points
    Hi @alessio Welcome to the forum. You just need to add transformOrigin to your tween so the element scales from the middle like this: TweenMax.fromTo('.test', 0.6, {scale: 1}, {scale: 1.1, transformOrigin:"center center", repeat: -1, yoyo: true}); More info here: https://greensock.com/docs/Plugins/CSSPlugin#transformOrigin Hopefully that helps. Happy tweening and welcome aboard.
  9. 6 points
    Sure, GSAP can do everything anime can do plus a lot more. And GSAP is faster too. It looks like the demo you provided leverages some other helper classes pretty heavily, and anime was only used for small portions. Here's a fork where I swapped in GSAP for the anime code: The structure of things seemed a bit convoluted so I may have missed something, but it appears to work just fine with my edits. Is that what you were looking for?
  10. 6 points
    Hi @ericshew I think the easiest approach would be to use the x/y attributes. Here's a fork of your pen with that possibility. That works well for circles(cx/cy) and rectangles, but you can also get the BBox of paths and loop through for those as well. We had a similar question here: Here's the demo I made as an answer to that question. Hopefully that all helps. Happy tweening.
  11. 6 points
    Hello @hanslibuzli .. Regarding the trailing pixels that you see, that @OSUblake advised about. I cant see what your code is like, but i have seen this in webkit based browser before. You could try setting -webkit-backface-visibility: hidden; to that element. That usually helps with that sort of evil. If it doesn't help you might want to create a reduced codepen demo example
  12. 6 points
    the way I understand it you need a repeating animation to happen for the entire duration of another animation and all animations need to be in the same timeline. I would suggest instead of putting the repeating animation in the timeline, just use tweenTo() to create a tween from the repeating animations start time to the end time of the other animations. Using PointC's great demo... var rain = new TimelineMax() rain.set("#stage", {xPercent:-50, yPercent:-50}); rain.set(".rain2", {y:-500}); rain.to(".rain1 , .rain2", 1.5, {y:"+=500", repeat:-1, ease:Linear.easeNone}); var box = new TimelineMax(); box.to("#box", 3, {x:600, ease:Linear.easeNone}); var main = new TimelineLite({id:"main"}); main.add(box); main.add(rain.tweenTo(box.duration()), 0) GSDevTools.create({animation:"main"}); DevTools now has a finite time and it controls one timeline which includes all the animations. Docs for TimelineMax.tweenTo()
  13. 6 points
    Hi @Annika Providing a simple demo is always the best way to get help, even if it doesn't work. You only have 1 object, demos, but you need 2 objects. The best way to go about what you're doing is to create an array of objects. You can add more animations later by adding another loop, but this should help you get started.
  14. 6 points
    Here is how I would do it.
  15. 6 points
    I'm not sure if it will help with what you're doing, but the ThrowPropsPlugin has a track() method that will allow you to track velocity. https://greensock.com/docs/Plugins/ThrowPropsPlugin Happy tweening.
  16. 6 points
    Hi @hemmoleg Welcome to the forum. I see you're using TweenLite so perhaps you didn't load the EasePack? Another thing to check is if you've put the ease in the correct place in your tween vars? Here's a simple pen with a few different eases. My pen loads TweenMax which also loads the EasePack, but if you're loading TweenLite only, you need to load the EasePack too. TweenMax loads: TweenLite TweenMax TimelineLite TimelineMax CSSPlugin AttrPlugin RoundPropsPlugin DirectionalRotationPlugin BezierPlugin EasePack If you have other questions, a demo is most helpful in getting you the best answers. Hopefully that helps. Happy tweening.
  17. 5 points
    The trigger property might be what you're looking for.
  18. 5 points
    setInterval seems unnecessary because you can listen to event directly. Even that is unnecessary because on play you are listening to tick event and updating everything. GSAP uses requestAnimationFrame so it reduces update calls to 60 per second, that will be best way to go. Also the jQuery UI slider doesn't work on touch screen plus you are not using jQuery, so I think it will be better to go with draggable. In following fork, I have removed many unnecessary calls. If you can't picture what is updating what then writing down will be helpful. But don't worry about it too much even I write unnecessary code many times, just eliminating it simplifies your code. Lastly, for any reason if you feel like you need to use setInterval/setTimeout, I will suggest to go with TweenMax.delayedCall.
  19. 5 points
    It would be great if in cases like this you could reduce your demo so that it only includes the code necessary to replicate the problem. No need for loops and multiple timelines. It just adds an additional layer of complexity. Being that every time I ran your demo it gave different results of showing different images in different places my guess is that your javascript code is running before your images are loaded and thus the engine has nothing to take a height measurement from. Try adding height attribute to your images or waiting until all the images are loaded.
  20. 5 points
    Thanks for the demo. It seems you were passing bad strings into document.getElementById() You were passing in something like "#bird" as the SectionC param in sceneHelper(sectionA, sectionB, sectionC). when you called the function sceneHelper('#section1', '#owl', '#bird'); Inside of sceneHelper() you were doing var x = document.getElementById(sectionC + i).style.fill and the sectionC + i expression was evaluating as "#bird1" or "#bird2" etc. You can't pass the # into document.getElementById(), you just want to use "bird", "horse", "lion" I've probably made the same mistake a hundred times. Without changing a bunch of code just use: var x = document.querySelector(sectionC + i).style.fill
  21. 5 points
    Demo that fixes fast clicking, Demo with swipe only. I think to take advantage of all features of draggable, it will be a lot better to create a fixed rotating cube and change the images on the fly as it rotates.
  22. 5 points
    You need to think about what the loop is doing. It's running a hit test on EVERY element, so adding a class will only remain if the last hit test you run is true. If you drag something over the first element, you'll see that your code works. The loop is running backwards, so the first element is the last one you hit test. To fix the problem, you need to stop running the loop on the first hit test that is true. You can stop a loop by using a break statement. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/break
  23. 5 points
  24. 5 points
    That is so true. I've noticed that a lot of people think GSAP is only for HTML and SVG, even from long time users. That needs to change. Somewhere on my todo list is to make some tutorials showing how to use GSAP + canvas. It's hard enough trying to find a decent canvas tutorial, let alone one that uses GSAP. To get a regular polygon to start at 12 o'clock, you just need to swap the sin and cos calls, and negate the y value. // To start at 3 o'clock var x = centerX + radius * Math.cos(angle); var y = centerY + radius * Math.sin(angle); // To start at 12 o'clock var x = centerX + radius * Math.sin(angle); var y = centerY - radius * Math.cos(angle); And to draw your particles, canvas has a new feature called Path2D that will allow you to create and combine reusable paths, so you could use the same path for all your particles. Here's a quick fork of your last demo using Path2D with the corrected angles. The formula used for a regular polygon is based on a circle, so it seems that the center of a polygon should be the same as the circle that circumscribes it, but look at what happens when the polygons has an odd number of sides. It's not symmetrical going up and down, so the top is further away from the center than the bottom. That means the center needs to be moved down a little if you want to have it perfectly centered inside a container. So we need to calculate the bounds of the polygon, find the difference between the height of the circle and the polygon, and then offset it half of the difference. And to make the shape and your animations responsive, it will be easier if we calculate the points of a polygon with a radius of 1, and then scale those points based on some desired scale/radius. That's basically how an SVG works. Check out how everything is nicely centered and responsive in this demo. I'll incorporate that in another version of your demo, which I'll have to do later as I gotta run.
  25. 5 points
    @DD77 The below example is just quick and dirty but you will get the idea: This is how you can use hover (mouseenter and mouseleave) using a timeline instead of just a tween.
  26. 5 points
    Hi @Anya You need to save a reference to a timeline if you want to check if it's active.
  27. 5 points
    Actually, this might be easier. I just modified the closestPoint function from this d3 demo. https://bl.ocks.org/mbostock/8027637
  28. 5 points
    Most questions usually get a response within a couple of hours. Maybe longer on the weekends. What you're trying to do makes more sense after looking at that site. And it looks like they are also using GSAP to animate those particles. That's a pretty advanced animation, but the basic idea is that you animate a particle along a path, and rotate the particle around its position on the path while scaling it. Easier said than done if you've never worked with canvas before. The hardest thing to understand is probably transforms, which that animation uses extensively. Here's a very quick and dirty demo showing how that animation could work. And be sure to check out that thread I posted above for some tips on getting started with canvas and GSAP.
  29. 5 points
    A complicated shape where you can drag along the x and y axis would probably require finding the closest point on a curve. http://phrogz.net/svg/closest-point-on-bezier.html That's based on this SO answer. https://stackoverflow.com/a/44993719/2760155 Definitely not an easy task. For dragging along a single axis, this thread might be of help.
  30. 5 points
    Hi @radiohead To calculate the difference between two shapes, Clipper might work better than comparing pixel data. Well, it should at least be faster, and work in IE. https://sourceforge.net/projects/jsclipper/ http://jsclipper.sourceforge.net/ If you want to take that to the next level, gesture recognition might be another possibility. $1 recognition is probably the most basic/common. http://depts.washington.edu/madlab/proj/dollar/index.html Then you have machine learning, like with Google's Quick Draw game. I think that is using Paper.js, which can also do boolean operations like Clipper. https://quickdraw.withgoogle.com/ https://github.com/googlecreativelab/quickdraw-dataset
  31. 5 points
    Hello @alessio and Welcome to the GreenSock Forum! You can find more info on transform-origin and CSS transforms here: https://developer.mozilla.org/en-US/docs/Web/CSS/transform-origin https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transforms/Using_CSS_transforms Happy Tweening
  32. 5 points
    And just an FYI if you ever want to know what GSAP has set as the x, y or any other transform related value you can log out myElement._gsTransform. You will get an object that has all of the properties shown below Object { force3D: "auto", perspective: 0, rotation: 0, rotationX: 0, rotationY: 0, scaleX: 1, scaleY: 1, scaleZ: 1, skewType: "compensated", skewX: 0, skewY: 0, svg: false, x: 100, xOffset: 0, xPercent: 0, y: 0, yOffset: 0, yPercent: 0, z: 0, zOrigin: 0 } open console to see values...
  33. 5 points
    Hi @hanslibuzli GSAP taps into the RAF ticker requestAnimationFrame() web API. But the scroll event is firing before the RAF is fired, since RAF is fired on every frame tick, whereas the scroll event is fired at a very high rate. The best way to optimize scroll performance is with RAF like your trying to do but also taking advantage of debouncing. But you might want to look into this article by Paul Lewis regarding this https://www.html5rocks.com/en/tutorials/speed/animations/ You might also want to look at throttling the scroll event. Happy Tweening!
  34. 5 points
    You and @Jonathan pretty much covered what I was going to post. Basically that SVG is downright crazy!!! I've never seen such a complicated SVG before. Graphically it doesn't look complicated, but it took Illustrator and Inkscape around 10 minutes to load it. What's weird is that you can draw it immediately to a canvas element without any problems or delays. 630kb is the file size. The size in memory will be MUCH higher than that. If your image is 3000 x 2500, and each pixel is 3 bytes... 3000 * 2500 * 3 => 22,500,000 => 22.5MB On a HiDPI display like a phone, your SVG would be even higher than that. If the device pixel ratio is 3, then the browser would be drawing your SVG at 9000 * 7500. 9000 * 7500 * 3 => 202,500,000 => 202.5MB!!! And now your phone is out of vram! You'll probably need to break your image up into smaller images, and only display what is visible with a little buffer around the edges. Pretty much the same thing that tile-based games do. https://developer.mozilla.org/en-US/docs/Games/Techniques/Tilemaps
  35. 5 points
    I believe the problem is actually caused by the fact that for <circle> elements, Apple makes the origin of the stroke at a completely different spot than all the other browsers. It has nothing to do with rotation or a bug in GSAP. It's just an annoying choice Apple made. You can resolve it by converting the <circle> to a <path> so that the coordinates are explicit about where to start. MorphSVGPlugin has a super convenient method for doing this, so all you'd need to do is add this line to the top of your JS: MorphSVGPlugin.convertToPath("#progress"); But I noticed you're not a Club GreenSock member, so you don't have access to MorphSVGPlugin. I ran the conversion for you and got this, which you can just swap in for your <circle> instead (thus you wouldn't need MorphSVGPlugin): <path class="st2" id="progress" d="M589,319 C589,468.1,468.1,589,319,589,169.9,589,49,468.1,49,319,49,169.9,169.9,49,319,49,468.1,49,589,169.9,589,319z"></path> Does that help?
  36. 5 points
    I see @OSUblake is about to respond so I'm sure he will have some great insight. As Jonathan said, that SVG is insanely complex. I saw 1500 classes defined and what looked like hundreds of gradients and paths. I tried pasting the raw html source of the svg into CodePen and my browser locked up and the fans went nuts (i suspect CodePen was choking trying to apply the syntax highlighting). I did a quick screen capture of the svg at around 1500 x 1500 and my busted up iPhone6 running iOS8 had no problem with the image of that size. Quick test using a png: https://s.codepen.io/GreenSock/debug/eyEWyw This is definitely appears to be a case of a complex SVG sucking too many resources to render and update. I wish I had better news for you.
  37. 5 points
    Mikel, Happy new year! Wish you and GreenSock community great 2018!
  38. 5 points
    Well problem is that when you animate element above target and reduce height, it offsets scrollTo's target location. So assuming you don't really need to do animation as it is not visible anyway, you can use following method so you won't see any jumps. Otherwise you will just have to constantly update target using onUpdate callback so you won't see any jumps, but still it will have some awkward behavior depending on height reduction and position of elements.
  39. 5 points
  40. 5 points
    To the members of the CommaClub, I pay you great respect and I am always fascinated by the commitment and the outstanding solutions ... Congratulations @Dipscom. May more follow ... Kind regards Mikel
  41. 4 points
    I know you were just looking for advice, but I did say it doesn't have to be working. Rather than explaining something in words, it's easier to just modify a demo. That's all. Is the search not working at all for you? I usually just do a site search on Google. site:greensock.com your search terms
  42. 4 points
    It was because you were updating canvas height n width on every frame, though I don't know why it should cause the issue. I also changed the implementation, so instead of using for loop I am using delayedCall and looping through one element at a time.
  43. 4 points
    Hello @Lovestoned and welcome to the GreenSock Forum! Just to add to the Mighty @Carl and @Sahil great advice and examples! I made some quick optimizations so when you animate it animates each slide using matrix3d() instead of matrix() for a smoother animation, by adding a slight rotation of 0.01. Since i was seeing some jank (lost frames) on windows 10 latest Firefox when animating left or right. As well as adding the CSS transform-style: preserve-3d on the .slide CSS rule elements for cross browser compatibility and preventing some browser bugs. Happy Tweening!
  44. 4 points
    I just posted my first question. Then I was browsing the forum and saw your post. I hope to be writing a post like this in 12 months. Awesome, Inspiring & Motivational. Thanks!
  45. 4 points
    Hi and welcome to the GreenSock forums, Thanks for the demo. Stuff like this where you want a bunch of different transitions on the same elements isn't always as straightforward as you might think. It can get kind of messy taking existing timelines and then trying to put them in different timelines at different times especially if you are reversing them. Once you put user interaction into the mix and let people jump to any state at any time it just gets complicated. For situations like this its probably better to create your animations on the fly. In basic terms you can create functions that create animations for animating certain elements out, and certain elements in. So you might call a function that creates your "AnimateLoadingOut" timeline and then call a function that creates your AnimateErrorIn timeline. You can glue the timelines that those functions create together into a parent timeline. Again, it isn't exactly easy to do or explain quickly. The article below is packed with information on the technique of using functions to create timelines. https://css-tricks.com/writing-smarter-animation-code/
  46. 4 points
    Here's how to make a really simple camera. Just move the world in the opposite direction your target is moving. To keep the target centered in the view, the path should be at least 1/2 a screen away from the edge of the world. I didn't do that in this demo, and you'll notice when the bee gets close to the edge of world because it has to move away from the center of the screen.
  47. 4 points
    Hi, To be honest, I just wanted to try different easings and a countdown. But with a little story it was really funny ... Kind regards Mikel By the way: GSDevTools is very helpful. I noticed, however, that in reverse, the centering of the object (pathDataToBezier) is not interpreted expected. Is that due to my coding?
  48. 4 points
    Why does it reminds me of somebody here with a moustache?
  49. 4 points
    I used to animate position based attributes, like x/y on rects and cx/cy on circles, but then I started noticing problems if you also animate other transforms on the same element. I haven't brought the issue up with @GreenSock before, but I'm guessing it's causing problems with the way GSAP calculates origins. It all depends on the order and when they are applied, but changing a position/size based attribute causes the bounding box to change, which GSAP might not be aware of. So it might be better to use getBBox, and animating transform based x/y just to be safe. Another reason is that there can be a performance advantage in certain browsers when animating a transform over an attribute. For what you're doing, you don't need to set an origin. svgOrigin is just like transformOrigin. It's defines the point/anchor that an element will scale from and rotate around. It has nothing to do with translation, i.e. animating x and y. The difference between the two is where the origin is relative to. For svgOrigin, it's relative to the svg element, and for transformOrigin, it's relative to the element. This is a very simple problem. All you have to do is get the center of 2 bounding boxes, and then subtract the difference.
  50. 4 points
    BTW, there is only 1 box variable, and it's not copying the object. You can copy the value of a primitive (string, number, boolean, null, undefined, symbol). // Copies value var foo = "eggs"; var bar = foo; foo = "ham"; console.log(foo); // "ham" console.log(bar); // "eggs" For everything else, it's not that straightforward. Try searching for pass by value and by reference as it can be hard to explain. Variables do not store the value of an object, they just hold a reference to an object's location in memory, kind of like a home address. And just like your home address, it can be passed around and be used by more than 1 person. Notice how alpha and bravo appear to have the same value, but they are not equal. On the other hand, alpha and charlie are equal even though I changed the value of the msg property. That's because they are pointing to the same object. var alpha = { msg: "Hello World!" }; var bravo = { msg: "Hello World!" }; console.log(alpha === bravo); // false // Copies reference var charlie = alpha; charlie.msg = 123; console.log(alpha === charlie); // true console.log(alpha.msg); // 123 console.log(charlie.msg); // 123 And about there only being 1 box variable, that's because of something called hoisting. There is no difference between these two loops. All var declarations are moved to the top of their scope by the JavaScript compiler, so the first loop will end up looking just like the second loop. for (var i = 0; i < 2; i++) { var box = boxes[i]; } var box; for (var i = 0; i < 2; i++) { box = boxes[i]; } That's why this crazy looking code is totally valid. The num variable gets moved to the top. num = 8; num += 4; var num; console.log(num); // => 12