Rodrigo last won the day on July 26 2016

Rodrigo had the most liked content!

Rodrigo

Moderators
  • Content count

    1,543
  • Joined

  • Last visited

  • Days Won

    148

Rodrigo last won the day on July 26 2016

Rodrigo had the most liked content!

Community Reputation

1,807 Superhero

2 Followers

About Rodrigo

  • Rank
    Advanced Member

Contact Methods

  • Skype
    r_hernando

Profile Information

  • Gender
    Male
  • Location
    Santiago - Chile

Recent Profile Visitors

18,376 profile views
  1. Yep, as I said I'm not convinced that my answer is what the issue is about. just never did a lot of unit test or end-to-end on gsap instances and the end values of the properties they affect, mostly checked that the instance was created by checking some specific properties. Also I haven't done a lot of testing on virtual DOM, mostly browser or Node, so I was attracted to the thread because of that. I've never used a lot of testing on the values because of my blind faith in GSAP, I just create the instances and I know that id something is not working is because I blew it at some point. I posted that answer with the hope that the phrase:"Sometimes the simplest solution is the best solution" could become true in it I'll keep waiting on @UncommonDave's posts to see how it develops. Happy Tweening!!
  2. Hi, Couldn't help to pinch in with a simple suggestion, and perhaps I'm overlooking the real issue in question. If I am please correct me and excuse me for not understanding the conversation. Is the problem that you need to run the tweens in order to check for callbacks and the elements' position?. What I think I understand for your posts is that, your test suite is taking far too long by waiting for a, let's say 5 seconds tween to be completed to check that everything actually happened. If that's the case why don't you use either seek(), or progress(), or time() to advance your GSAP instances to the end and check the values and callbacks. All those methods suppress callbacks by default, but you can pass a second parameter to trigger the callbacks between the current and final positions. You can do that at runtime after defining your instances or even at a specific moment or event of your code: var t = TweenLite.to(e, 1, {x:100, onStart:startCallback, onComplete:completeCallback}); // then move the playhead to the end triggering all the callbacks t.progress(1, false); // using time t.time(t.duration(), false); // using seek t.seek(t.duration(), false); Again, sorry if I'm misunderstanding the problem, if so... sorry. Happy Tweening!!
  3. Bingo!!!, that's the key to understand it. As always @OSUblake has the nail locked and He hits it in the head!!! @GreenSock, well, this is kind of tricky. First when working with React data is normally passed either as a JSON file or in object notation. So normally elements that share something in common (such as a specific class) are stored in arrays: const els = [ {name: "Jack", ocupation:"Master of GSAP"}, {name: "Carl", ocupation:"Geek Ambassador"}, {name: "Blake", ocupation:"Superstar Moderator and JS wikipedia"}, {name: "Jonathan", ocupation:"Superstar Moderator and Browser-Quirks reference"}, {name: "PointC", ocupation:"Superstar Moderator and SVG Mastermind"} ]; When adding this to the virtual DOM you can use the map array helper: render(){ <div className="staff-wrapper"> {els.map((element, index)=>{ return <div className="staff-card" ref={element.name}></div>; });} </div> } Now when it come to select them all, normally we use querySelectorAll or getElementsByClassName. I'm not very familiar with the specs of this methods, but I can assume that they involve some traversing the DOM tree looking for elements that match the argument. In this case we're setting the ref name for every element by hand, so we have full control over that aspect of our code, so we can loop trough our collection again, matching the ref name using a for or forEach loop, or even using the map method to get a new array: // to create a single animation for each element els.forEach((e,i)=>{ TweenLite.to(e, 1, {rotation:360}); }); // to create a stagger animation const targets = els.map((e,i)=>{ this.refs[e.name]; }); TweenMax.staggerTo(targets, 1, {rotation:360}, 0.1); Here are a couple of samples of a marquee I made for a React app using the modifiers plugin, this is just a simple prototype because I'm bound by some silly NDA for the complete code . This is just React and CSS: And this uses PIXI, just an experiment to see if there was a better performance, since the real thing uses images and text: Well, that's about it, hopefully this helps to make things clear about this and other questions regarding React. Last but not least, @Carl, thanks buddy, is always a pleasure to come back home. Things are going pretty well, still not having a lot of free time but hopefully at some point I'll be back full-time. It certainly feels good when I post an answer or a thread and everyone welcomes me, I feel like Norm in Cheers Happy Tweening!!!
  4. Hi, I was passing by to se the new features in the forums and ran into this post and I thought I'd offer some tips about using GSAP and React. First the following is a big NO-NO: Never use regular selectors while working with React. This because the component could get an update later and re-render. In this case the id(s) could change or even a DOM node with a specific ID could not be render again, then you get the can't tween a null target error. This goes to master Doyle as well, but we'll forgive his sins because He has given us GSAP . To get a specific element just use this.refs, that points to the node being rendered in the DOM. Second, you added almost 300 lines of SVG code on the component's render method, try to avoid this in order to keep your components small, clean, easy to read/debug/maintain and reusable, which are the cornerstone of component-based development, not only with React, but also with Angular2/4+, Vue, etc. If you can break your svg into smaller component it'll be very easy, remember: "Divide and Conquer" Finally is not necessary to use the bracket notation on JSX. Keep in mind that the component's reference is an object, so you can pass an string to it and React will look for that ref attribute on the code and pass whatever string to the object: render(){ return <div ref="myDiv"></div>; } // Then React does this (this is very simplified of course component.refs["myDiv"] = nodeObject; // So you can access your node this.refs.myDiv; So a real GSAP code could be like this: componentDidMount(){ const target = this.refs.targetGroup; TweenLite.to(target, 1, {}); } render(){ return( <svg xmlns="http://www.w3.org/2000/svg" id="svg2" version="1.1" viewBox="0 -10 573 367" height="367px" width="573px"> <g ref='targetGroup'> // svg code or component here </g> </svg> ); } As for the attribute plugin part, Jack has that already working so no need to go into that. Happy Tweening!!
  5. Hi, In the case of TweenMax/TimelineMax instances, yoyo does not acts as reverse(), the yoyo feature basically alters the direction of the repeat feature. From the docs: yoyo : Boolean - If true, every other repeat cycle will run in the opposite direction so that the tween appears to go back and forth (forward then backward). This has no affect on the "reversed" property though. So if repeat is 2 and yoyo isfalse, it will look like: start - 1 - 2 - 3 - 1 - 2 - 3 - 1 - 2 - 3 - end. But if yoyo is true, it will look like: start - 1 - 2 - 3 - 3 - 2 - 1 - 1 - 2 - 3 - end. What I can suggest is to detect the direction of the instance or the progress value inside a function and use that on the onRepeat callback: // at startup the direction of an instance is forward // THIS IS NOT RELATED TO THE REVERSED STATUS var forward = true; function cBack(){ forward = !forward; if( !forward) { // the instance is repeating from the end to the start } else { // the instance is repeating from the start to the end } } TweenMax.to(el, 1, {vars, onRepeat:cBack}); Codepen sample: http://codepen.io/rhernando/pen/WRvVqN?editors=0010 Hopefully this makes things a bit more clear. Happy Tweening!!
  6. Hi Nate, The issue here could be resolved using TimelineMax, labels and the tweenTo and tweenFromTo methods. http://greensock.com/docs/#/HTML5/Sequencing/TimelineMax/tweenTo/ http://greensock.com/docs/#/HTML5/Sequencing/TimelineMax/tweenFromTo/ Also it could be solved using just labels and the play and reverse methods using the labels as starting points: var tl = new TimelineLite({paused:true}); tl .to(element, 1, {vars}, "label_1") .to(element, 1, {vars}, "label_2") .to(element, 1, {vars}, "label_3") .to(element, 1, {vars}, "label_4"); // then on the click/key events function eventHandler(label, direction){ switch (direction) { case "forward": tl.play(label); // plays the timeline from the specific label break; case "back": tl.reverse(label); // reverses the timeline from the specific label } } // then calling the function eventHandler(forward, "label_2");// plays from label_2 Unfortunately I don't have time to create a working sample of this. Hopefully this is enough to get you started.
  7. Hi, Since getChildren() returns an array you can do a simple indexOf() in order to check if the instance is in the parent timeline already: var master = new TimelineMax({paused:true}), child1 = new TimelineMax({paused:true}), child2 = new TimelineMax({paused:true}), child3 = new TimelineMax({paused:true}), children; master .add(child1, 1) .add(child2, 2); // get childs children = master.getChildren(); console.log( children.indexOf(child1) );// return 0 console.log( children.indexOf(child2) );// return 1 console.log( children.indexOf(child3) );// return -1 doesn't exists in the array https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf
  8. Hi Kevin, This is not a GSAP issue, but an HTML thing. Looking in google I found these stack overflow posts: http://stackoverflow.com/questions/9620122/stop-html-text-being-highlighted http://stackoverflow.com/questions/3779534/how-do-i-disable-text-selection-with-css-or-javascript The second one should work with the onDragStart method, you could attach the event handler and then remove it if you want, otherwise you can run a loop through all the elements you don't want highlighted and leave it like this. Although the first option would be the one of my choice, using a IE9 and older conditional to use the JS code: http://caniuse.com/#feat=user-select-none Please let us know how it goes, this will be helpful for other users. Happy Tweening!!
  9. Hi, Nice sample, works really well. Glad that you were able to figure it out. By now you're getting into the GSAP way (since today there's a way for absolutely everything, why not GSAP, right? ) and how things work under the hood. From now on, things will get simpler and easier for you, trust me. Great job and happy tweening!!
  10. No problemo. Again, sorry it took us this long to answer. Happy Tweening!!
  11. Hi, 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.
  12. Hi and sorry for the late response There are a few things throwing errors in your codepen sample. First you didn't include the GSAP files and also is this code right here: // navigation UI var piemenu = new wheelnav('piemenu'); piemenu.clockwise = false; piemenu.wheelRadius = piemenu.wheelRadius * 0.83; piemenu.createWheel(); The class wheelnav is not defined or included anywhere, so it throws an error. Also the target id does exists but there's no style definition for it so is basically a div with 0px of width and height, and doesn't have a background color neither. Use this css on the codepen and you should see it: #animlogo { width: 50px; height: 50px; background: blue; position:relative; } Finally comment out or remove the wheelnav code and the codepen should work. Then you can add the controller code from the GreenSock collection's codepen. Let us know if you have more questions. Happy Tweening!!
  13. 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()
  14. Hi, Without seeing a live sample I would go with shiftChildren(). All you need to know is where the first instance you want to change sits on the timeline, in order to affect the start time of all the instances from that point until the end of the timeline. http://greensock.com/docs/#/HTML5/GSAP/TimelineLite/shiftChildren/ There could be some other ways to do this, such as using a function to create and populate the timeline and passing a value to change the delay of the specific instances. Also is important to know if all your tweens are in straight sequence or if there's some overlaping or staggering between them. As you can see we could keep discussing about different ways to do this, so if you could provide a reduce live sample that is as closest as possible to your real app, it would be great.
  15. Mhh... my first try would be to do it in the link function of the directive. But I've never done something like this, mostly simple enter, leave and view stuff. Perhaps this article could help you: http://onehungrymind.com/build-super-smooth-rollover-angularjs-greensock-timelinelite/ I'm sure Blake will come with the right answer for this.