daybrush / moveable

Moveable! Draggable! Resizable! Scalable! Rotatable! Warpable! Pinchable! Groupable! Snappable!
https://daybrush.com/moveable/
MIT License
10.08k stars 618 forks source link

Retrieve the generated snap line when "snap" event is triggered #707

Closed alexconstantin closed 2 years ago

alexconstantin commented 2 years ago

Environments

Description

Hello, I was playing around with the .on("snap") event and I saw that we receive arrays for gaps, elements, guidelines, which is pretty cool! I was wondering if there was a way to also receive the generated moveable-line div in that event (through a unique class name or the actual html element). The reason for this is that, for purely UI/UX considerations, I would want to color some lines differently. I am achieving this at the moment by using a MutationObserver object on the control-box div and I am searching for lines with a certain width / height. This works as expected, but I think this is poor from performance POV.

Would this functionality be achievable or is there another way of obtaining the same result without using the MutationObserver API?

Thank you!

Screenshot 2022-07-24 at 15 00 25

daybrush commented 2 years ago

@alexconstantin

moveable's new version is released.

Added object types to verticalGuidelines and horizontalGuidelines.

https://daybrush.com/moveable/storybook2/?path=/story/advanced-snappable--guidelines-with-custom-styles



verticalGuidelines: [
   0,
   100,
   { pos: 200, className: "red" },
],
alexconstantin commented 2 years ago

@daybrush Thank you so much! This already is offering a lot of customisation options. One more follow-up question:

Is there a way to identify / retrieve these generated divs (in case of gaps, for example)?

Screenshot 2022-07-26 at 10 07 58

Background: Starting from this issue https://github.com/daybrush/moveable/issues/200 , when working with a lot of html objects in the page, it can get crowded to display all snap distances to all elements at the same time, especially when a lot of distances are "compatible", so I am looking for a "display snap digits to the closest elements" / "display snaps only with a certain distance" solution (for example I have 4 snaps, 2 of them are 30px difference, the other 2 are 85px difference, so I will try to only display the 30px ones, based on some object distance calculations / number of concurrent snap digits being displayed.

Would something like this be achievable?

daybrush commented 2 years ago

@alexconstantin

It's a good feature. I'll consider Maybe to add it in the next release.

daybrush commented 2 years ago

@alexconstantin

moveable's new version is released.

Use maxSnapElementGuidelineDistance prop to adjust distance with element guidelines.

className is also applied to gaps.

/* pos guidelines */
.moveable-normal.red {
    background: red!important;
}
/* gap guidelines */
.moveable-gap.red {
    background: red!important;
}
/* When snapped to an element in elementGuidelines */
.moveable-bold.red {
    background: red!important;
}
/* A dashed line between target and element */
.moveable-dashed.red {
    border-top-color: red!important;
    border-left-color: red!important;
}
alexconstantin commented 2 years ago

@daybrush Thank you very much! I've played with it a bit and it seems to work as expected. Thanks again!

alexconstantin commented 2 years ago

@daybrush when you get a chance please take a look at this sample: https://codesandbox.io/s/jovial-breeze-1id0ub?file=/src/index.ts and try to position the element as in the image:

Screenshot 2022-08-03 at 12 17 09

  1. The code from .on("snap") element will be executed. In this case, how can I hide the longer distance without getting the flickering effect (at first it's displayed, but afterwards hidden)? Is there an onBeforeSnap event triggered?

  2. In this scenario, the distance between 2 - target - 6 is of 50px. However, the distance between 4 - 5 is also 50px. Would it be possible to display all similar gap distances in the page?

Screenshot 2022-08-03 at 12 12 22

Thank you!

daybrush commented 2 years ago

@alexconstantin

  1. Sorry. It is very difficult to call beforeSnap. drag, resize, scale (with snap) => update => render JSX with (trigger snap event) => (DOM updated)

What is long distance? 1, 4? and 5?

Didn't it work well with maxSnapElementGuidelineDistance: 80?

Even if it's a snap, don't you want it to be invisible?

image
  1. The gap between 2-target-6 is 50,50. But even if the distance of 4-5 is 50, it is too unrelated.
alexconstantin commented 2 years ago

@daybrush For point 1, I've made another demo here: https://codesandbox.io/s/aged-leaf-dyzfzp?file=/src/styles.css and I've disabled the code that hides the longer snap.

Screenshot 2022-08-03 at 20 33 19

Basically what I am trying to do is to hide the 252 px gap lines and only leave the 50px ones (while keeping the blue alignment lines). I am calculating the smallest gap line on the "snap" event and afterwards I am hiding the other ones, but in this case, a small flickering appears.

For point 2, I also thought it was way too unrelated, but I decided to ask, maybe it was something easy to do.

P.S.: yes, maxSnapElementGuidelineDistance works great, but only for the blue alignment lines.

Please let me know if there is a way to hide those lines (at the moment I am trying to hide them by default, and only display the 50px ones, in order to avoid the flickering).

Thank you for all your work!

daybrush commented 2 years ago

@alexconstantin

Okay. I'll hide the line from 252 in the next patch.

The red line will also be applied through maxSnapElementGuidelineDistance.

alexconstantin commented 2 years ago

@daybrush thank you! that would be great!

One question: would it be possible to introduce another property, just for the red line? So that maxSnapElementGuidelineDistance will affect the blue lines, and something like 'maxSnapElementGapDistance' to affect only the red lines? The outcome would be that setting

maxSnapElementGuidelineDistance = 500 maxSnapElementGapDistance = 100

will display the long blue line, but not the long red line.

daybrush commented 2 years ago

@alexconstantin

moveable's new version is released.

maxSnapElementGapDistance prop is added.

Changed to show only the nearest red gap.

alexconstantin commented 2 years ago

Thank you!