feat(canvas): 画布插件与视觉 - 合并 PR #289 并保留任务计费边界

This commit is contained in:
ddCat
2026-08-22 10:01:41 +08:00
45 changed files with 5649 additions and 240 deletions

View File

@@ -291,7 +291,9 @@ export const CanvasNode = React.memo(function CanvasNode({
data-node-state={nodeState}
data-state={data.metadata?.status || (isActive ? "active" : isRelated ? "related" : "idle")}
style={{
background: hasImageContent || hasVideoContent ? "transparent" : "var(--card-surface)",
background: hasImageContent || hasVideoContent ? "transparent" : theme.node.fill,
border: `1px solid ${theme.node.edge}`,
boxShadow: isSelected ? `0 0 0 2px ${theme.node.activeStroke}, ${theme.node.hoverShadow}` : hovered ? theme.node.hoverShadow : theme.node.shadow,
}}
onMouseDown={(event) => onMouseDown(event, data.id)}
onDoubleClick={(event) => {
@@ -329,7 +331,7 @@ export const CanvasNode = React.memo(function CanvasNode({
className={`relative flex h-full w-full items-center justify-center rounded-[inherit] ${isBatchRoot || data.type === CanvasNodeType.Script ? "overflow-visible" : "overflow-hidden"}`}
style={
{
background: hasImageContent || hasVideoContent ? "transparent" : "var(--card-surface)",
background: hasImageContent || hasVideoContent ? "transparent" : theme.node.fill,
"--batch-from-x": `${batchMotion?.x || 0}px`,
"--batch-from-y": `${batchMotion?.y || 0}px`,
"--batch-from-rotate": `${6 + (batchMotion?.index || 0) * 4}deg`,
@@ -632,7 +634,17 @@ function NodeExternalHeader({ node, scale, active, editable, editing, draft, the
return (
<div
className="canvas-node-external-header absolute bottom-full left-0 z-[var(--node-z-overlay)] flex h-6 items-center gap-1 overflow-hidden"
style={{ maxWidth: maxHeaderWidth, color: active ? theme.node.text : theme.node.label, transform: `scale(var(--canvas-live-inverse-scale, ${inverseScale}))`, transformOrigin: "left bottom" }}
style={{
maxWidth: maxHeaderWidth,
border: `1px solid ${theme.node.edge}`,
borderRadius: "var(--r-sm)",
background: theme.node.panel,
paddingInline: "var(--space-1-half)",
color: active ? theme.node.text : theme.node.label,
boxShadow: active ? theme.node.shadow : undefined,
transform: `scale(var(--canvas-live-inverse-scale, ${inverseScale}))`,
transformOrigin: "left bottom",
}}
onMouseDown={(event) => event.stopPropagation()}
onPointerDown={(event) => event.stopPropagation()}
>