Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
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?

Link to comment
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
Link to comment
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:

 

See the Pen Batoc by rhernando (@rhernando) on CodePen

  • Like 1
Link to comment
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.

 

See the Pen RNZxJx by osublake (@osublake) on CodePen

  • Like 3
Link to comment
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);
});

See the Pen zxdWNm by MAW (@MAW) on CodePen

  • Like 3
Link to comment
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
Link to comment
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>
Link to comment
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.

Link to comment
Share on other sites

  • 1 month later...

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 :

 

See the Pen QwxXgx by MAW (@MAW) on CodePen

 

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
Link to comment
Share on other sites

  • 1 month later...

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

Link to comment
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
Link to comment
Share on other sites

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

Link to comment
Share on other sites

  • 3 weeks later...
  • 2 months later...

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: 

See the Pen MYMMxx by chrisgannon (@chrisgannon) on CodePen

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:

 

See the Pen xGmygp?editors=101 by praneybehl (@praneybehl) on CodePen

 

Any ideas on how can this be fixed?

 

Thanks

Link to comment
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 !

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

 

See the Pen xGmygp?editors=101 by praneybehl (@praneybehl) on CodePen

Link to comment
Share on other sites

hmm , pls add this to your css :

svg{ overflow : visible; }
  • Like 1
Link to comment
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
Link to comment
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:

See the Pen BNvEMv by praneybehl (@praneybehl) on CodePen

 

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

 

Hope it makes more sense.

Link to comment
Share on other sites

  • 8 months later...

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.

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

Link to comment
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
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.
×