我使用一個叫 handleAnswerProcess 的函示,去包含會在作答的時候去處理作答相關的工作,但主要三大功能為
if (currentCardState.bottom > timelineElState.top) {
isShowHint.value = true;
handleTimelineContainerExtend(true);
} else {
isShowHint.value = false;
handleTimelineContainerExtend(false);
}
calcTimelineEventCenterLines 函數主要是用於計算時間軸上每個事件(timeline event)的中心線位置,並根據當前拖曳的卡片(clue card)的位置來更新 overOutlineCount 的值。overOutlineCount 邏輯處理流程
示意圖
const calcTimelineEventCenterLines = (timelineEventsElState, currentCardState) => {
let timelineEventCenterLines = timelineEventsElState.map((el) => window.scrollY + el.top + el.height / 2);
overOutlineCount.value = timelineEventCenterLines.reduce((acc, cur) => {
if (currentCardState.bottom > cur) {
return acc + 1;
}
return acc;
}, 0);
};
if (gameStatus.currentStep === 1) {
if (currentCardState.bottom > timelineEventsElState[0].bottom) {
hintPostionTop.value = `${hintDefaultTop + overOutlineCount.value * (timelineEventHeight + timelineEventMarginTop) + hintHeight + timelineEventMarginTop}px`;
} else {
hintPostionTop.value = `${hintDefaultTop}px`;
}
}
if (gameStatus.currentStep === 2) {
//計算每張 timelineEvent 的中心線,如果超過就移動 hint
calcTimelineEventsCurrentStyles(hintHeight, timelineEventMarginTop);
hintPostionTop.value = `${hintDefaultTop + overOutlineCount.value * (timelineEventHeight + timelineEventMarginTop)}px`;
}
if (gameStatus.currentStep === 3) {
//計算每張 timelineEvent 的中心線,如果超過就移動 hint
hintDefaultTop = -40;
calcTimelineEventsCurrentStyles(hintHeight, timelineEventMarginTop);
if (overOutlineCount.value === 0) {
hintPostionTop.value = `${hintDefaultTop}px`;
} else {
hintPostionTop.value = `${hintDefaultTop + overOutlineCount.value * (timelineEventHeight + timelineEventMarginTop)}px`;
}
}
if (gameStatus.currentStep > 3) {
hintDefaultTop = -40;
calcTimelineEventsCurrentStyles(hintHeight, timelineEventMarginTop);
if (overOutlineCount.value === 0) {
hintPostionTop.value = `${hintDefaultTop}px`;
} else {
hintPostionTop.value = `${
hintDefaultTop + (1 * (hintHeight + timelineEventHeight + timelineEventMarginTop)) / 2 + (overOutlineCount.value - 1) * (timelineEventHeight / 2 + timelineEventMarginTop)
}px`;
}
}
const calcTimelineEventsCurrentStyles = (hintHeight, timelineEventMarginTop) => {
timelineEventsStyleRaw.value.forEach((element, index) => {
if (index < overOutlineCount.value) {
timelineEventsStyleRaw.value[index].transform = `translate(-50%, ${currentTimelinePosition.value[index]?.y - (hintHeight + timelineEventMarginTop)}px)`;
} else {
timelineEventsStyleRaw.value[index].transform = `translate(-50%, ${currentTimelinePosition.value[index]?.y}px)`;
}
});
};
//因為手機長度的限制,當每一個卡片放進作答位置的時候,會更新卡片的排版
currentTimelinePosition
const handleClueCardTouchOff = async (cardIndex, ev) => {
// 略
if (isShowHint.value) {
handleUpdateTimelinePosition(gameStatus.currentStep);
} else {
//略
}
handleTimelineContainerExtend(false);
document.removeEventListener('touchmove', handleClueCardMove);
};
抓取每一個步驟預設的排版
const handleUpdateTimelinePosition = (currentStep) => {
// 更新 timelineEvents 的位置
const updateTimelineEventsPosition = (currentStep, timelineEvents, timelinePositions) => {
for (let i = 0; i < currentStep; i++) {
timelineEvents[i].transform = `translate(-50%, ${timelinePositions[i]?.y}px)`;
}
};
currentTimelinePosition.value = clueDefaultPosition[gameStatus.currentStep - 1];
//略
};
預設遊戲每一個步驟的排版資料,基本上 x 軸都是在中間位置,只有 y 軸有不同高度
[
[
{
"x": "-50%",
"y": 150
}
],
[
{
"x": "50%",
"y": 150
},
{
"x": "50%",
"y": 260
}
],
[
{
"x": "50%",
"y": 40
},
{
"x": "50%",
"y": 150
},
{
"x": "50%",
"y": 260
}
],
[
{
"x": "50%",
"y": 40
},
{
"x": "50%",
"y": 100
},
{
"x": "50%",
"y": 160
},
{
"x": "50%",
"y": 220
},
{
"x": "50%",
"y": 280
},
{
"x": "50%",
"y": 340
},
{
"x": "50%",
"y": 400
},
{
"x": "50%",
"y": 460
},
{
"x": "50%",
"y": 520
}
],
[
{
"x": "50%",
"y": 40
},
{
"x": "50%",
"y": 100
},
{
"x": "50%",
"y": 160
},
{
"x": "50%",
"y": 220
},
{
"x": "50%",
"y": 280
},
{
"x": "50%",
"y": 340
},
{
"x": "50%",
"y": 400
},
{
"x": "50%",
"y": 460
},
{
"x": "50%",
"y": 520
}
],
[
{
"x": "50%",
"y": 40
},
{
"x": "50%",
"y": 100
},
{
"x": "50%",
"y": 160
},
{
"x": "50%",
"y": 220
},
{
"x": "50%",
"y": 280
},
{
"x": "50%",
"y": 340
},
{
"x": "50%",
"y": 400
},
{
"x": "50%",
"y": 460
},
{
"x": "50%",
"y": 520
}
],
[
{
"x": "50%",
"y": 40
},
{
"x": "50%",
"y": 100
},
{
"x": "50%",
"y": 160
},
{
"x": "50%",
"y": 220
},
{
"x": "50%",
"y": 280
},
{
"x": "50%",
"y": 340
},
{
"x": "50%",
"y": 400
},
{
"x": "50%",
"y": 460
},
{
"x": "50%",
"y": 520
}
],
[
{
"x": "50%",
"y": 40
},
{
"x": "50%",
"y": 100
},
{
"x": "50%",
"y": 160
},
{
"x": "50%",
"y": 220
},
{
"x": "50%",
"y": 280
},
{
"x": "50%",
"y": 340
},
{
"x": "50%",
"y": 400
},
{
"x": "50%",
"y": 460
},
{
"x": "50%",
"y": 520
}
]
]