refactor: move cardlayer to just load store

This commit is contained in:
hypercross 2026-02-28 13:27:15 +08:00
parent 5c26fa407d
commit 9d189bd842
4 changed files with 24 additions and 36 deletions

View File

@ -1,53 +1,44 @@
import { For } from 'solid-js'; import {createMemo, For} from 'solid-js';
import { marked } from '../../markdown'; import { marked } from '../../markdown';
import { getLayerStyle } from './hooks/dimensions'; import { getLayerStyle } from './hooks/dimensions';
import type { LayerConfig, Dimensions, CardData } from './types'; import type { CardData } from './types';
import {DeckStore} from "./hooks/deckStore";
import {processVariables} from "../utils/csv-loader";
export interface CardLayerProps { export interface CardLayerProps {
layers: LayerConfig[];
dimensions: Dimensions;
cardData: CardData; cardData: CardData;
showBounds?: boolean; store: DeckStore;
}
/**
* body {{prop}} markdown
*/
function processBody(body: string, currentRow: CardData): string {
const processedBody = body.replace(/\{\{(\w+)\}\}/g, (_, key) => currentRow[key] || '');
return marked.parse(processedBody) as string;
}
/**
* layer
*/
function renderLayerContent(layer: { prop: string }, cardData: CardData): string {
const content = cardData[layer.prop] || '';
return processBody(content, cardData);
} }
export function CardLayer(props: CardLayerProps) { export function CardLayer(props: CardLayerProps) {
const layers = createMemo(() => props.store.state.layerConfigs.filter((l) => l.visible));
const dimensions = () => props.store.state.dimensions!;
const showBounds = () => props.store.state.isEditing;
function renderLayerContent(content: string) {
return marked.parse(processVariables(content, props.cardData, props.store.state.cards)) as string;
}
return ( return (
<For each={props.layers}> <For each={layers()}>
{(layer) => { {(layer) => {
return ( return (
<> <>
<article <article
class="absolute flex items-center justify-center text-center prose prose-sm" class="absolute flex items-center justify-center text-center prose prose-sm"
style={{ style={{
...getLayerStyle(layer, props.dimensions), ...getLayerStyle(layer, dimensions()),
'font-size': `${layer.fontSize || 3}mm` 'font-size': `${layer.fontSize || 3}mm`
}} }}
innerHTML={renderLayerContent(layer, props.cardData)} innerHTML={renderLayerContent(props.cardData[layer.prop])}
/> />
{props.showBounds && ( {showBounds() && (
<div <div
class="absolute border-2 border-blue-500/50 pointer-events-none select-none" class="absolute border-2 border-blue-500/50 pointer-events-none select-none"
style={{ style={{
left: `${(layer.x1 - 1) * props.dimensions.cellWidth}mm`, left: `${(layer.x1 - 1) * dimensions().cellWidth}mm`,
top: `${(layer.y1 - 1) * props.dimensions.cellHeight}mm`, top: `${(layer.y1 - 1) * dimensions().cellHeight}mm`,
width: `${(layer.x2 - layer.x1 + 1) * props.dimensions.cellWidth}mm`, width: `${(layer.x2 - layer.x1 + 1) * dimensions().cellWidth}mm`,
height: `${(layer.y2 - layer.y1 + 1) * props.dimensions.cellHeight}mm` height: `${(layer.y2 - layer.y1 + 1) * dimensions().cellHeight}mm`
}} }}
/> />
)} )}

View File

@ -15,7 +15,6 @@ export function CardPreview(props: CardPreviewProps) {
const { store } = props; const { store } = props;
const currentCard = createMemo(() => store.state.cards[store.state.activeTab]); const currentCard = createMemo(() => store.state.cards[store.state.activeTab]);
const visibleLayers = createMemo(() => store.state.layerConfigs.filter((l) => l.visible));
const selectionStyle = createMemo(() => const selectionStyle = createMemo(() =>
getSelectionBoxStyle(store.state.selectStart, store.state.selectEnd, store.state.dimensions) getSelectionBoxStyle(store.state.selectStart, store.state.selectEnd, store.state.dimensions)
); );
@ -78,10 +77,8 @@ export function CardPreview(props: CardPreviewProps) {
</Show> </Show>
<CardLayer <CardLayer
layers={visibleLayers()}
dimensions={store.state.dimensions!}
cardData={currentCard()} cardData={currentCard()}
showBounds={store.state.isEditing} store={store}
/> />
</div> </div>
</div> </div>

View File

@ -1,6 +1,6 @@
import { createStore } from 'solid-js/store'; import { createStore } from 'solid-js/store';
import { calculateDimensions } from './dimensions'; import { calculateDimensions } from './dimensions';
import { loadCSV } from '../../utils/csv-loader'; import { loadCSV, CSV } from '../../utils/csv-loader';
import { initLayerConfigs, formatLayers } from './layer-parser'; import { initLayerConfigs, formatLayers } from './layer-parser';
import type { CardData, LayerConfig, Dimensions } from '../types'; import type { CardData, LayerConfig, Dimensions } from '../types';
@ -32,7 +32,7 @@ export interface DeckState {
dimensions: Dimensions | null; dimensions: Dimensions | null;
// 卡牌数据 // 卡牌数据
cards: CardData[]; cards: CSV<CardData>;
activeTab: number; activeTab: number;
// 图层配置 // 图层配置

View File

@ -91,7 +91,7 @@ export function processVariables<T extends JSONObject> (body: string, currentRow
const frontMatter = csv.frontmatter; const frontMatter = csv.frontmatter;
if(key in row) return row[key]; if(key in row) return row[key];
if(frontMatter && key in frontMatter) return frontMatter[key]; if(frontMatter && key in frontMatter) return frontMatter[key];
return ''; return `{{${key}}}`;
} }
return body.replace(/\{\{(\w+)\}\}/g, (_, key) => `${replaceProp(key)}`); return body.replace(/\{\{(\w+)\}\}/g, (_, key) => `${replaceProp(key)}`);