Jump to content
Search Community

How to set the initial position of Draggable elements without creating a snapping offset?

Eunomiac test
Moderator Tag

Go to solution Solved by GreenSock,

Recommended Posts

I'm trying to create a game mechanic where players grab and toss dice to and from each other's home circles.  However, I can't seem to set the initial positions of the dice to within the player circles without creating an offset to their snapping.  This image illustrates what I mean:  The large circles are the player home circles, and the smaller green circles are the dice.  The dice should all snap to the player circles after a throw, but are offset as shown (the dice in the player circles haven't been thrown yet, and are where they were initially positioned).

image.thumb.png.a0ba864d41026755bced3c906b612549.png

If I don't initialize the dice positions (i.e. they all default to the top left of the screen), then the snapping works perfectly, so I know it has something to do with my confusion over offset()/position() and the snap property.  I've linked to my CodePen, but here is where I suspect I'm making my mistake --- either in setting the dice offset, or in how I'm applying the snap coordinates ("wiggle" is just a simple position randomizer, to spread the dice out a bit):
 

const [die] = Draggable.create(
    $(`<div id="${dieID}" />`)
      .appendTo("body")
      .css({
        "position": "absolute",
        "background": `radial-gradient(ellipse, #FFFFFF, ${color} 90%)`,
        "height": 20,
        "width": 20,
        "border-radius": 10,
        "border": `3px solid ${color}`
      })
      .offset({ 
        // If I comment out this offset, the snapping works, but I'd like to initialize
        // the dice to start in one of the circles (not at the top left of the document)
        left: wiggle($(circle).offset().left, $(circle).width(), 0.6),
        top: wiggle($(circle).offset().top, $(circle).height(), 0.6)
      }),
    {
      dragResistance: 0.65,
      type: "x,y",
      inertia: true,
      snap: {
        points: function(point) {
          const closestCircle = getClosestToPoint({
            posX: point.x,
            posY: point.y
          }, CIRCLES, this.startCircle ?? false);
          return {
            x: wiggle($(closestCircle).offset().left, $(closestCircle).width(), 0.6),
            y: wiggle($(closestCircle).offset().top, $(closestCircle).height(), 0.6)
          }
        }
      },
  	// ... events
  }

Any help is much appreciated, and thank you in advance!

See the Pen powQgeM by eunomiac (@eunomiac) on CodePen

Link to comment
Share on other sites

  • Solution

Welcome to the forums, @Eunomiac

 

It may solve things if you just use transforms (x, y) to position things instead of left/top. Right now, you're mixing them, setting the initial position with top/left and then the Draggable is affecting the x/y (transforms). If things work as you'd expect when you have everything at a top/left of 0, that tells me you've set up your logic to depend on that and it's throwing things off to position with top/left. 

 

I don't know for sure, though, because we don't have the resources here to provide free general consulting for solving logic or CSS issues. We love helping with GSAP-specific questions around here, though. Please see the forum guidelines

 

I'd recommend just using transforms (x/y) to do all your positioning and always do it through GSAP. Hopefully that'll solve it for you, but if you still need some help with any GSAP-specific questions, you'll greatly increase your chances of getting an answer if you make your demo simpler (150 lines of code is a lot to ask people to go through). 

 

Good luck! 👍

  • Like 2
Link to comment
Share on other sites

1 hour ago, GreenSock said:

Welcome to the forums, @Eunomiac

 

It may solve things if you just use transforms (x, y) to position things instead of left/top. Right now, you're mixing them, setting the initial position with top/left and then the Draggable is affecting the x/y (transforms). If things work as you'd expect when you have everything at a top/left of 0, that tells me you've set up your logic to depend on that and it's throwing things off to position with top/left. 

 

I don't know for sure, though, because we don't have the resources here to provide free general consulting for solving logic or CSS issues. We love helping with GSAP-specific questions around here, though. Please see the forum guidelines

 

I'd recommend just using transforms (x/y) to do all your positioning and always do it through GSAP. Hopefully that'll solve it for you, but if you still need some help with any GSAP-specific questions, you'll greatly increase your chances of getting an answer if you make your demo simpler (150 lines of code is a lot to ask people to go through). 

 

Good luck! 👍

Thank you for your reply! 

 

Firstly, I apologize for the length of the codepen example; I certainly didn't attach it expecting a full code review, just saw the field in the post form and filled it in for completeness' sake --- I assumed I was making a fairly basic error that could be solved from my description and the bit of code I copied into the post proper.

 

And in that, at least, I was right!  Your advice was exactly what I needed to solve my problem --- thanks again!

Just one clarification regarding the positioning of elements:  When I go on to apply some (non-Draggable) animations to the container elements that my Draggables will be snapping to, are you recommending that I animate them through GSAP and not, for example, through CSS keyframes or the like?

Link to comment
Share on other sites

6 hours ago, Eunomiac said:

when I go on to apply some (non-Draggable) animations to the container elements that my Draggables will be snapping to, are you recommending that I animate them through GSAP and not, for example, through CSS keyframes or the like?

I'm saying it's always safest to set your transforms through GSAP, especially for anything that you'll be animating. Explanation is here. I'm not saying you should never ever use CSS animations but of course I think you'll give yourself the most flexibility if you leverage GSAP.

Link to comment
Share on other sites

10 hours ago, GreenSock said:

I'm saying it's always safest to set your transforms through GSAP, especially for anything that you'll be animating. Explanation is here. I'm not saying you should never ever use CSS animations but of course I think you'll give yourself the most flexibility if you leverage GSAP.

Yeah, I agree with you there: Best to be consistent.  Plus, the more I learn about GSAP, the deeper in love I fall. *swoon*

 

Thanks once again for your help!  As a quick update, I'm well on my way to implementing that game mechanic I described --- check out that spiffy CodePen example I posted to see how far I've come :)--- I'm finding GSAP to be very grokkable, plus the documentation is amazing!

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

5 hours ago, Eunomiac said:

Plus, the more I learn about GSAP, the deeper in love I fall. *swoon* ...I'm finding GSAP to be very grokkable, plus the documentation is amazing!

Music to my ears, @Eunomiac! Thanks so much. Very happy to hear it's clicking for you. We have certainly put a lot of time into those docs. 🙌

 

Happy tweening!

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