GRDC

Draggable SVG element which is also rotatable

Recommended Posts

Hello,

 

I'm attempting to make an SVG element (which is already draggable) rotatable by using a handle positioned at the bottom right of the element.  I have done this in the past on a div (not SVG) with the jQuery rotatable plugin, which came pre-packaged with this functionality.   Does anyone have advice on how to proceed on this to perform the same with SVG using GSAP?

Share this post


Link to post
Share on other sites

Sounds like it should be possible with the proper nesting of DOM elements and Draggables.

Something like making a child rotatable and its parent draggable.

Probably easier to help if you provided a demo that showed what you have in place already. 

  • Like 1

Share this post


Link to post
Share on other sites

Hi,

 

If you can get a number for the bounds or limit of your drag instance, you'll know the max value of a specific property of that instance. Then all you have to do is transform that number to something between 0 and 1 and use that number as the progress of a tween that rotates the element.

 

Perhaps this simple set up could help you get started:

 

http://codepen.io/rhernando/pen/Batoc

  • Like 1

Share this post


Link to post
Share on other sites

Hi Reanimator,

 

Taking off from the example in this thread, what you can do is change your draggable's instance type (rotation, x/y) depending on where you click. So if you click on the element, make it type x,y. If you click on the handle, change your draggable instance to type rotation.

 

http://codepen.io/osublake/pen/RNZxJx

  • Like 3

Share this post


Link to post
Share on other sites

Hi guys :)

 

for DOM base you can use something like this too , but seems there's an issue with SVG <g> !!! ( or at least i can't figure out how)

i think for now you can solve that ( svg <g> ) with something like Rodrigo solution .

var drag = $(".base"), handle = $(".knob");

var r = Draggable.create(drag, { type: "rotation"})[0].disable();
var m = Draggable.create(drag,{type: "x,y"})[0].enable();


$(handle).on("mousedown", function(event) {
  event.stopPropagation(); 
  m.disable();
  r.enable().startDrag(event);
});

$(drag).on("mousedown", function(event) {
  r.disable();
  m.enable().startDrag(event);
});

http://codepen.io/MAW/pen/zxdWNm

  • Like 3

Share this post


Link to post
Share on other sites

Diaco, 

 

I like what you did! I didn't know you could have different draggables associated with the same element. Nice to know.

  • Like 1

Share this post


Link to post
Share on other sites

Of course there isn't any problem with SVG tag , try doing that with <g> tag :geek:  :) ...

<g id="base" >
  <rect width="250" height="150" rx="10" ry="10" style="fill:green" />
  <circle class="knob" r="10" cy="130" cx="230" style="fill:red" />  
</g>

Share this post


Link to post
Share on other sites

Thanks all for the advice and examples.  OSUBlake's SVG example is exactly what I'm looking for, and far more simple than creating two separate draggable elements, one of which (the handle) you would have to observe from starting position to ending position.

 

Diaco's example is similar to what I'm currently doing, but done through the jQuery.rotatable() plugin.

 

Cheers to an excellent group of coders and a platform that continues to impress.

Share this post


Link to post
Share on other sites

Hi reanimator  :)

 

If you're interested , now with new version ( 1.16.0 ) you can even have <g> tags Draggable rotatable + moveable , with same method :

 

something like this :

 

http://codepen.io/MAW/pen/QwxXgx

 

GSAP ( version 1.16.0 ) : CSSPlugin recognizes a new "svgOrigin" special property that allows you to set the transform origin based on absolute SVG coordinate system which can be more convenient than transformOrigin (which is relative to the element's own top left corner). svgOrigin always trumps transformOrigin if both are set. So you can do TweenLite.to(svgElement, 1, {rotation:270, svgOrigin:"250 100"}) if you'd like to rotate svgElement as though its origin is at x:250, y:100 in the SVG canvas's global coordinates. It also records the value in the data-svg-origin attribute so that it can be parsed back that way as well. svgOrigin doesn't accommodate percentage-based values.

  • Like 3

Share this post


Link to post
Share on other sites

How could you rotate such a circle according to the system time and use it like a clock while not dragging with the mouse?

Share this post


Link to post
Share on other sites

Hi mcweb and welcome to the GreenSock forums.

 

Our support is very focused on the GreenSock API. Providing instructions on how to program a clock is way beyond the support we offer.

Perhaps try studying this: http://codepen.io/chrisgannon/pen/MYMMxx or searching CodePen for some more clock examples, just to get a handle on the various techniques and find one that appeals to you.

 

If you have any questions pertaining to GSAP, we welcome you to post a new topic.

 

Thanks!

  • Like 2

Share this post


Link to post
Share on other sites

already looked at this one your suggestions looks pretty interesting too :) thank you for your help 

