Jump to content
Search Community

Challenge: Convert SVG path to Bezier anchor and control points

Carl test
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

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

  • 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 ;)

  • 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

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

 

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

  • 1 month later...
  • 1 month later...

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

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

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