Jump to content

Codepen Notification

You didn't provide a codepen sample that illustrates the problem. It really helps us quickly identify problems. This isn't mandatory, but it will get you better/faster results. Would you like to add one?

Draw Svg polygon

Started by 335, Feb 17 2017 03:03 PM svg draw javascript

7 replies to this topic
335
  • 335
  • 1 Like
  • 17 posts

Post #1 by 335 , 17 February 2017 - 03:03 PM

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!




  • Back to top

PointC
  • PointC
  • 2,081 Likes (Superhero)
  • 1,002 posts

Post #2 by PointC , 17 February 2017 - 04:08 PM

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.c...ygon-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.

:)


If you only travel from point a to point b, you won't find me because I'm PointC.

Real name: Craig | Home base: Seattle area
Forum answers: always well-intentioned, usually accurate, not necessarily guaranteed.

CodePen: http://codepen.io/PointC/  |  Twitter: https://twitter.com/Craig_PointC

  • Back to top

335
  • 335
  • 1 Like
  • 17 posts

Post #3 by 335 , 20 February 2017 - 12:23 PM

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.


  • Back to top

PointC
  • PointC
  • 2,081 Likes (Superhero)
  • 1,002 posts

Post #4 by PointC , 20 February 2017 - 06:28 PM

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.

:)


If you only travel from point a to point b, you won't find me because I'm PointC.

Real name: Craig | Home base: Seattle area
Forum answers: always well-intentioned, usually accurate, not necessarily guaranteed.

CodePen: http://codepen.io/PointC/  |  Twitter: https://twitter.com/Craig_PointC

  • Back to top

Jonathan
  • Jonathan
  • 3,360 Likes (Superhero)
  • 2,915 posts

Post #5 by Jonathan , 20 February 2017 - 07:03 PM

Very helpful PointC :)


  • Back to top

335
  • 335
  • 1 Like
  • 17 posts

Post #6 by 335 , 23 February 2017 - 11:25 AM

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!


  • Back to top

PointC
  • PointC
  • 2,081 Likes (Superhero)
  • 1,002 posts

Post #7 by PointC , 23 February 2017 - 07:25 PM

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.

:)


If you only travel from point a to point b, you won't find me because I'm PointC.

Real name: Craig | Home base: Seattle area
Forum answers: always well-intentioned, usually accurate, not necessarily guaranteed.

CodePen: http://codepen.io/PointC/  |  Twitter: https://twitter.com/Craig_PointC

  • Back to top

PointC
  • PointC
  • 2,081 Likes (Superhero)
  • 1,002 posts

Post #8 by PointC , 23 February 2017 - 09:05 PM

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.

:)


If you only travel from point a to point b, you won't find me because I'm PointC.

Real name: Craig | Home base: Seattle area
Forum answers: always well-intentioned, usually accurate, not necessarily guaranteed.

CodePen: http://codepen.io/PointC/  |  Twitter: https://twitter.com/Craig_PointC

  • Back to top




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

3rd Party Advertisement