From 4cd5962dc6043fa05ee9e89d63a3b2e4ad2c1dd7 Mon Sep 17 00:00:00 2001 From: yanzhuoran Date: Tue, 10 Sep 2024 14:02:27 +0800 Subject: [PATCH] feat: refactor constraints --- .../semi-foundation/resizable/group/index.ts | 108 ++++-------------- .../resizable/groupConstants.ts | 12 ++ .../resizable/_story/resizable.stories.jsx | 2 +- .../semi-ui/resizable/group/resizeGroup.tsx | 27 ++++- 4 files changed, 57 insertions(+), 92 deletions(-) diff --git a/packages/semi-foundation/resizable/group/index.ts b/packages/semi-foundation/resizable/group/index.ts index d7a3361e1d..5870044a20 100644 --- a/packages/semi-foundation/resizable/group/index.ts +++ b/packages/semi-foundation/resizable/group/index.ts @@ -1,7 +1,7 @@ import { getItemDirection } from '../groupConstants'; import BaseFoundation, { DefaultAdapter } from '../../base/foundation'; import { ResizeStartCallback, ResizeCallback } from "../singleConstants"; -import { getPixelSize } from '../groupConstants'; +import { getPixelSize, judgeConstraint } from '../groupConstants'; export interface ResizeHandlerAdapter

, S = Record> extends DefaultAdapter { getHandler: () => HTMLElement; getHandlerIndex: () => number; @@ -108,82 +108,18 @@ export class ResizeGroupFoundation

, S = Record { - // this item constaint last / next handler - let lastConstraints = new Map(), nextConstraints = new Map(); - if (this.direction === 'horizontal') { - const parentWidth = this.groupRef.getBoundingClientRect().width; - for (let i = 0; i < this._adapter.getItemCount(); i++) { - const child = this._adapter.getItem(i); - - let itemMin = this._adapter.getItemMin(i) - const minWidth = itemMin ? getPixelSize(itemMin, parentWidth) : 0; - const rect = child.getBoundingClientRect(); - let { borderLeftWidth, borderRightWidth } = this.window.getComputedStyle(child); - let leftWidth = Number(borderLeftWidth.replace('px', '')); - let rightWidth = Number(borderRightWidth.replace('px', '')); - let borderWidth = leftWidth + rightWidth + this.itemMinSize; - - let nextLeftConstraint = rect.left + minWidth + borderWidth, nextRightConstraint = undefined; - let lastRightConstraint = rect.right - minWidth - borderWidth, lastLeftConstraint = undefined; - let itemMax = this._adapter.getItemMax(i) - if (itemMax) { - const maxWidth = getPixelSize(itemMax, parentWidth); - nextRightConstraint = rect.left + maxWidth - borderWidth; - lastLeftConstraint = rect.right - maxWidth + borderWidth; - } - - lastConstraints.set(i - 1, [lastLeftConstraint, lastRightConstraint]); - nextConstraints.set(i, [nextLeftConstraint, nextRightConstraint]); - } - } else { - const parentHeight = this.groupRef.getBoundingClientRect().height; - for (let i = 0; i < this._adapter.getItemCount(); i++) { - const child = this._adapter.getItem(i); - - let itemMin = this._adapter.getItemMin(i) - const minHeight = itemMin ? getPixelSize(itemMin, parentHeight) : 0; - const rect = child.getBoundingClientRect(); - let { borderTopWidth, borderBottomWidth } = this.window.getComputedStyle(child); - let topWidth = Number(borderTopWidth.replace('px', '')); - let bottomWidth = Number(borderBottomWidth.replace('px', '')); - let borderWidth = (topWidth + bottomWidth) + this.itemMinSize; - - let nextTopConstraint = rect.top + minHeight + borderWidth, nextBottomConstraint = undefined; - let lastBottomConstraint = rect.bottom - minHeight - borderWidth, lastTopConstraint = undefined; - let itemMax = this._adapter.getItemMax(i) - if (itemMax) { - const maxHeight = getPixelSize(itemMax, parentHeight); - nextBottomConstraint = rect.top + maxHeight - borderWidth; - lastTopConstraint = rect.bottom - maxHeight + borderWidth; - } - - lastConstraints.set(i - 1, [lastTopConstraint, lastBottomConstraint]); - nextConstraints.set(i, [nextTopConstraint, nextBottomConstraint]); - - } - } - - for (let i = 0; i < this._adapter.getHandlerCount(); i++) { - // lastBack and nextFront wont be undefined - let [lastFront, lastBack] = lastConstraints.get(i); - let [nextFront, nextBack] = nextConstraints.get(i); - let front = lastFront === undefined ? nextFront : Math.max(lastFront, nextFront); - let back = nextBack === undefined ? lastBack : Math.min(lastBack, nextBack); - this.constraintsMap.set(i, [front, back]); - } - } - onResizeStart = (handlerIndex: number, e: MouseEvent) => { // handler ref let { clientX, clientY } = e; let lastItem = this._adapter.getItem(handlerIndex), nextItem = this._adapter.getItem(handlerIndex + 1); + let handler = this._adapter.getHandler(handlerIndex); + let lastOffset: number, nextOffset: number; if (this.direction === 'horizontal') { - this.itemMinSize = this._adapter.getHandler(handlerIndex).offsetWidth; - + this.itemMinSize = handler.offsetWidth; + lastOffset = clientX - handler.offsetLeft; + nextOffset = handler.offsetLeft + handler.offsetWidth - clientX; } else if (this.direction === 'vertical') { - this.itemMinSize = this._adapter.getHandler(handlerIndex).offsetHeight; + this.itemMinSize = handler.offsetHeight; } - this.updateConstraints(); this.setState({ isResizing: true, originalPosition: { @@ -191,6 +127,8 @@ export class ResizeGroupFoundation

, S = Record, S = Record= curConstraint[1]) { - return - } - } else if (this.direction === 'vertical') { - if (clientY <= curConstraint[0] || clientY >= curConstraint[1]) { - return - } - } - } + let { x: initX, y: initY, lastItemSize, nextItemSize, lastOffset, nextOffset } = originalPosition; + console.log(lastItemSize, nextItemSize, lastOffset, nextOffset) + let { clientX, clientY } = e; const props = this.getProps(); const { direction } = props; @@ -237,8 +164,15 @@ export class ResizeGroupFoundation

