Jump to content
Search Community

draggable knob - positioned by tap (touch)

TirochH 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

example.jpg.eb2f83352ed960e128b8132ce96df4db.jpg

 

I don't find an example from the draggable knob that does following (based on my codepen live example):

 

- knob is on position  15  percent

- I tap (touch) on position 70 percent

- knob moves to position 70 percent

 

It is only possible to tap and move (drag) to that position.

 

I don't find anything in your docu.  A "simple" answer from you will be "tap or touch" is not "drag". But this doesn't help me.

 

A link that explains what I want. https://radmie.github.io/ng-knob/

 

My link to my codepen live example. I want only show the missed functionality (compared to the upper example, based on ng-knob). For a review it's to complex.

But interesting for you. Hopefully. When you want play with different predefined variants than change line 20 in "JS". 

See the Pen eGqbNL by TirochH (@TirochH) on CodePen

 

Here a link from a "simple"  example from "Greensock" with the same missed functionality (with rotation angle, instead percentage).

See the Pen eWNRpe by PointC (@PointC) on CodePen

 

Hans

Link to comment
Share on other sites

After spending some I managed to partially implement it, just to realize it will be a lot simpler if there is any helper function that returns the angle of clicks respect to center. As technically you don't really need anything from Draggable, you just need angle/rotation and update GUI based on it.

 

See the Pen EbayVy by Sahil89 (@Sahil89) on CodePen

 

@OSUblake welcome back, hope you are well now.

 

Does GSAP have any helper functionality that will return the angle of clicks?

  • Like 1
Link to comment
Share on other sites

3 minutes ago, Sahil said:

Does GSAP have any helper functionality that will return the angle of clicks?

 

No, but it looks like the latest version of Draggable has a rotationOrigin property, which might be of useful as using getBBox for the center probably won't be correct.

Link to comment
Share on other sites

12 minutes ago, OSUblake said:

I think that is so you can use it with pointerX/pointerY properties, which are like pageX/pageY. However, I'm not exactly sure as I just noticed the rotationOrigin properties today, so @GreenSock would need to clarify their intended use.

 

Thank you for your idea's.

 

I also think that GreenSock need to clarify this.

 

My expectation is a integrated functionality, comparable with ng-knob.

 

The other alternative is, that I implement it with the same logic as ng-knob. I think it  is d3.js 

I have to explore it. The svg's in my example based on d3 v4.

 

Hans

Link to comment
Share on other sites

Maybe @GreenSock can add a feature for this because I don't see easy way to do it. Rotating the draggable to where you click isn't the problem, it's once you start dragging, the rotation gets out of sync.

 

The only way I can see doing this at the moment is to manually enable draggable with regular events.

 

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

 

  • Like 2
Link to comment
Share on other sites

Quote

Maybe @GreenSock can add a feature for this because I don't see easy way to do it.

 

Ya it can be very useful if there was option to get mouse position/angle from center(or any point as well maybe?). If you remember last question you solved involving this pen, it could have been solved very easily if there was way to get mouse angle. It can be used for parallax effects as well if support for all mouse events is added just to get mouse position.

 

My request would be,

  1. Method to get mouse position relative to target.
  2. Mouse angle respect to center and if possible any point passed using absolute values or percent.

What do you think?

 

@OSUblake What would be right approach to get element position irrespective of it's parent, for both DOM and SVG?

  • Like 2
Link to comment
Share on other sites

1 hour ago, Sahil said:

 

@OSUblake What would be right approach to get element position irrespective of it's parent, for both DOM and SVG?

 

For screen coordinates...

 

Relative to the viewport.

var rect = element.getBoundingClientRect();
var x = rect.left;
var y = rect.top;

 

Relative to the document.

var rect = element.getBoundingClientRect();
var x = rect.left + window.pageXOffset;
var y = rect.top + window.pageYOffset;

 

But there's a big gotcha. If the element has rotation/skew applied to it, the coords might not be what you are expecting. The getBoundingClientRect method returns a rectangle that is axis-aligned, like I explain here for getBBox.

 

 

  • Like 1
Link to comment
Share on other sites

7 hours ago, OSUblake said:

 

For screen coordinates...

........

But there's a big gotcha. If the element has rotation/skew applied to it, the coords might not be what you are expecting. The getBoundingClientRect method returns a rectangle that is axis-aligned, like I explain here for getBBox.

.............

 

 

my viewpoint is:

 

we need a draggable KNOB in 2 variants:

- one with the greensock's functionality (its a knob that spins)

- a second with the functionality of  https://radmie.github.io/ng-knob/ (this is, what needed functionality I described)  

 

From my point of view is this functionality with low manpower possible to build in Draggable-alternate  (=working name)

 When you look in the code  from ng-knob. you need only few lines-of-code.

 

To combine this functionality global is a hard way and only necessary in some preselected parts,

 

Hans

 

Link to comment
Share on other sites

Quote

- a second with the functionality of  https://radmie.github.io/ng-knob/ (this is, what needed functionality I described)  

 

Those are UI components, not something that GreenSock does out of box, GreenSock is library rather than a framework. Though I do feel that the required functionality is missing to achieve what you are trying to do. Personally I would be disappointed if I have to rely on yet another library to make something work or write a lot of code to make draggable work in certain way. I am eager for @GreenSock's response on this.

 

Quote

When you look in the code  from ng-knob. you need only few lines-of-code.

 

I doubt you will get out of box solution for this from GreenSock where you can write few lines of configuration code to that kind of UI component. At best you will get few utility functions that will help you implement it on your own. If your expectation is to write 10-15 lines of configuration then you should use ng knob instead.

  • Like 2
