v26110480 踢屏幕统一静止 25~35 秒一次;精彩分享 4~6 篇也出点赞头像(4~6 个随机),白底头像换深色
This commit is contained in:
File diff suppressed because one or more lines are too long
42
js/bump.js
42
js/bump.js
@@ -83,9 +83,10 @@
|
||||
/* ---------- 孕周 → 阶段 ---------- */
|
||||
const STAGES = {
|
||||
// drum:原地带节奏连踢的概率;chain:踢完不歇、旁边紧接着再踢的概率,最多连 chainMax 下(2026-10-04 用户:「有时会带点节奏、可以连续踢」)
|
||||
flutter: { order: ['flick', 'flick', 'tap', 'flick'], gap: [10, 18], kick: false, again: 0, double: .45, follow: false, drum: 0, chain: 0 },
|
||||
active: { order: ORDER, gap: [14, 25], kick: true, again: .34, double: 0, follow: true, drum: .4, chain: .3, chainMax: 3 },
|
||||
late: { order: ['roll', 'butt', 'foot', 'roll', 'knee'], gap: [14, 25], kick: false, again: .15, double: 0, follow: true, slow: true, drum: .22, chain: .15, chainMax: 2 }
|
||||
// 11-05 起间隔统一 25~35 秒(gap() 读 GAP,这里各阶段的 gap 只作记录)
|
||||
flutter: { order: ['flick', 'flick', 'tap', 'flick'], gap: [25, 35], kick: false, again: 0, double: .45, follow: false, drum: 0, chain: 0 },
|
||||
active: { order: ORDER, gap: [25, 35], kick: true, again: .34, double: 0, follow: true, drum: .4, chain: .3, chainMax: 3 },
|
||||
late: { order: ['roll', 'butt', 'foot', 'roll', 'knee'], gap: [25, 35], kick: false, again: .15, double: 0, follow: true, slow: true, drum: .22, chain: .15, chainMax: 2 }
|
||||
};
|
||||
// 原地连踢的节奏型(每拍间隔,秒):匀速「哒哒哒」、「哒哒—哒」、「哒—哒哒」、两下一组
|
||||
const RHYTHMS = [[.42, .42, .42], [.3, .3, .75, .3], [.6, .28, .28], [.32, .9, .32], [.38, .38, .38, .38]];
|
||||
@@ -94,7 +95,12 @@
|
||||
const stageOf = w => w == null || w < 20 ? null : w < 26 ? STAGES.flutter : w < 34 ? STAGES.active : STAGES.late;
|
||||
let stage = stageOf(week);
|
||||
// 两次之间隔多久:20~22 周最稀(再 +40%),越往后越接近本阶段的基准
|
||||
const gap = () => { const g = stage ? stage.gap : [6, 10], m = week != null && week < 23 ? 1.4 : 1; return (g[0] + Math.random() * (g[1] - g[0])) * m; };
|
||||
/* 11-05 用户:「用户来到首页静止不动,至少停 25 秒、25~35 秒之间随机才踢一次,所有孕周都这样」→ 各阶段统一 25~35 秒,不再按阶段 / 20~22 周加长;
|
||||
而且要「一直没动」:点屏幕、滑动都会把倒计时重新从 25~35 秒数起(见 restart() 调用处),回到首页、开关打开也从头数 */
|
||||
const GAP = [25, 35];
|
||||
const gap = () => GAP[0] + Math.random() * (GAP[1] - GAP[0]);
|
||||
let lastInput = -1e9; /* 最近一次真正的手指 / 滚轮操作(图片加载、布局变化引起的 scroll 不算用户动了) */
|
||||
const restart = () => { if (mode === 'wait') wait = gap(); };
|
||||
addEventListener('mb-preg', e => {
|
||||
if (dbgWeek) return;
|
||||
week = e.detail ? e.detail.week : null; stage = stageOf(week);
|
||||
@@ -313,7 +319,7 @@
|
||||
}
|
||||
|
||||
scr.addEventListener('pointerdown', e => {
|
||||
lastTouch = performance.now();
|
||||
lastTouch = lastInput = performance.now(); restart();
|
||||
if (isOff() || (mode !== 'show' && !(mode === 'hide' && ft.h.v > 3)) || !ft.catchable) return;
|
||||
const p = toContent(e.clientX, e.clientY), fx = ft.x + ft.ox, fy = ft.y + ft.oy;
|
||||
// 只认鼓包中心那一圈;点在边上照常走原来的点击
|
||||
@@ -329,7 +335,9 @@
|
||||
window.addEventListener('click', e => {
|
||||
if (performance.now() < blockUntil) { blockUntil = 0; e.preventDefault(); e.stopImmediatePropagation(); }
|
||||
}, true);
|
||||
scr.addEventListener('scroll', () => { lastTouch = performance.now(); run(); }, { passive: true });
|
||||
/* 手指松开后的惯性滑动(3 秒内)也算在动;上面模块高度变化引起的滚动校正(浏览器 scroll anchoring)不算,否则停在页面中间时一直数不到 */
|
||||
scr.addEventListener('scroll', () => { const t = performance.now(); if (t - lastInput < 3000) { lastTouch = t; restart(); } run(); }, { passive: true });
|
||||
['touchstart', 'wheel'].forEach(t => scr.addEventListener(t, () => { lastInput = performance.now(); restart(); }, { passive: true }));
|
||||
|
||||
/* ---------- 物理 ---------- */
|
||||
function step(dt) {
|
||||
@@ -381,8 +389,8 @@
|
||||
else if (still < .4 && (still += dt) >= .4) {
|
||||
const fy = ft.y + ft.oy - top, seen = fy > 30 && fy < scr.clientHeight - 30;
|
||||
if (!seen && stage && stage.follow) {
|
||||
if (mode === 'show' || mode === 'hide') { ft.h.v = 0; ft.h.vel = 0; mode = 'wait'; release(); }
|
||||
if (mode === 'wait') wait = Math.min(wait, 1 + Math.random() * .6);
|
||||
if (mode === 'show' || mode === 'hide') { ft.h.v = 0; ft.h.vel = 0; mode = 'wait'; release(); wait = gap(); ft.chainNext = false; } /* 11-05 正踢着被滑走:重新等 25~35 秒 */
|
||||
/* 11-05 起不再把等待缩到 1 秒多(要静止 25~35 秒才踢),只把宝宝挪到这一屏 */
|
||||
}
|
||||
}
|
||||
spring(ft.h, dt); if (ft.h.v < 0) { ft.h.v = 0; ft.h.vel *= -.2; }
|
||||
@@ -495,9 +503,12 @@
|
||||
/* ---------- 循环:有东西在动才跑 rAF,静止时只用定时器数「下一次什么时候顶」 ---------- */
|
||||
let running = false, last = 0, painted = false;
|
||||
function frame(now) {
|
||||
const dt = Math.min((now - last) / 1000, 1 / 20); last = now;
|
||||
const wall = Math.min((now - last) / 1000, 1), dt = Math.min(wall, 1 / 20); last = now;
|
||||
/* 物理按 dt 封顶防跳帧;等待倒计时按真实时间补齐(掉帧 / 省电模式下 rAF 慢,按封顶的 dt 数会数成一倍长) */
|
||||
if (mode === 'wait' && active() && idle() && wall > dt) wait -= wall - dt;
|
||||
if (!active()) {
|
||||
if (mode !== 'wait') { mode = 'wait'; wait = 2; }
|
||||
if (mode !== 'wait') mode = 'wait';
|
||||
wait = gap(); /* 不在首页时一直重置:回到首页后从头数 25~35 秒 */
|
||||
ft.h.v = ft.h.vel = 0; pk.d.v = pk.d.vel = 0; pk.held = false; jg.x.v = jg.y.v = jg.x.vel = jg.y.vel = 0;
|
||||
}
|
||||
const n = Math.max(1, Math.round(dt * 120));
|
||||
@@ -515,18 +526,21 @@
|
||||
let tickT = 0;
|
||||
function tick() {
|
||||
clearTimeout(tickT);
|
||||
const t0 = performance.now();
|
||||
tickT = setTimeout(() => {
|
||||
if (running) return;
|
||||
if (active() && idle() && mode === 'wait') { wait -= .25; if (wait <= 0) { appear(); if (running) return; } }
|
||||
const el = Math.min((performance.now() - t0) / 1000, 1); /* 按真实经过的时间减(定时器会拖慢,按 .25 数会越数越长) */
|
||||
if (!active()) { if (mode === 'wait') wait = gap(); } /* 11-05 不在首页 / 切后台:回来从头数 25~35 秒 */
|
||||
else if (idle() && mode === 'wait') { wait -= el; if (wait <= 0) { appear(); if (running) return; } }
|
||||
tick();
|
||||
}, 250);
|
||||
}
|
||||
// 开关切换(「隐私权限」里那一行)
|
||||
addEventListener('mb-bump', () => {
|
||||
if (isOff()) { mode = 'wait'; ft.h.v = pk.d.v = 0; release(); cx.clearRect(0, 0, cv.width, cv.height); }
|
||||
else { wait = 1.2; tick(); }
|
||||
else { wait = gap(); tick(); }
|
||||
});
|
||||
// 调试 / 截图用:URL 带 bumpdebug 才挂
|
||||
if (/bumpdebug/.test(location.href)) window.__bump = { ft, pk, atoms: () => atoms.map(a => [a.el.className || a.el.tagName, Math.round(a.x), Math.round(a.y), a.el.style.transform.slice(0, 90)]), mode: () => mode, now: () => { wait = 0; lastTouch = 0; }, week: () => week, at: (k, x, y) => { lastTouch = 0; appear(k, { x, y: y + scr.scrollTop }); } };
|
||||
wait = 3; tick();
|
||||
if (/bumpdebug/.test(location.href)) window.__bump = { ft, pk, atoms: () => atoms.map(a => [a.el.className || a.el.tagName, Math.round(a.x), Math.round(a.y), a.el.style.transform.slice(0, 90)]), mode: () => mode, w: () => [Math.round(wait * 10) / 10, Math.round(performance.now() - lastTouch), active(), running], now: () => { wait = 0; lastTouch = 0; }, week: () => week, at: (k, x, y) => { lastTouch = 0; appear(k, { x, y: y + scr.scrollTop }); } };
|
||||
wait = gap(); tick();
|
||||
})();
|
||||
|
||||
@@ -244,5 +244,5 @@
|
||||
}
|
||||
/* feed.js 首页默认不加载(index.html 只引了 topics.js),这里按需拉一次 */
|
||||
if (window.GC_FEED) init();
|
||||
else { var fs = document.createElement('script'); fs.src = 'guangchang/feed.js?v=26110479'; fs.onload = fs.onerror = init; document.body.appendChild(fs); }
|
||||
else { var fs = document.createElement('script'); fs.src = 'guangchang/feed.js?v=26110480'; fs.onload = fs.onerror = init; document.body.appendChild(fs); }
|
||||
})();
|
||||
|
||||
@@ -95,7 +95,7 @@
|
||||
/* 11-04 用户:一行放下 作者头像 + 名字 + 点赞头像(仅前 3 条)+ N 点赞;不要小心心、不换行;同日再改:名字后面的孕周删掉 */
|
||||
var n = x.likes || 0,
|
||||
au = x.author ? '<span class="g6-au"><img src="' + esc(x.avatar || (window.MB_AVA && MB_AVA.S.author[x.id] ? MB_AVA.src(MB_AVA.S.author[x.id], '') : auAv(x.author))) + '" alt="" loading="lazy" decoding="async" width="36" height="36"><b>' + esc(x.author) + '</b></span>' : '',
|
||||
heat = '<span class="g6-meta g6-sw"><span class="g6-rt">' + (i < 3 ? avs(i) : '') + '<span class="ms-h"><b>' + (n >= 1e4 ? Math.round(n / 1e3) / 10 + '万' : n) + ' 人点赞</b></span></span>' + au + '</span>'; /* 11-05 用户:两边对调 → 点赞头像 + N 人点赞在左,作者头像 + 名字在右 */ /* 11-04 用户:作者在左;访客头像 + 点赞数一起靠最右(点赞数在头像右边) */
|
||||
heat = '<span class="g6-meta g6-sw"><span class="g6-rt">' + avs(i) + '<span class="ms-h"><b>' + (n >= 1e4 ? Math.round(n / 1e3) / 10 + '万' : n) + ' 人点赞</b></span></span>' + au + '</span>'; /* 11-05 用户:两边对调 → 点赞头像 + N 人点赞在左,作者头像 + 名字在右 */ /* 11-04 用户:作者在左;访客头像 + 点赞数一起靠最右(点赞数在头像右边) */
|
||||
var q = new URLSearchParams(location.search); q.set('n', x.id);
|
||||
return '<a class="ms-it ripple g6-nt" href="' + esc('guangchang/?' + q.toString() + location.hash) + '"><i class="ms-no">' + (i + 1) + '</i>' +
|
||||
'<span class="ms-m"><span class="ms-q">' + esc(x.title) + '</span>' + heat + '</span>' +
|
||||
@@ -133,7 +133,8 @@
|
||||
function lkSrc(n) { return /:|^\//.test(n) && window.MB_AVA ? MB_AVA.src(n, '') : 'assets/img/mom/' + n + '.jpg'; }
|
||||
function avaEl(n) { return '<img src="' + lkSrc(n) + '" alt="" loading="lazy" decoding="async" width="40" height="40">'; }
|
||||
/* 11-03 用户:「头像错落一下,不一定都是 3 个,3、4、5、6 个都有」→ 每行个数打乱(固定表,刷新不跳),头像按顺序不重复取 */
|
||||
var AV_N = [5, 6, 6]; /* 11-05 用户:「大家都在关注」第二篇头像 4 → 6 */ /* 11-04 三改:作者 + 孕周 + 点赞头像要挤一行,6~8 个放不下 → 4~6 个 */ /* 11-04 二改:只前 3 条带头像,每条 6~8 个、头像缩小 */
|
||||
/* 11-05 用户:第 4、5、6 篇前面也出点赞头像,每篇随机 4~6 个(每次打开随机);头像池 likers 扩到 36 个,6 篇最多 35 个不重复 */
|
||||
var AV_N = [5, 6, 6].concat([0, 0, 0].map(function () { return 4 + Math.floor(Math.random() * 3); })); /* 11-05 用户:「大家都在关注」第二篇头像 4 → 6 */ /* 11-04 三改:作者 + 孕周 + 点赞头像要挤一行,6~8 个放不下 → 4~6 个 */ /* 11-04 二改:只前 3 条带头像,每条 6~8 个、头像缩小 */
|
||||
function avs(i) {
|
||||
var h = '', c = AV_N[i] || 3;
|
||||
if (!i) avaAt = 0;
|
||||
@@ -156,7 +157,7 @@
|
||||
likeT.forEach(clearTimeout); likeT = [];
|
||||
(function loop() {
|
||||
likeT[0] = setTimeout(function () {
|
||||
var rs = list.querySelectorAll('.g6-nt'), i = Math.floor(Math.random() * Math.min(3, rs.length));
|
||||
var rs = list.querySelectorAll('.g6-nt'), i = Math.floor(Math.random() * rs.length); /* 11-05 起 6 篇都有头像,6 篇里随机挑一篇换 */
|
||||
if (rs[i] && !document.hidden && list.offsetParent) swapOne(rs[i]);
|
||||
loop();
|
||||
}, 3000 + Math.random() * 6000);
|
||||
|
||||
Reference in New Issue
Block a user