Jump to content
Search Community

Draggable with SVG elements

SDP 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 am trying to use Draggable to rotate a <g> inside some inline SVG. 

    <script src="http://cdnjs.cloudflare.com/ajax/libs/gsap/1.11.6/TweenMax.min.js"></script>
    <script src="http://cdnjs.cloudflare.com/ajax/libs/gsap/1.11.6/plugins/CSSPlugin.min.js"></script>
    <script src="http://cdnjs.cloudflare.com/ajax/libs/gsap/1.11.6/utils/Draggable.min.js"></script>

...

 

    TweenLite.set(".group1", {transformOrigin:"50% 50%"})
    Draggable.create(".group1", {type: "rotation", throwProps: true });

This will allow the element to be rotated by dragging, but none of the momentum works and the rotation is incorrect in that the movement shifts from clockwise to counter clockwise mid-drag.

Link to comment
Share on other sites

The reason the momentum wasn't working is because you didn't load ThrowPropsPlugin. That's what does all the magic for tracking velocity, calculating the ending points smoothly, implementing slick bounce-back when necessary, etc. It's a membership benefit of Club GreenSock, FYI. http://www.greensock.com

 

As for the rotation strangeness, can you please create a super simple codepen example that demonstrates the issue? http://forums.greensock.com/topic/9002-read-this-first-how-to-create-a-codepen-demo/

Link to comment
Share on other sites

Thanks for the reply. I was under the impression that ThrowPropsPlugin was included in TweenMax.js. (I realize that the code I originally copy/pasted above incorrectly showed TweenLite.js... just corrected it) Does this new information change your advice at all?

Link to comment
Share on other sites

To demonstrate the strange rotation behavior, I created a jsfiddle here: http://jsfiddle.net/s_d_p/sy4AN/7/

 

Just click/drag one of the dots and try to drag a full 360 degree rotation.

 

You'll also see that I'm loading TweenMax and the momentum is not happening either.

 

My hunch is that this has related to the way X and Y coordinates work differently in SVG (the Y axis starts from zero at the top and increases as you move downward). Perhaps this is the problem? Or is this plugin meant to play nice with SVG already?

 

Thanks for your help!

Link to comment
Share on other sites

I haven't had time to look in-depth at this, but I'll mention two things:

  1. As mentioned previously, the momentum isn't working because you didn't load ThrowPropsPlugin. That plugin is NOT included in TweenMax. It is a membership benefit of Club GreenSock
  2. It looks to me like the rotation issue is caused by the browser reporting the SVG's width/height improperly (perhaps) such that it thinks the pivot point (transformOrigin) is in the upper left corner. In other words, even if it correctly discerns that transformOrigin is at "50% 50%", if the width/height is reported by the browser as 0, that will end up being its upper left corner. Have you tried wrapping it in a regular <div> that has the proper width/height set? And then make that <div> the target of your Draggable. Just an idea.
Link to comment
Share on other sites

Thanks Jack.

 

#1 solves the momentum mystery. Thanks for clarifying.

 

#2...

Later I will experiment to see if the <div> wrapper trick works, but ultimately it won't solve my problem because my actual SVG is a bit more complex. (I stripped out some elements to make the demo more readable) So although the jsfiddle makes it seem like a trivial change to just wrap the svg in a div, in my real svg I would end up rotating a bunch of extra elements (that I don't want to) also. Does that make sense?

 

Do I correctly infer from your answer that Draggable does not "officially" support SVG elements? So what I'm trying to do just might not be possible?

 

 

Update: Although it does not solve my problem yet, <div> wrapper trick does perform as expected: http://jsfiddle.net/s_d_p/hNz29/

Link to comment
Share on other sites

Glad to hear the <div> wrapper worked. As for "officially" supporting SVG, we have done no such testing, sorry. In theory, they're supposed to be just like any other element, although I'm no SVG expert. This may be an issue with the browser not reporting information correctly (width/height/offsetWidth/offsetHeight). Do you know if SVG elements fail to support offsetWidth/offsetHeight? 

Link to comment
Share on other sites

Hi,

 

Working on a project with SVG elements, specifically some leafs generated by Illustrator, that had to be animated using GSAP I came into some issues. First the lack of 3D animations in SVG and creating advanced animations for complex paths. For example the leafs had a mix of radial gradients, reason why I didn't use any SVG library. Although SnapSVG has support for radial gradients I didn't have enough time to learn how to replicate the illustrator shapes into Snap elements. Snap or Raphael would've been great because they do allow you to move individual elements in the <svg> parent.

 

Basically this was done using inline SVG and preloading the paths via ajax calls. The main point is that <g> and <path> elements can't be animated in every browser, the only way I found to animate every element was to wrap every path in it's own <svg> tag, which can be moved around with no problem in every browser that supports inline SVG (be aware that Safari 4 and 5 do support SVG but not inline SVG).

 

Perhaps you could try that in your project and create the Draggable instances on the <svg> elements, this can be done easily if you add a class to each element, making selecting far more easy.

 

Rodrigo.

Link to comment
Share on other sites

I'm not an SVG expert either..

 

I wonder if the SVG  animate attribute might be of any use?

Like instead of adding the transform styles to the style attribute of the <g> tag.. but using GSAP to animate the transform values in the SVG transform attribute that excepts CSS transforms:

 

https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform

 

Also what about using GSAP to change the values for these SVG animation tags:

 

SVG animate tag:

https://developer.mozilla.org/en-US/docs/Web/SVG/Element/animate

 

SVG animateTransform tag:

https://developer.mozilla.org/en-US/docs/Web/SVG/Element/animateTransform

 

But since GSAP can animate any JS object and property.. what if a custom proxy function was used so you could animate the CSS transform properties inside the transform attribute with GSAP, instead of the style attribute.

 

Maybe SVG within the browser will allow this type of transform manipulation, while being consistent cross browser,  and be able to report the proper offsetWidth / offsetHeight ???

 

Not sure if it adds to the discussion, but I'm curious if the transform attribute on the <g> tag would behave differently, than styles attribute ?

:)

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