huaanglimeng/components/spread-container/spread-container.js

106 lines
4.2 KiB
JavaScript
Raw Normal View History

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 });
}
}
}
});