mirror of
https://github.com/basketikun/infinite-canvas.git
synced 2026-08-05 08:54:23 +08:00
feat(panorama): enhance 3D panorama node with AI generation support and unified interaction toggle
This commit is contained in:
@@ -62,7 +62,6 @@ function HtmlEditor({ ctx, value }: { ctx: CanvasNodeContentProps["ctx"]; value:
|
||||
function HtmlContent({ ctx }: CanvasNodeContentProps) {
|
||||
const value = ctx.node.metadata?.content || "";
|
||||
const editing = Boolean(ctx.node.metadata?.editing);
|
||||
const interactive = Boolean(ctx.node.metadata?.interactive);
|
||||
const upstreamText = useMemo(
|
||||
() =>
|
||||
ctx
|
||||
@@ -87,15 +86,15 @@ function HtmlContent({ ctx }: CanvasNodeContentProps) {
|
||||
);
|
||||
}
|
||||
|
||||
// 预览态:iframe 仅在「节点已选中 + 开启交互」时接收鼠标;否则穿透,保证首次点击能选中节点、弹出工具条。
|
||||
const liveIframe = interactive && ctx.isSelected;
|
||||
// 预览态:iframe 的鼠标交互由宿主「交互 ⇄ 移动」开关统一控制(见 interactionToggle),
|
||||
// 这里无需再手动做 pointer-events 穿透。data-canvas-no-zoom 保证交互时滚动作用于页面而非缩放画布。
|
||||
return (
|
||||
<div data-canvas-no-zoom={liveIframe || undefined} style={{ position: "relative", height: "100%", width: "100%" }}>
|
||||
<div data-canvas-no-zoom style={{ position: "relative", height: "100%", width: "100%" }}>
|
||||
<iframe
|
||||
title="html-preview"
|
||||
sandbox="allow-scripts allow-forms"
|
||||
srcDoc={html}
|
||||
style={{ height: "100%", width: "100%", border: 0, borderRadius: 16, background: "#fff", display: "block", pointerEvents: liveIframe ? "auto" : "none" }}
|
||||
style={{ height: "100%", width: "100%", border: 0, borderRadius: 16, background: "#fff", display: "block" }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
@@ -104,7 +103,7 @@ function HtmlContent({ ctx }: CanvasNodeContentProps) {
|
||||
export default definePlugin({
|
||||
id: "html",
|
||||
name: "HTML 节点",
|
||||
version: "1.1.0",
|
||||
version: "1.2.0",
|
||||
description: "沙箱 iframe 渲染 HTML,支持 {{input}} 注入上游文本",
|
||||
nodes: [
|
||||
{
|
||||
@@ -116,13 +115,14 @@ export default definePlugin({
|
||||
defaultMetadata: { content: "" },
|
||||
minimapColor: "#ec4899",
|
||||
hidePanel: true, // 纯展示型节点:点击/新建不弹出下方生图面板
|
||||
// 宿主统一提供「交互 ⇄ 移动」开关;编辑态强制可交互(编辑器始终可操作)并隐藏该开关
|
||||
interactionToggle: true,
|
||||
forceInteractive: (node) => Boolean(node.metadata?.editing),
|
||||
Content: HtmlContent,
|
||||
// 所有开关都在节点外的悬浮工具条,不占用节点内部空间
|
||||
// 仅保留「编辑/预览」开关;交互/移动 由宿主自动注入
|
||||
toolbar: (ctx) => {
|
||||
const editing = Boolean(ctx.node.metadata?.editing);
|
||||
const interactive = Boolean(ctx.node.metadata?.interactive);
|
||||
const hasContent = Boolean(ctx.node.metadata?.content);
|
||||
const items = [
|
||||
return [
|
||||
{
|
||||
id: "html-toggle-edit",
|
||||
title: editing ? "预览渲染结果" : "编辑 HTML 源码",
|
||||
@@ -132,18 +132,6 @@ export default definePlugin({
|
||||
onClick: () => ctx.updateMetadata({ editing: !editing }),
|
||||
},
|
||||
];
|
||||
// 预览且有内容时,才提供「交互」开关:开=可点击/滚动页面,关=整块可拖动
|
||||
if (!editing && hasContent) {
|
||||
items.push({
|
||||
id: "html-toggle-interactive",
|
||||
title: interactive ? "锁定预览(整块可拖动)" : "允许与页面交互(点击/滚动)",
|
||||
label: interactive ? "锁定" : "交互",
|
||||
icon: interactive ? "🔒" : "👆",
|
||||
active: interactive,
|
||||
onClick: () => ctx.updateMetadata({ interactive: !interactive }),
|
||||
});
|
||||
}
|
||||
return items;
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user