Jump to content
Search Community

Leaderboard

Popular Content

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

  1. 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.
    6 points
  2. 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?
    5 points
  3. 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.
    5 points
  4. 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.
    4 points
  5. @PointC link about animating an explosion from the center made me remember showing how to do something similar. You can create some pretty interesting effects with very little code.
    4 points
  6. 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.
    4 points
  7. @Tebbott Your SVG is like 4.64mb. That is a very huge asset to be pulling in the page via an <img> tag. You might have to mess with the SVG viewport attribute, to reduce the perceived size to the browser to render. But again that is a HUGE SVG that your pulling in the page with many assets inside that SVG. iOS has a very limited memory to render your asset based on the memory usage for iOS devices. Android probably has very different memory requirement than iOS. It seems to be since your using an SVG instead of an actual image via the <img> tag. You should or could convert to an actual image, and you wont see that type of behavior in iOS, but still even a 4.64 image would do the same thing. Maybe slightly better but still, that is a lot of memory your asking to render and load. The 2-3 seconds to respond due to the high memory it takes to render the SVG when delivered in a <img> tag. See the following which goes over the spec regarding memory usage for SVG and limits in iOS devices. https://developer.apple.com/library/ios/documentation/AppleApplications/Reference/SafariWebContent/CreatingContentforSafarioniPhone/CreatingContentforSafarioniPhone.html That limit is probably why even the SVG inside the <img> tag has that hesitation to load that huge SVG file, since it could be treated like a bitmap. But even if it isn't, that is way too big for memory usage in iOS.
    3 points
  8. 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!!!
    3 points
  9. @PointC, @OSUblake, @Carl, @lennco Having spent sometime exploring your various suggestions I have realised I was approaching the problem from the wrong angle. The answer has been to not try to integrate Greensock tweening WITH / INTO Babylon.js renderloops but to use Greensock tweening for all the diving animation and using timeScale to stop and start the dive as needed. I feared a Greensock tween would not allow other Babylon.js operations while it was being executed but this proved not to be the case. So with your help, the problem is solved. Again many thanks. Richard C
    2 points
  10. 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 4 bytes... 3000 * 2500 * 4 => 30,000,000 => 30MB 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 * 4 => 270,000,000 => 270MB!!! 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
    2 points
  11. Thanks for the demo. I vaguely recall something like this coming up in the past. I'm foggy on the details, but if you use 90.5 it seems to work: .set('#progress', { rotation: -90.5, transformOrigin: 'center center', drawSVG: 0 }, 0) I'll ask around and see if I can find a good answer or a real fix for you.
    2 points
  12. Hello @Tebbott Thank you for reducing your example so we can see it. There will be differences between Android and iOS since both use different ports of webkit. So even though they both use webkit they have modified their own version of webkit to suit the needs of their different browsers (chrome and safari). That will mean that the CSS and JS can behave differently with various quirks and bugs.. or even different requirements to animate using transforms You might want to look at making it so the cars only animate when inside the viewport. That will cut down on the constant frame rate of animating elements that are not even in the viewport to be seen. So one way is to use vanilla JS and have a function that detects the viewport bounds like in this stackoverflow post https://stackoverflow.com/a/7557433/1203457 Or you can try and use the Intersection Observer API to detect the viewport bounds https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API https://pawelgrzybek.com/the-intersection-observer-api-explained/ Then you can simply pause() and play() your animation depending if your elements are in the viewport. Other than you might want to fork (copy) the codepen example you made and add a couple of the cars animating so we can see them animate in context to offer advice on how to optimize those tweens and or timelines. Thanks
    2 points
  13. You will need TweenLite, TimelineLite and CSSPlugin.
    2 points
  14. You can do that by returning instance of timeline like in following demo, notice that it returns paused timeline. If you click the play button, animation only runs once. In your example every time you go to the section, you are calling function which triggers creation of new timeline and that plays by default. In my demo, you create only one instance and because your timeline's already becomes '1' on completion, the subsequent clicks don't trigger any animation. does that help?
    2 points
  15. @Rodrigo Thanks for the guidance, I managed to get it working. Here's the pen, just in case anyone needs it.
    2 points
  16. 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()
    2 points
  17. hmm, it seems your demo doesn't have GSDevTools controlling the animation at all. Please zip your fla and attach it here (without GSDevTools). The more you can simplify your file by removing unneccesary tweens and assets the better. If you can replicate the blink with 2 tweens that would be great.
    1 point
  18. Hey, Thanks for the quick replies The answers from both @Carl aswell as @GreenSock solved it! @GreenSock, thanks for the clear explanation and for converting that piece of svg. Our company has an Club GreenSock account but I rather use my personal account on the forum so I will keep that plugin in mind! @PointC, I 'll give it a read.
    1 point
  19. Hi @HindBeast, I am not sure ... But something like this could look like a solution: Happy tweening! Mikel
    1 point
  20. You will have to post a codepen demo with code limited to demonstrate your problem. Also, there are some articles and video tutorials that you can watch which might help you figure out all the basics of GSAP. https://greensock.com/get-started-js https://css-tricks.com/writing-smarter-animation-code/ And please don't edit your posts to something entirely different after my responses it will just confuse anybody else reading the thread.
    1 point
  21. Oh, one problem I see right away is that you're loading a very old version of GSAP. GSDevTools requires 1.20.3 or later. Please update and then if you're still having trouble, let us know.
    1 point
  22. Of course a 4.6MB SVG is too large! I'm a @£$%ing idiot. Having said that, I've just switched the SVG out for a JPG that's 630kb, and the map is still slow to respond. I've removed all animated elements from the mobile version of the site, so it's now simply a JPG background, with some links placed on top. The strange thing is, moving your finger across the map leads to short, sharp burst of movement after 1-2 seconds, however, if you leave your finger pressed for 1-2 seconds, and then drag the map, the map starts to respond and you can move the map around smoothly. I'll continue looking into this - I don't want to waste any more of your time - you've all been a real great help!
    1 point
  23. Wow. Thanks very much. I've gone over your solution multiple times now and I'm finally beginning to understand it. Your code is always so concise and clean. I really appreciate the clarification. Thanks!
    1 point
  24. Hey Sahil i added two lines of code document.getElementById('btn').addEventListener('click', function(){ clear = Math.ceil(tl.time()); tl.time(clear) //added tl.clear() //added }); so now it finishes the frame first and then clears thank you
    1 point
  25. I'm a little unclear about the last part How can i wait till the current animation has finished and then restart/clear? Are you saying that if the user clicks the button 5 seconds into a 20 second long animation they should watch the animation play for 15 more seconds before it restarts? If yes, assigning an onComplete callback dynamically (on click) to the timeline might work. timeline.eventCallback("onComplete", resetTimeline); https://greensock.com/docs/TimelineLite/eventCallback for complex scenarios like this its very helpful to provide a reduced demo that clearly illustrates the issue. I'm sure with some clarification, we can help figure this out.
    1 point
  26. 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
    1 point
  27. Hi @hanslibuzli GSAP uses a ticker, which is one continuous rAF loop that drives every animation. You can tap into it, which is nice for situations when you need to constantly update something, like a canvas animation. The ticker will power down when there are no active animations or listeners. https://greensock.com/docs/TweenLite/static.ticker You could actually use GSAP's ticker instead of calling requestAnimationFrame. It actually might be better because it will be synced with GSAP's update cycle, it just requires a little more code. var running = false; page.addEventListener("mousemove", function(event) { if (!running) { TweenLite.ticker.addEventListener("tick", onMove); running = true; } }); function onMove() { ... TweenLite.ticker.removeEventListener("tick", onMove); running = false; } About the artifacts in Safari... wow! Scaling can cause all sorts or weird rendering bugs. I'm not around a Safari browser at the moment, but have you tried setting will-change: transform in your CSS? @Jonathan is probably the best person to ask about what is going on. Perhaps he can chime in and offer some suggestions. He seems to always know some weird CSS hack to fix every rendering problem.
    1 point
  28. Hello @multivac and welcome to the GreenSock Forum! Just to add my two cents.. if you were to use a timeline to repeat a background, then you should do it the GSAP way. This is done by creating a master timeline and adding child timelines via functions being returned with the add() method. And here is a helpful video by the Mighty @Carl explaining this technique in a video tut... Revolutionize your animation workflow: Part 1: Revolutionize your animation workflow: Part 2: Happy Tweening!
    1 point
  29. HAPPY NEW YEAR GREENSOCK COMMUNITY.. May GreenSock be more prosperous in 2018 (sorry for the all CAPS.. im really not shouting at you all)
    1 point
  30. Unfortunately, you can't perform 3D animations on svg so it only supports rotation. Other things I noticed in demo, You need to use library files for any animation to work, in your pen you aren't including TweenMax. It can be done by clicking on settings > Javascript > there you can select files or search to include. You were using incorrect syntax this.Timeline.to(square, 4, { fill: "red", rotationY:180} ) Correct syntax is as follows, //TweenMax syntax TweenMax.to(element, 1, {}); //For timeline first you have to create instance and then add tweens to it var tl = TimelineMax(); tl.to(element, 1, {}); You can go through this getting started article for quick introduction https://greensock.com/get-started-js
    1 point
  31. Hello dear friends, No doubt Christmas is coming ... Hi @Jonathan - sorry, when I saw your new portrait, I just felt the need to redecorate my tree to dedicate it to the GreenSock community. I coded my first Christmas tree inspired by the work of Petr Tichy (here) Dec 2015. It was one of my first exercises. Kind regards Mikel
    1 point
  32. Awesome job, Mikel. Thanks so much for sharing. Love the little Jonathans
    1 point
  33. Using a little vector math, this is actually pretty easy to do. All you need to do is scale a vector. It's too bad JavaScript can't do operator overloading like a lot of other languages, because this could be a one-liner. var newPoint = (point - center) * scalar; Vectors are like points, but they have a definite direction and length, so the ratio between the x and y values is constant. This means you don't have to figure out the angle for a position. If you know the length of the x or y axis, you can figure out the other axis by multiplying it by a ratio/scale. If you've ever calculated an aspect-ratio for an element, like during a screen resize, it's the same concept. You can see how it works in this demo. As an element moves away from the center, the rate of change between the x and y axis remains constant. So to pull this effect off, all you have to do is multiply the difference between an element and the center by some scalar value. Check it out. It creates a pretty cool effect. It's pretty uniform right now, but you could add some randomization to it. Changing the stagger value can dramatically change how the explosion looks.
    1 point
  34. Hi chriswyl you need .applyBounds() : http://greensock.com/docs/#/HTML5/GSAP/Utils/Draggable/applyBounds/ var draggable = Draggable.create("#elmnt", { type:"x,y" , bounds:{minX:-200, maxX:0, minY:-200, maxY:0} }); draggable[0].applyBounds({minX:-100, maxX:0, minY:-150, maxY:0});// Immediately updates and applies bounds
    1 point
  35. Also, another integration would be placing your "need to load" asset file paths into a main array and then loop through that array and load that type of item. They could be images or other files like jQuery AJAX calls to web services, XML, JSON, etc. Then you simply iterate through that loading array of assets and simultaneously check the position of the current asset being loaded in which to drive a progress bar or increment some other visual element until the max length of the loading array is reached. It's not perfect but it does provide some sense of progress other than a looping animated GIF image. So if you have 47 images, 2 xml files and a 1 JSON AJAX web services request, you have 50 total 'assets' to load and each 'array index' that is being loaded is therefore equivalent to a factor of 2 on a progress bar from 0 to 100. Just remember to have a 'complete' or 'success' event fire off after loading each asset item in the array so that you can increment to the next asset to load and simultaneously update the progress bar. var assetsToLoadArray = [ 'image1.jpg', 'image2.jpg', 'image3.jpg', 'image4.jpg', //.. and so on up to 47 images... 'setup.xml', 'configuration.xml', 'http://www.somedomain.com/api/getJSONData?id=1234' ]; var totalAssets = assetsToLoadArray.length; // 50 total assets var currentAsset = 0; // refers to the first index in the array to load var progressFactor = Math.round(100 / totalAssets); // equals 2 function someLoadLoopCode(){ // loop code to iterate and load each asset by extension/file type // do a string search on each asset to load and find it's file type // and perform the appropriate conditional 'if' below // if .jpg use the new Image(); and its onload callback event // if .xml use jQuery AJAX and its success callback event // if http:// use jQuery AJAX and its complete event // each 'if' above would result in calling loadNextAsset() // to keep the iteration through all of the assets in the array } // need a function that is called for the load finished callback events function loadNextAsset(){ currentAsset++; setProgress(); if(currentAsset == (totalAssets - 1)){// check to see if on last item // all items loaded // do final callback or other code once all assets loaded }else{ // load next item code someLoadLoopCode(); } } function setProgress(){ var progress = Math.round(currentAsset * progressFactor); if(progress > 100){ progress = 100; }else if(progress < 0){ progress = 0; } // code here to set the progress to its visual element or text, etc. }
    1 point
×
×
  • Create New...