diff --git a/packages/react-moveable/src/react-moveable/MoveableManager.tsx b/packages/react-moveable/src/react-moveable/MoveableManager.tsx index 4e315d589..a76b7a736 100644 --- a/packages/react-moveable/src/react-moveable/MoveableManager.tsx +++ b/packages/react-moveable/src/react-moveable/MoveableManager.tsx @@ -337,7 +337,9 @@ export default class MoveableManager : props.rootContainer; this.updateState( getTargetInfo(this.controlBox && this.controlBox.getElement(), - target, container, container, + target, + container, + container, rootContainer || container, // isTarget ? state : undefined ), diff --git a/packages/react-moveable/src/react-moveable/ables/Draggable.tsx b/packages/react-moveable/src/react-moveable/ables/Draggable.tsx index d45ffd0c6..a6c67e18a 100644 --- a/packages/react-moveable/src/react-moveable/ables/Draggable.tsx +++ b/packages/react-moveable/src/react-moveable/ables/Draggable.tsx @@ -18,6 +18,7 @@ import { triggerChildGesto } from "../groupUtils"; import { startCheckSnapDrag } from "./Snappable"; import { IObject, getRad, throttle, throttleArray } from "@daybrush/utils"; import { checkSnapBoundsDrag } from "./snappable/snapBounds"; +import { TINY_NUM } from "../consts"; /** * @namespace Draggable @@ -181,6 +182,7 @@ export default { isBound: isHorizontalBound, offset: horizontalOffset, } = horizontalInfo; + isSnap = isVerticalSnap || isHorizontalSnap || isVerticalBound || isHorizontalBound; distX += verticalOffset; @@ -194,6 +196,8 @@ export default { throttleArray(translate, throttleDrag); throttleArray(beforeTranslate, throttleDrag); } + throttleArray(translate, TINY_NUM); + throttleArray(beforeTranslate, TINY_NUM); const beforeDist = minus(beforeTranslate, startValue); const dist = minus(translate, startValue); diff --git a/packages/react-moveable/src/react-moveable/ables/Snappable.tsx b/packages/react-moveable/src/react-moveable/ables/Snappable.tsx index f6a3999ed..580b2c094 100644 --- a/packages/react-moveable/src/react-moveable/ables/Snappable.tsx +++ b/packages/react-moveable/src/react-moveable/ables/Snappable.tsx @@ -107,10 +107,10 @@ export function snapStart( snapContainerRect.right - containerClientRect.right, snapContainerRect.bottom - containerClientRect.bottom, ]); - snapOffset.left = throttle(offset1[0], 0.1); - snapOffset.top = throttle(offset1[1], 0.1); - snapOffset.right = throttle(offset2[0], 0.1); - snapOffset.bottom = throttle(offset2[1], 0.1); + snapOffset.left = throttle(offset1[0], 0.00001); + snapOffset.top = throttle(offset1[1], 0.00001); + snapOffset.right = throttle(offset2[0], 0.00001); + snapOffset.bottom = throttle(offset2[1], 0.00001); } } diff --git a/packages/react-moveable/src/react-moveable/ables/snappable/snapBounds.ts b/packages/react-moveable/src/react-moveable/ables/snappable/snapBounds.ts index 0f0d8c01d..64068e9e2 100644 --- a/packages/react-moveable/src/react-moveable/ables/snappable/snapBounds.ts +++ b/packages/react-moveable/src/react-moveable/ables/snappable/snapBounds.ts @@ -257,6 +257,7 @@ export function checkSnapBoundsDrag( [isVerticalSnap, isHorizontalSnap], [verticalOffset, horizontalOffset] ); + return [ { isBound: isVerticalBound, diff --git a/packages/react-moveable/src/react-moveable/types.ts b/packages/react-moveable/src/react-moveable/types.ts index 9d4b854da..949d4043a 100644 --- a/packages/react-moveable/src/react-moveable/types.ts +++ b/packages/react-moveable/src/react-moveable/types.ts @@ -193,8 +193,8 @@ export type MoveableManagerState = { targetClientRect: MoveableClientRect; containerClientRect: MoveableClientRect; moveableClientRect: MoveableClientRect; + rootContainerClientRect: MoveableClientRect; rotation: number; - hasFixed: boolean; } & ElementSizes & T; diff --git a/packages/react-moveable/src/react-moveable/utils.tsx b/packages/react-moveable/src/react-moveable/utils.tsx index 432e2e005..d5524716b 100644 --- a/packages/react-moveable/src/react-moveable/utils.tsx +++ b/packages/react-moveable/src/react-moveable/utils.tsx @@ -471,7 +471,10 @@ export function calculateElementInfo( container?: SVGElement | HTMLElement | null, rootContainer: HTMLElement | SVGElement | null | undefined = container, isAbsolute3d?: boolean, -) { +): ReturnType + & ReturnType + & ElementSizes + & { width: number; height: number; rotation: number; } { let width = 0; let height = 0; let rotation = 0; @@ -492,6 +495,7 @@ export function calculateElementInfo( isAbsolute3d, // prevMatrix, prevRootMatrix, prevN, ); + const position = calculateMoveablePosition( result.allMatrix, result.transformOrigin, @@ -533,6 +537,8 @@ export function calculateElementInfo( pos4: [0, 0], direction: 1, hasFixed: false, + offsetContainer: null, + offsetRootContainer: null, ...allResult, }; } @@ -564,6 +570,7 @@ export function calculateMatrixStack( const { matrixes: rootMatrixes, is3d: isRoot3d, + offsetContainer: offsetRootContainer, } = getMatrixStackInfo(offsetContainer, rootContainer, true); // prevRootMatrix // if (rootContainer === document.body) { @@ -656,6 +663,8 @@ export function calculateMatrixStack( transformOrigin, targetOrigin, is3d: isNext3d, + offsetContainer: offsetContainer as HTMLElement | null, + offsetRootContainer: offsetRootContainer as HTMLElement | null, }; } export function makeMatrixCSS(matrix: number[], is3d: boolean = matrix.length > 9) { @@ -1016,12 +1025,19 @@ export function getSize( } const inlineWidth = convertUnitSize(targetStyle.width, 0); const inlineHeight = convertUnitSize(targetStyle.height, 0); + const computedWidth = parseFloat(style!.width); + const computedHeight = parseFloat(style!.height); cssWidth = parseFloat(style!.width); cssHeight = parseFloat(style!.height); - contentWidth = between(minWidth, inlineWidth || parseFloat(style!.width), maxWidth); - contentHeight = between(minHeight, inlineHeight || parseFloat(style!.height), maxHeight); + contentWidth = Math.abs(computedWidth - inlineWidth) < 1 + ? between(minWidth, inlineWidth || parseFloat(style!.width), maxWidth) + : computedWidth; + contentHeight = Math.abs(computedHeight - inlineHeight) < 1 + ? between(minHeight, inlineHeight || parseFloat(style!.height), maxHeight) + : computedHeight; + offsetWidth = contentWidth; offsetHeight = contentHeight; clientWidth = contentWidth; @@ -1085,8 +1101,9 @@ export function getTargetInfo( let beforeDirection: 1 | -1 = 1; let beforeOrigin = [0, 0]; let targetClientRect = resetClientRect(); - let containerClientRect = resetClientRect(); let moveableClientRect = resetClientRect(); + let containerClientRect = resetClientRect(); + let rootContainerClientRect = resetClientRect(); const result = calculateElementInfo( target, container!, rootContainer!, false, @@ -1106,10 +1123,10 @@ export function getTargetInfo( ); targetClientRect = getClientRect(target); - containerClientRect = getClientRect( - getOffsetInfo(parentContainer, parentContainer, true).offsetParent || document.body, - true, - ); + const offsetContainer = getOffsetInfo(parentContainer, parentContainer, true).offsetParent + || result.offsetRootContainer!; + containerClientRect = getClientRect(offsetContainer, true); + rootContainerClientRect = getClientRect(result.offsetRootContainer!); if (moveableElement) { moveableClientRect = getClientRect(moveableElement); } @@ -1119,6 +1136,7 @@ export function getTargetInfo( targetClientRect, containerClientRect, moveableClientRect, + rootContainerClientRect, beforeDirection, beforeOrigin, originalBeforeOrigin: beforeOrigin, @@ -1128,9 +1146,10 @@ export function getTargetInfo( } export function resetClientRect(): MoveableClientRect { return { - left: 0, right: 0, - top: 0, bottom: 0, + left: 0, top: 0, width: 0, height: 0, + right: 0, + bottom: 0, clientLeft: 0, clientTop: 0, clientWidth: 0, clientHeight: 0, scrollWidth: 0, scrollHeight: 0, @@ -1142,31 +1161,33 @@ export function getClientRect(el: HTMLElement | SVGElement, isExtends?: boolean) let width = 0; let height = 0; - if (el === document.body || el === document.documentElement) { - width = window.innerWidth; - height = window.innerHeight; - const scrollPos = getBodyScrollPos(); + if (el) { + if (el === document.body || el === document.documentElement) { + width = window.innerWidth; + height = window.innerHeight; + const scrollPos = getBodyScrollPos(); - [left, top] = [-scrollPos[0], -scrollPos[1]]; - } else { - const clientRect = el.getBoundingClientRect(); + [left, top] = [-scrollPos[0], -scrollPos[1]]; + } else { + const clientRect = el.getBoundingClientRect(); - left = clientRect.left; - top = clientRect.top; - width = clientRect.width; - height = clientRect.height; + left = clientRect.left; + top = clientRect.top; + width = clientRect.width; + height = clientRect.height; + } } const rect: MoveableClientRect = { left, - right: left + width, top, - bottom: top + height, width, height, + right: left + width, + bottom: top + height, }; - if (isExtends) { + if (el && isExtends) { rect.clientLeft = el.clientLeft; rect.clientTop = el.clientTop; rect.clientWidth = el.clientWidth; diff --git a/packages/react-moveable/stories/99-Tests/ReactAccuracyApp.tsx b/packages/react-moveable/stories/99-Tests/ReactAccuracyApp.tsx index 2097435e4..f141131bc 100644 --- a/packages/react-moveable/stories/99-Tests/ReactAccuracyApp.tsx +++ b/packages/react-moveable/stories/99-Tests/ReactAccuracyApp.tsx @@ -10,7 +10,7 @@ export default function App() { position: "relative", width: "800px", height: "800px", - // transform: "scale(0.67123)", + transform: "scale(0.67123)", transformOrigin: "top left", background: "#eee", }}>