fix: clamp canvas image toolbar inside viewport
This commit is contained in:
parent
d6149bd05d
commit
3569582b43
@ -121,6 +121,7 @@ interface BoxCutoutPoint {
|
||||
|
||||
const BOX_CUTOUT_DEFAULT_PADDING_RATIO = 0.08;
|
||||
const BOX_CUTOUT_MIN_EDGE_PX = 24;
|
||||
const FLOATING_TOOLBAR_SCALE = 0.8;
|
||||
|
||||
const clampNumber = (value: number, min: number, max: number) =>
|
||||
Math.min(max, Math.max(min, value));
|
||||
@ -972,8 +973,10 @@ export function ImageNode({ node, isSelected }: ImageNodeProps) {
|
||||
|
||||
let rafId: number | null = null;
|
||||
const measure = () => {
|
||||
const rect = toolbarEl.getBoundingClientRect();
|
||||
const next = { width: rect.width, height: rect.height };
|
||||
const next = {
|
||||
width: toolbarEl.offsetWidth,
|
||||
height: toolbarEl.offsetHeight,
|
||||
};
|
||||
setToolbarSize((prev) =>
|
||||
Math.abs(prev.width - next.width) < 0.5 &&
|
||||
Math.abs(prev.height - next.height) < 0.5
|
||||
@ -1028,8 +1031,10 @@ export function ImageNode({ node, isSelected }: ImageNodeProps) {
|
||||
|
||||
let rafId: number | null = null;
|
||||
const measure = () => {
|
||||
const rect = toolbarEl.getBoundingClientRect();
|
||||
const next = { width: rect.width, height: rect.height };
|
||||
const next = {
|
||||
width: toolbarEl.offsetWidth,
|
||||
height: toolbarEl.offsetHeight,
|
||||
};
|
||||
setBoxCutoutToolbarSize((prev) =>
|
||||
Math.abs(prev.width - next.width) < 0.5 &&
|
||||
Math.abs(prev.height - next.height) < 0.5
|
||||
@ -1729,14 +1734,13 @@ export function ImageNode({ node, isSelected }: ImageNodeProps) {
|
||||
const getToolbarPosition = () => {
|
||||
if (containerRef.current && typeof window !== "undefined") {
|
||||
const rect = containerRef.current.getBoundingClientRect();
|
||||
const toolbarScale = 0.8;
|
||||
const toolbarWidth = Math.max(
|
||||
280,
|
||||
toolbarSize.width * toolbarScale || 980
|
||||
(toolbarSize.width || 980) * FLOATING_TOOLBAR_SCALE
|
||||
);
|
||||
const toolbarHeight = Math.max(
|
||||
42,
|
||||
toolbarSize.height * toolbarScale || 48
|
||||
(toolbarSize.height || 60) * FLOATING_TOOLBAR_SCALE
|
||||
);
|
||||
const titleSafeHeight = 34;
|
||||
const gap = 12;
|
||||
@ -1751,15 +1755,13 @@ export function ImageNode({ node, isSelected }: ImageNodeProps) {
|
||||
|
||||
const maxToolbarWidth = Math.max(180, safeRight - safeLeft);
|
||||
const effectiveToolbarWidth = Math.min(toolbarWidth, maxToolbarWidth);
|
||||
const halfToolbar = effectiveToolbarWidth / 2;
|
||||
|
||||
let left = rect.left + rect.width / 2;
|
||||
let left = rect.left + rect.width / 2 - effectiveToolbarWidth / 2;
|
||||
if (effectiveToolbarWidth >= maxToolbarWidth - 1) {
|
||||
left = (safeLeft + safeRight) / 2;
|
||||
left = safeLeft;
|
||||
} else {
|
||||
left = Math.min(
|
||||
Math.max(left, safeLeft + halfToolbar),
|
||||
safeRight - halfToolbar
|
||||
Math.max(left, safeLeft),
|
||||
safeRight - effectiveToolbarWidth
|
||||
);
|
||||
}
|
||||
|
||||
@ -1775,14 +1777,13 @@ export function ImageNode({ node, isSelected }: ImageNodeProps) {
|
||||
const getBoxCutoutToolbarPosition = () => {
|
||||
if (containerRef.current && typeof window !== "undefined") {
|
||||
const rect = containerRef.current.getBoundingClientRect();
|
||||
const toolbarScale = 0.8;
|
||||
const toolbarWidth = Math.max(
|
||||
240,
|
||||
boxCutoutToolbarSize.width * toolbarScale || 460
|
||||
(boxCutoutToolbarSize.width || 460) * FLOATING_TOOLBAR_SCALE
|
||||
);
|
||||
const toolbarHeight = Math.max(
|
||||
42,
|
||||
boxCutoutToolbarSize.height * toolbarScale || 48
|
||||
(boxCutoutToolbarSize.height || 60) * FLOATING_TOOLBAR_SCALE
|
||||
);
|
||||
const gap = 14;
|
||||
const { viewportPadding, safeBottom, safeLeft, safeRight, maxTop } =
|
||||
@ -1796,15 +1797,13 @@ export function ImageNode({ node, isSelected }: ImageNodeProps) {
|
||||
|
||||
const maxToolbarWidth = Math.max(180, safeRight - safeLeft);
|
||||
const effectiveToolbarWidth = Math.min(toolbarWidth, maxToolbarWidth);
|
||||
const halfToolbar = effectiveToolbarWidth / 2;
|
||||
|
||||
let left = rect.left + rect.width / 2;
|
||||
let left = rect.left + rect.width / 2 - effectiveToolbarWidth / 2;
|
||||
if (effectiveToolbarWidth >= maxToolbarWidth - 1) {
|
||||
left = (safeLeft + safeRight) / 2;
|
||||
left = safeLeft;
|
||||
} else {
|
||||
left = Math.min(
|
||||
Math.max(left, safeLeft + halfToolbar),
|
||||
safeRight - halfToolbar
|
||||
Math.max(left, safeLeft),
|
||||
safeRight - effectiveToolbarWidth
|
||||
);
|
||||
}
|
||||
|
||||
@ -3425,10 +3424,13 @@ export function ImageNode({ node, isSelected }: ImageNodeProps) {
|
||||
style={{
|
||||
top: toolbarPosition.top,
|
||||
left: toolbarPosition.left,
|
||||
transform: "translateX(-50%) scale(0.8)",
|
||||
transformOrigin: "top center",
|
||||
transform: `scale(${FLOATING_TOOLBAR_SCALE})`,
|
||||
transformOrigin: "top left",
|
||||
pointerEvents: "auto",
|
||||
maxWidth: `${Math.max(180, Math.floor(toolbarPosition.maxWidth))}px`,
|
||||
maxWidth: `${Math.max(
|
||||
180,
|
||||
Math.floor(toolbarPosition.maxWidth / FLOATING_TOOLBAR_SCALE)
|
||||
)}px`,
|
||||
overflowX: "auto",
|
||||
scrollbarWidth: "none",
|
||||
}}
|
||||
@ -3593,10 +3595,13 @@ export function ImageNode({ node, isSelected }: ImageNodeProps) {
|
||||
style={{
|
||||
top: boxCutoutToolbarPosition.top,
|
||||
left: boxCutoutToolbarPosition.left,
|
||||
transform: "translateX(-50%) scale(0.8)",
|
||||
transformOrigin: "top center",
|
||||
transform: `scale(${FLOATING_TOOLBAR_SCALE})`,
|
||||
transformOrigin: "top left",
|
||||
pointerEvents: "auto",
|
||||
maxWidth: `${Math.max(180, Math.floor(boxCutoutToolbarPosition.maxWidth))}px`,
|
||||
maxWidth: `${Math.max(
|
||||
180,
|
||||
Math.floor(boxCutoutToolbarPosition.maxWidth / FLOATING_TOOLBAR_SCALE)
|
||||
)}px`,
|
||||
overflowX: "auto",
|
||||
scrollbarWidth: "none",
|
||||
}}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user