Share this post


Link to post
Share on other sites

Hi mcweb and welcome to the GreenSock forums.

 

Our support is very focused on the GreenSock API. Providing instructions on how to program a clock is way beyond the support we offer.

Perhaps try studying this: http://codepen.io/chrisgannon/pen/MYMMxx or searching CodePen for some more clock examples, just to get a handle on the various techniques and find one that appeals to you.

 

If you have any questions pertaining to GSAP, we welcome you to post a new topic.

 

Thanks!

 

Hi @Carl and @Diaco,

that a great example, however it seems to play up a bit if there are nested svgs. Dragging seems to work fine but the rotation looks a bit off. Here is an example:

 

http://codepen.io/praneybehl/pen/xGmygp?editors=101

 

Any ideas on how can this be fixed?

 

Thanks

Share this post


Link to post
Share on other sites

Hi Praney Behl  :)

 

i'm a bit confused about what you mean by SVG nested in another SVG ( in your demo ) !?... does it make sense !

Share this post


Link to post
Share on other sites

Hi Praney Behl  :)

 

i'm a bit confused about what you mean by SVG nested in another SVG ( in your demo ) !?... does it make sense !

Thanks for the reply mate,

I am working on something that needs an svg to have overflow:visible so to achieve that, I had to nest the svg inside another to have the overflow visible.

Now the inner SVG has elements that are draagable and rotatable. So has mention draggable works fine but when trying to rotate it plays up.

 

http://codepen.io/praneybehl/pen/xGmygp?editors=101

Share this post


Link to post
Share on other sites

hmm , pls add this to your css :

svg{ overflow : visible; }
  • Like 1

Share this post


Link to post
Share on other sites

 

hmm , pls add this to your css :

svg{ overflow : visible; }

 

Yeah I thought that should work and tried it yesterday, but for some odd mistake it just wouldn't work for me and today I found this post so I thought i'll ask.

Dang! too much high I guess :P. I feel so stupid right now - <hitting my head>

 

Thanks for the refresher mate.

  • Like 1

Share this post


Link to post
Share on other sites

 

hmm , pls add this to your css :

svg{ overflow : visible; }

 

Hey,

Ok I found why I had to nest the svgs, with svg{ overflow : visible; } draggable doesn't detect svg element when it is in the overflow region in Safari browser. 

Is it just me or Safari or is it something in Draggable.js

 

Here try this in Safari:

http://codepen.io/praneybehl/pen/BNvEMv

 

Drag the green element outside and then try to drag it back in.

 

Hope it makes more sense.

Share this post


Link to post
Share on other sites

Hi guys,

 

Just wondering if this a bug with Safari while using draggable on svg overflow? Still waiting for this to be fixed. Hope this gets some traction and I am not the only one suffering this issue.

Maybe I should start a new thread.

Share this post


Link to post
Share on other sites

Sorry that this fell through the cracks - I never saw it. We really try to get every question answered around here in a timely fashion. 

 

I looked at this now and it's definitely a Safari bug that's completely unrelated to Draggable. Basically, Safari ignores mouse events outside of the bounds of the <svg> element itself (where it has drawn its boundaries in the DOM, regardless of whether or not any artwork spills out). You can remove Draggable from the equation completely and see for yourself - try adding some sort of mouse event handlers on your element and place it outside the boundaries of the <svg> and you'll see that they don't trigger at all, even if you set pointer-events:all and clip-path:none. I cannot find a workaround unfortunately. Hopefully Safari will fix it soon. If anyone else has any ideas for solutions, please let us know. 

Share this post


Link to post
Share on other sites

By the way, a solution would be to make sure that your <svg> element is opened as wide as you want to allow dragging, so adjust its width/height accordingly. If you need other stuff clipped inside the SVG, use a clipping path or mask or something. 

  • Like 2

Share this post


Link to post
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.