"use client"; import { Box, Download, ImageIcon, Link2, Sparkles, Waypoints, } from "lucide-react"; import { useMemo, useState } from "react"; import { World3DViewer } from "@/components/canvas/world3d/World3DViewer"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { cn } from "@/lib/utils"; import type { World3DViewMode } from "@/types/canvas"; type SharedWorldPageProps = { title: string; prompt?: string | null; caption?: string | null; worldUrl?: string | null; imageUrl?: string | null; meshUrl?: string | null; splatUrl?: string | null; previewImageUrl?: string | null; semanticsMetadata?: Record | null; shareUrl: string; }; const VIEW_OPTIONS: Array<{ id: World3DViewMode; label: string; icon: typeof Sparkles; }> = [ { id: "splat", label: "World", icon: Sparkles }, { id: "image", label: "图像", icon: ImageIcon }, { id: "mesh", label: "Mesh", icon: Box }, ]; function resolveAvailableViews(params: { worldUrl?: string | null; imageUrl?: string | null; meshUrl?: string | null; splatUrl?: string | null; }) { const views: World3DViewMode[] = []; if (params.splatUrl) views.push("splat"); if (params.imageUrl) views.push("image"); if (params.meshUrl) views.push("mesh"); return views; } function inferInitialView(views: World3DViewMode[]) { if (views.includes("splat")) return "splat"; if (views.includes("image")) return "image"; if (views.includes("mesh")) return "mesh"; return "image"; } export function WorldSharePage({ title, prompt, caption, worldUrl, imageUrl, meshUrl, splatUrl, previewImageUrl, semanticsMetadata, shareUrl, }: SharedWorldPageProps) { const availableViews = useMemo( () => resolveAvailableViews({ worldUrl, imageUrl, meshUrl, splatUrl }), [imageUrl, meshUrl, splatUrl, worldUrl] ); const [activeView, setActiveView] = useState( inferInitialView(availableViews) ); const [firstPerson, setFirstPerson] = useState(false); const [copied, setCopied] = useState(false); const primaryDescription = caption || prompt || "这个 3D 世界已开启只读分享。"; const handleCopyShareUrl = async () => { try { const absoluteUrl = new URL(shareUrl, window.location.origin).toString(); await navigator.clipboard.writeText(absoluteUrl); setCopied(true); window.setTimeout(() => setCopied(false), 1500); } catch { setCopied(false); } }; const handleDownloadMesh = () => { if (!meshUrl) return; const link = document.createElement("a"); link.href = meshUrl; link.download = "shared-world.glb"; link.click(); }; return (
3D 世界分享 {availableViews.map((view) => ( {VIEW_OPTIONS.find((item) => item.id === view)?.label || view.toUpperCase()} ))}

{title}

{primaryDescription}

{meshUrl ? ( ) : null}
{VIEW_OPTIONS.filter((item) => availableViews.includes(item.id)).map((item) => ( ))}
{activeView === "splat" && splatUrl ? ( ) : null}

查看说明

`World` 视图最接近原生 3D 世界体验,支持方向键或 `WASD` 六向移动。

当前页面是只读分享页,不会修改原项目或原画布内容。

资源状态

World
{splatUrl ? "可查看" : "暂无"}
图像
{imageUrl || previewImageUrl ? "可查看" : "暂无"}
Mesh
{meshUrl ? "可下载" : "暂无"}
); }