Jump to content

Rodrigo last won the day on March 17 2019

Rodrigo had the most liked content!


  • Posts

  • Joined

  • Last visited

  • Days Won


Community Answers

  1. Rodrigo's post in adding controller class to control playback example was marked as the answer   
    It's working for me when I declare the  GSAP instance before the wheelnav. Keep in mind that JS reads the entire code before it's executed, saving variables into memory to access them later. Perhaps the issue comes when clicking on the text element of the pie-nav?. I see that it has no effect whatsoever, perhaps the developers didn't consider event handlers in the text or tspan tags. But clicking on the green part (the path tag) always triggers the function regardless of where you declare the GSAP instances. If you remove the text you'll see that it works:
    <div id='piemenu' data-wheelnav data-wheelnav-slicepath='DonutSlice' data-wheelnav-marker data-wheelnav-markerpath='PieLineMarker' data-wheelnav-rotateoff data-wheelnav-navangle='270' data-wheelnav-cssmode data-wheelnav-init> <div data-wheelnav-navitemtext=' '></div> <div data-wheelnav-navitemtext=' '></div> <div data-wheelnav-navitemtext=' '></div> </div> Also a good way to avoid such issues is to use an immediately invoked function expression (IIFE), like that you can be completely sure that everything will be read before being executed and avoid any possible conflicts. When working with jQuery I use the following:
    (function($){$(function(){ var animlogo = $("#animlogo"),     tween = TweenLite.to(animlogo, 6, {left:"90%", ease:Linear.easeNone});   // declare wheelnav var piemenu = new wheelnav('piemenu'); piemenu.clockwise = false; piemenu.wheelRadius = piemenu.wheelRadius * 0.83; piemenu.createWheel(); piemenu.navItems[0].navSlice.mouseup(function () {    //alert('PLAY');    tween.play(); }); piemenu.navItems[1].navSlice.mouseup(function () {    //alert('PAUSE');   tween.pause(); }); piemenu.navItems[2].navSlice.mouseup(function () {    //('RESET');   tween.restart(); }); });}(jQuery)); That basically covers everything, avoids conflicts and has the document.ready as well.
    Give that a try and  let us know.
  2. Rodrigo's post in Passing variable into timeline via play? was marked as the answer   
    Well if you want to delay the start of the entire timeline and not just a few tweens in it, you could use shiftChildren(), although after you used it you'll have to remove that time if te user clicks on the button to play it immediately.
    Another option is to create a function and pass a time parameter and use a delayed call to start the timeline:
    var tl = new TimelineLite(); function startTl(delay){ TweenLite.delayedCall(delay, function(){tl.play();}); } And with the other button just use tl.play()
  3. Rodrigo's post in Cancelling transform 3D was marked as the answer   
    Hi and welcome to the GreenSock forums.
    It would be great if you could provide a reduced live sample in codepen.
    Also if you need to use the nodes holding the text after the animations there are two things you could do. One is to reverse the split text, like that the element goes back to it's original state. Two use clearProps to remove all the inline styles applied by GSAP to the elements.
    Revert SplitText:
    var split = new SplitText("#yourID"); // revert split.revert(); Clear Props (almost at the end of the page):
    Hope that helps.
  4. Rodrigo's post in Timing individual 3 simple svg circles to load at different times was marked as the answer   
    Hi and welcome to the GreenSock forums.
    The issue is that all your paths have the same id:
    <!-- CIRCLE 1 --> <path id="dot" style="stroke-linecap: round; ...></path> <!-- CIRCLE 2 --> <path id="dot" style="stroke-linecap: round; ...></path> <!-- CIRCLE 3 --> <path id="dot" style="stroke-linecap: round; ...></path> Then on your JS you have this:
    // this variable has all the elements with an id of "dot" var $dot = $("path#dot"); var $circle_1 = $("#circle_1"); var $circle_2 = $("#circle_2"); var $circle_3 = $("#circle_3"); var circle_tween = new TimelineMax() .to($dot, 4, { strokeDashoffset: 0, ease:Linear.easeNone}) .to('#circle_1', 10, {strokeDashoffset: 0,ease:Linear.easeNone}) .to('#circle_2', 10, {strokeDashoffset: 0, ease:Linear.easeNone}) .to('#circle_3', 10, {strokeDashoffset: 0, ease:Linear.easeNone}) .to("path", 1, {stroke:"#ffffff",ease:Linear.easeNone}); So basically all your paths with the dot ID are animating at the same time.
    You should give every path a different ID, like you're doing with the circles and then create an individual tween for each one.
  5. Rodrigo's post in Gaps between HTML Image in animation loop was marked as the answer   
    Perhaps you could use the new Modifiers Plugin to solve this. Check this video Carl made, there's a specific solution for this scenario:
  6. Rodrigo's post in Making image spin sideway was marked as the answer   
    Hi and welcome to the GreenSock forums.
    All you're missing is add the normal 2D rotation to the image inside the container. Also I added an ID to the image in your HTML:
    %img#card{:src=>"https://s32.postimg.org/9im9jyxkl/banner1.jpg"} JS
    tl .to($slide1, 1, {transformOrigin:"50% 50%", rotationX: 50, rotationY: 50, z: -200}) .to('#card', 5, {rotation:1080, ease:Linear.easeNone}, "rotation") .to($slide1, 5, {z:-1200, y:150}, "rotation"); Happy Tweening!!
  7. Rodrigo's post in Draggable - Init callback was marked as the answer   
    You mean something like when the instance is created by the Draggable.create() constructor?
    Draggable has the onDragStart callback when the user drags the element more than 2 pixels. Also there's a complete set of callback for the Draggable tool:
    It'd help if you could elaborate a bit more and provide some sort of sample or code snippet in order to get a better idea of what you're after.
  8. Rodrigo's post in List hover effect not working was marked as the answer   
    I believe that the issue is on your jquery code. My impression is that you're kind of over-complicating the code. Is simpler like this:
    var listItems = $("#list li"); listItems.each(function(i,e){ var t = TweenLite.to(e, 0.5, {fontSize:30, paused:true}); e.fontTween = t; $(e).hover(function(){ e.fontTween.play(); },function(){ e.fontTween.reverse(); }); });
    See the Pen PNaaMX by anon (@anon) on CodePen
  9. Rodrigo's post in Alternating a tween's direction on repeat after the yoyo finishes was marked as the answer   
    In this case the issue is that a Tween instance with a repeat:-1 is an infinite loop, therefore the onComplete will never be called. What you could try is use a timeline with a simple animation to 5 and then add a TweenMax instance that goes to -5 with the repeat:-1. That final instance will have as a starting point 5 and final point -5, so it'll loop between those values endlessly:
    var tl = new TimelineLite(); tl .to(object, 3, {x:-5, ease:Linear.easeNone}) .add(TweenMax.to(object, 3, {x:5, repeat:-1, yoyo:true, ease:Linear.easeNone})); EDIT:
    I missed the fact that a TimelineLite instance can have endless instances in it, therefore the code above is even simpler:
    var tl = new TimelineLite(); tl .to("#el", 1, {x:10, ease:Linear.easeNone}) .to("#el", 1, {x:-10, ease:Linear.easeNone, repeat:-1, yoyo:true});
    See the Pen grXmqV by rhernando (@rhernando) on CodePen
  10. Rodrigo's post in How to get the changing offset position of an element during tweenMax was marked as the answer   
    The issue here is that you're not changing the scroll property but the x transform value of the element containing the images, therefore the scroll value never changes, in fact if you check the scrollLeft property it's always 0.
    I can suggest two options. If you want to stick with the scroll value, use GSAP ScrollTo plugin:
    With it, you'll be able to animate the scroll position of the element and using an onUpdate callback, check when the scroll value has passed a certain point.
    Another option is keep using this approach and also use an onUpdate callback to check the progess of the animation and at a certain value, show the right button. Progress is very neat because it shows... well the progress of the animation between zero and one, being zero the animation's starting point and one the final point of the animation:
    For example if you want the right button to be visible after the 80% of the animation is completed, it could be like this:
    tl = new TimelineMax({ paused: true, onUpdate: checkValue }); // onUpdate callback function checkValue(){ if( tl.progress() >= 0.8 ) { TweenLite.to('#right-btn', 0.6, { x: 0 }, 'ease:Sine.easeIn'); } }
  11. Rodrigo's post in Tweenmax Beginner Help was marked as the answer   
    Hi and welcome to the GreenSock forums.
    The issue comes from your JS code. The problem is that you're creating a function but not giving it a name so it can be referenced and you're not invoking that function neither:
    function() { givemefruit = document.getElementById("givemefruit"); givemefruit.onclick = function() { TweenMax.staggerTo(".box", 1, {rotation:360, y:100}, 0.5); }; } Javascript needs to know how to reference a function. Basically the browser reads and interpretates your code, at that point it stores the function reference in memory so you can access it later on your code and execute it. In this case you're typing the word function but JS expects a name after the word function or the function expression to be stored in a variable, like this:
    // function name function myFunction(){ // code here } // invoke the function myFunction(); // anonymous function var myFunction = function(){ // code here }; myFunction(); Finally it seems that you're trying to wrap your code inside a IIFE to avoid your code to be stored in the global scope. In that case, after defining the function it should be invoked immediately, but everything should be wrap in parenthesis to avoid JS to see the word function at the start of the code line:
    (function() { givemefruit = document.getElementById("givemefruit"); givemefruit.onclick = function() { TweenMax.staggerTo(".box", 1, {rotation:360, y:100}, 0.5); }; } () );// the parenthesis after the curly bracket execute the function Finally take a look at this to get a better grasp of JS:
    JS Tutorial
    IIFE information
  12. Rodrigo's post in Slight page height jump, can't get rid of it was marked as the answer   
    Hi Ben,
    I can propose some solutions to this.
    One is set the element's position to absolute and set the top/y property relative to the previous element's height and add a padding equal to the arrow's height. Like that the height is set considering that element (text) you won't experience the height jump.
    Another solution is to set the overflow-y to hidden in desktops (that requires to check for desktops and change the overflow of the body and html tags via JS) and once the arrow animation is done, set the overflow-y to auto and allow scrolling using the onComplete callback.
    I'm pretty sure that other guys around might have some great ideas, but this is mainly about JS code and CSS layout than a GSAP issue. Hopefully this helps.
  13. Rodrigo's post in Jquery and GSAP are not interacting the way expected was marked as the answer   
    Hi and welcome to the GreenSock forums.
    Turns out that basically you're trying to mix oil and water, no matter how hard you try it won't work
    The method you're using is exclusive of jQuery and therefore it'll throw an error:
    Uncaught TypeError: TweenMax.to(...).queue is not a function
    Basically that says that .queue() is not a method of the TweenMax class. Keep in mind that most GSAP methods will return the instance itself, which makes chainability a real breeze, just like in jQuery (something that you're used to it seems;) ).
    Finally Diaco's advice is spot on, as usual, since GSAP has a ton of callbacks and when you work with Timelines you can even add the call() method to the mix. Also GSAP offers that ability to pass parameters to the callbacks and set the scope in the callbacks. Just take a good look at that link and you'll be on your way.
    If you have more questions, we're here to help.
    Happy Tweening!!
  14. Rodrigo's post in creating an array in js for simple mouseover was marked as the answer   
    Since you're using jQuery I see no reason to keep using documentGetElementById as a selctor, just use jquery. In order to keep using the dollar sign, you can keep jquery in a IIFE:
    (function($){ // this is the equivalent to document.ready(); $(function(){ // your code here }); }(jQuery)); Finally you can use a common class in all your spin elements (the ones that will trigger the spin function) and use that selector to spin the common element. Then you can create a single tween to spin the element and play/reverse it.

    See the Pen jbEggN by rhernando (@rhernando) on CodePen
    That creates far less code and it should work. Let us know if you need something else.
    Happy Tweening!!
  15. Rodrigo's post in Splittext on multiple items using an each function was marked as the answer   
    Hi Oliver,
    There were a few issues in your code.
    First the selector for the each loop wasn't working, therefore the each loop didn't even begun. In this situations is better to add a common class to the elements you want to loop through and use that as a selector, is far easier.
    Second, on your code you were referring to the SplitText instance and not the chars array created by SplitText, so even with the loop working you still would get an error or no animation at all.
    Finally is better to not use <span> for the SplitText since there are some browser issues animating transforms in elements with an displya:inline property, always use inline block elements, so I removed the spans from your markup.
    This code works
    <a class="nav-link" href="" id="live"><div class="sitenavTxt">Live</div></a> JS
    $(".nav-link").each(function(i,e) { var self = $(this), sitenavtxt = self.find(".sitenavTxt"), sitenavtxtSplit = new SplitText(sitenavtxt, {type:"words,chars"}), sitenavtxtChars = sitenavtxtSplit.chars, sitenavTL = new TimelineMax({paused:true}); sitenavTL.staggerFromTo(sitenavtxtChars, 0.1, {color: '#858585'}, {color: '#FFF'}, 0.08); e.hoverTl = sitenavTL; self.hover(function(){ sitenavTL.play(); }, function(){ sitenavTL.reverse(); }); }); Happy Tweening!!
  16. Rodrigo's post in TransformOrigin on Height transform? was marked as the answer   
    The issue is that according to the box model spec, the height and width are considered from the top/left corner of the element. Also keep in mind that the transform origin property is for... you got it!! transforms and not size animations, such as width and height. The transform origin will take effect using scales. So you could scale your element in the Y axis from 0 using that transform origin string:
    TweenLite.from(element, 1, {scaleY:0, transformOrigin:"center bottom"}); Another option is the solution Shaun posted in this thread:
  17. Rodrigo's post in Help with simple StaggerTo was marked as the answer   
    I thought about adding this link. It's a really nice example Jamie made some time ago, about using the CSS Rule plugin Diaco was talking about, perhaps you can get some ideas out of it:

    See the Pen ibHAt by jamiejefferson (@jamiejefferson) on CodePen
  18. Rodrigo's post in Problem with nested timelines was marked as the answer   
    Hi and welcome to the GreenSock forums.
    The point is that the function is returning itself and not the timeline, therefore at that point the timeline is empty.
    The best approach is using a function that returns the timeline being created:
    function createLine(){ var nestedTimeline = new TimelineLite(); nestedTimeline .to(el, 1, {vars}); return nestedTimeline; } var parentTimeline = new TimelineLite(); parentTimeline .add(createLine());
  19. Rodrigo's post in ImmediateRender Explained was marked as the answer   
    Normally immediateRender: false is required when using any type of from() instance (from, fromTo, staggerFrom and staggerFromTo). Keep in mind that this type of instances take the element you're animating from the values you're passing in the constructor to the position the element has when the instance was instantiated. Consider the following code:
    TweenLite.from("#myElement", 2, {x:300, y:300, paused:true}); The target of that tween will be rendered according to the CSS rules and any other code affecting both it's position and translation properties. Then when the tween is created, meaning the browser reads and executes the JS code, the values of the x and y properties will be changed immediately to 300 each. If the values of those properties at the time of that code execution are 0 each, then over the course of 2 seconds the element will be animated from 300 to 0 when the instance's paused states changes. If you use immediateRender: false then if you call play() then the element will go from 0 to 300 in a snap and then it'll be animated from 300 to 0. As you can see in this situation immediateRender is not very useful because it looks odd.
    Now let's assume that you have a timeline and in that timeline there are two instances controlling the element and the same properties, let's say that one is a to instance and another is a from instance, like this:
    var tl = new TimelineLite({paused:true}); tl .to("#myElement", 2, {x:300, y:300}) //other instances .fromTo("#myElement", 2, {x:300, y:300}, {x:0, y:0}); Let's say that no matter what happens you need to be sure that the final part of the timeline takes the target from 300 to 0 always. So GSAP reads that code and creates the timeline, then sees the first instance and does all the work to have that instance ready and finally it reaches the final instance. Then GSAP says, ok lets tween the x and y values from 300 to 0 and, hey this is a from instance so I'm going to take those values to 300 so when the playhead arrives to that time in the timeline animates it to the final position. Then the element will be at x:300 and y:300 and the timeline is paused!!, so when you play the timeline the first tween will have no effect because the element will be already at 300. Then the element will be animated back to 0 and when you restart the timeline you'll see a jump from 0 to 300.
    Using immediateRender: false in this case will prevent rendering the values of the from instance upon instantiation and those will be enforced when the playhead reaches that point in the timeline:

    See the Pen zGmzLv by rhernando (@rhernando) on CodePen
    Normally I use immediate render a lot when creating complex animations that need to be responsive and you can't use xPercent and yPercent, so when you pass a CSS breakpoint sometimes you have to create a tween or timeline completely again but that tween/timeline might already started, so you have to pause, record the progress create the instance again and set it back to the progress it had before and play it again. In those cases fromTo instances have safe my behind quite some times, because you have full control of where everything starts, ends and is at the moment you changed the screen size or device orientation.
    I'm pretty suer other users could give their inputs of how useful from instances are and how immediateRender is so important when working with complex timelines.
  20. Rodrigo's post in Box Flipping was marked as the answer   
    What you could do is detect a touch event in your main container, which will be the div with the site-container class, and on that event reverse the animation. Of course you'll have to prevent the touch event from bubbling up the DOM in the blue box, because that would reverse the animation as soon as it starts. I saw you're using modernizr, so you can bind a click event (I've seen a lot of consistency between jQuery click() and touch events in several devices) in the outer container and using modernizr you can check if the user is in a touch screen and then call the reverse. If the animation is already reversed it won't have any effect whatsoever, so you're covered there.
    jQuery(".site-container").click(function(e){ if(modernizr.touch){ travelerscol[0].animation.reverse(); } }); // now the click event on the element travelerscol.click(function(e){ e.stopPropagation(); }); Give that a try an let us know how it goes.
  21. Rodrigo's post in Is it possible to change an array of target dynamically ? was marked as the answer   
    Hi and welcome to the GreenSock forums.
    The behaviour you're seeing is completely expected. One of many implementations that makes GSAP super fast is avoiding continuous read-write operations. So once an instance have been instantiated all that info is stored for faster access to it. So once you change your array, that change has no effect on any instance created before the array was updated.
    Something similar was in discussion not too long ago, check the following link, I believe you'll find some helpful information there:
    Let us know if you need something else.
    Happy Tweening!!
  22. Rodrigo's post in Simple linear gradient animation was marked as the answer   
    I believe you're asking too much from the CSS Plugin. Parsing all that data apparently is not possible, so what you have to do is create a common JS object with a property with a starting value of 0 and then tween that property to 1. Using an onUpdate callback pass that to your element:
    var testObj = {a:0}; TweenLite.to(testObj, 3, {a:1, onUpdate: updateGradient}); function updateGradient(){ $("#demo").css("background","linear-gradient(to top,rgba(255,255,255,0) 0%, rgba(255,255,255,"+testObj.a); } If you want a full crossbrowser support you'll have to use all the strings in the callback. I set up an example that can save you from typing some of that code:

    See the Pen KAuLp by rhernando (@rhernando) on CodePen
  23. Rodrigo's post in Converting keyframes to JS animation with GSAP was marked as the answer   
    In that case it would be better to use a Timeline and set the delays between the instances with the position parameter, like this:
    var tl = new TimelineLite(); tl .to("#ball",2,{bezier:{curviness:1.5,values:[{x:0,y:0},{x:-100,y:100},{x:0,y:200},{x:100,y:100},{x:0,y:0}]},ease:Power0.easeNone}) .fromTo("#ball", 0.4, {scale:0.2}, {scale:1}, 0) .add(TweenMax.to("#ball",0.05,{scale:0.3,repeat:1,yoyo:true}), 1.9);
  24. Rodrigo's post in Help getting started with buttons was marked as the answer   
    Hi and welcome to the GreenSock forums.
    As we understand that coming from flash to HTML/CSS/JS can be a bit daunting at times, I can assure you that taming that beast it's easier than it seems.
    In HTML everything can have a button behaviour, you just need to add the click event listener to it. As you can see here's a similarity with AS and in the path of discovering how JS works you'll find other parts more familiar and other less familiar.
    Unfortunately we can't spend a lot of time teaching how HTML/CSS/JS works, because of time issues we have to leave that to the users. But don't be discouraged at all, there are plenty of learning resources out there, some free (a lot actually) and some paid (also a lot). In order to start with JS I'd recommend you to start working with jQuery as it will simplify start working with JS and as yo become more familiar with it you can start going into more complex JS stuff. Take a look at this pages in order to get a fast way to learn about jQuery:
    Finally here's a simple example of how to create buttons in HTML and use GSAP to animate them:

    See the Pen LVQJJb by anon (@anon) on CodePen
  25. Rodrigo's post in Emulating CSS3 Step Animation with Timelinelite? was marked as the answer   
    Why don't you use TweenLite and the Ease Pack, together they're 8kb gzipped.
    You can create the tween to a regular JS object and use an onUpdate callback to pass those values to the element's style.
    var target = document.getElementById("my-element"), myObject = {a:0}, t; t = TweenLite.to(myObject, 1, {a:-2450, ease:SteppedEase.config(16), onUpdate:updateFn, onComplete:repeatFn}); function updateFn(){ target.style.backgroundPosition = myObject.a+"px 0px"; } function repeatFn(){ r.restart(); }