feat: card back support?
This commit is contained in:
@@ -24,8 +24,9 @@ const PRINT_MARGIN = 5;
|
||||
*/
|
||||
export function usePageLayout(store: DeckStore): UsePageLayoutReturn {
|
||||
const orientation = () => store.state.printOrientation;
|
||||
const oddPageOffsetX = () => store.state.printOddPageOffsetX;
|
||||
const oddPageOffsetY = () => store.state.printOddPageOffsetY;
|
||||
const doubleSided = () => store.state.printDoubleSided;
|
||||
const frontOddPageOffsetX = () => store.state.printFrontOddPageOffsetX;
|
||||
const frontOddPageOffsetY = () => store.state.printFrontOddPageOffsetY;
|
||||
|
||||
const getA4Size = () => {
|
||||
if (orientation() === 'landscape') {
|
||||
@@ -52,56 +53,119 @@ export function usePageLayout(store: DeckStore): UsePageLayoutReturn {
|
||||
const baseOffsetY = (a4Height - maxGridHeight) / 2;
|
||||
|
||||
const result: PageData[] = [];
|
||||
let currentPage: PageData = {
|
||||
pageIndex: 0,
|
||||
cards: [],
|
||||
bounds: { minX: Infinity, minY: Infinity, maxX: -Infinity, maxY: -Infinity },
|
||||
frameBounds: { minX: Infinity, minY: Infinity, maxX: -Infinity, maxY: -Infinity }
|
||||
};
|
||||
|
||||
if (doubleSided()) {
|
||||
// 双面打印模式:每张卡牌需要 2 页(正面 + 背面)
|
||||
// 背面卡牌顺序在长边方向上逆转
|
||||
const totalCards = cards.length;
|
||||
|
||||
for (let i = 0; i < totalCards; i++) {
|
||||
const frontPageIndex = i * 2;
|
||||
const backPageIndex = i * 2 + 1;
|
||||
|
||||
// 确保页面数组有足够长度
|
||||
while (result.length <= backPageIndex) {
|
||||
result.push({
|
||||
pageIndex: result.length,
|
||||
cards: [],
|
||||
bounds: { minX: Infinity, minY: Infinity, maxX: -Infinity, maxY: -Infinity },
|
||||
frameBounds: { minX: Infinity, minY: Infinity, maxX: -Infinity, maxY: -Infinity }
|
||||
});
|
||||
}
|
||||
|
||||
const frontPage = result[frontPageIndex];
|
||||
const backPage = result[backPageIndex];
|
||||
|
||||
// 正面:正常顺序排列
|
||||
const frontRow = Math.floor(i / cardsPerRow);
|
||||
const frontCol = i % cardsPerRow;
|
||||
const frontX = baseOffsetX + frontCol * cardWidth + frontOddPageOffsetX();
|
||||
const frontY = baseOffsetY + frontRow * cardHeight + frontOddPageOffsetY();
|
||||
|
||||
frontPage.cards.push({ data: cards[i], x: frontX, y: frontY, side: 'front' as const });
|
||||
frontPage.bounds.minX = Math.min(frontPage.bounds.minX, frontX);
|
||||
frontPage.bounds.minY = Math.min(frontPage.bounds.minY, frontY);
|
||||
frontPage.bounds.maxX = Math.max(frontPage.bounds.maxX, frontX + cardWidth);
|
||||
frontPage.bounds.maxY = Math.max(frontPage.bounds.maxY, frontY + cardHeight);
|
||||
|
||||
// 背面:逆转顺序排列(长边方向)
|
||||
// 对于竖向打印,长边是垂直方向,所以逆转行
|
||||
// 对于横向打印,长边是水平方向,所以逆转列
|
||||
const backIndex = totalCards - 1 - i;
|
||||
const backRow = orientation() === 'portrait'
|
||||
? Math.floor(backIndex / cardsPerRow)
|
||||
: Math.floor(i / cardsPerRow);
|
||||
const backCol = orientation() === 'portrait'
|
||||
? backIndex % cardsPerRow
|
||||
: (cardsPerRow - 1 - (i % cardsPerRow));
|
||||
|
||||
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 {
|
||||
// 单面打印模式:原有逻辑
|
||||
let currentPage: PageData = {
|
||||
pageIndex: 0,
|
||||
cards: [],
|
||||
bounds: { minX: Infinity, minY: Infinity, maxX: -Infinity, maxY: -Infinity },
|
||||
frameBounds: { minX: Infinity, minY: Infinity, maxX: -Infinity, maxY: -Infinity }
|
||||
};
|
||||
|
||||
for (let i = 0; i < cards.length; i++) {
|
||||
const pageIndex = Math.floor(i / cardsPerPage);
|
||||
const indexInPage = i % cardsPerPage;
|
||||
const row = Math.floor(indexInPage / cardsPerRow);
|
||||
const col = indexInPage % cardsPerRow;
|
||||
for (let i = 0; i < cards.length; i++) {
|
||||
const pageIndex = Math.floor(i / cardsPerPage);
|
||||
const indexInPage = i % cardsPerPage;
|
||||
const row = Math.floor(indexInPage / cardsPerRow);
|
||||
const col = indexInPage % cardsPerRow;
|
||||
|
||||
if (pageIndex !== currentPage.pageIndex) {
|
||||
if (pageIndex !== currentPage.pageIndex) {
|
||||
result.push(currentPage);
|
||||
currentPage = {
|
||||
pageIndex,
|
||||
cards: [],
|
||||
bounds: { minX: Infinity, minY: Infinity, maxX: -Infinity, maxY: -Infinity },
|
||||
frameBounds: { minX: Infinity, minY: Infinity, maxX: -Infinity, maxY: -Infinity }
|
||||
};
|
||||
}
|
||||
|
||||
const isOddPage = pageIndex % 2 === 0;
|
||||
const pageOffsetX = isOddPage ? frontOddPageOffsetX() : 0;
|
||||
const pageOffsetY = isOddPage ? frontOddPageOffsetY() : 0;
|
||||
|
||||
const cardX = baseOffsetX + col * cardWidth + pageOffsetX;
|
||||
const cardY = baseOffsetY + row * cardHeight + pageOffsetY;
|
||||
|
||||
currentPage.cards.push({ data: cards[i], x: cardX, y: cardY, side: 'front' as const });
|
||||
currentPage.bounds.minX = Math.min(currentPage.bounds.minX, cardX);
|
||||
currentPage.bounds.minY = Math.min(currentPage.bounds.minY, cardY);
|
||||
currentPage.bounds.maxX = Math.max(currentPage.bounds.maxX, cardX + cardWidth);
|
||||
currentPage.bounds.maxY = Math.max(currentPage.bounds.maxY, cardY + cardHeight);
|
||||
}
|
||||
|
||||
if (currentPage.cards.length > 0) {
|
||||
result.push(currentPage);
|
||||
currentPage = {
|
||||
pageIndex,
|
||||
cards: [],
|
||||
bounds: { minX: Infinity, minY: Infinity, maxX: -Infinity, maxY: -Infinity },
|
||||
frameBounds: { minX: Infinity, minY: Infinity, maxX: -Infinity, maxY: -Infinity }
|
||||
};
|
||||
}
|
||||
|
||||
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], x: cardX, y: cardY });
|
||||
currentPage.bounds.minX = Math.min(currentPage.bounds.minX, cardX);
|
||||
currentPage.bounds.minY = Math.min(currentPage.bounds.minY, cardY);
|
||||
currentPage.bounds.maxX = Math.max(currentPage.bounds.maxX, cardX + cardWidth);
|
||||
currentPage.bounds.maxY = Math.max(currentPage.bounds.maxY, cardY + cardHeight);
|
||||
}
|
||||
|
||||
if (currentPage.cards.length > 0) {
|
||||
result.push(currentPage);
|
||||
}
|
||||
|
||||
return result.map(page => ({
|
||||
...page,
|
||||
frameBounds: {
|
||||
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)
|
||||
}
|
||||
}));
|
||||
return result.map(page => {
|
||||
const offsetX = doubleSided() && page.pageIndex % 2 === 0 ? frontOddPageOffsetX() : 0;
|
||||
const offsetY = doubleSided() && page.pageIndex % 2 === 0 ? frontOddPageOffsetY() : 0;
|
||||
|
||||
return {
|
||||
...page,
|
||||
frameBounds: {
|
||||
minX: baseOffsetX + offsetX,
|
||||
minY: baseOffsetY + offsetY,
|
||||
maxX: baseOffsetX + maxGridWidth + offsetX,
|
||||
maxY: baseOffsetY + maxGridHeight + offsetY
|
||||
}
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
const cropMarks = createMemo<CropMarkData[]>(() => {
|
||||
|
||||
Reference in New Issue
Block a user