diff --git a/src/components/md-deck/PrintPreview.tsx b/src/components/md-deck/PrintPreview.tsx index e576504..a170bae 100644 --- a/src/components/md-deck/PrintPreview.tsx +++ b/src/components/md-deck/PrintPreview.tsx @@ -24,22 +24,38 @@ export function PrintPreview(props: PrintPreviewProps) { const { store } = props; // A4 纸张尺寸(mm):210 x 297 - const A4_WIDTH = 210; - const A4_HEIGHT = 297; + const A4_WIDTH_PORTRAIT = 210; + const A4_HEIGHT_PORTRAIT = 297; + const A4_WIDTH_LANDSCAPE = 297; + const A4_HEIGHT_LANDSCAPE = 210; const PRINT_MARGIN = 5; // 打印边距 + // 获取打印设置 + const orientation = () => store.state.printOrientation; + const oddPageOffsetX = () => store.state.printOddPageOffsetX; + const oddPageOffsetY = () => store.state.printOddPageOffsetY; + + // 根据方向获取 A4 尺寸 + const getA4Size = () => { + if (orientation() === 'landscape') { + return { width: A4_WIDTH_LANDSCAPE, height: A4_HEIGHT_LANDSCAPE }; + } + return { width: A4_WIDTH_PORTRAIT, height: A4_HEIGHT_PORTRAIT }; + }; + // 计算每张卡牌在 A4 纸上的位置(居中布局) const pages = createMemo(() => { const cards = store.state.cards; const cardWidth = store.state.dimensions?.cardWidth || 56; const cardHeight = store.state.dimensions?.cardHeight || 88; + const { width: a4Width, height: a4Height } = getA4Size(); // 每行可容纳的卡牌数量 - const usableWidth = A4_WIDTH - PRINT_MARGIN * 2; + const usableWidth = a4Width - PRINT_MARGIN * 2; const cardsPerRow = Math.floor(usableWidth / cardWidth); // 每页可容纳的行数 - const usableHeight = A4_HEIGHT - PRINT_MARGIN * 2; + const usableHeight = a4Height - PRINT_MARGIN * 2; const rowsPerPage = Math.floor(usableHeight / cardHeight); // 每页的卡牌数量 @@ -50,8 +66,8 @@ export function PrintPreview(props: PrintPreviewProps) { const maxGridHeight = rowsPerPage * cardHeight; // 居中偏移量(使卡牌区域在 A4 纸上居中) - const offsetX = (A4_WIDTH - maxGridWidth) / 2; - const offsetY = (A4_HEIGHT - maxGridHeight) / 2; + const baseOffsetX = (a4Width - maxGridWidth) / 2; + const baseOffsetY = (a4Height - maxGridHeight) / 2; // 分页 const result: { @@ -72,9 +88,14 @@ export function PrintPreview(props: PrintPreviewProps) { currentPage = { pageIndex, cards: [], bounds: { minX: Infinity, minY: Infinity, maxX: -Infinity, maxY: -Infinity } }; } - // 使用居中偏移量计算卡牌位置 - const cardX = offsetX + col * cardWidth; - const cardY = offsetY + row * cardHeight; + // 奇数页应用偏移(pageIndex 从 0 开始,所以偶数索引是奇数页) + const isOddPage = pageIndex % 2 === 0; + const pageOffsetX = isOddPage ? oddPageOffsetX() : 0; + const pageOffsetY = isOddPage ? oddPageOffsetY() : 0; + + // 使用居中偏移量 + 奇数页偏移计算卡牌位置 + const cardX = baseOffsetX + col * cardWidth + pageOffsetX; + const cardY = baseOffsetY + row * cardHeight + pageOffsetY; currentPage.cards.push({ data: cards[i], @@ -97,10 +118,10 @@ export function PrintPreview(props: PrintPreviewProps) { return result.map(page => ({ ...page, frameBounds: { - minX: offsetX, - minY: offsetY, - maxX: offsetX + maxGridWidth, - maxY: offsetY + maxGridHeight + minX: baseOffsetX + (page.pageIndex % 2 === 0 ? oddPageOffsetX() : 0), + minY: baseOffsetY + (page.pageIndex % 2 === 0 ? oddPageOffsetY() : 0), + maxX: baseOffsetX + maxGridWidth + (page.pageIndex % 2 === 0 ? oddPageOffsetX() : 0), + maxY: baseOffsetY + maxGridHeight + (page.pageIndex % 2 === 0 ? oddPageOffsetY() : 0) } })); }); @@ -160,13 +181,76 @@ export function PrintPreview(props: PrintPreviewProps) { return (
+ {/* 打印样式:根据方向设置 @page 规则 */} +
{/* 打印预览控制栏 */} -
+

打印预览

共 {pages().length} 页,{store.state.cards.length} 张卡牌

+
+ {/* 方向选择 */} +
+ +
+ + +
+
+ {/* 奇数页偏移 */} +
+ +
+ X: + store.actions.setPrintOddPageOffsetX(Number(e.target.value))} + class="w-16 px-2 py-1 border border-gray-300 rounded text-sm" + step="0.1" + /> + mm +
+
+ Y: + store.actions.setPrintOddPageOffsetY(Number(e.target.value))} + class="w-16 px-2 py-1 border border-gray-300 rounded text-sm" + step="0.1" + /> + mm +
+
+