Saya bekerja dengan 1.0.0-rc.
Dalam 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);
}
};
Saat ini sepertinya saya perlu mendapatkan offset dari halaman item asli, kemudian saya dapat menemukan offset dari halaman tempat saya menjatuhkan, lalu saya perlu menemukan offset wadah drop dari halaman, lalu lakukan perhitungan itu dan saya memiliki posisi relatif dalam wadah target penurunan saya.
Ini sepertinya banyak pekerjaan untuk sesuatu yang cukup umum ...
Sepertinya getClientOffset
mengembalikan saya posisi relatif terhadap viewport. Jadi yang harus saya lakukan adalah menemukan offset saya di target drop saya. Apakah menurut Anda masih layak untuk memiliki metode kenyamanan relatif terhadap target jatuh?
Ya saya kira kita bisa memiliki ini untuk simetri. Untuk saat ini, Anda dapat menggunakan findDOMNode(component).getBoundingClientRect()
, tetapi saya tidak keberatan menambahkan ini jika lebih banyak orang mendukung suara. Biarkan ini tetap terbuka dan lihat apa yang orang lain katakan.
Saya ingin sesuatu seperti ini juga. Saya perlu mendapatkan rect/koordinat pembatas dari target drop, jadi ketika saya mengarahkan sesuatu di atasnya, saya dapat menghitung apakah itu di sisi kiri, kanan, atas atau bawah di dalam target drop.
Koordinat relatif dapat berguna untuk kasus penggunaan lainnya. Untuk aplikasi mirip Trello, saat Anda menyeret kartu ke atas daftar, daftar akan bergulir ke bawah saat melayang di dekat bagian bawah area pelepasan, dan menggulir ke atas saat melayang di dekat bagian atas.
Sepele untuk diterapkan pada ruang pengguna.
Juga, saya samar-samar ingat pernah membaca bahwa mengakses kotak pembatas memicu reflow di browser dan agak mahal. Tidak yakin apakah ini masih terjadi.
Saya tidak berpikir ada cara untuk melakukan ini tanpa benar-benar mengakses getBoundingClientRect
karena Anda tidak pernah tahu apakah item tersebut dipindahkan.
Untuk aplikasi mirip Trello, saat Anda menyeret kartu ke atas daftar, daftar akan bergulir ke bawah saat melayang di dekat bagian bawah area pelepasan, dan menggulir ke atas saat melayang di dekat bagian atas.
Itu kasus penggunaan yang bagus.
Hukuman kinerja memang, signifikan, dan akan sia-sia jika ditambahkan ke React DnD tetapi aplikasi Anda tidak menggunakannya. Oleh karena itu, saya tidak ingin menambahkan ini ke React DnD.
Ini mudah diterapkan di userland, dan Anda akan dapat melakukan hal-hal seperti membatasi panggilan getBoundingClientRect
, atau memasukkan kode pengguliran terkait ke dalam bingkai animasi.
Saya terbuka untuk menambahkan "gulir saat mengarahkan kursor ke bawah" _sebagai contoh_ ke tes stres yang dapat diurutkan . Ini akan melibatkan penambahan target penurunan lain di tingkat Penampung yang hanya mendengarkan hover
dan menggulir di dalam bingkai animasi.
Namun saya tidak akan menambahkan metode koordinat DOM ke React DnD karena alasan yang dijelaskan di atas.
@gaearon Saya tertarik dengan solusi umum. Bagaimana kita bisa menggunakan react-dnd-html5-backend
daripada getBoundingClientRect
secara langsung?
Saya memecahkan ini dengan meneruskan fungsi DropTargetMonitor
getInitialSourceClientOffset
dan getSourceClientOffset
ke fungsi panggilan balik di dalam acara onDrop
. Dengan cara ini, fungsi panggilan balik saya dapat menghitung koordinat yang benar terkait dengan port tampilan.
// 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
tidak bekerja dengan komponen fungsional, dan useDrop#drop
tidak memasukkan component
. Sekarang jika saya ingin mendapatkan ref
dari komponen saya, saya punya untuk menyimpannya secara terpisah dan secara manual panggil konektor drop untuk meneruskannya. Apakah ada cara yang lebih ringkas untuk melakukan ini?
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 apakah Anda memiliki contoh kode lengkap yang ingin Anda bagikan?
@dendrochronology
Contoh yang dibuat-buat: https://codesandbox.io/s/elastic-liskov-00ldf
API lebih bagus ketika kita tidak perlu menyimpan ref
sendiri ( useGlobalDrop
vs useLocalDrop
). Sekarang jika hanya ref
, yang saya asumsikan react-dnd
sudah diperoleh, dilampirkan ~ke objek monitor
~ di suatu tempat (dapat diakses di drop
, saya tidak punya pendapat di mana), itu akan menyelesaikan ini.
solusi ini tidak dapat diandalkan terutama ketika Anda memperbesar browser atau perubahan resolusi perangkat. ada ide?
saya punya pertanyaan yang sama @sepehr09
Baru saja lewat setelah beberapa pencarian google... Ada pembaruan pada pertanyaan awal? (memperoleh x/y dari item yang dijatuhkan relatif terhadap target yang dijatuhkan)
Saya kira saya akan bergabung dengan daftar mereka, yang membutuhkan ini. Mohon bantuannya?
Menurut saya fitur ini sangat diperlukan, perlu ditambahkan di library. Saat ini, Siapapun yang bekerja dengannya, tolong bantu kami!
Komentar yang paling membantu
Ya saya kira kita bisa memiliki ini untuk simetri. Untuk saat ini, Anda dapat menggunakan
findDOMNode(component).getBoundingClientRect()
, tetapi saya tidak keberatan menambahkan ini jika lebih banyak orang mendukung suara. Biarkan ini tetap terbuka dan lihat apa yang orang lain katakan.