From fd19725ab683fef5efff971cff32f68cb69920a8 Mon Sep 17 00:00:00 2001 From: pubuzhixing8 Date: Wed, 9 Oct 2024 09:40:41 +0800 Subject: [PATCH] feat: improve active-toolbar --- package-lock.json | 48 ++-- package.json | 12 +- .../src/components/toolbar/active-toolbar.tsx | 230 +++++++++++------- 3 files changed, 167 insertions(+), 123 deletions(-) diff --git a/package-lock.json b/package-lock.json index b3335175..8991008d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,12 +10,12 @@ "license": "MIT", "dependencies": { "@floating-ui/react": "^0.26.24", - "@plait/common": "^0.66.1", - "@plait/core": "^0.66.1", - "@plait/draw": "^0.66.1", - "@plait/layouts": "^0.66.1", - "@plait/mind": "^0.66.1", - "@plait/text-plugins": "^0.66.1", + "@plait/common": "^0.67.0", + "@plait/core": "^0.67.0", + "@plait/draw": "^0.67.0", + "@plait/layouts": "^0.67.0", + "@plait/mind": "^0.67.0", + "@plait/text-plugins": "^0.67.0", "@radix-ui/react-popover": "^1.0.3", "ahooks": "^3.8.0", "browser-fs-access": "^0.35.0", @@ -3927,17 +3927,17 @@ } }, "node_modules/@plait/common": { - "version": "0.66.1", - "resolved": "https://registry.npmjs.org/@plait/common/-/common-0.66.1.tgz", - "integrity": "sha512-nnMUsO2n1bcdcUYITV+BFR5ymcnfnDLjCQJYN04bHT/F41BQMwDhL48mqxaPGwHoS4yZKGBPIasnrFP2Dmoicw==", + "version": "0.67.0", + "resolved": "https://registry.npmjs.org/@plait/common/-/common-0.67.0.tgz", + "integrity": "sha512-rHjIxtU+OKKDZ2YdN7tk2/w6+w+dmT51NaCaYhNWJnRp6delT9WITlazpmCdhIJcHuCoVwOMSBG31CkD8HMLkA==", "dependencies": { "tslib": "^2.3.0" } }, "node_modules/@plait/core": { - "version": "0.66.1", - "resolved": "https://registry.npmjs.org/@plait/core/-/core-0.66.1.tgz", - "integrity": "sha512-ie/0SW0iy+hRJr3VuR1tZtJvvKIX6y1kVvALiraIKlZAeK1rmx2jajTvd5SQIES6giEeig/ekhUEKfN/sx5CUA==", + "version": "0.67.0", + "resolved": "https://registry.npmjs.org/@plait/core/-/core-0.67.0.tgz", + "integrity": "sha512-Yh3MczAmvATeoAmPewXDWwZKiGUklWzzEbU3RqWWN47hxsefGjweJ5TYhCLgDDWAfj3NpRD/eYMH4+KtsE4qXg==", "dependencies": { "tslib": "^2.3.0" }, @@ -3950,33 +3950,33 @@ } }, "node_modules/@plait/draw": { - "version": "0.66.1", - "resolved": "https://registry.npmjs.org/@plait/draw/-/draw-0.66.1.tgz", - "integrity": "sha512-X/wX2mtWUonXAZmQWkKE30U9FZeZYG4ixXHOMD/M2mU1U79LB/sktaqVZOGoDUB++2Ab+dXLdeyXM9OqFQR0eQ==", + "version": "0.67.0", + "resolved": "https://registry.npmjs.org/@plait/draw/-/draw-0.67.0.tgz", + "integrity": "sha512-QBq1VswNAOlszuHVs+LbaLYozOBZvsZAd8spaCjaAKkJNc745ZnQfCKUsVz5QsgkmR6thPvPU68lncMjPbskyQ==", "dependencies": { "tslib": "^2.3.0" } }, "node_modules/@plait/layouts": { - "version": "0.66.1", - "resolved": "https://registry.npmjs.org/@plait/layouts/-/layouts-0.66.1.tgz", - "integrity": "sha512-lSTzA5ipj0fQbdgdjrkKXQGjst6LCX65ZqfxT5b/lkWqTfY9+Wsl2w9vzL0VlyXX+VWUDTnWAY6cWP72gvH9SA==", + "version": "0.67.0", + "resolved": "https://registry.npmjs.org/@plait/layouts/-/layouts-0.67.0.tgz", + "integrity": "sha512-IWtiieUF1oIH3Tps+8kuJp2Dkxc8KItxtPtM1IHr79NbY23T5zfOzQGIyx0Wh77HWwKa+EIj9MYHeGSQOzcv3w==", "dependencies": { "tslib": "^2.3.0" } }, "node_modules/@plait/mind": { - "version": "0.66.1", - "resolved": "https://registry.npmjs.org/@plait/mind/-/mind-0.66.1.tgz", - "integrity": "sha512-NFSqUnH2yvYAKhwaAjB8c0w5AJt3wjBQPeS1hAGM1AK8r0I7W38CbXhj1spuC1P38Hg32hAuVLcya+/KhAhS+w==", + "version": "0.67.0", + "resolved": "https://registry.npmjs.org/@plait/mind/-/mind-0.67.0.tgz", + "integrity": "sha512-XYMobd9WuF/S5p/qMuYYDd94M4CjGeIWwsMr5DqbGAN/e/5XyUw8RMU/nsvVasoOOvxmykaXB0ri0Ptyjyp6dQ==", "dependencies": { "tslib": "^2.3.0" } }, "node_modules/@plait/text-plugins": { - "version": "0.66.1", - "resolved": "https://registry.npmjs.org/@plait/text-plugins/-/text-plugins-0.66.1.tgz", - "integrity": "sha512-A13FUCOG9OKU2alp/Zmf7MHcx3Xbm6iIVpRNVIQRp5/ko9n7eEzVS4LjkFqpBXx/77lhdTVROIiGFlyv3udOXA==", + "version": "0.67.0", + "resolved": "https://registry.npmjs.org/@plait/text-plugins/-/text-plugins-0.67.0.tgz", + "integrity": "sha512-b4k1YyNxOk4h0WlMyktEZdJUOTASA8+c1IDfBTaxXNJUA+5EwFgsAA//tNF3SEwbeCn0ZBQ3VuVl3RcyQxUosw==", "dependencies": { "tslib": "^2.3.0" } diff --git a/package.json b/package.json index 09412805..66bbfca7 100644 --- a/package.json +++ b/package.json @@ -10,12 +10,12 @@ "private": true, "dependencies": { "@floating-ui/react": "^0.26.24", - "@plait/common": "^0.66.1", - "@plait/core": "^0.66.1", - "@plait/draw": "^0.66.1", - "@plait/layouts": "^0.66.1", - "@plait/mind": "^0.66.1", - "@plait/text-plugins": "^0.66.1", + "@plait/common": "^0.67.0", + "@plait/core": "^0.67.0", + "@plait/draw": "^0.67.0", + "@plait/layouts": "^0.67.0", + "@plait/mind": "^0.67.0", + "@plait/text-plugins": "^0.67.0", "@radix-ui/react-popover": "^1.0.3", "ahooks": "^3.8.0", "browser-fs-access": "^0.35.0", diff --git a/packages/drawnix/src/components/toolbar/active-toolbar.tsx b/packages/drawnix/src/components/toolbar/active-toolbar.tsx index 87ee52d1..f78309d9 100644 --- a/packages/drawnix/src/components/toolbar/active-toolbar.tsx +++ b/packages/drawnix/src/components/toolbar/active-toolbar.tsx @@ -3,6 +3,8 @@ import { BackgroundColorIcon, FontColorIcon, StrokeIcon } from '../icons'; import { ATTACHED_ELEMENT_CLASS_NAME, getSelectedElements, + isDragging, + isMovingElements, isSelectionMoving, Path, PlaitBoard, @@ -11,7 +13,7 @@ import { SELECTION_RECTANGLE_CLASS_NAME, Transforms, } from '@plait/core'; -import React, { useEffect } from 'react'; +import React, { useEffect, useRef, useState } from 'react'; import { useBoard } from '@plait/react-board'; import { flip, offset, useFloating } from '@floating-ui/react'; import { Island } from '../island'; @@ -43,14 +45,14 @@ export type DrawActiveProps = {}; export const ActiveToolbar: React.FC = ({}) => { const board = useBoard(); const selectedElements = getSelectedElements(board); - const isOpen = selectedElements.length > 0 && !isSelectionMoving(board); - - const { viewport, selection } = board; + const [movingOrDragging, setMovingOrDragging] = useState(false); + const movingOrDraggingRef = useRef(movingOrDragging); + const open = selectedElements.length > 0 && !isSelectionMoving(board); + const { viewport, selection, children } = board; const { refs, floatingStyles } = useFloating({ placement: 'top', middleware: [offset(32), flip()], }); - let state: { fill: string | undefined; strokeColor?: string; @@ -61,8 +63,7 @@ export const ActiveToolbar: React.FC = ({}) => { } = { fill: 'red', }; - - if (isOpen) { + if (open && !movingOrDragging) { const hasFill = selectedElements.some((value) => hasFillProperty(board, value) ); @@ -71,9 +72,8 @@ export const ActiveToolbar: React.FC = ({}) => { ); state = { ...getElementState(board), hasFill, hasFontColor: hasText }; } - useEffect(() => { - if (isOpen) { + if (open) { let selectionG = PlaitBoard.getBoardContainer(board).querySelector( `.${SELECTION_RECTANGLE_BOUNDING_CLASS_NAME}` ); @@ -82,104 +82,148 @@ export const ActiveToolbar: React.FC = ({}) => { `.${SELECTION_RECTANGLE_CLASS_NAME}` ); } - refs.setPositionReference(selectionG); + if (selectionG) { + const rect = selectionG?.getBoundingClientRect(); + refs.setPositionReference({ + getBoundingClientRect() { + return { + width: rect.width, + height: rect.height, + x: rect.x, + y: rect.y, + top: rect.top, + left: rect.left, + right: rect.right, + bottom: rect.bottom, + }; + }, + }); + } } - }, [viewport, selection]); + }, [viewport, selection, children, movingOrDragging]); + + useEffect(() => { + movingOrDraggingRef.current = movingOrDragging; + }, [movingOrDragging]); + + useEffect(() => { + const { pointerUp, pointerMove } = board; + + board.pointerMove = (event: PointerEvent) => { + if ( + (isMovingElements(board) || isDragging(board)) && + !movingOrDraggingRef.current + ) { + setMovingOrDragging(true); + } + pointerMove(event); + }; + + board.pointerUp = (event: PointerEvent) => { + if ( + movingOrDraggingRef.current && + (isMovingElements(board) || isDragging(board)) + ) { + setMovingOrDragging(false); + } + pointerUp(event); + }; + + return () => { + board.pointerUp = pointerUp; + board.pointerMove = pointerMove; + }; + }, [board]); return ( <> - {isOpen && ( -
- - - {state.hasFontColor && ( - - } - onSelect={(selectedColor: string) => { - TextTransforms.setTextColor( - board, - selectedColor, - undefined, - getSelectedTableCellsEditor(board) - ); - }} - > - )} - + + {state.hasFontColor && ( + + } onSelect={(selectedColor: string) => { - console.log(`selectedColor: ${selectedColor}`); - PropertyTransforms.setStrokeColor(board, selectedColor, { + TextTransforms.setTextColor( + board, + selectedColor, + undefined, + getSelectedTableCellsEditor(board) + ); + }} + > + )} + { + console.log(`selectedColor: ${selectedColor}`); + PropertyTransforms.setStrokeColor(board, selectedColor, { + getMemorizeKey, + }); + }} + > + + + {state.hasFill && ( + { + PropertyTransforms.setFillColor(board, selectedColor, { getMemorizeKey, + callback: (element: PlaitElement, path: Path) => { + const tableElement = + PlaitDrawElement.isElementByTable(element); + if (tableElement) { + DrawTransforms.setTableFill( + board, + element, + selectedColor, + path + ); + } else { + if (isDrawElementClosed(element as PlaitDrawElement)) { + Transforms.setNode( + board, + { fill: selectedColor }, + path + ); + } + } + }, }); }} > - {state.hasFill && ( - { - PropertyTransforms.setFillColor(board, selectedColor, { - getMemorizeKey, - callback: (element: PlaitElement, path: Path) => { - const tableElement = - PlaitDrawElement.isElementByTable(element); - if (tableElement) { - DrawTransforms.setTableFill( - board, - element, - selectedColor, - path - ); - } else { - if ( - isDrawElementClosed(element as PlaitDrawElement) - ) { - Transforms.setNode( - board, - { fill: selectedColor }, - path - ); - } - } - }, - }); - }} - > - - - )} - - -
+ )} + + )} );