Jump to content
GreenSock

AustinNotAustin

Snapping to a draggable item

Go to solution Solved by AustinNotAustin,

Recommended Posts

Hey everyone,

I'm attempting to create dynamic snapping to other snappable objects. I thought I could simply assign the liveSnap points to a global variable, and then change that variable. It worked, kinda. I can now dynamically add additional snap points to an array and the remaining snappable objects will have access to these new points.

The problems exists when attempting to remove a snap point from the global variable. I honestly don't think this problem pertains to GreenSock, and is a vanilla javascript issue that I'm having on my own. However, I'm curious to see if there is a way I can snap two snappable objects together, easier than my way. If not, here's the part giving me a problem.
(I think)

// Remove this obj's snap points from the global snap point list
this.removeSnapPoints = () => {
let pointLocations = [
this.snapPoints.tl,
this.snapPoints.tm,
this.snapPoints.tr,
this.snapPoints.ml,
this.snapPoints.mr,
this.snapPoints.bl,
this.snapPoints.bm,
this.snapPoints.br,
];
// for (let val of )
// console.log(this.snapPoints.tl);
console.log(`Before: ${snappablePoints}`);
pointLocations.forEach(pointLoc => {
console.log(`Index of tl: ${snappablePoints.indexOf(pointLoc)}`);
console.log(`Value of tl: ${JSON.stringify(pointLocations)}`);
snappablePoints.forEach(snap => {
if (JSON.stringify(pointLoc) == JSON.stringify(snap)) {
console.log(`pointLoc: ${JSON.stringify(pointLoc)} | snap: ${JSON.stringify(snap)}`);
}
 
});
// This function is deleting all of the items in the array instead of just the ones I identified (i.e. the points that belong to the panel being moved)
});
};

See the Pen abwdqwQ by AustinNotAustin (@AustinNotAustin) on CodePen

Link to comment
Share on other sites

I noticed that the snapping points are only applying to the individual object and not all the objects. This is a new problem since I had it working before. I'll see about fixing that and maybe solve this. Either way, I'd like to hear everyone else's thoughts on the best way to implement this.

Link to comment
Share on other sites

Welcome to the forums, @AustinNotAustin. I don't have time to work through all the custom code and logic you've got in there (we really try to keep these forums focused on GSAP-specific questions rather than more general logic things), but I wonder if you really need to be managing all those points like that. Did you know that you can set the "points" property to a FUNCTION rather than an Array so that you can run whatever logic you want in there? Like:

 

liveSnap: {
  points: function(point) {
    // now you can run whatever logic you want in here, like
    // looping through the other boxes to see which is closest 
    // and if it's within a certain distance, apply the snapping.
    // Just return the adjusted point with x/y properties or 
    // if it's not within the range, return the original point:
    return point;
  }
}

Does that help? 

  • Like 2
Link to comment
Share on other sites

@GreenSock

 

Thanks,
I am aware that I can make a custom function. Do you believe your approach would be better than mine?

Your approach being: Search for the closest object, then perform logic to find snappable points.
My approach being: Store all snappable points available in an array, and remove respective snappable points when an object is moved.

 

If you have a minute or two, could you elaborate on why one or the other is the better option?

Link to comment
Share on other sites

Yep, that would be my instinct. 

  • Fewer things to manage
  • Instead of looping through many points per item to find the closest one, I can just loop through ONCE for each item and find the closest to its center and then if it's within a threshold, calculate which edge it should snap to. Fewer calculations; faster.

@OSUblake what's your instinct? (Blake is a pro at this kind of stuff too)

Link to comment
Share on other sites

10 minutes ago, GreenSock said:

@OSUblake what's your instinct? (Blake is a pro at this kind of stuff too)

 

Yep. I would go with a function.

 

Not a draggable demo, but the logic in this thread would be pretty close to what you want for a function to snap to. Easier to calculate distances using the center of objects.


 

 

  • Like 2
Link to comment
Share on other sites

 Thanks,

I'll have to digest that post a little more. I'll see what I can come up with using the approach both of you suggested.

Link to comment
Share on other sites

  • Solution

I got it working.

Thanks for the help you two.


I used the approach suggestion from @GreenSock, and I plan on making some optimizations from the post you linked to me @OSUblake.

Here's the codepen solution: 

See the Pen abwdqwQ by AustinNotAustin (@AustinNotAustin) on CodePen



It's probably an awful implementation, but I plan to continue working on it.

  • Like 1
Link to comment
Share on other sites

Glad you got it working. Yeah, you could definitely optimize that a lot more. You shouldn't need to create so many objects in that function. I don't think you even need to create those 8 points - you could probably just get the angle to determine which edge/corner should be snapped to. But it's not "wrong" to do it the way  you're doing it, especially if that makes the most sense in your brain - you're the one who needs to work with all that code in the future, so it needs to be intuitive for you. 

 

Small tip: you don't need to worry about Math.abs() in the hypotenuse equation because when you square a negative it becomes a positive anyway:

// OLD
const getHypotenuse = (x1, y1, x2, y2) => {
	let a = Math.abs(x1 - x2); // Get a
	let b = Math.abs(y1 - y2); // Get b
	let c = Math.sqrt((a * a) + (b * b));
	return c;
}

// NEW
const getHypotenuse = (x1, y1, x2, y2) => Math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2);

 

Link to comment
Share on other sites

@GreenSock,

Okay thanks. I'll get rid if those Math.abs statements.

 

Would you still recommend getting the angle and not using the 8 points if you plan on implementing a turning ability? 

 

I will be turning these rectangles and snapping to them while turned. That would also turn the draggable.

 

Still think an angle would be the best approach?

Your last recommendation worked great so I'm all ears haha.

Link to comment
Share on other sites

I'm not really sure exactly what you mean by "turn" but you should be able to factor in rotation to whatever you do, sure. I don't mean to make it sounds crazy simple, of course. I'm just saying that rotation wouldn't make me say "oh, then nevermind, don't do that solution I recommended"

 

I wish we had the resources to provide free general consulting around here, but we get pretty overwhelmed with just the GSAP-specific questions. If you are interested in paid consulting services (since this isn't really a GSAP-specific question), that's always an option although we have limited availability. 

Link to comment
Share on other sites

Okay,

Do GreenSock Club members get limited consulting, or are you referring to something else?

Link to comment
Share on other sites

7 minutes ago, AustinNotAustin said:

Do GreenSock Club members get limited consulting, or are you referring to something else?

Oh, definitely not. We'd be bankrupt in no time :) 

 

People join Club GreenSock for 3 primary reasons:

  1. To get access to the bonus plugins like MorphSVGPlugin, Flip, DrawSVGPlugin, SplitText, etc.
  2. To get the special commercial license that comes with "Business Green" memberships
  3. To support our ongoing development efforts and innovation. We couldn't possibly do what we do without the support of Club GreenSock members. 

Unrelated to Club GreenSock, we offer paid custom consulting services to a limited number of customers. You're also welcome to post in the "Jobs & Freelance" forum if you'd like. Our hourly rate will almost surely be significantly higher than someone else you might find there, but of course we like to think we offer the best bang-for-the-buck considering what you get and our level of expertise with the tools. You can contact us privately to discuss pricing and scheduling if that's something that interests you. 

 

Good luck with the project!

  • Like 1
Link to comment
Share on other sites

Thanks for your help. My project doesn't nearly as qualify for the level of professional consulting you'd provide. I'll just use brute force techniques as usual 😅

  • Haha 1
Link to comment
Share on other sites

Ah, the brute force technique - I'm quite familiar with that myself. Good luck :) 

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