Jump to content
Search Community

Draggable SVG element which is also rotatable

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

Posted

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?

Posted

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
Posted

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
Posted

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
Posted

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
Posted

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
Posted

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

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.

  • 1 month later...
Posted

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
  • 1 month later...
Posted

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

Posted

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
Posted

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

  • 3 weeks later...
  • 2 months later...
Praney Behl
Posted

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

Posted

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 !

Praney Behl
Posted

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.

Posted

hmm , pls add this to your css :

svg{ overflow : visible; }
  • Like 1
Praney Behl
Posted

 

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
Praney Behl
Posted

 

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.

  • 8 months later...
Praney Behl
Posted

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.

Posted

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. 

Praney Behl
Posted

Thanks for replying jack.

Posted

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

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