mirror of
https://github.com/Powerful-517/yys-editor.git
synced 2026-03-05 15:05:27 +00:00
5.2 KiB
5.2 KiB
样式与节点结构说明(v1)
背景
- 目标:统一节点的样式字段与渲染消费路径,避免各节点分散管理填充/描边/阴影/文字等样式。
- 数据载体:沿用 LogicFlow 的
GraphData,仅约定node.properties内的业务字段与样式字段。
样式模型:properties.style
位于每个节点 properties.style,是尺寸与外观的单一事实来源;渲染时会同步 style.width/height 到节点的 width/height。
interface NodeStyle {
// 尺寸与变换
width: number; // px,必填
height: number; // px,必填
rotate?: number; // deg,逆时针,围绕节点中心
// 形状
fill?: string; // 背景填充色
stroke?: string; // 描边色
strokeWidth?: number; // ≥0,px
radius?: number | [number, number, number, number]; // 圆角(rect 生效)
opacity?: number; // 0..1
// 阴影
shadow?: { color?: string; blur?: number; offsetX?: number; offsetY?: number };
// 文本样式(text 节点或带文本的节点)
textStyle?: {
color?: string;
fontFamily?: string;
fontSize?: number; // px
fontWeight?: number | string;
lineHeight?: number; // 推荐 1..3
align?: 'left' | 'center' | 'right';
verticalAlign?: 'top' | 'middle' | 'bottom';
letterSpacing?: number; // px
padding?: [number, number, number, number];
background?: string;
};
}
默认值参考 src/ts/schema.ts:DefaultNodeStyle:
width=180, height=120, rotate=0fill='#ffffff', stroke='#dcdfe6', strokeWidth=1, radius=4, opacity=1shadow={ color:'rgba(0,0,0,0.1)', blur:4, offsetX:0, offsetY:2 }textStyle={ color:'#303133', fontFamily:'system-ui', fontSize:14, fontWeight:400, lineHeight:1.4, align:'left', verticalAlign:'top', letterSpacing:0, padding:[8,8,8,8] }
归一化与工具(src/ts/nodeStyle.ts)
normalizeNodeStyle(style, sizeFallback):补全缺省,数值钳制(opacity ∈[0,1]),将散落的 width/height 收敛到 style。normalizePropertiesWithStyle(props):返回带规范化 style 的 props,并镜像width/height。toContainerStyle/toTextStyle:将NodeStyle转为 Vue 行内样式(背景、描边、圆角、阴影、透明度 / 文字)。styleEquals:归一化后比较,避免重复 setProperties。
节点元信息:properties.meta
interface NodeMeta {
z?: number; // 层级
locked?: boolean; // 锁定
visible?: boolean; // 可见
groupId?: string; // 分组
name?: string;
createdAt?: number;
updatedAt?: number;
}
FlowEditor 在渲染/normalize 时会补齐 meta.visible=true、meta.locked=false 并应用到节点模型(可见性、可拖拽等)。
监听与渲染路径
- 归一化入口:
FlowEditor.normalizeNodeModel在节点创建/属性变更/渲染后执行:- 归一化
properties.style和meta,必要时回写lf.setProperties。 - 同步
style.width/height到节点模型,保证渲染尺寸一致。
- 归一化
- 事件监听:节点组件通过 composable 监听
NODE_PROPERTIES_CHANGE,实时更新样式与自定义数据。
复用方案:useNodeAppearance(src/ts/useNodeAppearance.ts)
作用:在节点组件中统一获取样式和属性变更。
const { containerStyle, textStyle } = useNodeAppearance({
onPropsChange(props, node) {
// 可在这里同步业务字段,例如 image url、shikigami 数据等
}
});
内部行为:
- 注入
getNode/getGraph,挂载时读取当前节点 props。 - 监听
NODE_PROPERTIES_CHANGE,调用normalizeNodeStyle,输出containerStyle/textStyle。 - 自动解绑监听,减少重复代码。
已接入的节点组件:
- 图片节点
src/components/flow/nodes/common/ImageNode.vue - 式神节点
.../yys/ShikigamiSelectNode.vue - 御魂节点
.../yys/YuhunSelectNode.vue - 属性节点
.../yys/PropertySelectNode.vue
编辑入口:PropertyPanel
- 样式面板
src/components/flow/panels/StylePanel.vue写入properties.style:- 填充色、描边色/线宽、圆角、阴影(色/模糊/偏移)、透明度
- 文本对齐、行高、字重
- 图片面板
ImagePanel.vue写入宽高/fit/url,并保持与style.width/height同步。 - 其他面板(式神/御魂/属性)仅写业务字段,样式统一由
useNodeAppearance消费。
持久化与 schema
- 顶层导出结构:
RootDocument(见docs/2design/DataModel.md),包含schemaVersion。 - 保存/导入路径:
useFilesStore写出/读入schemaVersion;缺省数据走migrateToV1将散落的宽高/可见/锁定补齐到properties.style/meta。
校验建议
- width/height > 0;strokeWidth ≥ 0;radius ≥ 0 或四元组合法;opacity ∈ [0,1]。
- 文本:fontSize > 0,lineHeight 合理(1~3),padding 四元组 ≥ 0。
- 圆角仅对 rect 类节点生效;其他 kind 忽略 radius。
后续扩展建议
- 文本节点接入富文本:在
textStyle扩展行高倍数、字间距、背景/描边。 - 叠加高级效果:blendMode/filter;保持向后兼容,新增字段时通过
schemaVersion控制迁移。 - 矢量节点:在
vector节点中消费同一套style,并在编辑面板复用StylePanel。