็†ฑ้–€ๅˆ†้กž
 ่ผ‰ๅ…ฅไธญ…
็›ฎ้Œ„

๐Ÿงผ 3D ๅˆ—ๅฐๆฉŸ็ถญ่ญทๆŒ‡ๅ—:็†ฑ็ซฏ、ๅ™ดๅ˜ด、็šฎๅธถ、่ปธๆ‰ฟ、ๆป‘่ปŒ็š„ไฟ้คŠ้€ฑๆœŸ่ˆ‡ๆŠ€ๅทง

    ๐Ÿงผ 3D ๅˆ—ๅฐๆฉŸ็ถญ่ญทๆŒ‡ๅ—:็†ฑ็ซฏ、ๅ™ดๅ˜ด、็šฎๅธถ、่ปธๆ‰ฟ、ๆป‘่ปŒ็š„ไฟ้คŠ้€ฑๆœŸ่ˆ‡ๆŠ€ๅทง

    ไธ็ฎกๆ˜ฏ Bambu、ELEGOO、Creality ้‚„ๆ˜ฏไปปไฝ• CoreXY/FDM ๅฐ่กจๆฉŸ,ๅช่ฆ็ถญ่ญทๅพ—ๅฅฝ,้ƒฝ่ƒฝไฟๆŒ้ซ˜้€Ÿๅˆ็ฉฉๅฎš。 ๆœฌ็ฏ‡ๆ•ด็† ๅฎŒๆ•ด็ถญ่ญทๆธ…ๅ–ฎ,ๅŒ…ๅซๅ™ดๅ˜ด、็†ฑ็ซฏ、ๆ“ ๅ‡บๆฉŸ、็šฎๅธถ、ๆป‘่ปŒ、่ปธๆ‰ฟ、้ขจๆ‰‡、้›ปๆบ็ญ‰ๆ‰€ๆœ‰ๅฟ…้ ˆไฟ้คŠ็š„้ƒจไปถ。 ้€้Ž้€™็ฏ‡,ไฝ ๅฏไปฅ็›ดๆŽฅๅปบ็ซ‹ๅฑฌๆ–ผ่‡ชๅทฑ็š„「ๅˆ—ๅฐๆฉŸไฟ้คŠ้€ฑๆœŸๅˆถๅบฆ」。

    ๐Ÿ“Œ ไธ€、ๅ™ดๅ˜ด็ถญ่ญท(Nozzle Maintenance)

    ✓ ๅปบ่ญฐ้€ฑๆœŸ:ๆฏ 1~2 kg ่€—ๆ

    • ๆธ…้™ค็ขณๅŒ–ๅก‘ๆ–™
    • ไฝฟ็”จ 0.4 ๆธ…ๆฝ”้‡็–้€šๆฎ˜ๆ–™
    • ๅฟ…่ฆๆ™‚ๅŸท่กŒ Cold Pull(ๅ†ทๆ‹”)
    # Cold Pull ๆญฅ้ฉŸๆ‘˜่ฆ
    1. ๅŠ ็†ฑๅˆฐๆๆ–™ๅˆ—ๅฐๆบซๅบฆ
    2. ๆ”พ็ฝฎ 5 ็ง’ๅพŒ้™ๆบซ่‡ณ 90°C(PLA)
    3. ไธ€ๆฌกๆ‹‰ๅ‡บๆ•ดๆขๆๆ–™
    

    ่‹ฅไฝฟ็”จ็ขณ็บ–(CF)ๆๆ–™:ๅปบ่ญฐๆ”น็”จ Hardened Steel ๅ™ดๅ˜ด。

    ๐Ÿ“Œ ไบŒ、็†ฑ็ซฏ็ถญ่ญท(Hotend)

    ✓ ๅปบ่ญฐ้€ฑๆœŸ:ๆฏ 3~6 kg ่€—ๆ

    • ๆชขๆŸฅ็†ฑๆ–ท(Heatbreak)ๆ˜ฏๅฆ็ฉ็ขณ
    • ๆธ…็†ๅฐŽ็†ฑ่†(้ฉ็”จๆ–ผๅ…จ้‡‘ๅฑฌ็†ฑ็ซฏ)
    • ๆชขๆŸฅๆบซๅบฆๅตๆธฌๅ™จๆ˜ฏๅฆ้ฌ†่„ซ
    • ๆชขๆŸฅๅŠ ็†ฑๆฃ’ๆ˜ฏๅฆๅ›บๅฎš่‰ฏๅฅฝ

    ๐Ÿ“Œ ไธ‰、็šฎๅธถๅผตๅŠ›(Belt Tension)

    ✓ ๅปบ่ญฐ้€ฑๆœŸ:ๆฏ 1 ๅ€‹ๆœˆๆชขๆŸฅไธ€ๆฌก

    ็šฎๅธถๅคช้ฌ† → ๅฑค็งป、้‚Š็ทฃๆŒฏๅ‹• ็šฎๅธถๅคช็ทŠ → ้ฆฌ้”่ฒ ่ผ‰ๅขžๅŠ 、ๅ™ช้Ÿณ่ฎŠๅคง

    • CoreXY ้œ€่ฆไฟๆŒๅทฆๅณ็šฎๅธถๅผตๅŠ›ไธ€่‡ด
    • Ender ้กžๅบŠ็งปๅ‹•ๆฉŸ้œ€ๆชขๆŸฅ Y ่ปธๅผตๅŠ›

    ็พไปฃๆฉŸ(ๅฆ‚ Bambu、Centauri Carbon)ๅฏไฝฟ็”จ่‡ชๅ‹•ๅผตๅŠ›ๆชขๆธฌ。

    ๐Ÿ“Œ ๅ››、ๆป‘่ปŒ、็ทš่ปŒ(Linear Rail)่ˆ‡่ปธๆ‰ฟไฟ้คŠ

    ✓ ๅปบ่ญฐ้€ฑๆœŸ:ๆฏ 2~3 ๅ€‹ๆœˆ

    • ๆธ…ๆฝ”็ฐๅกต(้ฟๅ…ๅฐŽ่‡ดๅกๆปฏ)
    • ่ฃœๅ……ๆฉŸๆขฐ็”จๆฝคๆป‘ๆฒน(ๅฆ‚ Super Lube)
    • ๆชขๆŸฅๆ˜ฏๅฆๆœ‰「ๅก้ปž」、「้˜ปๅŠ›็ชๅขž」

    ็ทš่ปŒๆฏ” V-Slot ๆบ–็ขบ,ไฝ†้œ€่ฆๅฎšๆœŸ็ถญ่ญทๆ‰ๆœƒๆป‘้ †。

    ๐Ÿ“Œ ไบ”、ๆ“ ๅ‡บๆฉŸ(Extruder)ไฟ้คŠ

    ✓ ๅปบ่ญฐ้€ฑๆœŸ:ๆฏ 3~5 kg ่€—ๆ

    • ๆชขๆŸฅ้ฝ’่ผชๆ˜ฏๅฆ็ฃจๆ
    • ๆธ…้™ค้ฝ’่ผชไธŠๅกไฝ็š„ๅก‘ๆ–™็ฒ‰ๅกต
    • ็ขบไฟๅฝˆ็ฐงๅฃ“ๅŠ›ๆญฃๅธธ(็›ด้ฉ…็‰นๅˆฅ้‡่ฆ)

    ๐Ÿ“Œ ๅ…ญ、้ขจๆ‰‡(Fans)ๆธ…ๆฝ”

    ✓ ๅปบ่ญฐ้€ฑๆœŸ:ๆฏ 1~3 ๅ€‹ๆœˆ

    • ๅ†ทๅป้ขจๆ‰‡(Part Cooling Fan)
    • ็†ฑ็ซฏ้ขจๆ‰‡(Hotend Fan)
    • ไธปๆฉŸๆฟ้ขจๆ‰‡(Electronics Fan)

    ่‹ฅ้ขจๆ‰‡่ฝ‰้€Ÿ่ฎŠไฝŽ → ๅฐ‡็›ดๆŽฅๅฐŽ่‡ดๅ™ดๅ˜ด้Ž็†ฑๆˆ–ๅ†ทๅปไธ่ถณ。

    ๐Ÿ“Œ ไธƒ、็†ฑๅบŠๆธ…ๆฝ”(Print Bed Maintenance)

    ✓ ๅปบ่ญฐ้€ฑๆœŸ:ๆฏๆฌก้•ทๅˆ—ๅฐๅ‰ๅพŒ

    • PLA:้…’็ฒพๆธ…ๆฝ”
    • PETG:้ฟๅ…็›ดๆŽฅ้…’็ฒพๆธ…ๆฝ”(ๆœƒ่ฎŠ้ป),ๆ”น็”จ่‚ฅ็š‚ๆฐด
    • ABS/ASA:ๅฏไฝฟ็”จ่† ๆฐดๅฑค้ฟๅ…ๅคชๅผทๅธ้™„

    ๐Ÿ“Œ ๅ…ซ、้›ปๅญ่ˆ‡ๆฉŸๆง‹ๆชขๆŸฅ(ๆฏ 6 ๅ€‹ๆœˆ)

    • ๆชขๆŸฅ้›ปๆบๆŽฅ้ ญๆ˜ฏๅฆ้ฌ†ๅ‹•
    • ๆชขๆŸฅไธปๆฉŸๆฟๆ•ฃ็†ฑ
    • ๆชขๆŸฅ้ขจๆ‰‡ๆ˜ฏๅฆๅก็ฐๅกต
    • ็ขบ่ชๆ‰€ๆœ‰่ฝ‰่ปธๆ˜ฏๅฆๆญฃๅธธ้‹ไฝœ

    ๐Ÿ“Œ ไน、ๅปบ่ญฐไฟ้คŠ้€ฑๆœŸ่กจ(ๅฏๆ”ถ่—)

    ้ƒจไปถๅปบ่ญฐ้€ฑๆœŸ
    ๅ™ดๅ˜ด1–2 kg ่€—ๆ
    ็†ฑ็ซฏ3–6 kg ่€—ๆ
    ็šฎๅธถๅผตๅŠ›1 ๅ€‹ๆœˆ
    ็ทš่ปŒ/่ปธๆ‰ฟ2–3 ๅ€‹ๆœˆ
    ้ขจๆ‰‡1–3 ๅ€‹ๆœˆ
    ็†ฑๅบŠๆธ…ๆฝ”ๆฏๆฌกๅˆ—ๅฐๅ‰ๅพŒ
    ้›ปๅญๆชขๆŸฅ6 ๅ€‹ๆœˆ

    ๐Ÿ“˜ ็ต่ชž

    ็ถญ่ญทๆ˜ฏ่ฎ“ 3D ๅˆ—ๅฐๆฉŸ「่ถŠ็”จ่ถŠ้ †」็š„้—œ้ต。 ๅช่ฆๅปบ็ซ‹ไธ€ๅฅ—ๅ›บๅฎšไฟ้คŠ้€ฑๆœŸ,ไฝ ็š„ๅˆ—ๅฐๆฉŸ่ƒฝ้•ทๆœŸไฟๆŒ้ซ˜้€Ÿ、็ฉฉๅฎš、ไฝŽๅ™ช้Ÿณ่ˆ‡้ซ˜ๅ“่ณช่ผธๅ‡บ。 ๆœฌ็ฏ‡ไนŸ้ฉๅˆๅˆ—ๅฐๅ‡บไพ†่ฒผๅœจไฝ ็š„ๅทฅไฝœๅ€,็•ถไฝœๅ›บๅฎšๅทกๆชข่กจ!


    ๐Ÿ“š 3D ๅˆ—ๅฐ็ณปๅˆ—ๆ–‡็ซ 

    • ๐Ÿงฑ 3D ๅˆ—ๅฐๅฎŒๆ•ดๅ…ฅ้–€ๆŒ‡ๅ—:้‹ไฝœๅŽŸ็†、ๆ‡‰็”จๆƒ…ๅขƒ่ˆ‡่จญๅ‚™้ธ่ณผไธ€ๆฌกๆžๆ‡‚
    • ๐Ÿ–จ️ ๆถˆ่ฒป็ดš 3D ๅˆ—ๅฐๆฉŸ้ธ่ณผๆŒ‡ๅ—:FDM / SLA ๆฏ”่ผƒ、ๆ ธๅฟƒ่ฆๆ ผ่งฃๆž
    • ๐Ÿ“ฆ 3D ๅˆ—ๅฐๆจกๅž‹ไพ†ๆบๅคงๅ…จ:Printables、Thingiverse、MakerWorld、Cults ๅนณๅฐๆฏ”่ผƒ่ˆ‡ไธ‹่ผ‰ๆŠ€ๅทง
    • ⚙️ ELEGOO ่ˆ‡ Bambu Lab ๆฏ”่ผƒ:้€Ÿๅบฆ、็ฒพๅบฆ、AMS、ๅคšๆๆ–™ๅ…จ้ข่งฃๆž
    • ๐Ÿท️ ๅธธ่ฆ‹ๆถˆ่ฒป็ดšๅ“็‰Œๆฏ”่ผƒ:ELEGOO、Creality、Anycubic、Bambu Lab ็š„ๅฎšไฝ่ˆ‡้ธๆ“‡็ญ–็•ฅ
    • ่ถ…้ซ˜้€Ÿ 3D ๅˆ—ๅฐๆฉŸๆฏ”่ผƒ:Centauri Carbon、Bambu P1/P2、K1 Max ๅฎŒๆ•ดๅˆ†ๆž
    • ๐Ÿงต 3D ๅˆ—ๅฐๆๆ–™็™พ็ง‘:PLA、ABS、PETG、TPU、Nylon、CF ็ณปๅˆ—ๅฎŒๆ•ด่งฃๆž
    • ๐Ÿ”ฅ ๅˆ—ๅฐๆบซๅบฆ、้€Ÿๅบฆ่ˆ‡ๅ†ทๅป่จญๅฎšๆŒ‡ๅ—:ๆๅ‡ๆˆๅŠŸ็އ่ˆ‡่กจ้ขๅ“่ณช็š„ๅฎŒๆ•ดๆŠ€่ก“็ญ†่จ˜
    • ๐Ÿ“ 3D ๅˆ—ๅฐๆ กๆญฃๅคงๅ…จ:Flow、EM、Z-Offset、Retraction、ๆบซๅบฆๅก”ๅฎŒๆ•ดๆ•™ๅญธ
    • ๐Ÿ”ง = 1100) { var hoverZone = document.getElementById('sidebar-hover-zone'); var hoverDelay = null; function startHoverOpen() { clearTimeout(hoverDelay); if (!isSidebarOpen()) openSidebar(); } function scheduleHoverClose(){ clearTimeout(hoverDelay); hoverDelay = setTimeout(function(){ if (isSidebarOpen()) closeSidebar(); }, 450); } [fab, hoverZone, sidebar].forEach(function(el) { if (!el) return; el.addEventListener('mouseenter', startHoverOpen); el.addEventListener('mouseleave', scheduleHoverClose); }); } // Restore saved state try { if (localStorage.getItem('wwf_sb2') === '1') { openSidebar(); } else { syncFab(); } } catch(e) { syncFab(); } // Close on outside click (mobile) document.addEventListener('click', function(e) { if (window.innerWidth >= 1100) return; if (!isSidebarOpen()) return; if (sidebar && !sidebar.contains(e.target) && fab && !fab.contains(e.target)) closeSidebar(); }); /* โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 3. READING PROGRESS BAR โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ var progressBar = document.getElementById('reading-progress'); var tocFloatBar = document.getElementById('toc-float-bar'); if (progressBar) { function updateProgress() { var article = document.querySelector('.full-post-body') || document.getElementById('content'); if (!article) return; var rect = article.getBoundingClientRect(); var total = rect.height - window.innerHeight; var scrolled = Math.max(0, -rect.top); var pct = total > 0 ? Math.min(100, (scrolled / total) * 100) : 0; progressBar.style.width = pct + '%'; if (tocFloatBar) tocFloatBar.style.height = pct + '%'; } if (document.body.classList.contains('item') || document.body.classList.contains('item-page')) { window.addEventListener('scroll', updateProgress, { passive: true }); updateProgress(); } } /* โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 4. BACK TO TOP BUTTON โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ var bttBtn = document.getElementById('back-to-top'); if (bttBtn) { window.addEventListener('scroll', function() { bttBtn.classList.toggle('visible', window.scrollY > 400); }, { passive: true }); bttBtn.addEventListener('click', function(e) { e.preventDefault(); window.scrollTo({ top: 0, behavior: 'smooth' }); var m = document.getElementById('content'); if (m) { m.setAttribute('tabindex', '-1'); m.focus({ preventScroll: true }); } }); } /* โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 5. SEARCH OVERLAY โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ var searchOverlay = document.getElementById('search-overlay'); var searchToggle = document.getElementById('search-toggle'); var searchInput = document.getElementById('search-input'); var lastFocusBeforeSearch = null; function openSearch() { if (!searchOverlay) return; lastFocusBeforeSearch = document.activeElement; searchOverlay.classList.add('open'); if (searchInput) setTimeout(function(){ searchInput.focus(); }, 50); } function closeSearch() { if (!searchOverlay) return; searchOverlay.classList.remove('open'); if (lastFocusBeforeSearch) lastFocusBeforeSearch.focus({ preventScroll: true }); } if (searchToggle) searchToggle.addEventListener('click', function(e){ e.preventDefault(); openSearch(); }); if (searchOverlay) searchOverlay.addEventListener('click', function(e){ if (e.target === searchOverlay) closeSearch(); }); // Search focus trap if (searchOverlay) { searchOverlay.addEventListener('keydown', function(e) { if (!searchOverlay.classList.contains('open')) return; var focs = Array.from(searchOverlay.querySelectorAll(FOCUSABLE)); if (!focs.length) return; var first = focs[0], last = focs[focs.length - 1]; if (e.key === 'Tab') { if (e.shiftKey) { if (document.activeElement === first) { e.preventDefault(); last.focus(); } } else { if (document.activeElement === last) { e.preventDefault(); first.focus(); } } } }); } if (searchInput) { searchInput.addEventListener('keydown', function(e) { if (e.key === 'Enter' && this.value.trim()) { var q = encodeURIComponent(this.value.trim()); window.location.href = window.location.protocol + '//' + window.location.hostname + '/search?q=' + q; } }); } // Global keyboard shortcuts document.addEventListener('keydown', function(e) { if (e.key === 'Escape') { closeSearch(); closeLightbox(); } if ((e.ctrlKey || e.metaKey) && e.key === 'k') { e.preventDefault(); openSearch(); } }); /* โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 6. POPULAR STRIP TICKER โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ (function loadTicker() { var tickerEl = document.getElementById('ticker-inner'); if (!tickerEl) return; var origin = window.location.protocol + '//' + window.location.hostname; var feedUrl = origin + '/feeds/posts/summary?alt=json&max-results=20&orderby=published'; window._wwfTicker = function(data) { try { var entries = (data && data.feed && data.feed.entry) ? data.feed.entry : []; if (entries.length === 0) { tickerEl.textContent = ''; return; } var html = ''; var sep = ' โœฆ '; entries.forEach(function(entry) { var title = entry.title ? entry.title.$t : ''; var url = ''; if (entry.link) { for (var j = 0; j < entry.link.length; j++) { if (entry.link[j].rel === 'alternate') { url = entry.link[j].href; break; } } } if (title && url) html += '' + title + '' + sep; }); if (!html) { tickerEl.textContent = ''; return; } tickerEl.innerHTML = html + html; tickerEl.style.opacity = '1'; tickerEl.style.fontStyle = 'normal'; var charLen = entries.length * 20; tickerEl.style.animationDuration = Math.max(22, Math.round(charLen * 0.14)) + 's'; } catch(err) {} delete window._wwfTicker; }; var s = document.createElement('script'); s.async = true; s.src = feedUrl + '&callback=_wwfTicker'; s.onerror = function() { if (tickerEl) tickerEl.textContent = ''; }; document.head.appendChild(s); })(); /* โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 7. LABEL TOOLBAR (Top 10 labels) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ (function buildLabelToolbar() { var pillsEl = document.getElementById('ltb-pills'); if (!pillsEl) return; var activeLabelRaw = ''; var labelMatch = window.location.pathname.match(/\/search\/label\/(.+)/); if (labelMatch) { try { activeLabelRaw = decodeURIComponent(labelMatch[1]); } catch(e) { activeLabelRaw = labelMatch[1]; } } var CACHE_KEY = 'wwf_top_labels_v3'; /* bumped: force cache refresh */ var CACHE_TTL = 6 * 60 * 60 * 1000; /* 6 hours */ function renderPills(labels) { if (!labels || labels.length === 0) { pillsEl.innerHTML = ''; return; } var origin = window.location.protocol + '//' + window.location.hostname; var medals = ['โ‘ ','โ‘ก','โ‘ข','โ‘ฃ','โ‘ค','โ‘ฅ','โ‘ฆ','โ‘ง','โ‘จ','โ‘ฉ']; var html = ''; labels.forEach(function(item, idx) { var labelUrl = origin + '/search/label/' + encodeURIComponent(item.name); var isActive = activeLabelRaw && (activeLabelRaw.toLowerCase() === item.name.toLowerCase()); var rankStr = medals[idx] || (idx + 1) + '.'; html += '' + '' + rankStr + '' + item.name + '' + item.count + '' + ''; }); pillsEl.innerHTML = html; pillsEl.querySelectorAll('.ltb-pill').forEach(function(el, i) { el.style.opacity = '0'; el.style.transform = 'translateY(6px)'; setTimeout(function() { el.style.transition = 'opacity .35s ease, transform .35s ease, background var(--t) var(--ease-smooth), color var(--t) var(--ease-smooth), border-color var(--t) var(--ease-smooth), box-shadow var(--t) var(--ease-smooth), transform .22s var(--ease)'; el.style.opacity = '1'; el.style.transform = 'translateY(0)'; }, i * 60 + 20); }); } try { var cached = JSON.parse(localStorage.getItem(CACHE_KEY) || 'null'); if (cached && cached.ts && (Date.now() - cached.ts < CACHE_TTL) && cached.labels) { renderPills(cached.labels); return; } } catch(e) {} /* Blogger JSON feed: fetch up to 1000 posts in 2 calls to get accurate label counts */ var origin = window.location.protocol + '//' + window.location.hostname; var allCounts = {}; var fetched = 0; var batchSize = 500; function processBatch(data) { try { var entries = (data && data.feed && data.feed.entry) ? data.feed.entry : []; entries.forEach(function(entry) { if (!entry.category) return; entry.category.forEach(function(cat) { var term = cat.term; if (!term) return; allCounts[term] = (allCounts[term] || 0) + 1; }); }); fetched += entries.length; /* If we got a full batch, try fetching next page */ if (entries.length === batchSize && fetched < 1500) { fetchBatch(fetched + 1); } else { finalize(); } } catch(err) { finalize(); } } function finalize() { var sorted = Object.keys(allCounts) .map(function(k) { return { name: k, count: allCounts[k] }; }) .sort(function(a, b) { return b.count - a.count; }) .slice(0, 10); renderPills(sorted); try { localStorage.setItem(CACHE_KEY, JSON.stringify({ ts: Date.now(), labels: sorted })); } catch(e) {} } function fetchBatch(startIdx) { var callbackName = '_wwfLabels' + startIdx; var feedUrl = origin + '/feeds/posts/summary?alt=json&max-results=' + batchSize + '&start-index=' + startIdx + '&fields=entry(category)&callback=' + callbackName; window[callbackName] = function(data) { delete window[callbackName]; processBatch(data); }; var s = document.createElement('script'); s.async = true; s.src = feedUrl; s.onerror = function() { finalize(); }; document.head.appendChild(s); } window._wwfLabels = function(data) { delete window._wwfLabels; processBatch(data); }; var feedUrl = origin + '/feeds/posts/summary?alt=json&max-results=' + batchSize + '&start-index=1&fields=entry(category)'; var s = document.createElement('script'); s.async = true; s.src = feedUrl + '&callback=_wwfLabels'; s.onerror = function() { if (pillsEl) finalize(); }; document.head.appendChild(s); })(); /* โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 8. ESTIMATED READING TIME โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ var readTimeEl = document.getElementById('post-read-time'); var postBody = document.querySelector('.full-post-body'); if (readTimeEl && postBody) { var chars = (postBody.innerText || postBody.textContent || '').replace(/\s/g, '').length; var mins = Math.max(1, Math.round(chars / 500)); readTimeEl.innerHTML = ' ็ด„ ' + mins + ' ๅˆ†้˜'; } /* โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 9. TABLE OF CONTENTS (inline + floating) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ (function buildTOC() { var tocList = document.getElementById('toc-list'); var tocToggle = document.getElementById('toc-toggle'); var tocFloat = document.getElementById('toc-float'); var tocFloatList = document.getElementById('toc-float-list'); var body = document.querySelector('.full-post-body'); if (!body) return; var headings = body.querySelectorAll('h2, h3'); if (headings.length < 2) { var tc = document.getElementById('toc-container'); if (tc) tc.style.display = 'none'; if (tocFloat) tocFloat.style.display = 'none'; return; } var inlineHtml = '', floatHtml = ''; headings.forEach(function(h, idx) { var id = 'toc-heading-' + idx; h.id = id; var lvl = h.tagName.toLowerCase(); var txt = h.textContent.trim(); inlineHtml += '
    • ' + txt + '
    • '; floatHtml += '
    • ' + txt + '
    • '; }); if (tocList) tocList.innerHTML = inlineHtml; if (tocFloatList) tocFloatList.innerHTML = floatHtml; // Inline collapse toggle if (tocToggle && tocList) { tocToggle.addEventListener('click', function() { var collapsed = tocList.classList.toggle('collapsed'); tocToggle.classList.toggle('collapsed', collapsed); tocToggle.setAttribute('aria-expanded', collapsed ? 'false' : 'true'); }); } // Show floating TOC on scroll if (tocFloat) { var titleEl = document.querySelector('.full-post-title'); var lastEl = document.querySelector('.full-post-share'); var floatObs = new IntersectionObserver(function(entries) { entries.forEach(function(entry) { if (!entry.isIntersecting) { tocFloat.classList.add('visible'); } }); }, { threshold: 0 }); if (titleEl) floatObs.observe(titleEl); var hideObs = new IntersectionObserver(function(entries) { entries.forEach(function(entry) { if (entry.isIntersecting) tocFloat.classList.remove('visible'); }); }, { threshold: 0 }); if (lastEl) hideObs.observe(lastEl); } // Active heading observer (both TOCs) function makeActiveObserver(listEl) { if (!listEl) return; var links = listEl.querySelectorAll('a'); var obs = new IntersectionObserver(function(entries) { entries.forEach(function(entry) { if (entry.isIntersecting) { links.forEach(function(a) { a.classList.remove('active'); }); var active = listEl.querySelector('a[href="#' + entry.target.id + '"]'); if (active) active.classList.add('active'); } }); }, { rootMargin: '-20% 0px -75% 0px' }); headings.forEach(function(h) { obs.observe(h); }); // Smooth scroll links.forEach(function(a) { a.addEventListener('click', function(e) { e.preventDefault(); var target = document.getElementById(this.getAttribute('href').slice(1)); if (target) { target.scrollIntoView({ behavior: 'smooth', block: 'start' }); target.focus({ preventScroll: true }); } }); }); } makeActiveObserver(tocList); makeActiveObserver(tocFloatList); })(); /* โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 10. LIGHTBOX with gallery nav โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ var lightbox = document.getElementById('lightbox'); var lightboxImg = document.getElementById('lightbox-img'); var lightboxClose = document.getElementById('lightbox-close'); var lightboxCap = document.getElementById('lightbox-caption'); var lightboxPrev = document.getElementById('lightbox-prev'); var lightboxNext = document.getElementById('lightbox-next'); var lastFocusBeforeLightbox = null; var galleryImgs = []; var galleryIdx = 0; // Collect all post body images if (postBody) { galleryImgs = Array.from(postBody.querySelectorAll('img')); } function openLightbox(src, alt, idx) { if (!lightbox || !lightboxImg) return; lastFocusBeforeLightbox = document.activeElement; lightboxImg.src = src; lightboxImg.alt = alt || ''; if (lightboxCap) lightboxCap.textContent = alt || ''; galleryIdx = (typeof idx === 'number') ? idx : 0; if (lightboxPrev) lightboxPrev.style.display = galleryImgs.length > 1 ? '' : 'none'; if (lightboxNext) lightboxNext.style.display = galleryImgs.length > 1 ? '' : 'none'; lightbox.classList.add('open'); document.body.style.overflow = 'hidden'; if (lightboxClose) lightboxClose.focus(); } function closeLightbox() { if (!lightbox) return; lightbox.classList.remove('open'); document.body.style.overflow = ''; if (lastFocusBeforeLightbox) lastFocusBeforeLightbox.focus({ preventScroll: true }); } window.navLightbox = function navLightbox(dir) { if (!galleryImgs.length) return; galleryIdx = (galleryIdx + dir + galleryImgs.length) % galleryImgs.length; var img = galleryImgs[galleryIdx]; if (lightboxImg) { lightboxImg.style.opacity = '0'; setTimeout(function(){ lightboxImg.src = img.src; lightboxImg.alt = img.alt || ''; lightboxImg.style.opacity = '1'; if (lightboxCap) lightboxCap.textContent = img.alt || ''; }, 150); } }; if (lightboxClose) lightboxClose.addEventListener('click', closeLightbox); if (lightbox) lightbox.addEventListener('click', function(e){ if (e.target === lightbox) closeLightbox(); }); if (lightboxPrev) lightboxPrev.addEventListener('click', function(e){ e.stopPropagation(); navLightbox(-1); }); if (lightboxNext) lightboxNext.addEventListener('click', function(e){ e.stopPropagation(); navLightbox(1); }); // Keyboard inside lightbox if (lightbox) { lightbox.addEventListener('keydown', function(e) { if (!lightbox.classList.contains('open')) return; if (e.key === 'ArrowLeft') { e.preventDefault(); navLightbox(-1); } if (e.key === 'ArrowRight') { e.preventDefault(); navLightbox(1); } if (e.key === 'Escape') closeLightbox(); // Focus trap var focs = Array.from(lightbox.querySelectorAll(FOCUSABLE)); if (!focs.length) return; var first = focs[0], last = focs[focs.length-1]; if (e.key === 'Tab') { if (e.shiftKey) { if (document.activeElement===first){e.preventDefault();last.focus();} } else { if (document.activeElement===last) {e.preventDefault();first.focus();} } } }); } // Attach to images if (postBody) { galleryImgs.forEach(function(img, idx) { img.style.cursor = 'zoom-in'; img.setAttribute('tabindex', '0'); img.setAttribute('role', 'button'); img.setAttribute('aria-label', (img.alt || 'ๅœ–็‰‡') + '๏ผŒ้ปžๆ“Šๆ”พๅคง'); img.addEventListener('click', function() { openLightbox(this.src, this.alt || this.getAttribute('title') || '', idx); }); img.addEventListener('keydown', function(e){ if (e.key === 'Enter' || e.key === ' '){ e.preventDefault(); openLightbox(this.src, this.alt || '', idx); } }); }); } /* โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 11. SCROLL-REVEAL for cards (CSS animation handles initial entrance) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ /* Card entrance animation is now CSS-only via @keyframes cardEnter */ /* โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 12. HERO IMAGE PARALLAX โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ var heroImg = document.getElementById('hero-img'); if (heroImg) { window.addEventListener('scroll', function() { var scrollY = window.scrollY; heroImg.style.transform = 'translateY(' + (scrollY * 0.25) + 'px)'; }, { passive: true }); } /* โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 13. CODE BLOCK ENHANCEMENTS โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ if (postBody) { postBody.querySelectorAll('pre').forEach(function(pre) { var code = pre.querySelector('code'); var cls = ((code ? code.className : pre.className) || '').match(/language-(\w+)/); if (cls) { var langLabel = document.createElement('span'); langLabel.className = 'code-lang-label'; langLabel.setAttribute('aria-hidden', 'true'); langLabel.textContent = cls[1]; pre.appendChild(langLabel); } var copyBtn = document.createElement('button'); copyBtn.className = 'code-copy-btn'; copyBtn.type = 'button'; copyBtn.textContent = '่ค‡่ฃฝ'; copyBtn.setAttribute('aria-label', '่ค‡่ฃฝ็จ‹ๅผ็ขผ'); copyBtn.addEventListener('click', function() { var textToCopy = code ? code.innerText : pre.innerText; navigator.clipboard.writeText(textToCopy || '').then(function() { copyBtn.textContent = 'โœ“ ๅทฒ่ค‡่ฃฝ'; copyBtn.classList.add('copied'); setTimeout(function() { copyBtn.textContent = '่ค‡่ฃฝ'; copyBtn.classList.remove('copied'); }, 2200); }).catch(function() { copyBtn.textContent = 'ๅคฑๆ•—'; setTimeout(function(){ copyBtn.textContent = '่ค‡่ฃฝ'; }, 2000); }); }); pre.appendChild(copyBtn); }); } /* โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 14. HEADING ANCHORS โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ if (postBody) { postBody.querySelectorAll('h2, h3, h4').forEach(function(h) { var id = h.id; if (!id) { id = h.textContent.trim() .toLowerCase() .replace(/\s+/g, '-') .replace(/[^\w\u4e00-\u9fff\-]/g, '') .replace(/^-+|-+$/g, ''); if (id) h.id = id; } if (id) { var a = document.createElement('a'); a.href = '#' + id; a.className = 'heading-anchor'; a.setAttribute('aria-label', '้€ฃ็ต่‡ณๆญคๆฎต่ฝ'); a.innerHTML = ''; h.appendChild(a); } }); } /* โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 15. EXTERNAL LINKS โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ if (postBody) { postBody.querySelectorAll('a[href]').forEach(function(a) { var href = a.getAttribute('href') || ''; if (href.startsWith('http') && !href.includes(window.location.hostname)) { var rel = (a.getAttribute('rel') || ''); if (!rel.includes('noopener')) a.setAttribute('rel', (rel + ' noopener noreferrer').trim()); a.setAttribute('target', '_blank'); if (!a.getAttribute('aria-label')) { var t = a.textContent.trim(); if (t) a.setAttribute('aria-label', t + '๏ผˆๅœจๆ–ฐ่ฆ–็ช—้–‹ๅ•Ÿ๏ผ‰'); } } }); } /* โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 16. LAZY LOADING for non-first images + fade-in โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ if (postBody) { var imgs = postBody.querySelectorAll('img'); var isFirst = true; imgs.forEach(function(img) { if (isFirst) { isFirst = false; img.classList.add('loaded'); return; } if (!img.getAttribute('loading')) img.setAttribute('loading', 'lazy'); if (img.complete) { img.classList.add('loaded'); } else { img.addEventListener('load', function() { this.classList.add('loaded'); }); } }); } /* โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 17. FONT SIZE CONTROLLER โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ (function initFontSizeCtrl() { var SIZES = [14, 15, 15.5, 16, 16.5, 17, 18, 19, 20]; var LS_KEY = 'wwf_font_size_v1'; var DEFAULT_IDX = 4; var curIdx = DEFAULT_IDX; var fscUp = document.getElementById('fsc-up'); var fscDown = document.getElementById('fsc-down'); var fscReset = document.getElementById('fsc-reset'); function applySize(idx) { curIdx = Math.max(0, Math.min(SIZES.length - 1, idx)); var pb = document.querySelector('.full-post-body'); if (pb) pb.style.fontSize = SIZES[curIdx] + 'px'; try { localStorage.setItem(LS_KEY, curIdx); } catch(e) {} if (fscDown) fscDown.disabled = curIdx <= 0; if (fscUp) fscUp.disabled = curIdx >= SIZES.length - 1; } try { var saved = parseInt(localStorage.getItem(LS_KEY), 10); if (!isNaN(saved)) curIdx = saved; } catch(e) {} applySize(curIdx); if (fscUp) fscUp.addEventListener('click', function(){ applySize(curIdx + 1); }); if (fscDown) fscDown.addEventListener('click', function(){ applySize(curIdx - 1); }); if (fscReset) fscReset.addEventListener('click', function(){ applySize(DEFAULT_IDX); }); })(); /* โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 18. COPY URL BUTTON (share row) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ var copyUrlBtn = document.getElementById('copy-url-btn'); if (copyUrlBtn) { copyUrlBtn.addEventListener('click', function() { navigator.clipboard.writeText(window.location.href).then(function() { copyUrlBtn.classList.add('copied'); copyUrlBtn.innerHTML = 'ๅทฒ่ค‡่ฃฝ๏ผ'; setTimeout(function() { copyUrlBtn.classList.remove('copied'); copyUrlBtn.innerHTML = '่ค‡่ฃฝ้€ฃ็ต'; }, 2400); }); }); } /* โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 19. STAGGER CARD ANIMATIONS โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ document.querySelectorAll('.tl-card').forEach(function(el, i) { el.style.setProperty('--i', i); }); /* โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 20. ACTIVE NAV ITEM โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ var curPath = window.location.pathname; document.querySelectorAll('#main-nav a.nav-item').forEach(function(a) { var href = a.getAttribute('href') || ''; try { if (href && curPath === new URL(href, window.location.href).pathname) { a.classList.add('active'); } } catch(e) {} }); if (!document.querySelector('#main-nav a.nav-item.active')) { var first = document.querySelector('#main-nav a.nav-item'); if (first) first.classList.add('active'); } /* โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 21. READING PROGRESS PERCENTAGE โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ var readPctEl = document.getElementById('reading-pct'); if (readPctEl && progressBar) { var scrollTimer = null; window.addEventListener('scroll', function() { document.body.classList.add('is-scrolling'); clearTimeout(scrollTimer); scrollTimer = setTimeout(function() { document.body.classList.remove('is-scrolling'); }, 1200); var w = parseFloat(progressBar.style.width) || 0; readPctEl.textContent = Math.round(w) + '%'; }, { passive: true }); } /* โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 22. LIVE SEARCH PREVIEW โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ (function initLiveSearch() { var input = document.getElementById('search-input'); var container = document.getElementById('search-live-results'); if (!input || !container) return; var cache = null; var debounce = null; var origin = window.location.protocol + '//' + window.location.hostname; function fetchFeed(cb) { if (cache) { cb(cache); return; } var url = origin + '/feeds/posts/summary?alt=json&max-results=500'; var s = document.createElement('script'); var cbName = '_wwfLiveSearch'; window[cbName] = function(data) { delete window[cbName]; var entries = (data && data.feed && data.feed.entry) || []; cache = entries.map(function(e) { var title = e.title ? e.title.$t : ''; var url = ''; if (e.link) { for (var i = 0; i < e.link.length; i++) { if (e.link[i].rel === 'alternate') { url = e.link[i].href; break; } } } var thumb = ''; if (e.media$thumbnail) thumb = e.media$thumbnail.url.replace(/\/s72-c\//, '/s120-c/'); var pub = e.published ? e.published.$t.substring(0, 10) : ''; return { title: title, url: url, thumb: thumb, date: pub }; }); cb(cache); }; s.src = url + '&callback=' + cbName; s.onerror = function() { delete window[cbName]; }; document.head.appendChild(s); } function highlight(text, q) { if (!q) return text; var re = new RegExp('(' + q.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + ')', 'gi'); return text.replace(re, '$1'); } input.addEventListener('input', function() { clearTimeout(debounce); var q = this.value.trim(); if (q.length < 2) { container.innerHTML = ''; container.classList.remove('has-results'); return; } debounce = setTimeout(function() { fetchFeed(function(items) { var ql = q.toLowerCase(); var matches = items.filter(function(it) { return it.title.toLowerCase().indexOf(ql) !== -1; }).slice(0, 6); if (matches.length === 0) { container.innerHTML = '
      ๆ‰พไธๅˆฐ็›ธ้—œๆ–‡็ซ 
      '; container.classList.add('has-results'); return; } var html = ''; matches.forEach(function(m) { html += ''; if (m.thumb) html += ''; html += '
      ' + highlight(m.title, q) + '
      '; if (m.date) html += '
      ' + m.date + '
      '; html += '
      '; }); container.innerHTML = html; container.classList.add('has-results'); }); }, 200); }); /* Clear on close */ var overlay = document.getElementById('search-overlay'); if (overlay) { var obsClose = new MutationObserver(function() { if (!overlay.classList.contains('open')) { container.innerHTML = ''; container.classList.remove('has-results'); } }); obsClose.observe(overlay, { attributes: true, attributeFilter: ['class'] }); } })(); /* โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 23. LIGHTBOX TOUCH SWIPE โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ (function initLightboxSwipe() { var lb = document.getElementById('lightbox'); if (!lb) return; var startX = 0, startY = 0, distX = 0; lb.addEventListener('touchstart', function(e) { if (e.touches.length === 1) { startX = e.touches[0].clientX; startY = e.touches[0].clientY; distX = 0; } }, { passive: true }); lb.addEventListener('touchmove', function(e) { if (e.touches.length === 1) { distX = e.touches[0].clientX - startX; var distY = Math.abs(e.touches[0].clientY - startY); if (Math.abs(distX) > distY && Math.abs(distX) > 30) { e.preventDefault(); } } }, { passive: false }); lb.addEventListener('touchend', function() { if (Math.abs(distX) > 60) { if (typeof navLightbox === 'function') navLightbox(distX > 0 ? -1 : 1); } distX = 0; }, { passive: true }); })(); /* โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 24. TOC KEYBOARD NAVIGATION โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */ (function initTocKeyNav() { var tocList = document.getElementById('toc-list'); if (!tocList) return; tocList.addEventListener('keydown', function(e) { if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp') return; e.preventDefault(); var links = Array.from(tocList.querySelectorAll('a')); if (!links.length) return; var idx = links.indexOf(document.activeElement); if (e.key === 'ArrowDown') idx = Math.min(idx + 1, links.length - 1); else idx = Math.max(idx - 1, 0); links[idx].focus(); }); })(); })(); //]]>