mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): split dnd overlay to separate component
This reduces top-level rerenders when zooming in and out on workflow editor
This commit is contained in:
parent
5d4610d981
commit
7eb79266c4
@ -1,28 +1,19 @@
|
|||||||
import {
|
import { MouseSensor, TouchSensor, useSensor, useSensors } from '@dnd-kit/core';
|
||||||
DragOverlay,
|
|
||||||
MouseSensor,
|
|
||||||
TouchSensor,
|
|
||||||
useSensor,
|
|
||||||
useSensors,
|
|
||||||
} from '@dnd-kit/core';
|
|
||||||
import { logger } from 'app/logging/logger';
|
import { logger } from 'app/logging/logger';
|
||||||
import { dndDropped } from 'app/store/middleware/listenerMiddleware/listeners/imageDropped';
|
import { dndDropped } from 'app/store/middleware/listenerMiddleware/listeners/imageDropped';
|
||||||
import { useAppDispatch } from 'app/store/storeHooks';
|
import { useAppDispatch } from 'app/store/storeHooks';
|
||||||
import { parseify } from 'common/util/serialize';
|
import { parseify } from 'common/util/serialize';
|
||||||
import { useScaledModifer } from 'features/dnd/hooks/useScaledCenteredModifer';
|
import DndOverlay from 'features/dnd/components/DndOverlay';
|
||||||
import type {
|
import type {
|
||||||
DragEndEvent,
|
DragEndEvent,
|
||||||
DragStartEvent,
|
DragStartEvent,
|
||||||
TypesafeDraggableData,
|
TypesafeDraggableData,
|
||||||
} from 'features/dnd/types';
|
} from 'features/dnd/types';
|
||||||
import { customPointerWithin } from 'features/dnd/util/customPointerWithin';
|
import { customPointerWithin } from 'features/dnd/util/customPointerWithin';
|
||||||
import type { AnimationProps } from 'framer-motion';
|
import type { PropsWithChildren } from 'react';
|
||||||
import { AnimatePresence, motion } from 'framer-motion';
|
import { memo, useCallback, useState } from 'react';
|
||||||
import type { CSSProperties, PropsWithChildren } from 'react';
|
|
||||||
import { memo, useCallback, useMemo, useState } from 'react';
|
|
||||||
|
|
||||||
import { DndContextTypesafe } from './DndContextTypesafe';
|
import { DndContextTypesafe } from './DndContextTypesafe';
|
||||||
import DragPreview from './DragPreview';
|
|
||||||
|
|
||||||
const AppDndContext = (props: PropsWithChildren) => {
|
const AppDndContext = (props: PropsWithChildren) => {
|
||||||
const [activeDragData, setActiveDragData] =
|
const [activeDragData, setActiveDragData] =
|
||||||
@ -77,9 +68,6 @@ const AppDndContext = (props: PropsWithChildren) => {
|
|||||||
|
|
||||||
const sensors = useSensors(mouseSensor, touchSensor);
|
const sensors = useSensors(mouseSensor, touchSensor);
|
||||||
|
|
||||||
const scaledModifier = useScaledModifer();
|
|
||||||
const modifiers = useMemo(() => [scaledModifier], [scaledModifier]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DndContextTypesafe
|
<DndContextTypesafe
|
||||||
onDragStart={handleDragStart}
|
onDragStart={handleDragStart}
|
||||||
@ -89,45 +77,9 @@ const AppDndContext = (props: PropsWithChildren) => {
|
|||||||
autoScroll={false}
|
autoScroll={false}
|
||||||
>
|
>
|
||||||
{props.children}
|
{props.children}
|
||||||
<DragOverlay
|
<DndOverlay activeDragData={activeDragData} />
|
||||||
dropAnimation={null}
|
|
||||||
modifiers={modifiers}
|
|
||||||
style={dragOverlayStyles}
|
|
||||||
>
|
|
||||||
<AnimatePresence>
|
|
||||||
{activeDragData && (
|
|
||||||
<motion.div
|
|
||||||
layout
|
|
||||||
key="overlay-drag-image"
|
|
||||||
initial={initial}
|
|
||||||
animate={animate}
|
|
||||||
>
|
|
||||||
<DragPreview dragData={activeDragData} />
|
|
||||||
</motion.div>
|
|
||||||
)}
|
|
||||||
</AnimatePresence>
|
|
||||||
</DragOverlay>
|
|
||||||
</DndContextTypesafe>
|
</DndContextTypesafe>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default memo(AppDndContext);
|
export default memo(AppDndContext);
|
||||||
|
|
||||||
const dragOverlayStyles: CSSProperties = {
|
|
||||||
width: 'min-content',
|
|
||||||
height: 'min-content',
|
|
||||||
cursor: 'grabbing',
|
|
||||||
userSelect: 'none',
|
|
||||||
// expand overlay to prevent cursor from going outside it and displaying
|
|
||||||
padding: '10rem',
|
|
||||||
};
|
|
||||||
|
|
||||||
const initial: AnimationProps['initial'] = {
|
|
||||||
opacity: 0,
|
|
||||||
scale: 0.7,
|
|
||||||
};
|
|
||||||
const animate: AnimationProps['animate'] = {
|
|
||||||
opacity: 1,
|
|
||||||
scale: 1,
|
|
||||||
transition: { duration: 0.1 },
|
|
||||||
};
|
|
||||||
|
@ -0,0 +1,60 @@
|
|||||||
|
import { DragOverlay } from '@dnd-kit/core';
|
||||||
|
import { useScaledModifer } from 'features/dnd/hooks/useScaledCenteredModifer';
|
||||||
|
import type { TypesafeDraggableData } from 'features/dnd/types';
|
||||||
|
import type { AnimationProps } from 'framer-motion';
|
||||||
|
import { AnimatePresence, motion } from 'framer-motion';
|
||||||
|
import type { CSSProperties } from 'react';
|
||||||
|
import { memo, useMemo } from 'react';
|
||||||
|
|
||||||
|
import DragPreview from './DragPreview';
|
||||||
|
|
||||||
|
type DndOverlayProps = {
|
||||||
|
activeDragData: TypesafeDraggableData | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const DndOverlay = (props: DndOverlayProps) => {
|
||||||
|
const scaledModifier = useScaledModifer();
|
||||||
|
const modifiers = useMemo(() => [scaledModifier], [scaledModifier]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DragOverlay
|
||||||
|
dropAnimation={null}
|
||||||
|
modifiers={modifiers}
|
||||||
|
style={dragOverlayStyles}
|
||||||
|
>
|
||||||
|
<AnimatePresence>
|
||||||
|
{props.activeDragData && (
|
||||||
|
<motion.div
|
||||||
|
layout
|
||||||
|
key="overlay-drag-image"
|
||||||
|
initial={initial}
|
||||||
|
animate={animate}
|
||||||
|
>
|
||||||
|
<DragPreview dragData={props.activeDragData} />
|
||||||
|
</motion.div>
|
||||||
|
)}
|
||||||
|
</AnimatePresence>
|
||||||
|
</DragOverlay>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default memo(DndOverlay);
|
||||||
|
|
||||||
|
const dragOverlayStyles: CSSProperties = {
|
||||||
|
width: 'min-content',
|
||||||
|
height: 'min-content',
|
||||||
|
cursor: 'grabbing',
|
||||||
|
userSelect: 'none',
|
||||||
|
// expand overlay to prevent cursor from going outside it and displaying
|
||||||
|
padding: '10rem',
|
||||||
|
};
|
||||||
|
|
||||||
|
const initial: AnimationProps['initial'] = {
|
||||||
|
opacity: 0,
|
||||||
|
scale: 0.7,
|
||||||
|
};
|
||||||
|
const animate: AnimationProps['animate'] = {
|
||||||
|
opacity: 1,
|
||||||
|
scale: 1,
|
||||||
|
transition: { duration: 0.1 },
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user