From f87ccb662d61f05525f1ff891019a3fa43395d27 Mon Sep 17 00:00:00 2001 From: hypercross Date: Sun, 15 Mar 2026 10:57:18 +0800 Subject: [PATCH] refactor: clean up --- src/components/md-deck/PltPreview.tsx | 313 +++++++++--------------- src/components/md-deck/PrintPreview.tsx | 4 +- 2 files changed, 113 insertions(+), 204 deletions(-) diff --git a/src/components/md-deck/PltPreview.tsx b/src/components/md-deck/PltPreview.tsx index bc1ad80..6734829 100644 --- a/src/components/md-deck/PltPreview.tsx +++ b/src/components/md-deck/PltPreview.tsx @@ -1,29 +1,12 @@ import { createSignal, For, Show, createMemo } from 'solid-js'; import { parsePlt, extractCutPaths } from '../../plotcutter/parser'; import { generateTravelPaths, travelPathsToSvg } from '../../plotcutter/layout'; -import { pts2plotter } from '../../plotcutter/plotter'; -import type { CardPath, CardShape } from '../../plotcutter/types'; -import { - getCardShapePoints, - calculateCenter, - contourToSvgPath -} from '../../plotcutter/contour'; +import type { CardPath } from '../../plotcutter/types'; +import { calculateCenter, contourToSvgPath } from '../../plotcutter/contour'; export interface PltPreviewProps { /** PLT 文件内容 */ pltCode: string; - /** 卡片形状(用于生成刀路) */ - shape: CardShape; - /** 卡片宽度 (mm) */ - cardWidth: number; - /** 卡片高度 (mm) */ - cardHeight: number; - /** 出血 (mm) */ - bleed: number; - /** 圆角半径 (mm) */ - cornerRadius: number; - /** 打印方向 */ - orientation: 'portrait' | 'landscape'; /** 关闭回调 */ onClose: () => void; } @@ -31,9 +14,11 @@ export interface PltPreviewProps { /** * 从 PLT 代码解析并生成卡片路径数据 */ -function parsePltToCardPaths(pltCode: string, a4Height: number): { +function parsePltToCardPaths(pltCode: string): { cutPaths: [number, number][][]; cardPaths: CardPath[]; + width: number; + height: number; } { const parsed = parsePlt(pltCode); const cutPaths = extractCutPaths(parsed, 5); // 5mm 阈值 @@ -57,151 +42,66 @@ function parsePltToCardPaths(pltCode: string, a4Height: number): { }; }); - return { cutPaths, cardPaths }; -} - -/** - * 生成单页满排时的 PLT 代码(用于预览对比) - */ -function generateSinglePagePlt( - shape: CardShape, - cardWidth: number, - cardHeight: number, - bleed: number, - cornerRadius: number, - orientation: 'portrait' | 'landscape' -): string { - const a4Width = orientation === 'landscape' ? 297 : 210; - const a4Height = orientation === 'landscape' ? 210 : 297; - const printMargin = 5; - - const usableWidth = a4Width - printMargin * 2; - const usableHeight = a4Height - printMargin * 2; - const cardsPerRow = Math.floor(usableWidth / cardWidth); - const rowsPerPage = Math.floor(usableHeight / cardHeight); - const cardsPerPage = cardsPerRow * rowsPerPage; - - const maxGridWidth = cardsPerRow * cardWidth; - const maxGridHeight = rowsPerPage * cardHeight; - const offsetX = (a4Width - maxGridWidth) / 2; - const offsetY = (a4Height - maxGridHeight) / 2; - - const cutWidth = cardWidth - bleed * 2; - const cutHeight = cardHeight - bleed * 2; - - const allPaths: [number, number][][] = []; - - for (let i = 0; i < cardsPerPage; i++) { - const row = Math.floor(i / cardsPerRow); - const col = i % cardsPerRow; - const x = offsetX + col * cardWidth; - const y = offsetY + row * cardHeight; - - const shapePoints = getCardShapePoints(shape, cutWidth, cutHeight, cornerRadius); - const pagePoints = shapePoints.map(([px, py]) => [ - x + bleed + px, - a4Height - (y + bleed + py) - ] as [number, number]); - - allPaths.push(pagePoints); - } - - if (allPaths.length === 0) return ''; - - const startPoint: [number, number] = [0, a4Height]; - const endPoint: [number, number] = [0, a4Height]; - return pts2plotter(allPaths, a4Width, a4Height, 1, startPoint, endPoint); + return { + cutPaths, + cardPaths, + width: parsed.width || 0, + height: parsed.height || 0 + }; } /** * PLT 预览组件 - 基于 PLT 文本解析显示切割路径预览 + * + * 所有显示参数(尺寸、路径等)都从 PLT 文本解析获取。 */ export function PltPreview(props: PltPreviewProps) { - const a4Width = props.orientation === 'landscape' ? 297 : 210; - const a4Height = props.orientation === 'landscape' ? 210 : 297; - - // 使用传入的圆角值,但也允许用户修改 - const [cornerRadius, setCornerRadius] = createSignal(props.cornerRadius); - // 解析传入的 PLT 代码 const parsedData = createMemo(() => { if (!props.pltCode) { - return { cutPaths: [] as [number, number][][], cardPaths: [] as CardPath[] }; + return { cutPaths: [] as [number, number][][], cardPaths: [] as CardPath[], width: 0, height: 0 }; } - return parsePltToCardPaths(props.pltCode, a4Height); + return parsePltToCardPaths(props.pltCode); }); // 生成空走路径 const travelPathD = createMemo(() => { const cardPaths = parsedData().cardPaths; + const height = parsedData().height; if (cardPaths.length === 0) return ''; - const travelPaths = generateTravelPaths(cardPaths, a4Height); + const travelPaths = generateTravelPaths(cardPaths, height); return travelPathsToSvg(travelPaths); }); - // 生成单页满排时的 PLT 代码(用于对比) - const singlePagePltCode = createMemo(() => { - return generateSinglePagePlt( - props.shape, - props.cardWidth, - props.cardHeight, - props.bleed, - cornerRadius(), - props.orientation - ); - }); - - // 生成当前 PLT 的 HPGL 代码(重新生成,确保圆角更新) - const currentPltCode = createMemo(() => { - const cardPaths = parsedData().cardPaths; - if (cardPaths.length === 0) return ''; - const allPaths = cardPaths.map(p => p.points); - const startPoint: [number, number] = [0, a4Height]; - const endPoint: [number, number] = [0, a4Height]; - return pts2plotter(allPaths, a4Width, a4Height, 1, startPoint, endPoint); - }); - const handleDownload = () => { - if (!currentPltCode()) { + if (!props.pltCode) { alert('没有可导出的卡片'); return; } - const blob = new Blob([currentPltCode()], { type: 'application/vnd.hp-HPGL' }); + const blob = new Blob([props.pltCode], { type: 'application/vnd.hp-HPGL' }); const url = URL.createObjectURL(blob); const link = document.createElement('a'); link.href = url; - link.download = `deck-export-${new Date().toISOString().slice(0, 19).replace(/:/g, '-')}.plt`; + link.download = `deck-plt-${new Date().toISOString().slice(0, 19).replace(/:/g, '-')}.plt`; document.body.appendChild(link); link.click(); document.body.removeChild(link); URL.revokeObjectURL(url); }; - const handleCornerRadiusChange = (e: Event) => { - const target = e.target as HTMLInputElement; - setCornerRadius(Number(target.value)); - }; - return (
{/* 头部控制栏 */}

PLT 切割预览

-
- - -
+ 0}> + + 尺寸:{parsedData().width.toFixed(1)}mm × {parsedData().height.toFixed(1)}mm + +