fix: 首尾帧模式 aspect ratio 默认改为 adaptive(自适应)

切换到 keyframe 模式时自动设为 adaptive,API 根据首帧图片比例
自动匹配最接近的输出比例,避免图片与视频比例不匹配。
用户仍可手动选择固定比例覆盖。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
seaislee1209 2026-03-16 01:33:53 +08:00
parent 85f76d8543
commit 4c0605e589
3 changed files with 19 additions and 20 deletions

View File

@ -88,6 +88,11 @@ const ratioItems = [
{ label: '9:16', value: '9:16' as AspectRatio }, { label: '9:16', value: '9:16' as AspectRatio },
]; ];
const keyframeRatioItems = [
{ label: '自适应', value: 'adaptive' as AspectRatio },
...ratioItems,
];
const durationItems = Array.from({ length: 12 }, (_, i) => { const durationItems = Array.from({ length: 12 }, (_, i) => {
const v = i + 4; const v = i + 4;
return { label: `${v}s`, value: String(v) }; return { label: `${v}s`, value: String(v) };
@ -175,25 +180,18 @@ export function Toolbar() {
/> />
{/* Aspect ratio */} {/* Aspect ratio */}
{isKeyframe ? ( <Dropdown
<button className={styles.btn} style={{ opacity: 0.5, pointerEvents: 'none' }}> items={isKeyframe ? keyframeRatioItems : ratioItems}
<MonitorIcon /> value={aspectRatio}
<span className={styles.label}></span> onSelect={(v) => setAspectRatio(v as AspectRatio)}
</button> minWidth={100}
) : ( trigger={
<Dropdown <button className={styles.btn}>
items={ratioItems} <MonitorIcon />
value={aspectRatio} <span className={styles.label}>{aspectRatio === 'adaptive' ? '自适应' : aspectRatio}</span>
onSelect={(v) => setAspectRatio(v as AspectRatio)} </button>
minWidth={100} }
trigger={ />
<button className={styles.btn}>
<MonitorIcon />
<span className={styles.label}>{aspectRatio}</span>
</button>
}
/>
)}
{/* Duration */} {/* Duration */}
<Dropdown <Dropdown

View File

@ -214,6 +214,7 @@ export const useInputBarStore = create<InputBarState>((set, get) => ({
mode, mode,
prevReferences: state.references, prevReferences: state.references,
references: [], references: [],
aspectRatio: 'adaptive',
duration: 5, duration: 5,
}); });
} else { } else {

View File

@ -1,6 +1,6 @@
export type CreationMode = 'universal' | 'keyframe'; export type CreationMode = 'universal' | 'keyframe';
export type ModelOption = 'seedance_2.0' | 'seedance_2.0_fast'; export type ModelOption = 'seedance_2.0' | 'seedance_2.0_fast';
export type AspectRatio = '16:9' | '9:16' | '1:1' | '21:9' | '4:3' | '3:4'; export type AspectRatio = '16:9' | '9:16' | '1:1' | '21:9' | '4:3' | '3:4' | 'adaptive';
export type Duration = 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15; export type Duration = 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15;
export type GenerationType = 'video' | 'image'; export type GenerationType = 'video' | 'image';
export type UserRole = 'super_admin' | 'team_admin' | 'member'; export type UserRole = 'super_admin' | 'team_admin' | 'member';