Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
Carl

Challenge: Convert SVG path to Bezier anchor and control points

Recommended Posts

Alright Guys, I have a little challenge / question for you.

 

I really want to be able to get SVG path d attribute data into a format that BezierPlugin can use.

 

 

So given this string M0,0c0,0,14,184,157,184V86h173c0,0,105-3,105,93, I'd want either

 

an array of all the x/y values of all the anchor and control points like

[0,0,0,0,14,184,157,184,157,184,157,86,157,86,157,86,330,86,330,86,330,86,435,83,435,179]

or an array of point objects (which ultimately would get passed to BezierPlugin)

[{x:0, y:0},{x:0, y:0},{x:14, y:184},{x:157, y:184},{x:157, y:184},{x:157, y:86},{x:157, y:86},{x:157, y:86},{x:330, y:86},{x:330, y:86},{x:330, y:86},{x:435, y:83},{x:435, y:179}]

The end goal is draw a continuous path in Illustrator, smack svg  output into an html page, use the svg path for a Bezier tween.

 

This video explains all this in glorious detail: 

 

Does raphael, or snapSVG or any other library offer a convenient conversion method?

It seems that since the same curves can be represented each way it should be easy to convert 1 format to the other, right?

 

I'm not looking to have a robust tool built that analyzes svgs and builds animations automatically, just a function that I can do

convertPath(dPath) {
  ...
  //turn dPath string into an Array of anchor and control points
  return BezierPointData
}

//usage
var bezierAnchorAndControlPoints = convertPath("M0,0c0,0,14,184,157,184V86h173c0,0,105-3,105,93");

Any help is greatly appreciated. 

 

Carl

 

 

p.s: This mission was greatly inspired by Chris Gannon's DrawScript converter: http://gannon.tv/drawscript-to-gsap/ and I'd like to publicly thank Rodrigo for helping me get a good leap into Raphael.

See the Pen c25fcc65f231a291698a2be6ca4c542a?editors=101 by GreenSock (@GreenSock) on CodePen

  • Like 1
Link to comment
Share on other sites

Well Snap (and Raphael) has a pretty handy function to convert the path to cubic data, so 

See the Pen ff30ccf7f3a8b69989142d664325f3b9?editors=101 by jamiejefferson (@jamiejefferson) on CodePen

 

Since Snap is Apache 2, you could probably extract the functions needed to reduce the filesize, but I'm feeling lazy right now ;)

  • Like 3
Link to comment
Share on other sites

Hey Jamie,

Thanks a ton! Very nice. That really is exactly what I was looking for. 

 

Just a little while ago, Rodrigo emailed me privately with pretty much the same solution. (i should have marked this "solved" sooner).

I jammed a "complex" path into his demo and was quite pleased: http://codepen.io/GreenSock/pen/ecdfb83c70724638f83376a0cfad6b26

 

It seems you and Rodrigo were on the same path (ha) using Snap's toCubic().

 

This is really great and I appreciate the help (and seeing how your 2 great minds think alike) I think lots of folks will appreciate this type of functionality. 

 

Best,

 

Carl

  • Like 4
Link to comment
Share on other sites

Hi,

 

Like Jamie points Snap, and therefore Raphael, have this particular method that returns a series of arrays containing the control points and coordinates for every part of the cubic bezier, also the first element of each array is a letter (M or C) so it should be left outside.

 

If someone is interested in Jamie's idea of extracting the code here are the sources of Raphael and Snap:

 

SNAP

https://github.com/adobe-webplatform/Snap.svg/blob/master/dist/snap.svg.js#L5859-L6000

 

RAPHAEL

https://github.com/DmitryBaranovskiy/raphael/blob/master/raphael.js#L2355-L2465

 

Also Jamie's method goes straight to the SVG tag and gets the path from it which gives a lot of flexibility, while the method I came up with uses a string directly on the code in order to get the bezier values.

  • Like 4
Link to comment
Share on other sites

Nice i was up all night trying to convert a PHP script to JS.. but it was all for not. :o

 

Great Job Rodrigo and Jamie .. really awesome!

 

This will save me so much time in the conversion of d path to points. Much appreciated :)

  • Like 2
Link to comment
Share on other sites

  • 2 months later...

I thought TweenMax takes care of the array of points on the curve, when looking at the codePen code there is JS Loops and empty arrays happening before TweenMax is even called, what's up with that ?

hqdefault.jpg

 

One more thing, the curve doesn't orient to the path, is this not possible ?

Link to comment
Share on other sites

It's right there in the title of this topic, and in the code comments:

// convert cubic data to GSAP bezier

The path data from the SVG is a string (which may not be a cubic bezier path), so it needs to be converted to cubic bezier points, and then arranged into the format used by the BezierPlugin.

