Files
Genarrative/src/components/image-editor/ImageCanvasCropExpandPanelView.tsx
T
JenkenB ea29887d9c 完善快速编辑参考图与生成占位
- 快速编辑支持最多8张额外参考图,并将原图自动作为最后一张参考图提交

- 快速编辑尺寸和模型沿用原图配置,按禁用态参数胶囊展示

- 快速编辑提交前同步改写原图引用为实际图序号

- 快速编辑生成改为创建独立画布生成占位,并支持键盘删除生成中对象

- 对齐生成类面板参考图图标、规范类固定参数和相关文档测试
2026-06-18 22:50:42 +08:00

121 lines
3.7 KiB
TypeScript

import { type CSSProperties, type Dispatch, type SetStateAction } from 'react';
import { PlatformActionButton } from '../common/PlatformActionButton';
import type {
CropExpandPanelState,
CropExpandRatioValue,
} from './ImageCanvasEditorTypes';
type ImageCanvasCropExpandPanelViewProps = {
panel: CropExpandPanelState;
style: CSSProperties;
setCropExpandPanel: Dispatch<SetStateAction<CropExpandPanelState | null>>;
onSubmit: () => void;
};
const CROP_EXPAND_RATIO_OPTIONS: Array<{
value: CropExpandRatioValue;
label: string;
shape?: 'square' | 'landscape' | 'portrait';
}> = [
{ value: 'free', label: '自由比例' },
{ value: '1:1', label: '1:1', shape: 'square' },
{ value: '4:3', label: '4:3', shape: 'landscape' },
{ value: '3:4', label: '3:4', shape: 'portrait' },
{ value: '16:9', label: '16:9', shape: 'landscape' },
{ value: '9:16', label: '9:16', shape: 'portrait' },
] as const;
function resetFailedCropExpandPanel(panel: CropExpandPanelState) {
return {
...panel,
status: panel.status === 'failed' ? 'idle' : panel.status,
errorMessage: panel.status === 'failed' ? undefined : panel.errorMessage,
};
}
export function ImageCanvasCropExpandPanelView({
panel,
style,
setCropExpandPanel,
onSubmit,
}: ImageCanvasCropExpandPanelViewProps) {
return (
<form
className="image-canvas-editor__crop-expand-panel"
style={style}
role="dialog"
aria-label="裁扩图片"
onPointerDown={(event) => event.stopPropagation()}
onSubmit={(event) => {
event.preventDefault();
if (panel.status !== 'processing') {
onSubmit();
}
}}
>
<div className="image-canvas-editor__crop-expand-head">
<strong>裁扩</strong>
</div>
<div className="image-canvas-editor__crop-expand-ratios">
{CROP_EXPAND_RATIO_OPTIONS.map((option) => (
<button
key={option.value}
type="button"
className={`image-canvas-editor__crop-expand-ratio ${
panel.ratio === option.value
? 'image-canvas-editor__crop-expand-ratio--selected'
: ''
}`}
aria-pressed={panel.ratio === option.value}
onClick={() =>
setCropExpandPanel((currentPanel) =>
currentPanel
? {
...resetFailedCropExpandPanel(currentPanel),
ratio: option.value,
}
: currentPanel,
)
}
>
<span
className={`image-canvas-editor__crop-expand-ratio-shape ${
option.shape
? `image-canvas-editor__crop-expand-ratio-shape--${option.shape}`
: ''
}`}
aria-hidden="true"
/>
<span>{option.label}</span>
</button>
))}
</div>
{panel.status === 'failed' ? (
<p className="image-canvas-editor__crop-expand-error" role="alert">
{panel.errorMessage}
</p>
) : null}
<div className="image-canvas-editor__crop-expand-actions">
<PlatformActionButton
type="button"
tone="secondary"
size="sm"
disabled={panel.status === 'processing'}
onClick={() => setCropExpandPanel(null)}
>
取消
</PlatformActionButton>
<PlatformActionButton
type="submit"
tone="primary"
size="sm"
disabled={panel.status === 'processing'}
>
{panel.status === 'processing' ? '处理中' : '完成'}
</PlatformActionButton>
</div>
</form>
);
}