335

Draw Svg polygon

  • 8 posts in this topic

8 posts in this topic

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:

 

 

http://codepen.io/i76/pen/vgwKKX

 

 

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!

Share this post


Link to post
Share on other sites

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 people like this

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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 people like this

Share this post


Link to post
Share on other sites

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!

Share this post


Link to post
Share on other sites

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 people like this

Share this post


Link to post
Share on other sites

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 person likes this

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.


Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.