mirror of
https://github.com/basketikun/infinite-canvas.git
synced 2026-08-05 17:04:27 +08:00
feat: add seedance media params and model visibility
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
import React, { useCallback, useEffect, useRef, useState } from "react";
|
||||
import type { ReactNode } from "react";
|
||||
import { ChevronRight, Image as ImageIcon, RefreshCw, Star, Video } from "lucide-react";
|
||||
import { ChevronRight, Image as ImageIcon, Music2, RefreshCw, Star, Video } from "lucide-react";
|
||||
|
||||
import { canvasThemes } from "@/lib/canvas-theme";
|
||||
import { formatBytes } from "@/lib/image-utils";
|
||||
@@ -99,6 +99,7 @@ export const CanvasNode = React.memo(function CanvasNode({
|
||||
const [isEditingContent, setIsEditingContent] = useState(false);
|
||||
const hasImageContent = data.type === CanvasNodeType.Image && Boolean(data.metadata?.content);
|
||||
const hasVideoContent = data.type === CanvasNodeType.Video && Boolean(data.metadata?.content);
|
||||
const hasAudioContent = data.type === CanvasNodeType.Audio && Boolean(data.metadata?.content);
|
||||
const isBatchRoot = data.type === CanvasNodeType.Image && Boolean(data.metadata?.isBatchRoot) && batchCount > 1;
|
||||
const isBatchChild = data.type === CanvasNodeType.Image && Boolean(data.metadata?.batchRootId);
|
||||
const isActive = isConnectionTarget || isSelected || isFocusRelated;
|
||||
@@ -301,7 +302,7 @@ export const CanvasNode = React.memo(function CanvasNode({
|
||||
|
||||
{showImageInfo && hasImageContent ? <ImageInfoBar node={data} /> : null}
|
||||
|
||||
{!hasImageContent && !hasVideoContent ? <div className="pointer-events-none absolute inset-x-0 bottom-0 h-12" style={{ background: `linear-gradient(to top, ${theme.canvas.background}66, transparent)` }} /> : null}
|
||||
{!hasImageContent && !hasVideoContent && !hasAudioContent ? <div className="pointer-events-none absolute inset-x-0 bottom-0 h-12" style={{ background: `linear-gradient(to top, ${theme.canvas.background}66, transparent)` }} /> : null}
|
||||
|
||||
<ResizeHandle corner="top-left" onMouseDown={handleResizeMouseDown} />
|
||||
<ResizeHandle corner="top-right" onMouseDown={handleResizeMouseDown} />
|
||||
@@ -332,6 +333,7 @@ const nodeContentRenderers = {
|
||||
[CanvasNodeType.Image]: ImageNodeContent,
|
||||
[CanvasNodeType.Config]: EmptyImageContent,
|
||||
[CanvasNodeType.Video]: VideoNodeContent,
|
||||
[CanvasNodeType.Audio]: AudioNodeContent,
|
||||
} satisfies Record<CanvasNodeType, (props: NodeContentRendererProps) => ReactNode>;
|
||||
|
||||
function LoadingContent({ theme }: Pick<NodeContentRendererProps, "theme">) {
|
||||
@@ -472,6 +474,25 @@ function VideoNodeContent({ node, theme }: NodeContentRendererProps) {
|
||||
return <video src={node.metadata.content} controls className="h-full w-full rounded-[18px] bg-black object-contain" data-canvas-no-zoom />;
|
||||
}
|
||||
|
||||
function AudioNodeContent({ node, theme }: NodeContentRendererProps) {
|
||||
if (!node.metadata?.content)
|
||||
return (
|
||||
<div className="flex h-full w-full flex-col items-center justify-center gap-2" style={{ color: theme.node.placeholder }}>
|
||||
<Music2 className="size-7 opacity-35" />
|
||||
<span className="text-sm">空音频节点</span>
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<div className="flex h-full w-full flex-col justify-center gap-3 px-4" style={{ background: theme.node.fill, color: theme.node.text }}>
|
||||
<div className="flex min-w-0 items-center gap-2 text-sm opacity-70">
|
||||
<Music2 className="size-4 shrink-0" />
|
||||
<span className="truncate">{node.title || "音频"}</span>
|
||||
</div>
|
||||
<audio src={node.metadata.content} controls className="w-full" data-canvas-no-zoom />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function ImageContent({
|
||||
node,
|
||||
isBatchRoot,
|
||||
|
||||
Reference in New Issue
Block a user