2026-10-20 TUE UTC 12:42 PM TPE 8:42 PM 每小時自動更新 中文 EN
LIVE 快訊
← 返回網站更新紀錄 Site Changelog

提交原始紀錄

改善手機 LIVE 快訊跑馬燈速度與字型 (#65) 依文字寬度控制手機跑馬燈為約 24 px/s,改用繁中系統字型並支援減少動態效果。

SHA
7ab6038e6fb68cefbf3d4c0703c568a4d61dab12
提交時間
作者
nnneeeooo-nnneeeooo
提交者
web-flow

變更檔案 (4)

  • static/app.js modified · +18 / −0
  • static/site.css modified · +21 / −1
  • templates/base.html modified · +1 / −1
  • tests/test_mobile_layout.py modified · +7 / −0

完整差異

@@ -77,6 +77,24 @@\n     });\n   }\n \n+  /* — LIVE ticker: keep a readable speed even as headline length changes — */\n+  var marqueeTrack = document.querySelector(".marquee-track");\n+  function setMarqueeDuration() {\n+    if (!marqueeTrack) return;\n+    var tickerPass = marqueeTrack.querySelector(".ticker-pass");\n+    if (!tickerPass) return;\n+    var pixelsPerSecond = window.matchMedia("(max-width: 720px)").matches ? 24 : 52;\n+    var seconds = Math.max(20, tickerPass.scrollWidth / pixelsPerSecond);\n+    marqueeTrack.style.setProperty("--ticker-duration", seconds.toFixed(1) + "s");\n+  }\n+  if (marqueeTrack) {\n+    setMarqueeDuration();\n+    if (document.fonts && document.fonts.ready) {\n+      document.fonts.ready.then(setMarqueeDuration);\n+    }\n+    window.addEventListener("resize", setMarqueeDuration);\n+  }\n+\n   /* — home: category filter over feed rows ([data-cat]) — */\n   var catBtns = Array.prototype.slice.call(document.querySelectorAll("[data-filter-cat]"));\n   catBtns.forEach(function (b) {\n@@ -35,6 +35,7 @@ a:hover { color: var(--color-accent-600); }\n      ↗ mark + hover color (owner: clickable-looking but NO underline);\n      the track pauses on hover so items can actually be clicked. — */\n .marquee-track:hover { animation-play-state: paused; }\n+.ticker-pass { padding-right: 70px; font-size: 13px; white-space: nowrap; }\n .ticker-item { color: inherit; text-decoration: none; }\n a.ticker-item:hover { color: var(--color-accent); }\n a.ticker-item:hover .ticker-time { color: var(--color-accent); }\n@@ -56,7 +57,10 @@ a.ticker-item:hover .ticker-time { color: var(--color-accent); }\n   box-shadow: 0 0 32px rgba(0, 0, 0, .08);\n }\n .pulse-dot { width: 8px; height: 8px; background: var(--color-accent); animation: avwire-pulse 2s infinite; }\n-.marquee-track { display: flex; width: max-content; animation: avwire-marquee 80s linear infinite; white-space: nowrap; }\n+.marquee-track {\n+  display: flex; width: max-content; white-space: nowrap;\n+  animation: avwire-marquee var(--ticker-duration, 80s) linear infinite;\n+}\n \n /* — Google-style search, deliberately the first row of every page — */\n .header-search-row {\n@@ -492,6 +496,22 @@ a.flash-row:hover { color: inherit; }\n   }\n   .nav-link.active { border-color: var(--color-accent); }\n   .ticker-label { padding: 7px 10px; font-size: 11px; letter-spacing: .08em; }\n+  .marquee-track { --ticker-duration: 180s; }\n+  .ticker-pass {\n+    font-family: -apple-system, BlinkMacSystemFont, "PingFang TC", "Noto Sans TC", sans-serif;\n+    font-size: 14px; font-weight: 500; line-height: 1.5; letter-spacing: .01em;\n+    -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;\n+  }\n+  .ticker-time {\n+    font-family: "SFMono-Regular", ui-monospace, "Roboto Mono", Consolas, monospace;\n+    font-size: 12px; font-weight: 700; letter-spacing: 0; font-variant-numeric: tabular-nums;\n+  }\n+}\n+\n+@media (prefers-reduced-motion: reduce) {\n+  .ticker-window { overflow-x: auto; }\n+  .marquee-track { animation: none; transform: none; }\n+  .marquee-track .ticker-pass:nth-child(2) { display: none; }\n }\n \n @media (max-width: 640px) {\n@@ -88,7 +88,7 @@\n     <div class="ticker-window">\n       <div class="marquee-track">\n         {% for pass in range(2) %}\n-        <span style="padding-right:70px;font-size:13px;white-space:nowrap;">\n+        <span class="ticker-pass">\n           {%- for it in ticker_items -%}\n           {%- if it.url -%}\n           <a class="ticker-item" href="{{ it.url }}"{% if it.external %} target="_blank" rel="noopener"{% endif %}><b class="ticker-time{% if it.hot %} hot{% endif %}">{{ it.time }}</b>&#8195;{{ it.text }}<span class="ticker-go">↗</span></a>\n@@ -25,6 +25,7 @@ def main() -> None:\n     assert 'class="site-nav" id="site-nav"' in home\n     assert 'class="utility-row"' in home\n     assert 'class="ticker-window"' in home\n+    assert 'class="ticker-pass"' in home\n     assert 'class="feed-copy"' in home\n     assert 'class="article-page"' in article\n     assert 'class="article-source-row"' in article\n@@ -34,9 +35,15 @@ def main() -> None:\n     assert "grid-template-columns: repeat(2, minmax(0, 1fr))" in css\n     assert ".center-col { order: 1;" in css\n     assert ".feed-copy { grid-column: 1 / -1; }" in css\n+    assert "--ticker-duration: 180s" in css\n+    assert '"PingFang TC"' in css\n+    assert "@media (prefers-reduced-motion: reduce)" in css\n+    assert ".marquee-track .ticker-pass:nth-child(2) { display: none; }" in css\n     assert 'setAttribute("aria-expanded"' in script\n     assert 'event.key === "Escape"' in script\n     assert 'matchMedia("(min-width: 721px)")' in script\n+    assert 'matches ? 24 : 52' in script\n+    assert 'style.setProperty("--ticker-duration"' in script\n \n     print("test_mobile_layout: OK")\n 

你發現了隱藏主題!

8-bit 主題已解鎖。重新整理後,就能在主題選單選擇 8-bit。