Estoy trabajando con 1.0.0-rc.
En drag-around-naive
:
const boxTarget = {
drop(props, monitor, component) {
const item = monitor.getItem();
const delta = monitor.getDifferenceFromInitialOffset();
const left = Math.round(item.left + delta.x);
const top = Math.round(item.top + delta.y);
component.moveBox(item.id, left, top);
}
};
En la actualidad, parece que necesito obtener el desplazamiento de la página del elemento original, luego puedo encontrar el desplazamiento de la página donde lo dejé caer, luego necesito encontrar el desplazamiento del contenedor de caída de la página, luego lo hago ese cálculo y tengo la posición relativa en mi contenedor de destino de caída.
Esto parece mucho trabajo para algo bastante común ...
Parece que getClientOffset
me devuelve la posición relativa a la ventana gráfica. Entonces, todo lo que tengo que hacer es encontrar mi compensación en mi destino de caída. ¿Crees que todavía vale la pena tener un método de conveniencia en relación con el objetivo de caída?
Sí, supongo que podríamos tener esto por simetría. Por ahora, puede usar findDOMNode(component).getBoundingClientRect()
, pero no me importaría agregar esto si más personas expresan su apoyo. Mantengamos esto abierto y veamos qué dicen los demás.
También me gustaría algo como esto. Necesito obtener los rectángulos delimitadores / coordenadas del destino de colocación, de modo que cuando coloco el cursor sobre algo, puedo calcular si está en el lado izquierdo, derecho, superior o inferior dentro del destino de colocación.
Las coordenadas relativas pueden ser útiles para otros casos de uso. Para una aplicación similar a Trello, cuando arrastra una tarjeta sobre una lista, la lista se desplaza hacia la parte inferior cuando se sitúa cerca de la parte inferior del área de colocación y se desplaza hacia arriba cuando se desplaza hacia la parte superior.
Trivial de implementar en el espacio del usuario aunque.
Además, recuerdo vagamente haber leído que acceder al rectángulo delimitador desencadena el reflujo en los navegadores y es algo costoso. No estoy seguro de si este sigue siendo el caso.
No creo que haya una manera de hacer esto sin acceder a getBoundingClientRect
porque nunca se sabe si el elemento se movió.
Para una aplicación similar a Trello, cuando arrastra una tarjeta sobre una lista, la lista se desplaza hacia la parte inferior cuando se sitúa cerca de la parte inferior del área de colocación y se desplaza hacia arriba cuando se desplaza hacia la parte superior.
Ese es un gran caso de uso.
La penalización de rendimiento es, de hecho, significativa y se desperdiciará si se agrega a React DnD pero su aplicación no la usa. Por lo tanto, no quiero agregar esto a React DnD.
Es fácil de implementar en el área del usuario y podrá hacer cosas como acelerar las llamadas getBoundingClientRect
o poner el código de desplazamiento relacionado en un cuadro de animación.
Estoy dispuesto a agregar "desplazarse al pasar el mouse en la parte inferior" _como ejemplo_ a la prueba de esfuerzo ordenable . Esto implicaría agregar otro destino de colocación en el nivel del contenedor que solo escucha hover
y se desplaza dentro de un cuadro de animación.
Sin embargo, no agregaré los métodos de coordenadas DOM a React DnD por las razones descritas anteriormente.
@gaearon Estoy interesado en una solución generalizada. ¿Cómo podemos usar react-dnd-html5-backend
lugar de getBoundingClientRect
directamente?
Resolví esto pasando las funciones DropTargetMonitor
getInitialSourceClientOffset
y getSourceClientOffset
a una función de devolución de llamada dentro de mi evento onDrop
. De esta manera, mi función de devolución de llamada puede calcular las coordenadas correctas relacionadas con el puerto de visualización.
// some code before...
const [, dropRef] = useDrop({
accept: 'STICKY',
drop(item, monitor) {
move(
item.id,
monitor.getInitialSourceClientOffset(),
monitor.getSourceClientOffset()
);
},
});
// I'm updating my state with npm immer (immutable helper) throuthg the produce function...
const move = (id, initialPosition, finalPosition) => {
setList(
produce(list, draft => {
list.map(item => {
if (item.id === id) {
item.position = getCorrectDroppedOffsetValue(
initialPosition,
finalPosition
);
}
return item;
});
})
);
};
// and finally, my getCorrectDroppedOffsetValue function
const getCorrectDroppedOffsetValue = (initialPosition, finalPosition) => {
// get the container (view port) position by react ref...
const dropTargetPosition = ref.current.getBoundingClientRect();
const { y: finalY, x: finalX } = finalPosition;
const { y: initialY, x: initialX } = initialPosition;
// calculate the correct position removing the viewport position.
// finalY > initialY, I'm dragging down, otherwise, dragging up
const newYposition =
finalY > initialY
? initialY + (finalY - initialY) - dropTargetPosition.top
: initialY - (initialY - finalY) - dropTargetPosition.top;
const newXposition =
finalX > initialX
? initialX + (finalX - initialX) - dropTargetPosition.left
: initialX - (initialX - finalX) - dropTargetPosition.left;
return {
x: newXposition,
y: newYposition,
};
};
findDOMNode
no funciona con el componente funcional, y useDrop#drop
no pasa ningún component
in. Ahora, si quiero obtener el ref
de mi componente, tengo para almacenarlo por separado y llamar manualmente al conector de caída para pasarlo. ¿Hay alguna forma más concisa de hacer esto?
function useCustomDrop(onDrop: (info: unknown, xy: Point) => void) {
const ref = useRef<Element>();
const [, dropTarget] = useDrop<any, void, unknown>({
accept: 'item-type',
drop(item, monitor) {
const offset = monitor.getSourceClientOffset();
if (offset && ref.current) {
const dropTargetXy = ref.current.getBoundingClientRect();
onDrop(item.data, {
x: offset.x - dropTargetXy.left,
y: offset.y - dropTargetXy.top,
});
}
}
});
return (elem) => {
ref.current = elem;
dropTarget(ref);
};
}
@quanganhtran , ¿tiene alguna muestra de código completa que estaría dispuesto a compartir, por favor?
@dendrocronología
Un ejemplo artificial: https://codesandbox.io/s/elastic-liskov-00ldf
La API es mejor cuando no tenemos que almacenar el ref
nosotros mismos ( useGlobalDrop
vs useLocalDrop
). Ahora, si solo el ref
, que supongo que react-dnd
ya obtiene, se adjunta ~ al objeto monitor
~ en algún lugar (accesible en drop
, no tengo opinión donde), resolvería esto.
esta solución no es confiable, especialmente cuando hace zoom en el navegador o cambia la resolución del dispositivo. ¿alguna idea?
tengo la misma pregunta @ sepehr09
Pasando después de algunas búsquedas en Google ... ¿Alguna actualización sobre la pregunta original? (obteniendo el x / y de un elemento caído en relación con el objetivo de caída)
Supongo que me uniré a la lista de aquellos que necesitan esto. ¿Alguna ayuda por favor?
Creo que esta característica es muy necesaria, debe agregarse en la biblioteca. En este momento, cualquiera que haya trabajado con él, ¡ayúdenos!
Comentario más útil
Sí, supongo que podríamos tener esto por simetría. Por ahora, puede usar
findDOMNode(component).getBoundingClientRect()
, pero no me importaría agregar esto si más personas expresan su apoyo. Mantengamos esto abierto y veamos qué dicen los demás.