Only generate a preview image on first onPointerEnter event (#37)

This resolves a noticeable delay when the first paint required generating multiple preview images
This commit is contained in:
Evan Simkowitz 2024-06-11 14:28:17 -07:00 committed by GitHub
parent 1be376c679
commit 4293c749c4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -268,6 +268,13 @@ const TileNode = <T,>({
useEffect(() => {
if (isDragging) {
console.log("drag start", layoutNode.id, layoutNode, dragItem);
if (previewRef.current) {
toPng(previewRef.current).then((url) => {
const img = new Image();
img.src = url;
img.onload = () => dragPreview(img);
});
}
}
}, [isDragging]);
@ -284,20 +291,20 @@ const TileNode = <T,>({
);
}, []);
// Once the preview div is mounted, grab it and render a PNG, then register it with the DnD system. I noticed that if I call this immediately, it occasionally captures an empty HTMLElement.
// I found a hacky workaround of just adding a timeout so the capture doesn't happen until after the first paint.
useEffect(
debounce(() => {
if (previewRef.current) {
const [previewImageSet, setPreviewImageSet] = useState<boolean>(false);
// When a user first mouses over a node, generate a preview image and set it as the drag preview.
const generatePreviewImage = useCallback(() => {
console.log("generatePreviewImage", layoutNode.id);
if (!previewImageSet && previewRef.current) {
toPng(previewRef.current).then((url) => {
const img = new Image();
img.src = url;
dragPreview(img);
img.onload = () => dragPreview(img);
setPreviewImageSet(true);
});
}
}, 50),
[previewRef]
);
}, [previewRef, previewImageSet, dragPreview]);
// Register the tile item as a draggable component
useEffect(() => {
@ -328,6 +335,7 @@ const TileNode = <T,>({
flexBasis: layoutNode.size,
...transform,
}}
onPointerEnter={generatePreviewImage}
>
{leafContent}
{preview}