refactor: layer alignment
This commit is contained in:
parent
273f949839
commit
ea57cf8d2b
|
|
@ -26,16 +26,23 @@ export function CardLayer(props: CardLayerProps) {
|
||||||
const iconPath = resolvePath(props.store.state.cards.sourcePath, props.cardData.iconPath ?? "./assets");
|
const iconPath = resolvePath(props.store.state.cards.sourcePath, props.cardData.iconPath ?? "./assets");
|
||||||
return parseMarkdown(processVariables(content, props.cardData, props.store.state.cards), iconPath) as string;
|
return parseMarkdown(processVariables(content, props.cardData, props.store.state.cards), iconPath) as string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getAlignStyle = (align?: 'l' | 'c' | 'r') => {
|
||||||
|
if (align === 'l') return 'left';
|
||||||
|
if (align === 'r') return 'right';
|
||||||
|
return 'center';
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
<For each={layers()}>
|
<For each={layers()}>
|
||||||
{(layer) => {
|
{(layer) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<article
|
<article
|
||||||
class="absolute flex flex-col items-center justify-center text-center prose prose-sm"
|
class="absolute flex flex-col items-stretch justify-center prose prose-sm"
|
||||||
style={{
|
style={{
|
||||||
...getLayerStyle(layer, dimensions()),
|
...getLayerStyle(layer, dimensions()),
|
||||||
'font-size': `${layer.fontSize || 3}mm`
|
'font-size': `${layer.fontSize || 3}mm`,
|
||||||
|
'text-align': getAlignStyle(layer.align)
|
||||||
}}
|
}}
|
||||||
innerHTML={renderLayerContent(props.cardData[layer.prop])}
|
innerHTML={renderLayerContent(props.cardData[layer.prop])}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,13 @@ const ORIENTATION_OPTIONS = [
|
||||||
{ value: 'w', label: '← 西' }
|
{ value: 'w', label: '← 西' }
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
|
const ALIGN_OPTIONS = [
|
||||||
|
{ value: '', label: '对齐' },
|
||||||
|
{ value: 'l', label: '← 左' },
|
||||||
|
{ value: 'c', label: '≡ 中' },
|
||||||
|
{ value: 'r', label: '→ 右' }
|
||||||
|
] as const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 图层编辑面板:图层可见性切换、位置编辑、复制代码
|
* 图层编辑面板:图层可见性切换、位置编辑、复制代码
|
||||||
*/
|
*/
|
||||||
|
|
@ -38,6 +45,13 @@ export function LayerEditorPanel(props: LayerEditorPanelProps) {
|
||||||
updateFn(layerProp, { fontSize });
|
updateFn(layerProp, { fontSize });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const updateLayerAlign = (layerProp: string, align?: 'l' | 'c' | 'r') => {
|
||||||
|
const updateFn = store.state.activeSide === 'front'
|
||||||
|
? store.actions.updateFrontLayerConfig
|
||||||
|
: store.actions.updateBackLayerConfig;
|
||||||
|
updateFn(layerProp, { align });
|
||||||
|
};
|
||||||
|
|
||||||
const toggleLayerVisible = (layerProp: string) => {
|
const toggleLayerVisible = (layerProp: string) => {
|
||||||
const toggleFn = store.state.activeSide === 'front'
|
const toggleFn = store.state.activeSide === 'front'
|
||||||
? store.actions.toggleFrontLayerVisible
|
? store.actions.toggleFrontLayerVisible
|
||||||
|
|
@ -94,6 +108,17 @@ export function LayerEditorPanel(props: LayerEditorPanelProps) {
|
||||||
)}
|
)}
|
||||||
</For>
|
</For>
|
||||||
</select>
|
</select>
|
||||||
|
<select
|
||||||
|
value={layer.align || ''}
|
||||||
|
onChange={(e) => updateLayerAlign(layer.prop, e.target.value as 'l' | 'c' | 'r' | undefined || undefined)}
|
||||||
|
class="text-xs px-2 py-1 rounded border border-gray-300 bg-white cursor-pointer"
|
||||||
|
>
|
||||||
|
<For each={ALIGN_OPTIONS}>
|
||||||
|
{(opt) => (
|
||||||
|
<option value={opt.value}>{opt.label}</option>
|
||||||
|
)}
|
||||||
|
</For>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<label class="text-xs text-gray-600">字体/mm</label>
|
<label class="text-xs text-gray-600">字体/mm</label>
|
||||||
|
|
|
||||||
|
|
@ -3,15 +3,15 @@ import {CSV} from "../../utils/csv-loader";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析 layers 字符串
|
* 解析 layers 字符串
|
||||||
* 格式:body:1,7-5,8 title:1,1-4,1f6.6s
|
* 格式:body:1,7-5,8 title:1,1-4,1f6.6sl
|
||||||
* f[fontSize] 表示字体大小(可选),方向字母在最后(可选)
|
* f[fontSize] 表示字体大小(可选),方向字母(可选),对齐字母 l/c/r(可选)
|
||||||
*/
|
*/
|
||||||
export function parseLayers(layersStr: string): Layer[] {
|
export function parseLayers(layersStr: string): Layer[] {
|
||||||
if (!layersStr) return [];
|
if (!layersStr) return [];
|
||||||
|
|
||||||
const layers: Layer[] = [];
|
const layers: Layer[] = [];
|
||||||
// 匹配:prop:x1,y1-x2,y2[ffontSize][direction]
|
// 匹配:prop:x1,y1-x2,y2[ffontSize][direction][align]
|
||||||
const regex = /(\w+):(\d+),(\d+)-(\d+),(\d+)(?:f([\d.]+))?([nsew])?/g;
|
const regex = /(\w+):(\d+),(\d+)-(\d+),(\d+)(?:f([\d.]+))?([nsew])?([lcr])?/g;
|
||||||
let match;
|
let match;
|
||||||
|
|
||||||
while ((match = regex.exec(layersStr)) !== null) {
|
while ((match = regex.exec(layersStr)) !== null) {
|
||||||
|
|
@ -22,7 +22,8 @@ export function parseLayers(layersStr: string): Layer[] {
|
||||||
x2: parseInt(match[4]),
|
x2: parseInt(match[4]),
|
||||||
y2: parseInt(match[5]),
|
y2: parseInt(match[5]),
|
||||||
fontSize: match[6] ? parseFloat(match[6]) : undefined,
|
fontSize: match[6] ? parseFloat(match[6]) : undefined,
|
||||||
orientation: match[7] as 'n' | 's' | 'e' | 'w' | undefined
|
orientation: match[7] as 'n' | 's' | 'e' | 'w' | undefined,
|
||||||
|
align: match[8] as 'l' | 'c' | 'r' | undefined
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -43,6 +44,9 @@ export function formatLayers(layers: LayerConfig[]): string {
|
||||||
if (l.orientation && l.orientation !== 'n') {
|
if (l.orientation && l.orientation !== 'n') {
|
||||||
str += l.orientation;
|
str += l.orientation;
|
||||||
}
|
}
|
||||||
|
if (l.align) {
|
||||||
|
str += l.align;
|
||||||
|
}
|
||||||
return str;
|
return str;
|
||||||
})
|
})
|
||||||
.join(' ');
|
.join(' ');
|
||||||
|
|
@ -68,7 +72,8 @@ export function initLayerConfigsForSide(
|
||||||
x2: existing?.x2 || 2,
|
x2: existing?.x2 || 2,
|
||||||
y2: existing?.y2 || 2,
|
y2: existing?.y2 || 2,
|
||||||
orientation: existing?.orientation,
|
orientation: existing?.orientation,
|
||||||
fontSize: existing?.fontSize
|
fontSize: existing?.fontSize,
|
||||||
|
align: existing?.align
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ export interface Layer {
|
||||||
y2: number;
|
y2: number;
|
||||||
orientation?: 'n' | 's' | 'e' | 'w';
|
orientation?: 'n' | 's' | 'e' | 'w';
|
||||||
fontSize?: number;
|
fontSize?: number;
|
||||||
|
align?: 'l' | 'c' | 'r';
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LayerConfig {
|
export interface LayerConfig {
|
||||||
|
|
@ -25,6 +26,7 @@ export interface LayerConfig {
|
||||||
y2: number;
|
y2: number;
|
||||||
orientation?: 'n' | 's' | 'e' | 'w';
|
orientation?: 'n' | 's' | 'e' | 'w';
|
||||||
fontSize?: number;
|
fontSize?: number;
|
||||||
|
align?: 'l' | 'c' | 'r';
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Dimensions {
|
export interface Dimensions {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue