Share Posted November 12, 2013 Hey all, Got a bit of a quandary going here. So what I'd like to be able to do is to move the points of a polygon contained within a mask a variable amount (in this demo, 400 pts). A pen can be found here: (FF only) codepen.io/johnblazek/pen/CqEpd I'm using the attrPlugin, and adjusting the x/y coordinates within the point, but I'm getting no luck. Could the fact I'm using this as a mask be messin me up? 1 Link to comment Share on other sites More sharing options...
Share Posted November 12, 2013 It's actually not animating anything on that SVG, either fill, stroke, or x/y. Not exactly sure why but in general GSAP doesn't have much problem with path attributes. Link to comment Share on other sites More sharing options...
Share Posted November 13, 2013 It looks like the problem is that your value that you're tweening is not a number - it's a bunch of numbers (a comma-delimited list of them). The AttrPlugin can handle animating a number like: yourAttribute="1" But you've got: yourAttribute="949.5,553.1 -5.1,-401.4 1.4,-145.6 961.6,814.6 1923.3,-147 1924.3,-404" So you're expecting the tweening engine to see that long string and know how to split it apart into individual values and then match them up with the corresponding values in another complex value and then tween them. Nope, sorry, no dice. You can certainly accomplish what you're after using an onUpdate and a generic object or build your own plugin. For example: var values = {s1:949.5, m1:-5.1, e1:-401.4, s2:1.4, ...}; TweenLite.to(values, 1, {s1:200, m1:10, e1:-300, s2:6.2, ..., onUpdate:applyValues}); function applyValues() { yourElement.setAttribute("points", values.s1 + " " + values.m1 + " " + values.e1 + ", " + s2...); } 5 Link to comment Share on other sites More sharing options...
Share Posted October 15, 2015 You are awesome jack ! It really helps me a lot. Thanks... Link to comment Share on other sites More sharing options...
Share Posted January 15, 2016 hope this helps someone! See the Pen EPwYmb by johnmastri (@johnmastri) on CodePen 1 Link to comment Share on other sites More sharing options...
Share Posted January 15, 2016 Hi Vanillabass, The good news is that TweenLite and AttrPlugin can now tween complex strings that contain a bunch of numbers. Please read http://greensock.com/gsap-1-18-0 (Section: Tween complex string-based values) So to move all the points on a <polyline> you can just do: TweenMax.to("#hi", 1, {attr:{points:"159.5,400 213.8,209 302. ... "}, repeat:10, yoyo:true}) http://codepen.io/GreenSock/pen/gPGOxL?editors=001 Note this path morphing only works if the start path and end path data have the same number of points. For the most robust SVG morphing imaginable, please see our MorpshSVGPlugin: http://greensock.com/morphSVG 6 Link to comment Share on other sites More sharing options...
Share Posted September 8, 2016 Hello all, I am new here : ), @carl Is it possible to do TweenMax.to("#hi", 1, {attr:{points:"159.5,400 213.8,209 302. ... "}}) and staggering the animation of the points? Thank you Link to comment Share on other sites More sharing options...
Share Posted September 9, 2016 Hi francolsromain, Welcome to the GreenSock forums. Yes you could stagger the animation of the points but it isn't something that will happen automatically. You will have to animate your own point objects with x and y properties and then apply those values to your path when the tweens update. Using the cycle feature of staggerTo() it could look something like this: var points= [ {x:0, y:200, endX:100, endY:50}, {x:200, y:200, endX:400, endY:0}, {x:500, y:200, endX:600, endY:100} ] var tl = new TimelineMax({onUpdate:updateLine}) tl.staggerTo(points, 1, {cycle:{ x:function(index){ return points[index].endX; }, y:function(index){ return points[index].endY; } }}, 1) function updateLine() { TweenLite.set("#hi", {attr:{points:points[0].x + ", " + points[0].y + " " + points[1].x + ", " + points[1].y + " " + points[2].x + ", " + points[2].y}}); } http://codepen.io/GreenSock/pen/rrVEEx?editors=0011 There is definitely a more dynamic way to code it where you might have a start path and end path and you can loop through the values to create your points Array, but that would take me awhile. This is more of a brute-force approach. Read more about stagger and cycle here: http://greensock.com/docs/#/HTML5/GSAP/TimelineLite/staggerTo/ 1 Link to comment Share on other sites More sharing options...
Share Posted September 9, 2016 I got curious about this and enjoyed the challenge of making it into a single function that'll handle any number of points for you, so you can just feed in the string you want, the stagger, duration, etc. and it'll automate everything and spit back a TimelineLite instance containing all the animation Here's a forked version of Carl's: http://codepen.io/GreenSock/pen/fbb9dd44bf1c98a9842a6c05d6c1be2b?editors=0010 //this one function call does it all: staggerPoints("#hi", 2, {points:"100,-50 400,0 600,100"}, 0.5); //the work is done in this one function that spits back a TimelineLite. function staggerPoints(selector, duration, vars, stagger, onCompleteAll) { var numbersExp = /(?-)?\d*\.?\d*(?:e[\-+]?\d+)?)[0-9]/ig, element = document.querySelector(selector), startPoints = element.getAttribute("points").match(numbersExp), endPoints = vars.points.match(numbersExp), applyPoints = function() { element.setAttribute("points", startPoints.join(",")); }, copy = function(obj) { var o = {}, p; for (p in obj) { if (p !== "points") { o[p] = obj[p]; } } return o; }, tl = new TimelineLite({onUpdate:applyPoints, onComplete:onCompleteAll}), l = startPoints.length, obj, i; if (l !== endPoints.length) { console.log("Error: point quantities don't match"); } for (i = 0; i < l; i+=2) { obj = copy(vars); obj[i] = parseFloat(endPoints[i]); //note: we need to make sure the values are converted from strings to numbers. obj[i+1] = parseFloat(endPoints[i+1]); startPoints[i] = parseFloat(startPoints[i]); startPoints[i+1] = parseFloat(startPoints[i+1]); tl.to(startPoints, duration, obj, stagger * i); } return tl; } Play around with it and let us know if it works okay for you. 5 Link to comment Share on other sites More sharing options...
Share Posted September 9, 2016 @carl and @jack This is super cool! Thank you! 1 Link to comment Share on other sites More sharing options...
Share Posted July 5, 2018 On 9/9/2016 at 12:17 PM, GreenSock said: I got curious about this and enjoyed the challenge of making it into a single function that'll handle any number of points for you, so you can just feed in the string you want, the stagger, duration, etc. and it'll automate everything and spit back a TimelineLite instance containing all the animation Here's a forked version of Carl's: See the Pen fbb9dd44bf1c98a9842a6c05d6c1be2b?editors=0010 by GreenSock (@GreenSock) on CodePen //this one function call does it all: staggerPoints("#hi", 2, {points:"100,-50 400,0 600,100"}, 0.5); //the work is done in this one function that spits back a TimelineLite. function staggerPoints(selector, duration, vars, stagger, onCompleteAll) { var numbersExp = /(?-)?\d*\.?\d*(?:e[\-+]?\d+)?)[0-9]/ig, element = document.querySelector(selector), startPoints = element.getAttribute("points").match(numbersExp), endPoints = vars.points.match(numbersExp), applyPoints = function() { element.setAttribute("points", startPoints.join(",")); }, copy = function(obj) { var o = {}, p; for (p in obj) { if (p !== "points") { o[p] = obj[p]; } } return o; }, tl = new TimelineLite({onUpdate:applyPoints, onComplete:onCompleteAll}), l = startPoints.length, obj, i; if (l !== endPoints.length) { console.log("Error: point quantities don't match"); } for (i = 0; i < l; i+=2) { obj = copy(vars); obj[i] = parseFloat(endPoints[i]); //note: we need to make sure the values are converted from strings to numbers. obj[i+1] = parseFloat(endPoints[i+1]); startPoints[i] = parseFloat(startPoints[i]); startPoints[i+1] = parseFloat(startPoints[i+1]); tl.to(startPoints, duration, obj, stagger * i); } return tl; } Play around with it and let us know if it works okay for you. This is many line code . I want the code class to look like "anime.js" pls answer me : ????? Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now