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

# Challenge: Convert SVG path to Bezier anchor and control points

Go to solution Solved by jamiejefferson,

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax.

## 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

• 1
##### Share on other sites

• Solution

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

• 3
##### 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

• 4
##### 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

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.

• 4
##### Share on other sites

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

Great Job Rodrigo and Jamie .. really awesome!

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

• 2

##### 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 ?

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

##### 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.

• 1
##### 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!

##### 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

##### 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)```
• 3
##### Share on other sites

Pretty Awesome Carl

##### 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

##### Share on other sites

Hi Liam@II

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

`bezier:{type:"cubic",values:points,autoRotate:true}`
• 1
##### 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

##### 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

##### Share on other sites

Hi flysi3000

pls check this out :

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

##### 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?

##### 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);```
• 2
##### 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?

##### 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/

##### Share on other sites

Thanks @OSUblake (:

##### 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!!

##### 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.

• 2
##### 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!