/** * 直聊的滚轮分配:指针在哪张卡片上,就先滚那张卡片的正文; * 卡片到顶 / 到底后,这一格滚轮剩下的距离交给外面的大滚动条。 * 只算数,不碰 DOM,方便单测。 */ function clamp(value, min, max) { return Math.min(max, Math.max(min, value)); } /** * @param {object} input * @param {number} [input.cardScrollTop] 卡片正文当前滚动位置 * @param {number} [input.cardScrollMax] 卡片正文最多还能滚多少(0 = 不可滚) * @param {number} [input.deltaY] 这一格滚轮的距离,向下为正 * @param {number} [input.streamScrollTop] 大滚动条当前位置 * @param {number} [input.streamScrollMax] 大滚动条最多还能滚多少 * @returns {{ cardDelta: number, streamDelta: number, rest: number }} * `cardDelta` / `streamDelta` 是各自实际该滚的距离,`rest` 是两边都到头后没用掉的距离。 */ export function planWheelScroll({ cardScrollTop = 0, cardScrollMax = 0, deltaY = 0, streamScrollTop = 0, streamScrollMax = 0, } = {}) { const plan = { cardDelta: 0, streamDelta: 0, rest: 0 }; let rest = Number(deltaY) || 0; if (!rest) return plan; if (cardScrollMax > 0) { const next = clamp(cardScrollTop + rest, 0, cardScrollMax); const applied = next - cardScrollTop; if (applied) { plan.cardDelta = applied; rest -= applied; } } if (rest && streamScrollMax > 0) { const next = clamp(streamScrollTop + rest, 0, streamScrollMax); const applied = next - streamScrollTop; if (applied) { plan.streamDelta = applied; rest -= applied; } } plan.rest = rest; return plan; }