The documentation for BezierPlugin describes an autoRotate property which orients the object to the path.
 

  • Like 1
Link to comment
Share on other sites

  • 7 months later...

Once I have the array with x/y values for anchors and control points. Is there a convenient method to get a precise point given a position in the path (0 begin and 1 end), and maybe even the rotation (in case of autorotate)?

 

Thanks!

Link to comment
Share on other sites

Once I have the array with x/y values for anchors and control points. Is there a convenient method to get a precise point given a position in the path (0 begin and 1 end), and maybe even the rotation (in case of autorotate)?

 

Thanks!

 

Just realised svg.path has already a getPointAtLength method :S

Link to comment
Share on other sites

Hey nuthinking,

 

Yup, and you can also set the tween's progress() to a value between 0 and 1 and then grab the rotation of the target like

//get rotation of the element when the tween is halfway donetween.progress(0.5).pause();
console.log("rotation = " + tween.target[0]._gsTransform.rotation)
  • Like 3
Link to comment
Share on other sites

Pretty Awesome Carl ;)

Link to comment
Share on other sites

  • 1 month later...

Hi,

 

im looking at this version of the challenge. 

See the Pen dgfbF by leelou (@leelou) on CodePen

id love to know the code to auto rotate the cube.

 

the custom nature of this code is making is hard for me to implement the auto rotate. 

 

id be indebted to the person who can help

 

Liam

Link to comment
Share on other sites

Hi Liam@II  :)

 

pls add autoRotate:true to the bezier object , like this : 

bezier:{type:"cubic",values:points,autoRotate:true}
  • Like 1
Link to comment
Share on other sites

 

Hi Liam@II  :)

 

pls add autoRotate:true to bezier object , like this this : 

bezier:{type:"cubic",values:points,autoRotate:true}

Thanks a million, loving the site. as a Flash dude forced into html5, greensock is a godsend

Link to comment
Share on other sites

  • 1 month later...

Hey guys - can anyone help me figure out why the objects that I'm tweening along a bezier curve are offset in this example? I'm sure I'm missing something obvious...

 

See the Pen LpXXbL by flysi3000 (@flysi3000) on CodePen

Link to comment
Share on other sites

Thanks @Diaco - I see that you tweaked the position of the svg in its style attribute, which is helpful. But now I'm wondering how come the cards snap back to (0, 0) at the end of the tween, rather than just staying at the positions that were set up in the css? 

Link to comment
Share on other sites

you can set positions before the tween : 

See the Pen PPxLWd by MAW (@MAW) on CodePen

 

or

 

you can use onComplete function to set elems at the end of tween : 

 

tl.staggerFrom(["#card1","#card2","#card3"],1,{bezier:{type:"cubic",values:points,autoRotate:true},
  onComplete:function(){
    TweenLite.set(this.target,{ xPercent:0,yPercent:0,x:0,y:0 }) // set position here at the end of tween
  }
}, 0.25);
  • Like 2
Link to comment
Share on other sites

  • 2 weeks later...

So am I right to say if I want to animate an object along a complex path, I will need to include Snap.svg in my script?

Link to comment
Share on other sites

You can use the MorphSVG plugin to do same thing, but in a lot less code.

 

Super simple demo...

See the Pen OyBGyV?editors=001 by osublake (@osublake) on CodePen

 

There are two threads right now that discuss this.

 

http://greensock.com/forums/topic/13220-animating-along-a-path/

 

http://greensock.com/forums/topic/13224-extracting-x-and-ys-from-a-path-inside-a-svg/

Link to comment
Share on other sites

  • 8 months later...

Hi All,

 

I'm trying to implement this technique on my own SVG. But somehow the element  that I'm trying to animate (#gov) always gets out of the picture. I'm not sure how to fix that. 

 

here is the codepen: 

See the Pen NAmwyz by lifvic (@lifvic) on CodePen

 

Thanks!!

Link to comment
Share on other sites

Hi Lifvic,

 

Welcome to the forums.

I found it extremely difficult to read through the complexity of the SVG you created.

I took out everything but the path and added a circle.

 

http://codepen.io/GreenSock/pen/wWkpxL?editors=1010

 

it seems to work fine. 

I think you should try to reduce the svg to the key components as it may help you or us see what needs optimizing.

  • Like 2
Link to comment
Share on other sites

Hi Carl,

 

Thanks for the response! I cleaned up the codepen and it still doesn't work: 

See the Pen NAmwyz by lifvic (@lifvic) on CodePen

 

If you look at the bottom right corner, you will see the #gov element is animated there. It is showing up occasionally.

 

Thank you!

Link to comment
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.
×