, S = Record { } return typeof size === 'undefined' ? size : Number(size); +} + +export const judgeConstraint = (newSize: number, min: string, max: string, parentSize: number) => { + const minSize = getPixelSize(min, parentSize); + const maxSize = getPixelSize(max, parentSize); + if (newSize <= minSize) { + return false; + } + if (newSize >= maxSize) { + return false; + } + return true; } \ No newline at end of file diff --git a/packages/semi-ui/resizable/_story/resizable.stories.jsx b/packages/semi-ui/resizable/_story/resizable.stories.jsx index ec8b3f1d0e..caad713e26 100644 --- a/packages/semi-ui/resizable/_story/resizable.stories.jsx +++ b/packages/semi-ui/resizable/_story/resizable.stories.jsx @@ -251,7 +251,7 @@ export const Group_horizontal = () => { { setText('resizing') }} >

diff --git a/packages/semi-ui/resizable/group/resizeGroup.tsx b/packages/semi-ui/resizable/group/resizeGroup.tsx index b81cbefec3..0be4606a86 100644 --- a/packages/semi-ui/resizable/group/resizeGroup.tsx +++ b/packages/semi-ui/resizable/group/resizeGroup.tsx @@ -23,6 +23,8 @@ export interface ResizeGroupState { y: number; lastItemSize: number; nextItemSize: number; + lastOffset: number; + nextOffset: number; }; curHandler: number; curConstraint: [number, number] @@ -46,6 +48,8 @@ class ResizeGroup extends BaseComponent { y: 0, lastItemSize: 0, nextItemSize: 0, + lastOffset: 0, + nextOffset: 0, }, curHandler: null, curConstraint: null @@ -74,7 +78,21 @@ class ResizeGroup extends BaseComponent { let totalSizePercent = 0; let undefineLoc = [] let parentSize = this.props.direction === 'horizontal' ? this.groupRef.current.offsetWidth : this.groupRef.current.offsetHeight; - for (let i = 0; i < this.itemDefaultSizeList.length; i++) { + for (let i = 0; i < this.itemRefs.length; i++) { + const child = this.itemRefs[i].current; + let minSize = this.itemMinMap.get(i), maxSize = this.itemMaxMap.get(i); + let minSizePercent = minSize ? getPixelSize(minSize, parentSize) / parentSize * 100 : 0, + maxSizePercent = maxSize ? getPixelSize(maxSize, parentSize) / parentSize * 100 : 100; + if (minSizePercent > maxSizePercent) { + console.warn('min size bigger than max size'); + } + if (this.props.direction === 'horizontal') { + child.style.minWidth = minSize ?? '0%'; + child.style.maxWidth = maxSize ?? '100%'; + } else { + child.style.minHeight = minSize ?? '0%'; + child.style.maxHeight = maxSize ?? '100%'; + } if (this.itemDefaultSizeList[i]) { let itemSizePercent: number; if (this.itemDefaultSizeList[i].endsWith('%')) { @@ -83,11 +101,12 @@ class ResizeGroup extends BaseComponent { itemSizePercent = parseInt(this.itemDefaultSizeList[i].slice(0, -2)) / parentSize * 100; } totalSizePercent += itemSizePercent; - let minSizePercent = this.itemMinMap.get(i) ? getPixelSize(this.itemMinMap.get(i), parentSize) / parentSize * 100 : 0, - maxSizePercent = this.itemMaxMap.get(i) ? getPixelSize(this.itemMaxMap.get(i), parentSize) / parentSize * 100 : 100; + + if (itemSizePercent < minSizePercent) { console.warn('item size smaller than min size'); - } else if (itemSizePercent > maxSizePercent) { + } + if (itemSizePercent > maxSizePercent) { console.warn('item size bigger than max size'); } } else {