Size 面板(画布尺寸)
默认 SizePanel 提供了常用尺寸预设(Instagram / 海报 / 名片 / A4 等)和自定义宽高输入。
两种常见的定制需求:
- 增删预设列表(比如加入公司专用物料尺寸)
- 彻底换一套 UI(比如按业务分类、配缩略图)
场景 1:自定义尺寸列表
写一个自己的 Section 替换默认 size:
import { observer } from 'mobx-react-lite';
import { Button } from 'antd';
import { ImageUpscale } from 'lucide-react';
import {
SectionTab,
DEFAULT_SECTIONS,
SidePanel,
} from '@ydesign/react-editor/side-panel';
import type { Section } from '@ydesign/react-editor/side-panel';
// 你的预设尺寸清单(单位:像素)
const AVAILABLE_SIZES = [
{ label: '正方形 · 1000 × 1000', width: 1000, height: 1000 },
{ label: '竖屏 · 750 × 1334', width: 750, height: 1334 },
{ label: '横屏 · 1920 × 1080', width: 1920, height: 1080 },
{ label: '印刷 · A4(300dpi)', width: 2480, height: 3508 },
{ label: '名片 · 90 × 54mm', width: 1063, height: 638 },
];
const CustomSizeSection: Section = {
name: 'size', // 👈 用同名覆盖默认
Tab: observer(props => (
<SectionTab name="画布尺寸" {...props}>
<ImageUpscale size={20} />
</SectionTab>
)),
Panel: observer(({ store }) => (
<div style={{ display: 'flex', flexDirection: 'column', gap: 8, padding: 4 }}>
{AVAILABLE_SIZES.map(({ label, width, height }) => {
const active = store.width === width && store.height === height;
return (
<Button
key={label}
block
type={active ? 'primary' : 'default'}
onClick={() => store.setSize({ width, height })}
>
{label}
</Button>
);
})}
</div>
)),
};
const sections = DEFAULT_SECTIONS.map(s =>
s.name === 'size' ? CustomSizeSection : s
);
<SidePanel store={store} sections={sections} />;
要点:
- 通过
store.setSize({ width, height })触发尺寸变化 store.setSize内部会走workareaHandler.setSize,自动适配屏幕 + 写入历史栈store.width/store.height是响应式字段,observer会保证"当前选中态"的按钮高亮始终正确
场景 2:加入单位换算
印刷场景经常要按毫米 / 英寸配置,但 Fabric 的画布单位是像素。Ydesign 内置了一个 store.setUnit({ unit, dpi }) 来处理:
const AVAILABLE_PRINT_SIZES = [
{ label: 'A4 竖版', unit: 'mm', dpi: 300, width: 210, height: 297 },
{ label: 'A4 横版', unit: 'mm', dpi: 300, width: 297, height: 210 },
{ label: '名片', unit: 'mm', dpi: 300, width: 90, height: 54 },
];
// 点击时
onClick={() => {
store.setUnit({ unit: 'mm', dpi: 300 });
// setSize 的值仍然传像素;换算请按 mm * dpi / 25.4
const mmToPx = (mm: number) => Math.round((mm * 300) / 25.4);
store.setSize({
width: mmToPx(210),
height: mmToPx(297),
});
}}
store.unit / store.dpi 也是响应式字段,标尺等 UI 会自动响应。
场景 3:按业务分类的尺寸中心
如果你的产品有很多分类(社交 / 印刷 / 电商 / …),推荐的 UI 结构:
const SIZE_GROUPS = [
{
group: '社交媒体',
items: [
{ label: 'Instagram 正方形', width: 1080, height: 1080 },
{ label: 'Instagram 故事', width: 1080, height: 1920 },
{ label: '微信朋友圈', width: 1242, height: 828 },
],
},
{
group: '印刷物料',
items: [
{ label: '海报 · A2', width: 4961, height: 7016 },
{ label: 'A4 纸', width: 2480, height: 3508 },
],
},
];
const GroupedSizeSection: Section = {
name: 'size',
Tab: /* ... */,
Panel: observer(({ store }) => (
<div>
{SIZE_GROUPS.map(({ group, items }) => (
<div key={group} style={{ marginBottom: 16 }}>
<h4>{group}</h4>
{items.map(it => (
<Button key={it.label} block onClick={() => store.setSize(it)}>
{it.label} · {it.width}×{it.height}
</Button>
))}
</div>
))}
</div>
)),
};
相关 API
| API | 作用 |
|---|---|
store.setSize({ width, height }) | 修改画布尺寸(进历史栈) |
store.setUnit({ unit, dpi }) | 修改画布单位 |
store.width / store.height | 当前画布像素尺寸(响应式) |
store.unit / store.dpi | 当前单位与 DPI(响应式) |
store.editor?.workareaHandler.setSize(...) | 底层方法;大多数情况用 store.setSize 就够了 |