Jump to content
Search Community

Tween to first point of path

swampthang test
Moderator Tag

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

I'm playing around with a whiteboard drawing idea where a hand with a pen draws in the SVG. (i know it's not really a new idea - just playing around with it)


I've got it working but when the hand jumps to start drawing in a new line, it's immediate. Wondered what the best way to tween the hand to the first coordinate of a bezier curve would be.


Is there some built-in GSAP magic or should I create a bezier from the current point of the hand to the first point of the next line? Any ideas?

See the Pen xEyQGB by swampthang (@swampthang) on CodePen

Link to comment
Share on other sites

Ran across another issue. In my app, I wrap every SVG in a group so it can be moved using x/y coords. The group also contains some transform handles so it can be scaled. Is there a way using MorphSVGPlugin.pathDataToBezier to compensate for a resized SVG?


I wondered if there was a scale factor that could be passed that would rewrite the bezier to the scaled SVG?


Here's a codepen showing that the drawing tool is still trying to draw the original size.


See the Pen bwOLjb?editors=1010 by swampthang (@swampthang) on CodePen

Link to comment
Share on other sites

Ah! Your code keeps changing. Once you post a pen, you should create a fork if you want to change it so it doesn't confuse other people.


Sounds like you might be heading into some nasty territory working with nested transforms. The polyfill I posted on the SVG gotchas should help you out. You can pass in a matrix to MorphSVG like this.

var root = $("#stage-master")[0];
var t = path.getTransformToElement(root);    

var bzPath = MorphSVGPlugin.pathDataToBezier(data, {
  matrix: [t.a, t.b, t.c, t.d, t.e, t.f]

And MorphSVG can help split those compound paths up. This method returns an array of arrays with the coords for each subpath. 

var beziers = MorphSVGPlugin.pathDataToRawBezier(path);

for (var bezier of beziers) { 
  var data = ["M", bezier.shift(), bezier.shift(), "C", ...bezier].join(" ");

Check it out. Now it can draw rotated graphics.

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



  • Like 2
Link to comment
Share on other sites

Loved the first demo you provided! Looks very nice. Took me back to a project I had a very minor role on a gazillion years ago with Flash: http://www.impossibility.com/new-gallery-1/


That reminds me of this pen. It uses GSAP, Paper.js, and Three.js to draw on a canvas with a 3d pencil. 

See the Pen yJJxRj?editors=0010 by markmanx01 (@markmanx01) on CodePen

  • Like 1
Link to comment
Share on other sites

Ran across a puzzling thing. I copied Blake's code and created a new pen here... 

See the Pen KgbxKR?editors=1010 by swampthang (@swampthang) on CodePen


I'm testing different SVGs and one of them is some text that was converted to an SVG. When this section of the code runs:

var paths = document.querySelectorAll(`${svgID} path`);

var newPaths = breakApartPaths(paths,$(svgID)[0]);

for( path of paths ) {
for( path of newPaths ) {

... in the first iteration of the loop to removeChild paths, I get the following error:


Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.


Trying to figure this out. There are 6 paths in the paths array and it gets set just above.  

UPDATE: Oh, duh! removeChild looks for a direct descendant and the paths are in a group. 


Changed it to...

$(`${svgID} path`).remove();

Works fine. 

Link to comment
Share on other sites

This is twisting my noggin. I need to be able to set the drawing point for the pencil because there are times it needs to be rotated to either point down, up, sideways or even look like a left-hander's pencil. 


I have a draggable instance attached to the pencil so thought I should be able to use onPress to capture the mouse coords - pointerX and Y - and translate the offset for the drawing tool. Proving to be a little taller order than I thought it would be. I forked Blake's winning codepen above that is able to draw in an SVG even after it's rotated. 

See the Pen kkVmBR?editors=1010 by swampthang (@swampthang) on CodePen


I need to go back and really study the formulas involved in this. My brain is going "tilt!"

Link to comment
Share on other sites

When i view your codepen in Firefox on Windows 10 .. the pencil icon is not aligned with the point that is being drawn.


Also i would second Blakes advice on not to nest transforms. Since the origin will always change throwing off its child orientation.



The fact that it doesn't align is the issue. I need to be able to click to set the offset point but the draw tool might be rotated by the user.


The group that wraps the SVG is necessary because, in the app, it's the wrapper for the SVG that gets dragged around on the stage area and to which has transform handles attached. One handle resizes the SVG and the other rotates the group. I had removed the transform handle elements.


Also, this is an app being built in Electron which only uses the Chromium browser. 


(There was an extra group in there but wasn't being used. I've gotten rid of the extra group in both the SVGs so you can see what I'm talking about.)

Link to comment
Share on other sites

Thanks, Blake. Yea, makes sense. Added that and a check for scaling and it works as long as I don't rotate the group wrapping the pencil. As soon as I add rotate, I'm not sure how to incorporate that. Working on it. Not sure what to change if it's rotated say 180 deg and the click occurs on the rotated element.


See the Pen amXAJk by swampthang (@swampthang) on CodePen


Oh, and I won't touch the pen above. Forked and working on a fork.

Link to comment
Share on other sites

Is the user setting the point of the pencil, or were you only doing that to figure out the rotated point?


If the user is not setting the point, then you can use the point of the pencil for matrix transform.

var pencil = { x: 0, y: 123 };

function setOffset() {  
  pt.x = pencil.x;
  pt.y = pencil.y;  
  pt = pt.matrixTransform(handGp.getTransformToElement(stage));
  offsetCoords.x = -(pt.x - handGp._gsTransform.x);
  offsetCoords.y = -(pt.y - handGp._gsTransform.y);

See the Pen ZpPxYO?editors=0010 by osublake (@osublake) on CodePen



Link to comment
Share on other sites

Thanks, Blake. Yea, the user is setting the point. They can rotate the pencil, resize it, etc. So I've got to give them a way to click the tip of the drawing tool - could be almost anything actually - even like a little circle (which obviously doesn't have a tip - ha!) or a small design, or an airplane, etc. Gonna add the ability at that point to autoRotate. 

Link to comment
Share on other sites

Rethinking this. Your idea of setting it on the pencil is actually a better one in combination with the user clicking the drawing point. I'm thinking, if the drawing point gets set and the user wants to then rotate the pencil and draw something else, couldn't I store the initial coords relative to the pencil like you have it in your pen above and use that no matter how it gets transformed? 

Link to comment
Share on other sites

  • 1 month later...

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