-
Notifications
You must be signed in to change notification settings - Fork 1.1k
[WIP] plugin: Snap Mirror #396
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
This function need sensorEvent provide |
|
Hi @zjffun I am trying my own implementation of this. Does your implementation change the source position? When I tried creating my own plugin. The mirror snaps to the grid, but the source elements has a bit of offset. Thanks for your help. below is my implementation btw, also, it seems the drag:stop event doesn't seem to affect the source on drop class SnapPlugin {
static enabled = false // keep it static variable so it's share across all instances of SnapPlugin
static gridSize = 20
constructor(draggable, { enabled = false } = {}) {
this.draggable = draggable
this.snappable = enabled // this one checks if the data-grid-snappable is enabled on widget basis
this.cursorOffset = { x: 0, y: 0 }
this.lastSnapped = { screen: { x: 0, y: 0 }, relative: { x: 0, y: 0 } }
this.setGrid = this.setGrid.bind(this)
this.setEnabled = this.setEnabled.bind(this)
this.onDragStart = this.onDragStart.bind(this)
this.onMirrorMove = this.onMirrorMove.bind(this)
this.onDragStop = this.onDragStop.bind(this)
this.snapCoords = this.snapCoords.bind(this)
this.attach = this.attach.bind(this)
this.detach = this.detach.bind(this)
}
attach() {
this.draggable.on('drag:start', this.onDragStart)
this.draggable.on('mirror:move', this.onMirrorMove)
this.draggable.on('mirror:destroy', this.onDragStop)
// this.enabled = true
}
detach() {
this.draggable.off('drag:start', this.onDragStart)
this.draggable.off('mirror:move', this.onMirrorMove)
this.draggable.off('mirror:destroy', this.onDragStop)
this.enabled = false
}
setGrid(size) {
SnapPlugin.gridSize = size
}
setEnabled(state) {
SnapPlugin.enabled = state
if (!state) {
this.snappable = false
}
}
snapCoords(clientX, clientY) {
const containerRect = this.draggable.containers[0].getBoundingClientRect()
// Cursor relative to container
const relX = clientX - containerRect.left
const relY = clientY - containerRect.top
// Snap cursor itself to grid
const snappedCursorX = Math.round(relX / SnapPlugin.gridSize) * SnapPlugin.gridSize
const snappedCursorY = Math.round(relY / SnapPlugin.gridSize) * SnapPlugin.gridSize
return { x: snappedCursorX, y: snappedCursorY, containerRect }
}
onDragStart(event) {
if (!SnapPlugin.enabled) {
this.snappable = false
return
}
const { sensorEvent, source } = event
const { clientX, clientY } = sensorEvent
const rect = source.getBoundingClientRect()
this.snappable = SnapPlugin.enabled && source.dataset.gridSnappable === "true" // check if the widget allows snapping
// Where inside the element did the user grab?
this.cursorOffset = {
x: clientX - rect.left,
y: clientY - rect.top
}
}
onMirrorMove(event) {
if (!this.snappable) return
event.cancel()
const { sensorEvent, mirror, source } = event
const { clientX, clientY } = sensorEvent
const { containerRect } = this.snapCoords(clientX, clientY)
// Top-left position of element relative to container
const relX = clientX - containerRect.left - this.cursorOffset.x
const relY = clientY - containerRect.top - this.cursorOffset.y
// Snap the element’s top-left instead of the cursor
const snappedX = Math.round(relX / SnapPlugin.gridSize) * SnapPlugin.gridSize
const snappedY = Math.round(relY / SnapPlugin.gridSize) * SnapPlugin.gridSize
// Translate to screen coords for mirror
const mirrorX = containerRect.left + snappedX
const mirrorY = containerRect.top + snappedY
mirror.style.transform = `translate(${mirrorX}px, ${mirrorY}px)`
// source.style.transform = `translate(${snappedX}px, ${snappedY}px)`
console.log("soruce: ", event)
this.lastSnapped = {
screen: { x: mirrorX, y: mirrorY },
relative: { x: snappedX, y: snappedY },
containerRect
}
}
onDragStop(event) {
const { source } = event
const { x: snappedX, y: snappedY } = this.lastSnapped.relative
source.style.transform = `translate(${snappedX}px, ${snappedY}px)`
}
}
export default SnapPlugin |
|
Sorry, I figured it out. It wasn't problem with the GridSnap or the library, but how i hadnled the positioning after. Thanks again |
|
@PaulleDemon Sorry, It's been so long, I've forgotten my previous thoughts. Maybe you cloud try to clone the mirror and setTimeout for a while, then get the position and set to the source element. |
|
@zjffun thanks for replying, I actually figured it out, this code was correct, it was a different problem on how I was positioning my elements. Thanks again! |
Only a complish a simple demo now, there are still a long way to go.
This PR implements or fixes... (explain your changes)
#393
This PR closes the following issues... (if applicable)
#393
Does this PR require the Docs to be updated?
Yes
Does this PR require new tests?
Yes
This branch been tested on... (click all that apply / add new items)
Browsers: