2026-02-28 13:27:15 +08:00
|
|
|
import {createMemo, For} from 'solid-js';
|
2026-03-13 11:14:01 +08:00
|
|
|
import {parseMarkdown} from '../../markdown';
|
2026-02-27 21:12:23 +08:00
|
|
|
import { getLayerStyle } from './hooks/dimensions';
|
2026-03-13 17:26:00 +08:00
|
|
|
import type { CardData, CardSide } from './types';
|
2026-02-28 13:27:15 +08:00
|
|
|
import {DeckStore} from "./hooks/deckStore";
|
|
|
|
|
import {processVariables} from "../utils/csv-loader";
|
2026-03-13 11:46:18 +08:00
|
|
|
import {resolvePath} from "../utils/path";
|
2026-02-27 21:12:23 +08:00
|
|
|
|
|
|
|
|
export interface CardLayerProps {
|
|
|
|
|
cardData: CardData;
|
2026-02-28 13:27:15 +08:00
|
|
|
store: DeckStore;
|
2026-03-13 17:26:00 +08:00
|
|
|
side?: CardSide;
|
2026-02-27 21:12:23 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function CardLayer(props: CardLayerProps) {
|
2026-03-13 17:26:00 +08:00
|
|
|
const side = () => props.side || 'front';
|
|
|
|
|
const layers = createMemo(() =>
|
|
|
|
|
side() === 'front'
|
|
|
|
|
? props.store.state.frontLayerConfigs.filter((l) => l.visible)
|
|
|
|
|
: props.store.state.backLayerConfigs.filter((l) => l.visible)
|
|
|
|
|
);
|
2026-02-28 13:27:15 +08:00
|
|
|
const dimensions = () => props.store.state.dimensions!;
|
|
|
|
|
const showBounds = () => props.store.state.isEditing;
|
2026-03-13 17:26:00 +08:00
|
|
|
|
2026-02-28 13:27:15 +08:00
|
|
|
function renderLayerContent(content: string) {
|
2026-03-25 17:29:56 +08:00
|
|
|
const iconPath = resolvePath(props.store.state.cards.sourcePath, props.cardData.iconPath ?? "./assets");
|
2026-03-13 11:46:18 +08:00
|
|
|
return parseMarkdown(processVariables(content, props.cardData, props.store.state.cards), iconPath) as string;
|
2026-02-28 13:27:15 +08:00
|
|
|
}
|
2026-02-27 21:12:23 +08:00
|
|
|
return (
|
2026-02-28 13:27:15 +08:00
|
|
|
<For each={layers()}>
|
2026-02-27 22:56:06 +08:00
|
|
|
{(layer) => {
|
|
|
|
|
return (
|
|
|
|
|
<>
|
|
|
|
|
<article
|
2026-03-10 23:17:49 +08:00
|
|
|
class="absolute flex flex-col items-center justify-center text-center prose prose-sm"
|
2026-02-27 22:37:11 +08:00
|
|
|
style={{
|
2026-02-28 13:27:15 +08:00
|
|
|
...getLayerStyle(layer, dimensions()),
|
2026-02-28 12:18:52 +08:00
|
|
|
'font-size': `${layer.fontSize || 3}mm`
|
2026-02-27 22:37:11 +08:00
|
|
|
}}
|
2026-02-28 13:27:15 +08:00
|
|
|
innerHTML={renderLayerContent(props.cardData[layer.prop])}
|
2026-02-27 22:37:11 +08:00
|
|
|
/>
|
2026-02-28 13:27:15 +08:00
|
|
|
{showBounds() && (
|
2026-02-27 22:56:06 +08:00
|
|
|
<div
|
|
|
|
|
class="absolute border-2 border-blue-500/50 pointer-events-none select-none"
|
|
|
|
|
style={{
|
2026-02-28 13:27:15 +08:00
|
|
|
left: `${(layer.x1 - 1) * dimensions().cellWidth}mm`,
|
|
|
|
|
top: `${(layer.y1 - 1) * dimensions().cellHeight}mm`,
|
|
|
|
|
width: `${(layer.x2 - layer.x1 + 1) * dimensions().cellWidth}mm`,
|
|
|
|
|
height: `${(layer.y2 - layer.y1 + 1) * dimensions().cellHeight}mm`
|
2026-02-27 22:56:06 +08:00
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
</>
|
|
|
|
|
);
|
|
|
|
|
}}
|
2026-02-27 21:12:23 +08:00
|
|
|
</For>
|
|
|
|
|
);
|
|
|
|
|
}
|