From 5c550b4e2e7415abd433b0b0bbb24463689174c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= Date: Wed, 6 Sep 2023 14:57:38 +0200 Subject: [PATCH 1/2] feat: allow vieweranchor to have stickiness --- .../components/ViewerAnchor/ViewerAnchor.tsx | 44 ++++++++++++++++++- .../stories/ViewerAnchor.stories.tsx | 2 +- 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/react-components/src/components/ViewerAnchor/ViewerAnchor.tsx b/react-components/src/components/ViewerAnchor/ViewerAnchor.tsx index f254a681c9a..a65f44465e5 100644 --- a/react-components/src/components/ViewerAnchor/ViewerAnchor.tsx +++ b/react-components/src/components/ViewerAnchor/ViewerAnchor.tsx @@ -14,10 +14,17 @@ export type ViewerAnchorElementMapping = { export type ViewerAnchorProps = { position: Vector3; + sticky?: boolean; + stickyMargin?: number; children: ReactElement; }; -export const ViewerAnchor = ({ position, children }: ViewerAnchorProps): ReactElement => { +export const ViewerAnchor = ({ + position, + children, + sticky, + stickyMargin +}: ViewerAnchorProps): ReactElement => { const viewer = useReveal(); const [divTranslation, setDivTranslation] = useState(new Vector2()); const [visible, setVisible] = useState(false); @@ -52,6 +59,17 @@ export const ViewerAnchor = ({ position, children }: ViewerAnchorProps): ReactEl const htmlRef = useRef(null); + const domDimensions = [viewer.domElement.clientWidth, viewer.domElement.clientHeight] as [ + number, + number + ]; + const cssTranslation = computeCssOffsetWithStickiness( + divTranslation, + domDimensions, + sticky, + stickyMargin + ); + return visible ? (
{children}
@@ -67,3 +85,25 @@ export const ViewerAnchor = ({ position, children }: ViewerAnchorProps): ReactEl <> ); }; + +function computeCssOffsetWithStickiness( + unboundedPosition: Vector2, + [domWidth, domHeight]: [number, number], + sticky?: boolean, + stickyMargin?: number +) { + if (sticky !== true) { + return `translateX(${unboundedPosition.x}px) translateY(${unboundedPosition.y}px)`; + } + + const margin = stickyMargin ?? 0; + + const maxXPos = `${domWidth}px - 100% - ${margin}px`; + const maxYPos = `${domHeight}px - 100% - ${margin}px`; + + const minXPos = `${margin}px`; + const minYPos = `${margin}px`; + + return `translateX(max(${minXPos}, min(${maxXPos}, ${unboundedPosition.x}px))) +translateY(max(${minYPos}, min(${maxYPos}, ${unboundedPosition.y}px)))`; +} diff --git a/react-components/stories/ViewerAnchor.stories.tsx b/react-components/stories/ViewerAnchor.stories.tsx index 0c91566639a..75071c0d2a3 100644 --- a/react-components/stories/ViewerAnchor.stories.tsx +++ b/react-components/stories/ViewerAnchor.stories.tsx @@ -60,7 +60,7 @@ export const Main: Story = { - +

Date: Wed, 6 Sep 2023 16:28:48 +0200 Subject: [PATCH 2/2] chore: lint fix --- react-components/src/components/ViewerAnchor/ViewerAnchor.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/react-components/src/components/ViewerAnchor/ViewerAnchor.tsx b/react-components/src/components/ViewerAnchor/ViewerAnchor.tsx index a65f44465e5..2e8ea8d49ab 100644 --- a/react-components/src/components/ViewerAnchor/ViewerAnchor.tsx +++ b/react-components/src/components/ViewerAnchor/ViewerAnchor.tsx @@ -91,7 +91,7 @@ function computeCssOffsetWithStickiness( [domWidth, domHeight]: [number, number], sticky?: boolean, stickyMargin?: number -) { +): string { if (sticky !== true) { return `translateX(${unboundedPosition.x}px) translateY(${unboundedPosition.y}px)`; }