Link to comment
Share on other sites

Dear Sahil, dear Greensock support,

 

i learned that I have exactly define what I want:

 

I want a callback function that returns the rotation position where I touched (not dragged) the wheel.

e.g.: .onTouchwithoutDrag or .onTouchwithoutMove or .onTap or .onClick. (.onClick exists, but with annother functionality).

THIS IS THE SAME REQUIREMENT DEFINITION - IN OTHER WORDS - AS YOU  (SAHIL) POSTED ON MONDAY 11:03 AM.

 

All other input should only be a more detailed explanation.

 

I hope that this is more clear. I do not want a UI functionality. This I build by my own.

But it is clear, I need this functionality to build a UI. But from my view, all people who use Greensock Draggable build - more or less - a high sophisticated (animated) UI by their own.

 

The only reason, why I used external libraries is to ease my life and not make it more complicated. This is the message I want send. Thats the reason I discussed this topic more intensively and more emotional. 

 

I read in this forum, that the business model from Greensock based on the principle to extend their functionality. The question from me is, in which direction?  This is the job from Greensock to clearly define this. I also expect that the support help users such me to define a way that solves the problem, for me and for Greensock.

 

But my minimal expectaction is to get an anwer. A positive nor negative. No answer is the situation now.

 

Sorry.

 

Hans

Link to comment
Share on other sites

Here ya go: 

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

 

That forked pen shows how you can get the angle from the mouse position to the rotation origin. We end the drag and start it again after we adjust the rotation correctly. Here's the JS: 

var rotationOffset = 90, //in case the dial's "home" position isn't at 0 degrees (pointing right). In this case, we use 90 degrees.
    RAD2DEG = 180 / Math.PI, //for converting radians to degrees
    adjusting;

TweenLite.set("#spinner", {transformOrigin: "center"});

Draggable.create("#spinner", {
    type: "rotation",
    onPress: function(e) {
        if (!adjusting) {
            //figure out the angle from the pointer to the rotational origin (in degrees)
            var rotation = Math.atan2(this.pointerY - this.rotationOrigin.y, this.pointerX - this.rotationOrigin.x) * RAD2DEG;
            //set the rotation (with any offset that's necessary)
            TweenLite.set(this.target, {rotation:rotation + rotationOffset});
            //now we'll end the drag and start it again from this new place, but when we start again, it'll call the onPress of course so to avoid an endless loop, we use the "adjusting" variable to skip it in the triggered onPress.
            adjusting = true;
            this.endDrag(e);
            this.startDrag(e);
            adjusting = false;
        }
    }
});

 

Does that help? 

  • Like 3
  • Thanks 1
Link to comment
Share on other sites

27 minutes ago, GreenSock said:

That forked pen shows how you can get the angle from the mouse position to the rotation origin. We end the drag and start it again after we adjust the rotation correctly.

 

I was trying something similar to that, disable -> enable -> startDrag, and maybe an update somewhere, but kept getting call stack errors. Guess it was calling the same function over and over. Didn't think about that one.

 

8 minutes ago, Sahil said:

any smarter way to convert angle returned by atan2 to a 360 degree angle? In my solution I had used following code to adjust angle,

 


if(clickRotation >= -90){
  clickRotation += 90;
}else{
  clickRotation += 450;
}  

 

 

I'll post some helper angle functions I use.

  • Like 3
Link to comment
Share on other sites

Here is one example I have stitched together, I am still not good at SVGs so I haven't spent much time fixing it, but you should get the idea. Now you just need to place the triggering element on top of it with opacity 0 and you should be able to update UI however you want.

 

Ignore where the blue dialer points. Notice how I am using offset and rotation to calculate drawSVG.

 

See the Pen wPKOOY?editors=0011 by Sahil89 (@Sahil89) on CodePen

 

@OSUblake @GreenSock What changes when using pseudo target on Draggable with type 'rotation'? I tried using it with '#spinner' as trigger, but I was getting weird angles.

Link to comment
Share on other sites

I didn't quite understand your question, @Sahil. Are you asking how to make the blue #spinner sit right on top of your other dial so that the rotational angles match up? 

 

In case it's helpful, here's a fork of one of Chris Gannon's codepens that seems to be along the lines of what you're trying to accomplish: 

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

 

I'm sure it could be made into a more reusable component with parameters that'd draw the SVG dial and wire it up accordingly. 

  • Like 2
Link to comment
Share on other sites

Thanks. My idea was to keep UI separate from the target, so I tried to use proxy target '<div />' with '#spinner' as trigger. Hoping that it will work normally like many other slider examples I had seen that use proxy target. But it doesn't return expected angles.

 

EDIT: I meant to say what is difference when using proxy on Draggable of type 'rotation' as it behaves differently.

Link to comment
Share on other sites

Hm, I'm still a little fuzzy on what you mean. The reason the angles seemed odd in your demo was because your proxy wasn't positioned correctly. The angles were perfectly valid for the proxy object (move your mouse around the proxy and you'll see). Does that make sense? Just move the proxy to where it's supposed to be (so the rotation origin is on top of the "real" one). 

Link to comment
Share on other sites

I meant this, I am using trigger to rotate target element. My assumption was that if we use trigger, everything will be calculated based on trigger but in this case mouse starts responding on trigger but rotation is still calculated from the target element.

 

See the Pen POZBqb by Sahil89 (@Sahil89) on CodePen

 

EDIT: Reason I was trying to do it this way and still hoping to is, so if there is any crazy UI that someone wants to do, their interface won't be blocked by the triggering div.

 

PS: :D so silly of me to suggest OP to use that dialer as overlay rather than simple div.

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