Files
omniai-web/src/features/canvas/canvasConstants.ts
T
OmniAI Developer 192be0e701 feat: 内测申请弹窗 + 电商功能介绍页样式优化
- 新增 BetaApplicationModal 组件,支持文本输入、单/多选、签字等交互

- 顶部通知铃铛左侧添加「内测申请」按钮(脉冲动画)

- 电商功能介绍页等比例放大,减少空白,布局更紧凑

- 右侧卡片区域放大,卡片内容清晰可见
2026-06-08 14:40:47 +08:00

203 lines
6.3 KiB
TypeScript

import {
ENTERPRISE_DEFAULT_VIDEO_MODEL,
ENTERPRISE_DEFAULT_VIDEO_RESOLUTION,
ENTERPRISE_VIDEO_MODEL_OPTIONS,
ENTERPRISE_VIDEO_RESOLUTION_OPTIONS,
} from "../../utils/enterpriseVideoPolicy";
import type {
CanvasNodeKind,
CanvasNodeSize,
CanvasOption,
CanvasStylePickerTab,
CanvasVideoMode,
} from "./canvasTypes";
// --- Connector follow behavior ---
export const connectorFollowRadius = 96;
export const connectorFollowStrength = 1;
export const connectorMaxFollowOffset = 62;
export const connectorAnchorOutset = 9;
// --- Interaction thresholds ---
export const canvasNodeClickMoveThreshold = 5;
// --- Auto-save timing ---
export const canvasAutoSaveDebounceMs = 2_000;
export const canvasAutoSaveIdleTimeoutMs = 800;
// --- Viewport zoom limits ---
export const canvasViewportMinZoom = 0.25;
export const canvasViewportMaxZoom = 2.6;
// --- Node sizes ---
export const canvasNodeDefaultSizes: Record<CanvasNodeKind, CanvasNodeSize> = {
text: { width: 380, height: 260 },
image: { width: 460, height: 290 },
video: { width: 560, height: 315 },
};
export const canvasNodeMinSizes: Record<CanvasNodeKind, CanvasNodeSize> = {
text: { width: 300, height: 220 },
image: { width: 340, height: 220 },
video: { width: 420, height: 236 },
};
export const canvasNodeMaxSizes: Record<CanvasNodeKind, CanvasNodeSize> = {
text: { width: 720, height: 520 },
image: { width: 860, height: 620 },
video: { width: 960, height: 540 },
};
// --- Text model options ---
export const textModelOptions = [
{ id: "gemini-3.1-pro", label: "Gemini 3.1 Pro", description: "默认文本生成模型", speed: "20s" },
{ id: "gemini-2.5-pro", label: "Gemini 2.5 Pro", description: "通用文本生成模型", speed: "20s" },
{ id: "gpt-4o", label: "GPT-4o", description: "通用文本生成模型", speed: "20s" },
];
export const defaultTextModelId = textModelOptions[0].id;
// --- Image model options ---
export const imageModelOptions: CanvasOption[] = [
{ value: "wan2.7-image", label: "wan 2.7" },
{ value: "wan2.7-image-pro", label: "wan 2.7 Pro" },
{ value: "gpt-image-2", label: "omni-GPT" },
{ value: "gpt-image-2-vip", label: "omni-GPT VIP" },
{ value: "nano-banana-pro", label: "omni-水果 Pro" },
{ value: "nano-banana-2", label: "omni-水果 2" },
{ value: "nano-banana-fast", label: "omni-水果" },
];
export const imageRatioOptions: CanvasOption[] = [
{ value: "16:9", label: "16:9" },
{ value: "9:16", label: "9:16" },
{ value: "1:1", label: "1:1" },
{ value: "4:3", label: "4:3" },
{ value: "3:4", label: "3:4" },
];
export const imageFocusRatioOptions: CanvasOption[] = [
{ value: "16:9", label: "16:9" },
{ value: "3:2", label: "3:2" },
{ value: "4:3", label: "4:3" },
{ value: "1:1", label: "1:1" },
{ value: "3:4", label: "3:4" },
{ value: "2:3", label: "2:3" },
{ value: "9:16", label: "9:16" },
];
export const imageQualityOptions: CanvasOption[] = [
{ value: "1K", label: "1K" },
{ value: "2K", label: "2K" },
{ value: "4K", label: "4K" },
];
// --- Style picker ---
export const canvasStylePickerTabs: Array<{ key: CanvasStylePickerTab; label: string }> = [
{ key: "square", label: "广场" },
{ key: "favorites", label: "我的收藏" },
{ key: "recent", label: "最近使用" },
];
export const canvasStylePickerCategories = [
"推荐",
"摄影写真",
"电商营销",
"动漫游戏",
"风格插画",
"平面设计",
"建筑及室内设计",
"创意玩法",
"文创周边",
"小说推文",
];
// --- 4K capable image models ---
export const image4kCapableModels = new Set([
"wan2.7-image-pro",
"nano-banana-2",
"nano-banana-pro",
"nano-banana-pro-4k",
"nano-banana-pro-4k-vip",
"gpt-image-2-vip",
]);
// --- Video model options ---
export const videoModelOptions: CanvasOption[] = [
...ENTERPRISE_VIDEO_MODEL_OPTIONS.map((option) => ({
value: option.value,
label: option.label,
})),
];
// --- Video ratio & duration options ---
export const videoRatioOptions: CanvasOption[] = [
{ value: "21:9", label: "21:9" },
{ value: "16:9", label: "16:9" },
{ value: "4:3", label: "4:3" },
{ value: "1:1", label: "1:1" },
{ value: "3:4", label: "3:4" },
{ value: "9:16", label: "9:16" },
];
export const videoDurationOptions: CanvasOption[] = [
{ value: "5", label: "5s" },
{ value: "6", label: "6s" },
{ value: "7", label: "7s" },
{ value: "8", label: "8s" },
{ value: "9", label: "9s" },
{ value: "10", label: "10s" },
{ value: "11", label: "11s" },
{ value: "12", label: "12s" },
{ value: "13", label: "13s" },
{ value: "14", label: "14s" },
{ value: "15", label: "15s" },
];
// --- Video quality & resolution by model ---
export const fallbackVideoQualityOptions: CanvasOption[] = [
...ENTERPRISE_VIDEO_RESOLUTION_OPTIONS.map((option) => ({
value: option.value,
label: option.label,
})),
];
export const videoResolutionByModel: Record<string, CanvasOption[]> = {
...Object.fromEntries(ENTERPRISE_VIDEO_MODEL_OPTIONS.map((option) => [option.value, fallbackVideoQualityOptions])),
};
export const videoDefaultQualityByModel: Record<string, string> = {
...Object.fromEntries(ENTERPRISE_VIDEO_MODEL_OPTIONS.map((option) => [option.value, ENTERPRISE_DEFAULT_VIDEO_RESOLUTION])),
};
// --- Defaults ---
export const defaultImageModel = "nano-banana-pro";
export const defaultVideoModel = ENTERPRISE_DEFAULT_VIDEO_MODEL;
export const canvasVideoModes: CanvasVideoMode[] = ["text2video", "img2video", "firstlast"];
// --- Poll constants ---
export const imageNodeTaskPollIntervalMs = 3000;
export const imageNodeTaskPollAttempts = 180;
export const videoNodeTaskPollIntervalMs = 5000;
export const videoNodeTaskPollAttempts = 360;
// --- Asset library ---
export const assetTypePromptLabel: Record<import("../assets/localAssetStore").AssetLibraryCategory, string> = {
character: "角色主体",
scene: "环境场景",
prop: "关键道具",
video: "动态镜头",
image: "图片素材",
asset: "通用素材",
other: "其他素材",
};
export const assetLibraryCategories = [
{ key: "character", label: "人物" },
{ key: "scene", label: "场景" },
{ key: "prop", label: "物品" },
{ key: "video", label: "视频" },
{ key: "image", label: "图片" },
{ key: "asset", label: "素材" },
{ key: "other", label: "其他" },
] satisfies Array<{ key: import("../assets/localAssetStore").AssetLibraryCategory; label: string }>;