From 7c33db4c2c7193c63171f1ff01f39a4837f897d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Flatval?= <70905152+haakonflatval-cognite@users.noreply.github.com> Date: Thu, 7 Sep 2023 09:10:23 +0200 Subject: [PATCH] feat: allow vieweranchor to have stickiness (#3681) * feat: allow vieweranchor to have stickiness --------- Co-authored-by: cognite-bulldozer[bot] <51074376+cognite-bulldozer[bot]@users.noreply.github.com> --- .../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..2e8ea8d49ab 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 +): string { + 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 = { - +