fix: double side printing

This commit is contained in:
hypercross 2026-03-13 17:42:51 +08:00
parent 4b08a738a7
commit 984b8aa1c8
1 changed files with 51 additions and 41 deletions

View File

@ -53,16 +53,16 @@ export function usePageLayout(store: DeckStore): UsePageLayoutReturn {
const baseOffsetY = (a4Height - maxGridHeight) / 2; const baseOffsetY = (a4Height - maxGridHeight) / 2;
const result: PageData[] = []; const result: PageData[] = [];
if (doubleSided()) { if (doubleSided()) {
// 双面打印模式:每张卡牌需要 2 页(正面 + 背面) // 双面打印模式:每页多张卡牌,正面和背面分别在相邻的两页
// 背面卡牌顺序在长边方向上逆转
const totalCards = cards.length; const totalCards = cards.length;
const totalPages = Math.ceil(totalCards / cardsPerPage);
for (let i = 0; i < totalCards; i++) {
const frontPageIndex = i * 2; for (let pageIndex = 0; pageIndex < totalPages; pageIndex++) {
const backPageIndex = i * 2 + 1; const frontPageIndex = pageIndex * 2;
const backPageIndex = pageIndex * 2 + 1;
// 确保页面数组有足够长度 // 确保页面数组有足够长度
while (result.length <= backPageIndex) { while (result.length <= backPageIndex) {
result.push({ result.push({
@ -72,41 +72,51 @@ export function usePageLayout(store: DeckStore): UsePageLayoutReturn {
frameBounds: { minX: Infinity, minY: Infinity, maxX: -Infinity, maxY: -Infinity } frameBounds: { minX: Infinity, minY: Infinity, maxX: -Infinity, maxY: -Infinity }
}); });
} }
const frontPage = result[frontPageIndex]; const frontPage = result[frontPageIndex];
const backPage = result[backPageIndex]; const backPage = result[backPageIndex];
// 正面:正常顺序排列 // 计算当前正面页的卡牌范围
const frontRow = Math.floor(i / cardsPerRow); const startCardIndex = pageIndex * cardsPerPage;
const frontCol = i % cardsPerRow; const endCardIndex = Math.min(startCardIndex + cardsPerPage, totalCards);
const frontX = baseOffsetX + frontCol * cardWidth + frontOddPageOffsetX();
const frontY = baseOffsetY + frontRow * cardHeight + frontOddPageOffsetY(); for (let i = startCardIndex; i < endCardIndex; i++) {
// 正面:正常顺序排列
frontPage.cards.push({ data: cards[i], x: frontX, y: frontY, side: 'front' as const }); const indexInPage = i - startCardIndex;
frontPage.bounds.minX = Math.min(frontPage.bounds.minX, frontX); const row = Math.floor(indexInPage / cardsPerRow);
frontPage.bounds.minY = Math.min(frontPage.bounds.minY, frontY); const col = indexInPage % cardsPerRow;
frontPage.bounds.maxX = Math.max(frontPage.bounds.maxX, frontX + cardWidth); // 双面打印时,所有正面页都在奇数物理页上,所以都应用偏移
frontPage.bounds.maxY = Math.max(frontPage.bounds.maxY, frontY + cardHeight); const pageOffsetX = frontOddPageOffsetX();
const pageOffsetY = frontOddPageOffsetY();
// 背面:逆转顺序排列(长边方向)
// 对于竖向打印,长边是垂直方向,所以逆转行 const frontX = baseOffsetX + col * cardWidth + pageOffsetX;
// 对于横向打印,长边是水平方向,所以逆转列 const frontY = baseOffsetY + row * cardHeight + pageOffsetY;
const backIndex = totalCards - 1 - i;
const backRow = orientation() === 'portrait' frontPage.cards.push({ data: cards[i], x: frontX, y: frontY, side: 'front' as const });
? Math.floor(backIndex / cardsPerRow) frontPage.bounds.minX = Math.min(frontPage.bounds.minX, frontX);
: Math.floor(i / cardsPerRow); frontPage.bounds.minY = Math.min(frontPage.bounds.minY, frontY);
const backCol = orientation() === 'portrait' frontPage.bounds.maxX = Math.max(frontPage.bounds.maxX, frontX + cardWidth);
? backIndex % cardsPerRow frontPage.bounds.maxY = Math.max(frontPage.bounds.maxY, frontY + cardHeight);
: (cardsPerRow - 1 - (i % cardsPerRow));
// 背面:逆转顺序排列(长边方向)
const backX = baseOffsetX + backCol * cardWidth; // 对于竖向打印,长边是垂直方向,所以逆转行
const backY = baseOffsetY + backRow * cardHeight; // 对于横向打印,长边是水平方向,所以逆转列
const backRow = orientation() === 'portrait'
backPage.cards.push({ data: cards[i], x: backX, y: backY, side: 'back' as const }); ? (rowsPerPage - 1 - row)
backPage.bounds.minX = Math.min(backPage.bounds.minX, backX); : row;
backPage.bounds.minY = Math.min(backPage.bounds.minY, backY); const backCol = orientation() === 'portrait'
backPage.bounds.maxX = Math.max(backPage.bounds.maxX, backX + cardWidth); ? col
backPage.bounds.maxY = Math.max(backPage.bounds.maxY, backY + cardHeight); : (cardsPerRow - 1 - col);
const backX = baseOffsetX + backCol * cardWidth;
const backY = baseOffsetY + backRow * cardHeight;
backPage.cards.push({ data: cards[i], x: backX, y: backY, side: 'back' as const });
backPage.bounds.minX = Math.min(backPage.bounds.minX, backX);
backPage.bounds.minY = Math.min(backPage.bounds.minY, backY);
backPage.bounds.maxX = Math.max(backPage.bounds.maxX, backX + cardWidth);
backPage.bounds.maxY = Math.max(backPage.bounds.maxY, backY + cardHeight);
}
} }
} else { } else {
// 单面打印模式:原有逻辑 // 单面打印模式:原有逻辑