Component({ properties: { spread: { type: Object, value: null }, cards: { type: Array, value: [] }, revealedCount: { type: Number, value: 0 }, cardWidth: { type: Number, value: 160 } // 安全默认值 160 }, data: { displayList: [] // 统一渲染列表 (merged with layout info) }, lifetimes: { attached() { this.updateLayout(); } }, observers: { 'spread, cards, cardWidth': function (spread, cards, cardWidth) { this.updateLayout(); } }, methods: { updateLayout() { const { spread, cards, cardWidth } = this.data; if (!spread || !spread.layout || !cards || cards.length === 0) return; const layoutType = spread.layout.type; // 1. Grid 处理 (简单网格布局,不涉及复杂计算) if (layoutType === 'grid') { const list = cards.map((c, i) => ({ ...c, _posName: spread.positions[i], _seq: i + 1, _index: i, _style: '' // 无内联样式,交给 grid CSS })); this.setData({ displayList: list }); return; } // 2. Celtic Cross (静止百分比布局 - 600x900rpx 容器适配) if (layoutType === 'celtic') { // 容器: 600rpx x 900rpx // 卡牌: 140rpx x 210rpx // 安全水平间距: 140/600 = 23.3% -> 中心间距需 > 23.3% // 安全垂直间距: 210/900 = 23.3% -> 中心间距需 > 23.3% // 中轴 X: 38% (228rpx) - 左移给右侧列留空间 // 左牌 X: 38% - 25% = 13% (78rpx) - 安全 // 右牌 X: 38% + 25% = 63% (378rpx) - 安全 // 右侧列 X: 85% (510rpx) - 离右牌 22% = 132rpx > 140rpx 略挤,调整到 87% const positions = [ { left: 38, top: 47 }, // 1 现状 { left: 38, top: 47, rotate: 'rotate(90deg)' }, // 2 阻碍 (重叠) { left: 38, top: 73 }, // 3 根基 (47+26=73) { left: 13, top: 47 }, // 4 过去 { left: 38, top: 21 }, // 5 可能性 (47-26=21) { left: 63, top: 47 }, // 6 近期未来 // 右侧列 X: 87%, 纵向间距 ~22% of 900 = 198rpx > 210rpx 略挤 // 调整为 4 张牌均匀分布在 10%-90% 之间 // 间距: (90-10)/3 = 26.7% = 240rpx > 210rpx ✓ { left: 87, top: 15 }, // 7 你的态度 { left: 87, top: 38 }, // 8 外部影响 (15+23=38) { left: 87, top: 61 }, // 9 希望与恐惧 (38+23=61) { left: 87, top: 84 }, // 10 最终结果 (61+23=84) ]; // Merge Layout + Card Data const list = cards.map((c, i) => { const pos = positions[i] || {}; // 直接生成内联样式,移除所有动态计算 const style = `left: ${pos.left}%; top: ${pos.top}%; transform: translate(-50%, -50%) ${pos.rotate || ''};`; return { ...c, _posName: spread.positions[i], _seq: i + 1, _index: i, _style: style }; }); this.setData({ displayList: list }); } }, // 移除多余的 calcCelticLayout 方法,直接在 updateLayout 中处理 handleCardTap(e) { const idx = e.currentTarget.dataset.index; if (idx === undefined) return; if (idx === this.data.revealedCount) { this.triggerEvent('reveal', { index: idx }); } else if (idx < this.data.revealedCount) { this.triggerEvent('viewDetail', { index: idx }); } } } });