From a60ac3a10b9997f7b04de998406987c543c93cb5 Mon Sep 17 00:00:00 2001 From: markus-moser Date: Fri, 17 Jan 2025 12:10:42 +0100 Subject: [PATCH 1/2] Add image crop to gallery --- .../hotspot-image/hotspot-image.tsx | 22 +- .../components/hotspot-image/utils/drag.ts | 1 + .../image-preview/image-preview.tsx | 278 ++++++++++-------- .../sortable-item/sortable-item.tsx | 11 - .../image-gallery/image-gallery.tsx | 4 + .../helpers/hotspot-image/crop-modal.tsx | 124 ++++++++ .../hotspot-image/hotspot-markers-modal.tsx | 1 + .../helpers/hotspot-image/types/crop-types.ts | 7 + .../hotspot-image/types/hotspot-types.ts | 6 +- .../hotspot-image/utils/crop-converter.ts | 55 ++++ translations/studio.en.yaml | 2 + 11 files changed, 366 insertions(+), 145 deletions(-) create mode 100644 assets/js/src/core/modules/element/dynamic-types/defintinitions/objects/data-related/helpers/hotspot-image/crop-modal.tsx create mode 100644 assets/js/src/core/modules/element/dynamic-types/defintinitions/objects/data-related/helpers/hotspot-image/types/crop-types.ts create mode 100644 assets/js/src/core/modules/element/dynamic-types/defintinitions/objects/data-related/helpers/hotspot-image/utils/crop-converter.ts diff --git a/assets/js/src/core/components/hotspot-image/hotspot-image.tsx b/assets/js/src/core/components/hotspot-image/hotspot-image.tsx index 3fbeb6125..cdcabb91c 100644 --- a/assets/js/src/core/components/hotspot-image/hotspot-image.tsx +++ b/assets/js/src/core/components/hotspot-image/hotspot-image.tsx @@ -71,13 +71,14 @@ interface IHotspotImage { src: string styleOptions?: IStyleOptions data?: IHotspot[] - onRemove: (id: number) => void + onRemove?: (id: number) => void onEdit?: (id: number) => void onClone?: (id: number) => void - onUpdate: (item: IHotspot) => void + onUpdate?: (item: IHotspot) => void + disableContextMenu?: boolean } -export const HotspotImage = ({ src, data, styleOptions = defaultStyleOptions, onRemove, onEdit, onClone, onUpdate }: IHotspotImage): JSX.Element => { +export const HotspotImage = ({ src, data, styleOptions = defaultStyleOptions, onRemove, onEdit, onClone, onUpdate, disableContextMenu }: IHotspotImage): JSX.Element => { const { styles } = useStyle() const [imageLoaded, setImageLoaded] = useState(false) const imageRef = useRef(null) @@ -129,6 +130,11 @@ export const HotspotImage = ({ src, data, styleOptions = defaultStyleOptions, on evt.stopPropagation() } + const toNumber = (value: any): number => { + const number = Number(value) + return isNaN(number) ? 0 : number + } + const handleMouseMove = (evt: MouseEvent): void => { if (selectedId === null || containerRef.current === null) return const containerBounds = containerRef.current.getBoundingClientRect() @@ -137,9 +143,9 @@ export const HotspotImage = ({ src, data, styleOptions = defaultStyleOptions, on const dy = evt.clientY - resizeStart.y if (dragging) { - setItems(dragItem(evt, dragStart, containerBounds, items, hotspotIndex, Number(styleOptions[items[hotspotIndex].type].marginLeft), Number(styleOptions[items[hotspotIndex].type].marginTop))) + setItems(dragItem(evt, dragStart, containerBounds, items, hotspotIndex, toNumber(styleOptions[items[hotspotIndex].type].marginLeft), toNumber(styleOptions[items[hotspotIndex].type].marginTop))) } else if (resizeDirection !== null) { - setItems(resizeItem(evt, resizeStart, resizeDirection, containerBounds, items, hotspotIndex, Number(styleOptions[items[hotspotIndex].type].minSize), dx, dy)) + setItems(resizeItem(evt, resizeStart, resizeDirection, containerBounds, items, hotspotIndex, toNumber(styleOptions[items[hotspotIndex].type].minSize), dx, dy)) } } @@ -149,7 +155,7 @@ export const HotspotImage = ({ src, data, styleOptions = defaultStyleOptions, on const updatedItem = items.find(h => h.id === selectedId) if (updatedItem !== undefined) { - onUpdate(updatedItem) + onUpdate?.(updatedItem) } } @@ -192,7 +198,7 @@ export const HotspotImage = ({ src, data, styleOptions = defaultStyleOptions, on { onRemove(hotspot.id) } } + onClick={ () => { onRemove?.(hotspot.id) } } type={ 'link' } /> @@ -215,7 +221,7 @@ export const HotspotImage = ({ src, data, styleOptions = defaultStyleOptions, on onOpenChange={ (open) => { setPopoverOpen(open) } } open={ popoverOpen && selectedId === hotspot.id } overlayClassName={ [styles.Popover].join(' ') } - trigger={ ['contextMenu'] } + trigger={ disableContextMenu === true ? [] : ['contextMenu'] } >