Jump to content
Search Community

Challenge: Convert SVG path to Bezier anchor and control points

Carl
Moderator Tag

Go to solution Solved by jamiejefferson,

Warning: Please note

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

Posted

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
  • Solution
jamiejefferson
Posted

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
Posted

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
Posted

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
Posted

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
  • 2 months later...
Posted

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 ?

jamiejefferson
Posted

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
  • 7 months later...
Posted

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!

Posted

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

Posted

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
  • 1 month later...
Posted

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

Posted

Hi Liam@II  :)

 

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

bezier:{type:"cubic",values:points,autoRotate:true}
  • Like 1
Posted

 

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

  • 1 month later...
Posted

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.

Posted

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? 

Posted

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
  • 2 weeks later...
Posted

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?

  • 8 months later...
Posted

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

Posted

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
Posted

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!

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.
×
×
  • Create New...