Share Posted February 17, 2017 Hello! I am trying to make an animated SVG of a complex map. I have over 120 elements in my animation. Most of these are paths but some of them are also polygons (circular). Here's a CodePen: I am a JavaScript novice. I searched this forum and found a script (in Carl's post) which allows me to draw a path- var orig1 = document.querySelector('#lineAB'); var obj1 = {length:0, pathLength:orig1.getTotalLength()}; orig1.style.stroke = '#f60'; var t1 = TweenMax.to(obj1, 10, {length:obj1.pathLength, onUpdate:drawLine1, ease:Linear.easeNone}) function drawLine1() { orig1.style.strokeDasharray = [obj1.length,obj1.pathLength].join(' '); } However, this does not work with polygons. My guess is that there is not built-in polygon.Length object in JS. I have found this function on another forum that would measure the length of a polygon but I am not sure how to implement it- getPolygonLength:function(el){ var points = el.attr('points'); points = points.split(" "); var x1 = null, x2, y1 = null, y2 , lineLength = 0, x3, y3; for(var i = 0; i < points.length; i++){ var coords = points[i].split(","); if(x1 == null && y1 == null){ if(/(\r\n|\n|\r)/gm.test(coords[0])){ coords[0] = coords[0].replace(/(\r\n|\n|\r)/gm,""); coords[0] = coords[0].replace(/\s+/g,""); } if(/(\r\n|\n|\r)/gm.test(coords[1])){ coords[0] = coords[1].replace(/(\r\n|\n|\r)/gm,""); coords[0] = coords[1].replace(/\s+/g,""); } x1 = coords[0]; y1 = coords[1]; x3 = coords[0]; y3 = coords[1]; }else{ if(coords[0] != "" && coords[1] != ""){ if(/(\r\n|\n|\r)/gm.test(coords[0])){ coords[0] = coords[0].replace(/(\r\n|\n|\r)/gm,""); coords[0] = coords[0].replace(/\s+/g,""); } if(/(\r\n|\n|\r)/gm.test(coords[1])){ coords[0] = coords[1].replace(/(\r\n|\n|\r)/gm,""); coords[0] = coords[1].replace(/\s+/g,""); } x2 = coords[0]; y2 = coords[1]; lineLength += Math.sqrt(Math.pow((x2-x1), 2)+Math.pow((y2-y1),2)); x1 = x2; y1 = y2; if(i == points.length-2){ lineLength += Math.sqrt(Math.pow((x3-x1), 2)+Math.pow((y3-y1),2)); } } } } return lineLength; } If it doesn't take very long would anyone be able to include the above function into the snippet above so I have a way of animating the polygons as well? Many thanks in advance! See the Pen vgwKKX by i76 (@i76) on CodePen Link to comment Share on other sites More sharing options...
Share Posted February 17, 2017 If it were me, I'd convert the polygons to compound paths before exporting the SVG. How did you create the SVG? If you used Adobe Illustrator, all you have to do is right click on the polygon and choose 'Make Compound Path'. Problem solved. If that isn't an option for you, there is a CSS Tricks article about converting polygons to path data. https://css-tricks.com/snippets/javascript/convert-polygon-path-data/ Another option (the best one in my opinion) would be to join Club GreenSock and start using the DrawSVG plugin. You'll save a lot of time. If you haven't read about Club GreenSock yet, here's some more info: https://greensock.com/club/ Happy tweening. 3 Link to comment Share on other sites More sharing options...
Author Share Posted February 20, 2017 Many thanks PointC! I created the map in Illustrator and have now converted all polygons to compound paths. One more question- is it possible to reverse animation on some paths? I tried adding reverse()- function drawLine1() { orig1.style.strokeDasharray = [obj1.length,obj1.pathLength].reverse().join(' '); But this doesn't work... Also, I am considering joining Club Greenock but I do not have time to look into it properly at the moment. Link to comment Share on other sites More sharing options...
Share Posted February 20, 2017 Please try this for a reverse. var t1 = TweenMax.to(obj1, 10, {length:obj1.pathLength, onUpdate:drawLine1, ease:Linear.easeNone}).reverse(0) Yep - take a look at the Club when you get a chance. Lots of great benefits in there. DrawSVG makes this type of thing super easy. It's as simple as: TweenMax.fromTo(yourElement, 1, {drawSVG:"0% 0%"}, {drawSVG:"0% 100% " }); // forward TweenMax.fromTo(yourElement, 1, {drawSVG:"100% 100%"}, {drawSVG:"0% 100% " }); // reverse Happy tweening. 3 Link to comment Share on other sites More sharing options...
Share Posted February 20, 2017 Very helpful PointC 2 Link to comment Share on other sites More sharing options...
Author Share Posted February 23, 2017 Many Thanks PointC! I tried var t1 = TweenMax.to(obj1, 10, {length:obj1.pathLength, onUpdate:drawLine1, ease:Linear.easeNone}).reverse(0) and what this does is shaw the completed line animation and then goes back to where no line is shown. Is there a way of drawing the line in the different direction A-to-B or B-to-A? Many thanks! Link to comment Share on other sites More sharing options...
Share Posted February 23, 2017 ah... I thought you meant erase the line. The way you're animating the line will make a reverse a bit tricky. You'd have to animate the strokeDashOffset along with drawing the strokeDashArray to do a reverse. I'd still recommend Club GreenSock and DrawSVG to make your life easier. If you aren't able to do that right now, I think you should simply animate the strokeDashOffset instead. This can be done in a few lines and no onUpdate will be needed. var path = document.querySelector('#yourPath'); var pathLength = path.getTotalLength(); TweenMax.set(path, {strokeDasharray:pathLength}); // forward TweenMax.fromTo(path, 1, {strokeDashoffset:pathLength}, {strokeDashoffset:0}); // reverse TweenMax.fromTo(path, 1, {strokeDashoffset:-pathLength}, {strokeDashoffset:0}); That's basically what DrawSVG does under the hood, but it's much easier to drop in start and stop percentages. There's also no need to get all the path lengths and set the dashArray plus it's all done with one line. Hopefully that helps. Happy tweening. 2 Link to comment Share on other sites More sharing options...
Share Posted February 23, 2017 For anyone reading this and considering a Club membership - I was just talking to Jack about DrawSVG and he reminded me of some additional benefits of the plugin over the method I listed above. There are several browser bugs that DrawSVG works around such as: IE calling <path>.getTotalLength() locks the repaint area of the stroke to whatever its current dimensions are on that frame/tic Firefox throws an error if the element isn’t visible and you call getBBox() Plus DrawSVG works with all shape types (even though <path> is the only one that has a getTotalLength() method). Bottom line - a brute force approach can work, but the DrawSVG plugin prevents headaches & saves time and we all know time is money, right? Happy tweening. 1 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