/* ============================================================ 维特尔液冷 — 动效系统 1) 全站热路径:滚动驱动的流体脉冲,芯片 → 园区 2) 工程验证仪表台:六种测试图形,进入视口时绘制一次 零依赖 · prefers-reduced-motion 降级 · 移动端关闭重型背景动效 ============================================================ */ (function () { "use strict"; var REDUCED = window.matchMedia("(prefers-reduced-motion: reduce)").matches; var HOT = [255, 77, 74], COLD = [77, 163, 255], TEAL = [62, 207, 178]; function rgba(c, a) { return "rgba(" + c[0] + "," + c[1] + "," + c[2] + "," + a + ")"; } function lerpC(a, b, p) { return [Math.round(a[0] + (b[0] - a[0]) * p), Math.round(a[1] + (b[1] - a[1]) * p), Math.round(a[2] + (b[2] - a[2]) * p)]; } /* ================= 全站热路径 ================= */ (function () { var rail = document.getElementById("tpath"); var pulse = document.getElementById("tpathPulse"); if (!rail || !pulse) return; var stations = [].slice.call(rail.querySelectorAll(".tpath-st")); var docH = 0, ticking = false; function layout() { docH = document.documentElement.scrollHeight; rail.style.height = docH + "px"; stations.forEach(function (s) { var el = document.querySelector(s.dataset.target); if (!el) return; var y = el.getBoundingClientRect().top + window.scrollY + 120; s.style.top = y + "px"; s.dataset.y = y; }); update(); } function update() { ticking = false; var y = window.scrollY + window.innerHeight * 0.42; y = Math.max(140, Math.min(docH - 220, y)); var p = y / docH; if (!REDUCED) { pulse.style.transform = "translateY(" + (y - 48) + "px)"; /* 语义变色:芯片端偏热 → 中段冷却液蓝 → 园区端设施青 */ var c = p < 0.22 ? lerpC(HOT, COLD, p / 0.22) : p < 0.72 ? COLD : lerpC(COLD, TEAL, (p - 0.72) / 0.28); pulse.style.background = "linear-gradient(180deg, transparent, " + rgba(c, 0.85) + ", transparent)"; pulse.style.boxShadow = "0 0 12px " + rgba(c, 0.4); } stations.forEach(function (s) { s.classList.toggle("on", y >= parseFloat(s.dataset.y || "1e9")); }); } window.addEventListener("scroll", function () { if (!ticking) { ticking = true; requestAnimationFrame(update); } }, { passive: true }); new ResizeObserver(function () { layout(); }).observe(document.body); window.addEventListener("load", layout); layout(); })(); /* ================= 工程验证仪表台 ================= */ (function () { var vizzes = [].slice.call(document.querySelectorAll(".proof-viz")); if (!vizzes.length) return; function mulberry(seed) { return function () { seed |= 0; seed = (seed + 0x6D2B79F5) | 0; var z = Math.imul(seed ^ (seed >>> 15), 1 | seed); z = (z + Math.imul(z ^ (z >>> 7), 61 | z)) ^ z; return ((z ^ (z >>> 14)) >>> 0) / 4294967296; }; } var LN = function (a) { return "rgba(206,226,255," + a + ")"; }; var MONO = "500 8px ui-monospace, 'SF Mono', Menlo, monospace"; function axis(c, w, h) { c.strokeStyle = LN(0.14); c.lineWidth = 1; c.beginPath(); c.moveTo(0, h - 8.5); c.lineTo(w, h - 8.5); c.stroke(); c.strokeStyle = LN(0.1); for (var i = 1; i < 6; i++) { var x = (w / 6) * i; c.beginPath(); c.moveTo(x, h - 8.5); c.lineTo(x, h - 4.5); c.stroke(); } } /* 热循环:高低温往复波形,红顶蓝底 */ function vCycle(c, w, h, p) { axis(c, w, h); var grad = c.createLinearGradient(0, 6, 0, h - 12); grad.addColorStop(0, rgba(HOT, 0.55)); grad.addColorStop(1, rgba(COLD, 0.55)); c.strokeStyle = grad; c.lineWidth = 1.2; c.beginPath(); var N = Math.floor(w * p); for (var x = 0; x <= N; x++) { var ph = (x / w) * 5.5 * Math.PI * 2; var tri = Math.asin(Math.sin(ph)) / (Math.PI / 2); /* 三角波 */ var y = h / 2 - 9 - tri * (h / 2 - 16); x === 0 ? c.moveTo(x, y) : c.lineTo(x, y); } c.stroke(); } /* 保压:升压至 1.5×,平台保持;上方虚线为限值 */ function vHold(c, w, h, p) { axis(c, w, h); c.save(); c.setLineDash([3, 4]); c.strokeStyle = LN(0.2); c.lineWidth = 1; c.beginPath(); c.moveTo(0, 10.5); c.lineTo(w, 10.5); c.stroke(); c.restore(); c.fillStyle = LN(0.25); c.font = MONO; c.fillText("1.5×", w - 24, 8); var plateau = 16, riseEnd = 0.32; c.strokeStyle = rgba(COLD, 0.6); c.lineWidth = 1.2; c.beginPath(); var N = Math.floor(w * p); for (var x = 0; x <= N; x++) { var q = x / w; var y = q < riseEnd ? (h - 12) - (1 - Math.pow(1 - q / riseEnd, 2)) * (h - 12 - plateau) : plateau; x === 0 ? c.moveTo(x, y) : c.lineTo(x, y); } c.stroke(); if (p >= 1) { c.fillStyle = rgba(COLD, 0.08); c.fillRect(w * riseEnd, plateau, w * (1 - riseEnd), h - 8 - plateau); } } /* 氦检:对数刻度尺,游标锁定 10⁻⁶ */ function vLeak(c, w, h, p) { var y0 = h - 8.5; c.strokeStyle = LN(0.14); c.lineWidth = 1; c.beginPath(); c.moveTo(0, y0); c.lineTo(w, y0); c.stroke(); c.font = MONO; var exps = ["3", "4", "5", "6", "7"]; exps.forEach(function (e2, i2) { var x = 10 + (i2 / 4) * (w - 20); c.strokeStyle = LN(0.2); c.beginPath(); c.moveTo(x, y0); c.lineTo(x, y0 - 5); c.stroke(); c.fillStyle = LN(e2 === "6" ? 0.45 : 0.22); c.fillText("10⁻" + ["³", "⁴", "⁵", "⁶", "⁷"][i2], x - 8, y0 - 9); }); var xT = 10 + (3 / 4) * (w - 20); /* 10⁻⁶ 位置 */ var e = 1 - Math.pow(1 - Math.min(p / 0.8, 1), 3); var x = 10 + e * (xT - 10); var flick = p > 0.8 && p < 0.96 ? (Math.floor(p * 60) % 2 === 0 ? 0.4 : 1) : 1; c.globalAlpha = flick; c.fillStyle = rgba([111, 212, 255], 0.85); c.beginPath(); c.moveTo(x, y0 - 26); c.lineTo(x - 4, y0 - 33); c.lineTo(x + 4, y0 - 33); c.closePath(); c.fill(); c.strokeStyle = rgba([111, 212, 255], 0.5); c.lineWidth = 1; c.beginPath(); c.moveTo(x, y0 - 26); c.lineTo(x, y0); c.stroke(); c.globalAlpha = 1; if (p >= 0.96) { c.fillStyle = rgba([111, 212, 255], 0.7); c.font = MONO; c.fillText("LOCK", xT + 8, y0 - 28); } } /* 满载老化:噪声收敛至稳态 */ function vBurnin(c, w, h, p) { axis(c, w, h); var setpoint = h / 2 - 2; c.save(); c.setLineDash([3, 4]); c.strokeStyle = LN(0.16); c.beginPath(); c.moveTo(0, setpoint); c.lineTo(w, setpoint); c.stroke(); c.restore(); var rnd = mulberry(7); c.strokeStyle = rgba(HOT, 0.5); c.lineWidth = 1.1; c.beginPath(); var N = Math.floor(w * p); for (var x = 0; x <= N; x++) { var damp = Math.exp(-x / (w * 0.28)); var y = setpoint + (rnd() - 0.5) * 34 * damp - damp * 12; x === 0 ? c.moveTo(x, y) : c.lineTo(x, y); } c.stroke(); } /* 出厂检测:扫描线扫过设备编号 */ function vScan(c, w, h, p) { var rnd = mulberry(3), serials = []; for (var i2 = 0; i2 < 8; i2++) { serials.push("VT-" + (2600 + Math.floor(rnd() * 380))); } c.font = MONO; var scanX = p * (w + 30) - 15; serials.forEach(function (s2, i3) { var col = i3 % 4, row = Math.floor(i3 / 4); var x = 4 + col * (w / 4), y = 16 + row * 20; var passed = x + 20 < scanX; c.fillStyle = LN(passed ? 0.55 : 0.2); c.fillText(s2, x, y); if (passed) { c.strokeStyle = rgba(TEAL, 0.5); c.lineWidth = 1; c.beginPath(); c.moveTo(x, y + 4.5); c.lineTo(x + 34, y + 4.5); c.stroke(); } }); if (p < 1) { var g = c.createLinearGradient(scanX - 14, 0, scanX + 14, 0); g.addColorStop(0, "rgba(111,212,255,0)"); g.addColorStop(0.5, "rgba(111,212,255,0.14)"); g.addColorStop(1, "rgba(111,212,255,0)"); c.fillStyle = g; c.fillRect(scanX - 14, 0, 28, h); c.strokeStyle = rgba([111, 212, 255], 0.5); c.lineWidth = 1; c.beginPath(); c.moveTo(scanX, 0); c.lineTo(scanX, h); c.stroke(); } } /* SPC 控制图:UCL/LCL 虚线,点位依次落入 */ function vSpc(c, w, h, p) { var ucl = 10.5, lcl = h - 14.5, cl = (ucl + lcl) / 2; c.save(); c.setLineDash([3, 4]); c.strokeStyle = LN(0.2); c.lineWidth = 1; [ucl, lcl].forEach(function (y) { c.beginPath(); c.moveTo(0, y); c.lineTo(w, y); c.stroke(); }); c.restore(); c.strokeStyle = LN(0.12); c.beginPath(); c.moveTo(0, cl); c.lineTo(w, cl); c.stroke(); c.fillStyle = LN(0.25); c.font = MONO; c.fillText("UCL", w - 22, ucl - 3); c.fillText("LCL", w - 22, lcl + 9); var rnd = mulberry(11), pts = []; for (var i2 = 0; i2 < 12; i2++) { pts.push([14 + (i2 / 11) * (w - 50), cl + (rnd() - 0.5) * (lcl - ucl) * 0.55]); } var N = Math.floor(p * 12); c.strokeStyle = LN(0.3); c.lineWidth = 1; c.beginPath(); for (var j = 0; j < N; j++) { j === 0 ? c.moveTo(pts[j][0], pts[j][1]) : c.lineTo(pts[j][0], pts[j][1]); } c.stroke(); for (var m2 = 0; m2 < N; m2++) { c.beginPath(); c.arc(pts[m2][0], pts[m2][1], 1.6, 0, Math.PI * 2); c.fillStyle = LN(0.55); c.fill(); } if (p >= 1) { var lp = pts[11]; c.strokeStyle = rgba(TEAL, 0.6); c.beginPath(); c.arc(lp[0], lp[1], 4, 0, Math.PI * 2); c.stroke(); } } var DRAW = { cycle: vCycle, hold: vHold, leak: vLeak, burnin: vBurnin, scan: vScan, spc: vSpc }; var DUR = { cycle: 2.0, hold: 2.2, leak: 1.8, burnin: 2.0, scan: 2.2, spc: 2.0 }; function fit(cv) { var r = cv.getBoundingClientRect(); /* 小型仪表图无需按 2x 全量绘制,1.25x 已足够锐利且显著降低峰值开销。 */ var dpr = Math.min(window.devicePixelRatio || 1, 1.25); cv.width = Math.max(1, Math.round(r.width * dpr)); cv.height = Math.max(1, Math.round(r.height * dpr)); var c = cv.getContext("2d"); c.setTransform(dpr, 0, 0, dpr, 0, 0); return [c, r.width, r.height]; } function run(cv) { var kind = cv.dataset.viz; var draw = DRAW[kind]; if (!draw) return; var f = fit(cv), c = f[0], w = f[1], h = f[2]; if (REDUCED) { draw(c, w, h, 1); cv.dataset.done = "1"; return; } var t0 = performance.now(), dur = DUR[kind] * 1000; /* 氦检:锁定时数值闪一下 */ var valEl = kind === "leak" ? cv.parentElement.querySelector(".proof-val") : null; var flicked = false; (function frame(now) { var p = Math.min((now - t0) / dur, 1); c.clearRect(0, 0, w, h); draw(c, w, h, p); if (valEl && !flicked && p > 0.8) { flicked = true; valEl.classList.add("locking"); setTimeout(function () { valEl.classList.remove("locking"); }, 1100); } if (p < 1) requestAnimationFrame(frame); else cv.dataset.done = "1"; })(t0); } if (REDUCED) { /* 降级:不依赖 IO,直接绘制终态静帧 */ window.addEventListener("load", function () { vizzes.forEach(function (cv) { run(cv); }); }); vizzes.forEach(function (cv) { run(cv); }); } else { var io = new IntersectionObserver(function (entries) { entries.forEach(function (en) { if (en.isIntersecting && !en.target.dataset.done && !en.target.dataset.running) { en.target.dataset.running = "1"; run(en.target); io.unobserve(en.target); } }); }, { threshold: 0.45 }); vizzes.forEach(function (cv) { io.observe(cv); }); } /* 完成后的静态帧随尺寸重绘 */ var rt = null; window.addEventListener("resize", function () { clearTimeout(rt); rt = setTimeout(function () { vizzes.forEach(function (cv) { if (cv.dataset.done) { var f = fit(cv); DRAW[cv.dataset.viz](f[0], f[1], f[2], 1); } }); }, 200); }); })(); })();