Jump to content
Search Community

Rodrigo last won the day on June 22

Rodrigo had the most liked content!

Rodrigo

Administrators
  • Posts

    6,995
  • Joined

  • Last visited

  • Days Won

    295

Everything posted by Rodrigo

  1. Rodrigo

    Spinning images

    Hi, I got beat this time I crafted a different approach: http://codepen.io/rhernando/pen/piHch But Jack's code is crossbrowser, while my solution doesn't work in IE9 and older. Rodrigo.
  2. Even with a solution in place I agree with Carl, is much better to just kill the whole thing and create it again. Just a function with the variable parameters and you're set to go. Imagine if instead of 4 elements you're animating 20, and instead of 3 nested timelines you have 10, you're in for a freaking nightmare, and since I've in that position where everything breaks down because of that it's a lesson learned the "hard way".
  3. Hi, First thanks for providing the fiddle with the reduced issue, it makes the job so much easier For the timeline duration after you've killed the nested instances is normal, because the timeline's duration is recorded upon creation and I'm pretty sure that for optimization reasons it doesn't change. What invalidates does is to remove the data recorded the first time the tween runs, which is ideal for this case. The issue with the from instance is a little more tricky. When a from() instance is created it renders immediately and the element's starting position is the one given by the CSS style (left:0 in this case), then the tween goes from 1000px to the initial value 0px. When you invalidate you're removing the initial data which is left:0px and setting a new one, where the element is when the tween starts again, which is 1000px, therefore the next time the tween plays it goes from 1000px to 1000px. The solution is to change the from() instance to a to() instance and use a set() instance to adjust the element's initial position, like this: TweenLite.set($("#element4"), {left:1000}); tl3.to(element1, 2, {left:"0"}, "move3"); tl3.to(element2, 2, {left:"0"}, "move3"); tl3.to(element4, 2, {left:"0px"}, "move3"); Like that when you invalidate tl3 the red square will animate as expected. Also since the part you're changing is the one that correspond to tl2, there's no need to remove tl3 as well. For doing that you can add the timelines to the parent one with labels, then you remove tl1 and then add tl2 to the indicated label, like this: //add the original timelines to the parent mainTL.add(tl0.play(), 'intro'); mainTL.add(tl1.play(), 'middle'); mainTL.add(tl3.play(), 'outro'); //remove tl2 //no need to pause all the timelines, just the parent //since it controls the playhead of the nested ones mainTL.pause(0); tl3.invalidate(); mainTL.remove(tl1); //add tl2 mainTL.add(tl2.play(),'middle'); I updated your fiddle: http://jsfiddle.net/cXR7L/36/ Rodrigo.
  4. Hi and welcome to the Greensock forums. The kb indicated correspond to the files hosted in CDNJS that are GZIPPED and their weight is actually what is indicated in the download area. Actually what I'm getting in dev tools is the following: CSS Plugin: 12.8 Kb TweenLite: 8.5 Kb Is always a good idea to use the downloaded and uncompressed files in local environment development and when you upload the finished work point to the CDNJS links and just in case have fallback plan. You can find the links here: http://cdnjs.com/libraries/gsap And for the fallback I always use yepnope.js: http://yepnopejs.com/ Rodrigo.
  5. Hi and welcome to the Greensock forums. There are two possibilities: 1.- Use John Polacek's superscrollorama. A great JQuery plugin to control tweens and timelines with scroll. It also supports touch events, check it here: https://github.com/johnpolacek/superscrollorama 2.- Do everything by hand including add a library to support touch devices: http://codeaway.info/parallax-and-scrolling-control-of-tweens-with-greensock-ap-js/ As you can see is not very complicated, just need to tap into jQuery's scroll() event, the tricky part comes with the element's offsets, specially in dynamic pages. Rodrigo.
  6. Well Carl beat me to it, nice job!! I have a different approach though: http://codepen.io/rhernando/pen/GCgjH Rodrigo.
  7. Rodrigo

    Simple Question

    Hi, I'm going to presume that you have a variable called slide02 that most likely is a div element. Since the add method accepts a tween, timeline, label, function or an array there's nothing wrong with adding the append call at that particular point, but because you're using the append method directly instead of referencing to it it's get called immediately. Take the following: function addImage() { alert("foo bar!!"); } //this animates element1, then element2, then calls the function and finally animates element3 tl .to(element1, time, {vars}) .to(element2, time, {vars}) .add(addImage) .to(element3, time, {vars}); //this calls the function and animates element1 at the beggining, then animates element2 and finally animates element3 tl .to(element1, time, {vars}) .to(element2, time, {vars}) .add(addImage()) .to(element3, time, {vars}); What I don't quite get is why you want to load the image at a certain moment, keep in mind that the loading operation could take a little time (even for a smaller image) and during that time your timeline will keep playing, therefore you might get get some sync problems in your sequence because of it. The way I see it the best choice is to load your image in an invisible container, which you already have since you're tweening the autoAlpha value to 1, which means is at 0. var slide02 = document.getElementById("slide02"), newImg = document.createElement("img"), newImg.src = "http://www.domain.com/img/text.gif", tl = new TimelineLite(); //we set the container's opacity to 0 and remove it from document flow TweenLite.set(slide02, {autoAlpha:0}); //now we add the image slide02.appendChild(newImg); tl .to(element, time, {vars}) .to(element2, time, {vars}) .to(slide02, 1.2, {autoAlpha:1, ease:Power2.easeOut}) .to(element3, time, {vars}) Best, Rodrigo.
  8. Also you could try the engine's RaphaelJS plugin, considering the fact that Raphael supports back to IE6 there's a chance that it could help. And like Jonathan said a reduced sample of the issue is always helpful. Rodrigo.
  9. Rodrigo

    Simple Question

    Hi, What you could use is the add() method to append the function at a certain point of the timeline. You said that you need to play other animations before, so you can add those animations and then add the call to the function that adds the element, like this: var tl = new TimelineLite(); tl .to(element1, time, {vars}) .to(element2, time, {vars}) .add(addImageGif) .to(element3, time, {vars}); function addImageGif() { document.getElementById("imgText").innerHTML='<img src="img/text.gif">'; }; The same can be achieved with the call() method: var tl = new TimelineLite(); tl .to(element1, time, {vars}) .to(element2, time, {vars}) .call(addImageGif) .to(element3, time, {vars}); function addImageGif() { document.getElementById("imgText").innerHTML='<img src="img/text.gif">'; }; As for the removing part, that should be easy, just use removeChild(), you could call it on the children's specific index (which can become quite messy if you have more elements), on the children tag (but if you have more <img> elements inside it can also become a problem) or directly based on the element's id, which would be the best choice, for that you should modify your code a little: function addImageGif() { document.getElementById("imgText").innerHTML='<img src="img/text.gif" id="addedImage">'; }; document.getElementById("imgText").removeChild(document.getElementById("addedImage")); Rodrigo.
  10. Hi, Basically this is a overwrite conflict, while the first two timeline's can coexist without any trouble, but from the moment you add them to a third timeline they are subject to that timelne's playhead and so are their targets. Also since you have two parent timelines the parent that's created at the end "moveLeftRight" in this case, overwrites all other timelines considering the fact that all timelines affect the same target and the same property "X". If you use this: // Declare timelines var moveRight = new TimelineMax({paused: true}) .fromTo(box, 1, {x: 0}, {x: 300}); var moveLeft = new TimelineMax({paused: true}) .fromTo(box, 1, {x: 300}, {x: 0}); var moveRightLeft = new TimelineMax({paused: true}) .add(moveRight.play()) .add(moveLeft.play()); /*var moveLeftRight = new TimelineMax({paused: true}) .add(moveLeft.play()) .add(moveRight.play());*/ The moveRightLeft code works but you get odd results with the individual buttons. A solution is to create the master timelines on the button events, like that you avoid such conflicts by creating all the timelines as global variables: // Declare timelines var moveRight = new TimelineMax({paused: true}) .fromTo(box, 1, {x: 0}, {x: 300}); var moveLeft = new TimelineMax({paused: true}) .fromTo(box, 1, {x: 300}, {x: 0}); // Handler functions window.moveRight = function() { moveRight.play(0); } window.moveLeft = function() { moveLeft.play(0); } window.moveRightLeft = function() { var moveRightLeft = new TimelineMax() .add(moveRight) .add(moveLeft); } window.moveLeftRight = function() { var moveLeftRight = new TimelineMax() .add(moveLeft) .add(moveRight); } Another choice is use just one parent timeline and use play(0) and reverse(0), like this: // Declare timelines var moveRight = new TimelineMax({paused: true}) .fromTo(box, 1, {x: 0}, {x: 300}); var moveLeft = new TimelineMax({paused: true}) .fromTo(box, 1, {x: 300}, {x: 0}); var moveRightLeft = new TimelineMax({paused:true}) .add(moveRight) .add(moveLeft); // Handler functions window.moveRight = function() { moveRight.play(0); } window.moveLeft = function() { moveLeft.play(0); } window.moveRightLeft = function() { moveRightLeft.play(0); } window.moveLeftRight = function() { moveRightLeft.reverse(0); } I've updated your fiddle: http://jsfiddle.net/Zde5U/8/ The issue is that if you create two timelines and then add those timelines into another one, which timeline has the control?, it would be quite a mess if a nested timeline could control the playhead of it's parent timeline, what if the parent has 4 nested timelines and each one of those try to control the parent's playhead?, it's an animation chaos. Rodrigo.
  11. Hi, The only way I know to do that is using the updateTo() method, but since it works only on TweenMax instances and the timelines convenience methods (to, from, fromTo) return TweenLite instances, you need to use the add method to include TweenMax instances in the timeline, then you can update that particular instance, like this: var moveRight = new TimelineMax(), nestedTween = TweenMax..fromTo(el, 1, {x:0},{x:100}); moveRight.add( nestedTween ); //now we update the tween instance inside the timeline nestedTween.updateTo({x:200}, true); Like that you avoid creating two different timelines. Another chance is to clear the timeline or remove the particular instance you want to update and create a new instance with the updated values, but that might be a little more cumbersome, specially if you have more instances in the timeline. Rodrigo.
  12. Great job Chrysto!! You read this article too? http://www.thecssninja.com/javascript/pointer-events-60fps Also while we're in the subject this might come in handy as well: http://www.html5rocks.com/en/tutorials/speed/scrolling/ Happy Tweening!!
  13. Hi, I don't know if this solves the issue: var $quote = $("#quote"), mySplitText = new SplitText($quote, {type:"words"}); TweenLite.set($quote, {perspective:400}); //kill any animations and set text back to its pre-split state function kill(){ mySplitText.revert(); } $("#chars").click(function() { kill(); mySplitText.split({type:"chars, words"}) TweenMax.staggerFrom(mySplitText.chars, 0.6, {scale:4, autoAlpha:0, rotationX:-180, transformOrigin:"100% 50%", ease:Back.easeOut, onComplete:function(){this.reverse();}}, .02); }) //revert the text back to its pre-split state $("#revert").click(function() { mySplitText.revert(); }) Rodrigo.
  14. Hi Erik, The thing is that spaces are transformed to text nodes between the div elements created by the SplitText tool, therefore they aren't DOM elements so they can't be animated. The possible solutions are to underline just words using wordsClass or create a code to wrap each text node inside a <div> tag so they can be animated as well. If you use words as the split criteria you can see that the text nodes are the odd ones, while the divs are the evens, so you can use JQuery selectors to do that. Rodrigo.
  15. Hi, The engine has the progress() method, which allows to get or set a particular instance's (Tween or Timeline) progress. The value goes between 0 and 1 so it can be easily translated to percentage, in this cae it would be like this: In order to get the value on a given event, for example a click event: var tn = TweenLite.to(element, time, {vars}); var button = document.getElementById("button"), tweenProgress; button.onclick = function() { tweenProgress = tn.progress(); } To get the value as the tween plays: var tn = TweenLite.to(element, time, {vars, onUpdate:updateFunction}), tweenProgress; function updateFunction() { tweenProgress = tn.progress(); } Finally to set the tween/timeline progress you just pass a number between 0 and 1 in the progress call: var tn = TweenLite.to(element, time, {vars}); //set the tween's to be at half it's playtime tn.progress(0.5); Here is a codepen that show how you can get the tween's progress: http://codepen.io/rhernando/pen/Batoc Rodrigo.
  16. Hi, I've updated the codepen: http://codepen.io/rhernando/pen/ineuB That scenario is quite easier as you can see. Instead of a single relative delay we use an absolute positioning based on the element's index and the duration based on the amount of wagons left to animate. Rodrigo.
  17. Hi, Two users tackle this before the SplitText was ported to JS, Michael Dobekidis (Michael71) and Chrysto Panayotov(Chrysto), you can check their tutorials here: Michael71 http://nightlycoding.com/index.php/2013/02/text-effects-with-timelinemax/ Repository: http://netgfx.github.com/SplitText/ Chrysto: http://blog.bassta.bg/2013/05/text-animation-with-tweenmax/ Also you might want to take a shot at the SplitText contest, you could win a Club membership: http://www.greensock.com/splittext/ https://twitter.com/greensock/statuses/407972253020602368 Best, Rodrigo.
  18. Rodrigo

    Text Animation

    Hi Jeff, Yeah, unfortunately you'll have to learn the basis of a library to pull this off and my own knowledge of SVG is quite limited closing to none. But digging a little bit I came across Raphael's getPointAtLength() method, this might be exactly what you need since it returns an object with the x, y and alpha values. In the description of alpha it says angle of derivative, but I'm not sure if it refers to the angle of the segment or some other angle. Also there's this other method path2Curve() which turns any path to a collection of cubic bezier. perhaps with this one you can use the bezier method of the codepen, simulate through a loop the whole bezier, get the points at the specific times and apply them to the corresponding letter. Best, Rodrigo.
  19. Hi, I'm not sure why it doesn't work, perhaps because the lack of browser support has not been included in the CSSPlugin, Carl or Jack are more suited to answer that. In the mean time here' a workaround: var obj = {stroke:0}, elements = $("h4"); $("#button").click(function() { TweenLite.to(obj, 1, {stroke:3, onUpdate:updateStroke}); }); function updateStroke() { elements.css('-webkit-text-stroke',obj.stroke+'px rgba(0, 0, 0, 0.2)'); } Rodrigo.
  20. Hi and welcome to the Greensock forums. I'm not very sure if this fits somehow to what you need: http://codepen.io/rhernando/pen/ineuB Please feel free to fork it and adapt it to your scenario and let us know if you need anything else. Also the appendMultiple method has been deprecated in favour of the add method, which works in the exact way: for (var step in tlTrain) { tl.add(TweenMax.to([wagon0, wagon1, wagon2, wagon3], tlSpeed, { x: tlX, y: tlY }, delay)); delay = 0; } As well for this cases JS conditional operator comes in handy to set the delay between tweens: delay = 0.5 for(var i = 0; i < value; i++) { delay = i == 0 ? 0 : delay; } This works as follows: if the value of i is equal to 0 (i == 0) the value of delay will be 0, if the value of i is not 0 the value of delay will be the one assigned previously (0.5). Best, Rodrigo.
  21. Rodrigo

    Text Animation

    Hi Jeff, By no means my previous suggestions go in that direction. If you check the codepen and some of the Greensock collection that work using bezier like this, you'll see that the bezier is never used to actually animate the element. What's happening is that a dummy object is being tweened and the values of the bezier are collected and passed to position the element in a particular place on the bezier path. var letters = $("div.element"), dummy = $("div#dummy"), btn1 = $("button#btn1"), btn2 = $("button#btn2"), path = [{x:0,y:0},{x:100,y:-50},{x:200,y:400},{x:300,y:300},{x:400,y:400}], point, tween = TweenMax.to(dummy, letters.length, { bezier: { values:path, autoRotate:true }, paused:true, ease:Linear.easeNone }) What I do is give the tween a duration based on the amount of elements, in this case the letters amount. The element being tweened is actually a DOM element (needed to get the rotation angle) but with no background and an absolute positioning, therefore it doesn't interfere with document flow or rendering. tl = new TimelineMax({paused:true}); TweenLite.set(dummy, {x:0, y:0, rotation:0}); for(var i = 0; i < letters.length; i++) { tween.time(i); point = {x:dummy[0]._gsTransform.x, y:dummy[0]._gsTransform.y, rotation:dummy[0]._gsTransform.rotation}; tl.from(letters[i], .5, {x:point.x, y:point.y, rotation:point.rotation}, 0); } Then inside the loop and using the time() method the tween's playhead is moved to a particular time. In this case every second corresponds to a letter of the phrase, and since the loop increments the value of i, the next position of the dummy corresponds to the next letter. Then the _gsTransform object comes into play, with that we get the values of x, y and rotation of the dummy element in that particular time and those values are equivalent to the letter, with that index value, position and angle. Finally a instance is added to a timeline setting that particular letter into that position, since a from() instance is being used the letter will be animated from the bezier position to the inline common position. My idea is to get the particular x and y values of the SVG path for each letter and repeat that same procedure without the bezier path, just an object with the x and y values, then with a loop you add a from instance to the timeline and finally you animate it. As you can see the GSAP part is the easiest one, while extracting the points is the big challenge here, once you get those, you're in the promise land because the rest is very easy. Finally if you check this sample: http://bl.ocks.org/duopixel/3824661 You can see how the circle's cx and cy values change as you move the mouse, if you can get those values in the correct position you're good to go. One code snippet that could help you is this codepen of the Greensock collection: http://codepen.io/GreenSock/pen/zLiux Rodrigo.
  22. Rodrigo

    Text Animation

    Hi, You baked my noodle with this follow up My initial idea is get the specific x and y coordinates of a given point in the path, because with an onUpdate callback you can get that easily. After doing some research I found that you can do something like that with RaphaelJS, the beauty is that the engine does have a raphael plugin so that could mean a lot less work down the way. I can't give you a ready bake solution but you could start by digging into the following links: http://www.benknowscode.com/2012/11/finding-points-along-svg-path-using_2799.html http://bl.ocks.org/duopixel/3824661 I found this link regarding D3.js: https://www.dashingd3js.com/svg-paths-and-d3js Also perhaps you could find out about SVGJS and check the following post by Rob Aldred, who's building a very neat SVGJS plugin, perhaps He could give you a better advice: http://forums.greensock.com/topic/8676-svgjs-plugin/ Best, Rodrigo.
  23. Mhhh... as far as I know the Draggable tool includes a way to stop propagation , in order to avoid event bubbling, so it shouldn't be an issue. I forked your codepen and it is working, take a look here: http://codepen.io/rhernando/pen/DJuyq Rodrigo.
  24. Hi, Nope, ThrowProps is not included in draggable. ThrowProps is a Greensock Club benefit, take a look at the following link: http://www.greensock.com/club/ In order to use it in your projects you should sign up for a Club membership, login to your account area and go to the download area to get all the files. Rodrigo.
  25. Hi, What you could do is store the draggable instances in variables and then call the diable() method using the onDragStart callback in the scroll drag, then using th onDragEnd callback in the scroll drag, call the enable() method: var drag1 = Draggable.create(".panel", {type:"x,y" }); var drag2 = Draggable.create("#slideScrollText", { type:"scrollTop", onDragStart:function() { drag1[0].disable(); }, onDragEnd:function() { drag1[0].enable(); } }); Take a look at the docs to find out more about the great capacities of Draggable: http://api.greensock.com/js/com/greensock/utils/Draggable.html Rodrigo.
×
×
  • Create New...