fix: refine angle panel and agent workspace scroll
This commit is contained in:
parent
1991e5c4cc
commit
12671a1e36
@ -5335,8 +5335,39 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
currentPsdWorkflowContext?.fifthCategory || ""
|
||||
).trim();
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof document === "undefined") {
|
||||
return;
|
||||
}
|
||||
|
||||
const html = document.documentElement;
|
||||
const body = document.body;
|
||||
const previousHtmlOverflow = html.style.overflow;
|
||||
const previousBodyOverflow = body.style.overflow;
|
||||
const previousHtmlOverscrollBehavior = html.style.overscrollBehavior;
|
||||
const previousBodyOverscrollBehavior = body.style.overscrollBehavior;
|
||||
const previousHtmlBackgroundColor = html.style.backgroundColor;
|
||||
const previousBodyBackgroundColor = body.style.backgroundColor;
|
||||
|
||||
html.style.overflow = "hidden";
|
||||
body.style.overflow = "hidden";
|
||||
html.style.overscrollBehavior = "none";
|
||||
body.style.overscrollBehavior = "none";
|
||||
html.style.backgroundColor = "#050607";
|
||||
body.style.backgroundColor = "#050607";
|
||||
|
||||
return () => {
|
||||
html.style.overflow = previousHtmlOverflow;
|
||||
body.style.overflow = previousBodyOverflow;
|
||||
html.style.overscrollBehavior = previousHtmlOverscrollBehavior;
|
||||
body.style.overscrollBehavior = previousBodyOverscrollBehavior;
|
||||
html.style.backgroundColor = previousHtmlBackgroundColor;
|
||||
body.style.backgroundColor = previousBodyBackgroundColor;
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="flex h-dvh flex-col overflow-hidden bg-black">
|
||||
<div className="flex h-dvh min-h-0 flex-col overflow-hidden bg-black">
|
||||
<AgentCanvasTopNavDark
|
||||
siteName={siteName}
|
||||
siteLogo={siteLogo}
|
||||
@ -5348,7 +5379,7 @@ export function AgentGenerationWorkspaceDarkV2({
|
||||
/>
|
||||
|
||||
{/* Main Content */}
|
||||
<main className="flex-1 overflow-y-auto overscroll-contain pt-16">
|
||||
<main className="min-h-0 flex-1 overflow-y-auto overscroll-none bg-black pt-16">
|
||||
<div className="mx-auto flex w-full max-w-[1480px] flex-col gap-6 px-6 py-6 pb-24 lg:px-8 xl:px-10">
|
||||
{showcaseConfig ? (
|
||||
<motion.section
|
||||
|
||||
@ -42,7 +42,7 @@ import {
|
||||
} from "lucide-react";
|
||||
import type React from "react";
|
||||
import { useParams, useRouter } from "next/navigation";
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { Fragment, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { createPortal } from "react-dom";
|
||||
import { toast } from "sonner";
|
||||
import useSWR from "swr";
|
||||
@ -236,6 +236,7 @@ const BOX_CUTOUT_DEFAULT_PADDING_RATIO = 0.08;
|
||||
const BOX_CUTOUT_MIN_EDGE_PX = 24;
|
||||
const FLOATING_TOOLBAR_SCALE = 0.8;
|
||||
const IMAGE_EDIT_PANEL_SCALE = 0.5;
|
||||
const ANGLE_PANEL_SCALE = 0.65;
|
||||
const ANGLE_PREVIEW_HORIZONTAL_DRAG_MULTIPLIER = 0.72;
|
||||
const ANGLE_PREVIEW_VERTICAL_DRAG_MULTIPLIER = 0.46;
|
||||
const ANGLE_PANEL_SOURCE_WIDTH = 520;
|
||||
@ -243,12 +244,14 @@ const ANGLE_PANEL_SOURCE_HEIGHT = 700;
|
||||
const ANGLE_PANEL_PREVIEW_SIZE = 392;
|
||||
const ANGLE_PANEL_CAMERA_SCENE_SIZE = 384;
|
||||
const ANGLE_PANEL_WIREFRAME_RADIUS = 132;
|
||||
const ANGLE_PANEL_WIREFRAME_CENTER = 160;
|
||||
const ANGLE_PREVIEW_ORBIT_ROTATIONS = [
|
||||
0, 14, 28, 42, 56, 70, 84, 98, 112, 126, 140, 154, 168,
|
||||
const ANGLE_PANEL_WIREFRAME_DIAMETER = ANGLE_PANEL_WIREFRAME_RADIUS * 2;
|
||||
const ANGLE_PREVIEW_VERTICAL_RING_ROTATIONS = [
|
||||
0, 15, 30, 45, 60, 75, 90, 105, 120, 135, 150, 165,
|
||||
];
|
||||
const ANGLE_PREVIEW_LATITUDE_RATIOS = [1, 0.9, 0.78, 0.64, 0.5];
|
||||
const ANGLE_PREVIEW_MERIDIAN_RATIOS = [1, 0.9, 0.78, 0.64];
|
||||
const ANGLE_PREVIEW_HORIZONTAL_RING_ROTATIONS = [
|
||||
-78, -56, -34, -14, 0, 14, 34, 56, 78,
|
||||
];
|
||||
const ANGLE_PREVIEW_DIAGONAL_RING_ROTATIONS = [-62, -40, -18, 8, 34, 58];
|
||||
const DEFAULT_CROP_PRESET_ID = "1:1";
|
||||
const IMAGE_ADJUST_NOISE_DATA_URI = `data:image/svg+xml;utf8,${encodeURIComponent(
|
||||
"<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 160 160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='1.18' numOctaves='2' stitchTiles='stitch'/></filter><rect width='160' height='160' filter='url(#n)' opacity='1'/></svg>"
|
||||
@ -1642,6 +1645,7 @@ export function ImageNode({
|
||||
const [angleZoom, setAngleZoom] = useState(50);
|
||||
const [isApplyingAngleEdit, setIsApplyingAngleEdit] = useState(false);
|
||||
const [isAnglePreviewDragging, setIsAnglePreviewDragging] = useState(false);
|
||||
const [anglePanelOpening, setAnglePanelOpening] = useState(false);
|
||||
const [sceneFusionDialogOpen, setSceneFusionDialogOpen] = useState(false);
|
||||
const [resizeAnnotatorOpen, setResizeAnnotatorOpen] = useState(false);
|
||||
const [promptDialogOpen, setPromptDialogOpen] = useState(false);
|
||||
@ -1796,6 +1800,19 @@ export function ImageNode({
|
||||
setAngleZoom(clampNumber(savedSettings.zoom, 0, 100));
|
||||
}
|
||||
}, [anglePanelOpen, data.metadata]);
|
||||
useEffect(() => {
|
||||
if (!anglePanelOpen || typeof window === "undefined") {
|
||||
setAnglePanelOpening(false);
|
||||
return;
|
||||
}
|
||||
|
||||
setAnglePanelOpening(true);
|
||||
const timer = window.setTimeout(() => {
|
||||
setAnglePanelOpening(false);
|
||||
}, 560);
|
||||
|
||||
return () => window.clearTimeout(timer);
|
||||
}, [anglePanelOpen]);
|
||||
useEffect(() => {
|
||||
const nextDefaultTripoModelId =
|
||||
getDefaultThreeDModelAliasId(publicModelAliasConfig.tripoModels) ||
|
||||
@ -2140,13 +2157,18 @@ export function ImageNode({
|
||||
}, [angleCameraOrbitPosition]);
|
||||
const angleOrbitWireframeStyle = useMemo<React.CSSProperties>(
|
||||
() => ({
|
||||
transform: `rotateX(${-angleVerticalAngle * 0.22}deg) rotateY(${angleHorizontalAngle * 0.28}deg) rotateZ(${angleHorizontalAngle * 0.04}deg)`,
|
||||
transform: `rotateX(${(-angleVerticalAngle * 0.24) + (anglePanelOpening ? 14 : 0)}deg) rotateY(${(angleHorizontalAngle * 0.34) + (anglePanelOpening ? -34 : 0)}deg) rotateZ(${(angleHorizontalAngle * 0.05) + (anglePanelOpening ? 7 : 0)}deg)`,
|
||||
transformStyle: "preserve-3d",
|
||||
transition: isAnglePreviewDragging
|
||||
? "none"
|
||||
: "transform 180ms cubic-bezier(0.22, 1, 0.36, 1)",
|
||||
: `transform ${anglePanelOpening ? 560 : 180}ms cubic-bezier(0.22, 1, 0.36, 1)`,
|
||||
}),
|
||||
[angleHorizontalAngle, angleVerticalAngle, isAnglePreviewDragging]
|
||||
[
|
||||
angleHorizontalAngle,
|
||||
anglePanelOpening,
|
||||
angleVerticalAngle,
|
||||
isAnglePreviewDragging,
|
||||
]
|
||||
);
|
||||
const angleCameraSceneScale = useMemo(
|
||||
() => Number((0.94 + (angleZoom / 100) * 0.22).toFixed(3)),
|
||||
@ -3607,8 +3629,8 @@ export function ImageNode({
|
||||
}
|
||||
|
||||
const rect = containerRef.current.getBoundingClientRect();
|
||||
const panelWidth = ANGLE_PANEL_SOURCE_WIDTH * IMAGE_EDIT_PANEL_SCALE;
|
||||
const panelHeight = ANGLE_PANEL_SOURCE_HEIGHT * IMAGE_EDIT_PANEL_SCALE;
|
||||
const panelWidth = ANGLE_PANEL_SOURCE_WIDTH * ANGLE_PANEL_SCALE;
|
||||
const panelHeight = ANGLE_PANEL_SOURCE_HEIGHT * ANGLE_PANEL_SCALE;
|
||||
const spacing = 16;
|
||||
const maxTop = Math.max(12, window.innerHeight - panelHeight);
|
||||
|
||||
@ -4678,6 +4700,7 @@ export function ImageNode({
|
||||
setTextEditPanelOpen(false);
|
||||
setNotePanelOpen(false);
|
||||
resetBoxCutoutState();
|
||||
setAnglePanelOpening(true);
|
||||
setAnglePanelOpen(true);
|
||||
return;
|
||||
}
|
||||
@ -8219,7 +8242,7 @@ export function ImageNode({
|
||||
style={{
|
||||
top: anglePanelPosition.top,
|
||||
left: anglePanelPosition.left,
|
||||
transform: `scale(${IMAGE_EDIT_PANEL_SCALE})`,
|
||||
transform: `scale(${ANGLE_PANEL_SCALE})`,
|
||||
transformOrigin: "top left",
|
||||
}}
|
||||
>
|
||||
@ -8287,61 +8310,64 @@ export function ImageNode({
|
||||
className="pointer-events-none absolute inset-0 flex items-center justify-center"
|
||||
style={angleOrbitWireframeStyle}
|
||||
>
|
||||
<svg
|
||||
className="shrink-0"
|
||||
fill="none"
|
||||
height={ANGLE_PANEL_PREVIEW_SIZE}
|
||||
viewBox="0 0 320 320"
|
||||
width={ANGLE_PANEL_PREVIEW_SIZE}
|
||||
<div
|
||||
className="relative shrink-0 [transform-style:preserve-3d]"
|
||||
style={{
|
||||
width: `${ANGLE_PANEL_WIREFRAME_DIAMETER}px`,
|
||||
height: `${ANGLE_PANEL_WIREFRAME_DIAMETER}px`,
|
||||
}}
|
||||
>
|
||||
{ANGLE_PREVIEW_ORBIT_ROTATIONS.map((rotation, index) => (
|
||||
<ellipse
|
||||
key={`orbit-rotation-${rotation}`}
|
||||
cx={ANGLE_PANEL_WIREFRAME_CENTER}
|
||||
cy={ANGLE_PANEL_WIREFRAME_CENTER}
|
||||
rx={ANGLE_PANEL_WIREFRAME_RADIUS}
|
||||
ry={ANGLE_PANEL_WIREFRAME_RADIUS}
|
||||
stroke={index === 0 ? "#e5e8ef" : "#e8ebf1"}
|
||||
strokeOpacity={index === 0 ? 0.92 : 0.84}
|
||||
strokeWidth={index % 3 === 0 ? "1.12" : "1.02"}
|
||||
transform={
|
||||
rotation === 0
|
||||
? undefined
|
||||
: `rotate(${rotation} ${ANGLE_PANEL_WIREFRAME_CENTER} ${ANGLE_PANEL_WIREFRAME_CENTER})`
|
||||
}
|
||||
<div className="absolute inset-0 rounded-full border border-[#e4e8ef]/90" />
|
||||
|
||||
{ANGLE_PREVIEW_VERTICAL_RING_ROTATIONS.map((rotation, index) => (
|
||||
<div
|
||||
className="absolute inset-0 rounded-full border border-[#e7ebf2]"
|
||||
key={`angle-vertical-ring-${rotation}`}
|
||||
style={{
|
||||
backfaceVisibility: "hidden",
|
||||
opacity: 0.9 - index * 0.026,
|
||||
transform: `rotateY(${rotation}deg)`,
|
||||
transformStyle: "preserve-3d",
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
{ANGLE_PREVIEW_LATITUDE_RATIOS.map((ratio, index) => (
|
||||
<ellipse
|
||||
key={`orbit-latitude-${ratio}`}
|
||||
cx={ANGLE_PANEL_WIREFRAME_CENTER}
|
||||
cy={ANGLE_PANEL_WIREFRAME_CENTER}
|
||||
rx={ANGLE_PANEL_WIREFRAME_RADIUS}
|
||||
ry={Number(
|
||||
(ANGLE_PANEL_WIREFRAME_RADIUS * ratio).toFixed(2)
|
||||
)}
|
||||
stroke="#eceff4"
|
||||
strokeOpacity={0.86 - index * 0.08}
|
||||
strokeWidth={index === 0 ? "1.08" : "1.0"}
|
||||
|
||||
{ANGLE_PREVIEW_HORIZONTAL_RING_ROTATIONS.map((rotation, index) => (
|
||||
<div
|
||||
className="absolute inset-0 rounded-full border border-[#e6eaf1]"
|
||||
key={`angle-horizontal-ring-${rotation}`}
|
||||
style={{
|
||||
backfaceVisibility: "hidden",
|
||||
opacity: rotation === 0 ? 0.94 : 0.82 - index * 0.045,
|
||||
transform: `rotateX(${rotation}deg)`,
|
||||
transformStyle: "preserve-3d",
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
{ANGLE_PREVIEW_MERIDIAN_RATIOS.map((ratio, index) => (
|
||||
<ellipse
|
||||
key={`orbit-meridian-${ratio}`}
|
||||
cx={ANGLE_PANEL_WIREFRAME_CENTER}
|
||||
cy={ANGLE_PANEL_WIREFRAME_CENTER}
|
||||
rx={Number(
|
||||
(ANGLE_PANEL_WIREFRAME_RADIUS * ratio).toFixed(2)
|
||||
)}
|
||||
ry={ANGLE_PANEL_WIREFRAME_RADIUS}
|
||||
stroke="#e9edf3"
|
||||
strokeOpacity={0.78 - index * 0.08}
|
||||
strokeDasharray={index === 0 ? undefined : "4 6"}
|
||||
strokeWidth="1.0"
|
||||
transform={`rotate(90 ${ANGLE_PANEL_WIREFRAME_CENTER} ${ANGLE_PANEL_WIREFRAME_CENTER})`}
|
||||
/>
|
||||
|
||||
{ANGLE_PREVIEW_DIAGONAL_RING_ROTATIONS.map((rotation, index) => (
|
||||
<Fragment key={`angle-diagonal-ring-${rotation}`}>
|
||||
<div
|
||||
className="absolute inset-0 rounded-full border border-[#edf0f5]"
|
||||
style={{
|
||||
backfaceVisibility: "hidden",
|
||||
opacity: 0.54 - index * 0.035,
|
||||
transform: `rotateX(67deg) rotateY(${rotation}deg)`,
|
||||
transformStyle: "preserve-3d",
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
className="absolute inset-0 rounded-full border border-[#edf0f5]"
|
||||
style={{
|
||||
backfaceVisibility: "hidden",
|
||||
opacity: 0.5 - index * 0.032,
|
||||
transform: `rotateX(-67deg) rotateY(${rotation + 12}deg)`,
|
||||
transformStyle: "preserve-3d",
|
||||
}}
|
||||
/>
|
||||
</Fragment>
|
||||
))}
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user