Jump to content
Search Community

Creating a Wheel of Fortune – That little ticker bit

jh3y test
Moderator Tag

Recommended Posts

Hey y'all! 👋

 

I've tried digging around in the forums a bit for kinda what I'm looking for but some of the threads are pretty old and I'm wondering if there's maybe a newer/easier way to achieve this effect.

 

What I'm looking to do is create a spinning wheel that will land on a section with maybe some bounce back. My first thoughts are GSAP Draggable with rotation type and inertia which will get me most of the way. But, it's that little ticker piece at the top. How would you think to approach that? And potentially have it push back when the acceleration is slowing down from the inertia?

 

Is it purely a case of tapping into the callbacks and trying to work it out based on the state of the Draggable? And could you somehow sync a repeating animation of the ticker to sync with the acceleration of the Draggable?

 

I'm just sort of putting it out there. I haven't sat down to properly put something together yet. Attached is a very rudimentary CodePen with Draggable and Inertia in place. But, these were the first ideas that came to mind for approaching it. And there may be a much cleverer way of achieving it.

 

Thanks for all you're doing!

 

– Jhey ʕ •ᴥ•ʔ

See the Pen c1734f9bbdc58bdde1542aaee94b7fbf by jh3y (@jh3y) on CodePen

  • Like 1
Link to comment
Share on other sites

Hi,

 

I would start by tapping into the snap function in Draggable. Also keep in mind that enabling inertia expands the configuration options of Draggable. From the docs:

If inertia: true is defined, you may also use any of the following configuration properties that apply to the movement after the mouse/touch is released:

  • snap : [Function | Object | Array] - Allows you to define rules for where the element can land after it gets released. For example, maybe you want the rotation to always end at a 90-degree increment or you want the x and y values to be exactly on a grid (whichever cell is closest to the natural landing spot) or maybe you want it to land on a very specific value. You can define the snap in any of the following ways:
    • As a function - This function will be passed one numeric parameter, the natural ending value. The function must return whatever the new ending value should be (you run whatever logic you want inside the function and spit back the value). For example, to make the value snap to the closest increment of 50, you’d do snap: function(endValue) { return Math.round(endValue / 50) * 50; }.
    • As an Array - If you use an array of values, InertiaPlugin will first plot the natural landing position and then loop through the array and find the closest number (as long as it’s not outside any bounds you defined). For example, to have it choose the closest number from 10, 50, 200, and 450, you’d do snap: [10,50,200,450].
    • As an object - If you’d like to use different logic for each property, like if type is "x,y" and you’d like to have the x part snap to one set of values, and the y part snap to a different set of values, you can use an object that has matching properties, like: snap:{x: [5,20,80,400], y: [10,60,80,500]} or if type is "top,left" and you want to use a different function for each, you could do something like snap: {top: function(endValue) { return Math.round(endValue / 50) * 50; }, left: function(endValue) { return Math.round(endValue / 100) * 100; }}. You can define a points property inside this object that combines both x and y, like liveSnap: {points: [{x: 0, y: 0},{x: 100, y: 0}], radius: 20} which will snap to any point in the array when it’s within 20px (distance). Or you can even use a function-based value to run your own snapping logic, like liveSnap: {points: function(point) { //run custom logic and return a new point }}. See the snapping section of this page for examples.
  • onThrowUpdate : Function - A function that should be called each time the InertiaPlugin tween updates/renders (basically on each “tick” of the engine while the tween is active). This only applies to the tween that gets generated after the user releases their mouse/touch - the function is not called while the user is dragging the element (that’s what onDrag is for). By default, the scope of the onThrowUpdate is the Draggable instance itself, but you may define an callbackScope if you prefer, just like any other tween.
  • onThrowComplete : Function - A function that should be called when the InertiaPlugin tween finishes. This only applies to the tween that gets generated after the user releases their mouse/touch - the function is not called immediately when the user releases their mouse/touch - that’s what onDragEnd is for. By default, the scope of the onThrowComplete is the Draggable instance itself, but you may define an callbackScope if you prefer, just like any other tween.
  • throwResistance : Number - A number (1000 by default) that controls how much resistance or friction there is when the mouse/touch is released and momentum-based motion is enabled (by setting inertia: true). The larger the number, the more resistance and the quicker the motion decelerates. (requires InertiaPlugin and setting inertia: true, otherwise throwResistance will simply be ignored.)
  • maxDuration : Number - The maximum duration (in seconds) that the kinetic-based inertia tween can last. InertiaPlugin will automatically analyze the velocity and bounds and determine an appropriate duration (faster movements would typically result in longer tweens to decelerate), but you can cap the duration by defining a maxDuration. The default is 10 seconds. This has nothing to do with the maximum amount of time that the user can drag the object - it’s only the inertia tween that results after they release the mouse/touch. (requires InertiaPlugin and setting inertia: true, otherwise maxDuration will simply be ignored.)
  • minDuration : Number - The minimum duration (in seconds) that the kinetic-based inertia tween should last. InertiaPlugin will automatically analyze the velocity and bounds and determine an appropriate duration (faster movements would typically result in longer tweens to decelerate), but you can force the tween to take at least a certain amount of time by defining a minDuration. The default is 0.2 seconds. This has nothing to do with the minimum amount of time that the user can drag the object - it’s only the inertia tween that results after they release the mouse/touch. (requires InertiaPlugin and setting inertia: true, otherwise minDuration will simply be ignored.)
  • overshootTolerance : Number - Affects how much overshooting is allowed before smoothly returning to the resting position at the end of the tween. This can happen when the initial velocity from the flick would normally cause it to exceed the bounds/min/max. The larger the overshootTolerance the more leeway the tween has to temporarily shoot past the max/min if necessary. The default is 1. If you don’t want to allow any overshooting, you can set it to 0.

 

Maybe something like this could provide a good starting point:

Draggable.create('.wheel', {
  type: 'rotation',
  inertia: true,
  throwResistance: 5000,
  maxDuration: 1.5,
  snap: function(value) {
    return Math.round(value / 10) * 10;
  },
})

Hopefully this helps getting started.

Happy Spinning!

  • Like 1
Link to comment
Share on other sites

Thanks for the replies people! 🤙 Sorry if I wasn't clear @Rodrigo, I had an idea about what I was going to do for the Draggable part. It was animating the little ticker part so it syncs up with the inertia of the wheel I hadn't attempted in my head yet 😅

 

@Cassiehas come in with an awesome starting point! 🙏 That's pretty much there. I guess it'll just be a case of fiddling with the keyframes/timing of the ticker so I can almost scrub the ticking/clicking. It won't have to be super accurate for the demo I'm presenting. But, I'm always curious how close we can get with these things or what crafty techniques come out of exploring.

 

– Jhey \ʕ •ᴥ•ʔ/

  • Like 2
Link to comment
Share on other sites

Thanks for sharing them @Shrug ¯\_(ツ)_/¯ 🙏

 

Yeah, if I were doing a "Click to spin", I think I'd have already built it and moved on haha. But, the issue here was more about syncing with Draggable and Inertia. I want people to be able to grab and spin the wheel. It's an additional mechanic to the demo I'm presenting.

Link to comment
Share on other sites

One thing mine doesn't do is flick the other way when you spin the wheel the opposite direction. The velocity value is negative or positive based on direction, so that might be a start. You could set up a reversed ticker if it's spinning the other way. Something along those lines!

 

Taking all my willpower not to get distracted with this fun thing and carry on bug hunting 😂

Drop by when you've finished it, always like seeing where your demos end up!

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