From fdb684e96f6eecd825720cfea3ff4cba7946e26e Mon Sep 17 00:00:00 2001 From: Kibi Kelburton Date: Wed, 16 Sep 2026 05:50:50 +0200 Subject: [PATCH] gfdsgfds --- public/s/css/f0ckm.css | 35 ++++++-- public/s/js/f0ckm.js | 180 +++++++++++++++++++++++++++++++++-------- 2 files changed, 176 insertions(+), 39 deletions(-) diff --git a/public/s/css/f0ckm.css b/public/s/css/f0ckm.css index 2b72ec5..7e8f122 100644 --- a/public/s/css/f0ckm.css +++ b/public/s/css/f0ckm.css @@ -14,6 +14,7 @@ --gray: #262626; --accent: #9f0; --accent-rgb: 153, 255, 0; + --sidebar-w: 300px; --emoji-fav-color: #f5c518; --nav-bg: #2b2b2b; --nav-brand-border: inset 1px #242424; @@ -10388,19 +10389,43 @@ div.favs div.posts { top: 0; left: 0; bottom: 0; - right: 0; - width: 100%; + width: calc(100vw - var(--sidebar-w, 300px)); height: 100%; transform: translate3d(0, 0, 0) scale(var(--bg-canvas-zoom, 1.12)); transform-origin: center center; z-index: -2; - transition: opacity 1.5s cubic-bezier(0.4, 0, 0.2, 1); + transition: opacity 1.5s cubic-bezier(0.4, 0, 0.2, 1), width 0.3s ease-in-out; opacity: var(--bg-canvas-opacity, 1.0); filter: var(--bg-canvas-filter, none); -webkit-filter: var(--bg-canvas-filter, none); background-color: var(--bg-canvas-color, transparent); } +body.sidebar-right-hidden, +body:not(:has(.global-sidebar-right)):not(:has(.item-sidebar-right)):not(:has(.index-sidebar-right)) { + --sidebar-w: 0px !important; +} + +body.sidebar-right-hidden #bg, +body:not(:has(.global-sidebar-right)):not(:has(.item-sidebar-right)):not(:has(.index-sidebar-right)) #bg { + width: 100vw !important; +} + +@media (min-width: 600px) and (max-width: 999px) { + :root { + --sidebar-w: min(280px, 80vw); + } +} + +@media (max-width: 599px) { + :root { + --sidebar-w: 0px !important; + } + #bg { + width: 100vw !important; + } +} + button#togglebg { display: inline; cursor: pointer; @@ -20863,7 +20888,7 @@ body.onara-modal-open #bg.fader-out, body.onara-modal-open #bg.fast-fade { z-index: 51 !important; cursor: pointer !important; - transition: none !important; + transition: width 0.3s ease-in-out !important; animation: none !important; opacity: var(--bg-canvas-opacity, 1.0) !important; } @@ -20916,7 +20941,7 @@ body.onara-modal-open .admin-bar.open { top: var(--navbar-h, 50px) !important; bottom: 0 !important; left: 0 !important; - right: 300px !important; + right: var(--sidebar-w, 300px) !important; width: auto !important; height: calc(100vh - var(--navbar-h, 50px)) !important; z-index: 10050 !important; diff --git a/public/s/js/f0ckm.js b/public/s/js/f0ckm.js index bf10e6f..11e1c89 100644 --- a/public/s/js/f0ckm.js +++ b/public/s/js/f0ckm.js @@ -2628,6 +2628,38 @@ window.cancelAnimFrame = (function () { initialCanvas.classList.add('fader-out'); initialCanvas.classList.remove('fader-in'); } + + // Live-sync #bg canvas backing store dimensions and redraw when free space changes (sidebar toggle, resize, etc.) + if (window.ResizeObserver) { + let _bgResizeTimer = null; + let _lastBgW = 0; + let _lastBgH = 0; + const _bgObserver = new ResizeObserver((entries) => { + const entry = entries && entries[0]; + const cr = entry ? entry.contentRect : initialCanvas.getBoundingClientRect(); + const curW = Math.round(cr.width); + const curH = Math.round(cr.height); + if (Math.abs(curW - _lastBgW) <= 2 && Math.abs(curH - _lastBgH) <= 2) return; + _lastBgW = curW; + _lastBgH = curH; + + if (_bgResizeTimer) clearTimeout(_bgResizeTimer); + _bgResizeTimer = setTimeout(() => { + if (typeof window.redrawBgCanvas === 'function') { + window.redrawBgCanvas(); + } else if (typeof window.initBackground === 'function') { + window.initBackground(); + } + }, 50); + }); + _bgObserver.observe(initialCanvas); + } else { + window.addEventListener('resize', () => { + if (typeof window.redrawBgCanvas === 'function') { + window.redrawBgCanvas(); + } + }, { passive: true }); + } } @@ -4137,6 +4169,10 @@ window.cancelAnimFrame = (function () { canvas._bgFadingOut = false; canvas.classList.add('fader-in'); canvas.classList.remove('fader-out', 'fast-fade'); + if (document.body.classList.contains('onara-modal-open')) { + canvas.style.transition = 'none'; + canvas.style.opacity = 'var(--bg-canvas-opacity, 1.0)'; + } } else { // Don't clear the canvas here — let the existing content fade out. canvas._bgFadingOut = true; @@ -4153,8 +4189,17 @@ window.cancelAnimFrame = (function () { } const SCALE = 0.5; - const cw = Math.max(1, (canvas.clientWidth * SCALE) | 0); - const ch = Math.max(1, (canvas.clientHeight * SCALE) | 0); + const syncCanvasDimensions = () => { + const curCw = Math.max(1, (canvas.clientWidth * SCALE) | 0); + const curCh = Math.max(1, (canvas.clientHeight * SCALE) | 0); + if (canvas.width !== curCw || canvas.height !== curCh) { + canvas.width = curCw; + canvas.height = curCh; + } + return { w: canvas.width, h: canvas.height }; + }; + + const { w: cw, h: ch } = syncCanvasDimensions(); // Capture previous canvas snapshot for buttery-smooth crossfade transition let prevSnapshot = null; @@ -4170,11 +4215,6 @@ window.cancelAnimFrame = (function () { } } - if (canvas.width !== cw || canvas.height !== ch) { - canvas.width = cw; - canvas.height = ch; - } - const context = canvas.getContext('2d'); const cfgCurrent = window.audioVisualizerTuning || DEFAULT_AUDIO_TUNING; const blurSetting = cfgCurrent.bgCanvasBlur !== undefined ? Number(cfgCurrent.bgCanvasBlur) : 30; @@ -4200,6 +4240,8 @@ window.cancelAnimFrame = (function () { const drawCoverImage = (ctx, source) => { if (!source) return; + const targetCw = (ctx && ctx.canvas) ? ctx.canvas.width : canvas.width; + const targetCh = (ctx && ctx.canvas) ? ctx.canvas.height : canvas.height; let sw = 0, sh = 0; if (source.videoWidth && source.videoHeight) { sw = source.videoWidth; @@ -4216,14 +4258,14 @@ window.cancelAnimFrame = (function () { } if (sw > 0 && sh > 0) { - const scale = Math.max(cw / sw, ch / sh); + const scale = Math.max(targetCw / sw, targetCh / sh); const dw = sw * scale; const dh = sh * scale; - const dx = (cw - dw) / 2; - const dy = (ch - dh) / 2; + const dx = (targetCw - dw) / 2; + const dy = (targetCh - dh) / 2; ctx.drawImage(source, dx, dy, dw, dh); } else { - ctx.drawImage(source, 0, 0, cw, ch); + ctx.drawImage(source, 0, 0, targetCw, targetCh); } }; @@ -4242,13 +4284,17 @@ window.cancelAnimFrame = (function () { let crossfadeRafId = null; const crossfadeToSource = (sourceImg, onComplete) => { if (crossfadeRafId) window.cancelAnimFrame(crossfadeRafId); - if (!prevSnapshot) { - context.clearRect(0, 0, cw, ch); + syncCanvasDimensions(); + const targetW = canvas.width; + const targetH = canvas.height; + const isOnara = document.body.classList.contains('onara-modal-open') || (typeof isOnaraActive === 'function' && isOnaraActive()); + if (!prevSnapshot || isOnara) { + context.clearRect(0, 0, targetW, targetH); context.save(); context.filter = getCanvasFilter(); drawCoverImage(context, sourceImg); context.restore(); - applyBgColorOverlay(context, cw, ch); + applyBgColorOverlay(context, targetW, targetH); if (onComplete) onComplete(); return; } @@ -4261,13 +4307,16 @@ window.cancelAnimFrame = (function () { const progress = Math.min(1.0, elapsed / duration); const ease = progress < 0.5 ? 2 * progress * progress : -1 + (4 - 2 * progress) * progress; - context.clearRect(0, 0, cw, ch); + syncCanvasDimensions(); + const w = canvas.width; + const h = canvas.height; + context.clearRect(0, 0, w, h); // 1. Fade out previous background if (ease < 1.0 && prevSnapshot) { context.save(); context.globalAlpha = 1.0 - ease; - context.drawImage(prevSnapshot, 0, 0, cw, ch); + context.drawImage(prevSnapshot, 0, 0, w, h); context.restore(); } @@ -4281,7 +4330,7 @@ window.cancelAnimFrame = (function () { context.restore(); // 3. Color overlay tint if configured - applyBgColorOverlay(context, cw, ch); + applyBgColorOverlay(context, w, h); if (progress < 1.0) { crossfadeRafId = window.requestAnimFrame(step); @@ -4296,10 +4345,23 @@ window.cancelAnimFrame = (function () { const drawOnce = () => { if (!background || !context) return; + syncCanvasDimensions(); const itemId = window.getCurrentItemId(); const isDrawable = elem && elem.tagName === 'IMG'; if (itemId) { + if (document.body.classList.contains('onara-modal-open')) { + const onaraThumbImg = document.querySelector('.posts > a.thumb.onara-active img, .posts > a.thumb:focus img'); + if (onaraThumbImg && onaraThumbImg.complete && onaraThumbImg.naturalWidth > 0) { + crossfadeToSource(onaraThumbImg, () => { + if (isDrawable && elem.complete && elem.naturalWidth > 0) { + crossfadeToSource(elem); + } + }); + return; + } + } + const thumb = new Image(); thumb.onload = () => { crossfadeToSource(thumb, () => { @@ -4341,8 +4403,12 @@ window.cancelAnimFrame = (function () { return; } try { - context.clearRect(0, 0, cw, ch); - if (prevSnapshot) { + syncCanvasDimensions(); + const curCw = canvas.width; + const curCh = canvas.height; + context.clearRect(0, 0, curCw, curCh); + const isOnara = document.body.classList.contains('onara-modal-open') || (typeof isOnaraActive === 'function' && isOnaraActive()); + if (prevSnapshot && !isOnara) { const elapsed = performance.now() - videoFadeStartTime; const progress = Math.min(1.0, elapsed / 350); const ease = progress < 0.5 ? 2 * progress * progress : -1 + (4 - 2 * progress) * progress; @@ -4350,7 +4416,7 @@ window.cancelAnimFrame = (function () { if (ease < 1.0) { context.save(); context.globalAlpha = 1.0 - ease; - context.drawImage(prevSnapshot, 0, 0, cw, ch); + context.drawImage(prevSnapshot, 0, 0, curCw, curCh); context.restore(); } @@ -4366,7 +4432,7 @@ window.cancelAnimFrame = (function () { prevSnapshot = null; } } else { - // Video already loaded or resumed from pause: render directly at 100% opacity without fading from black + // Video already loaded or resumed from pause (or instant in Onara): render directly at 100% opacity without fading from black context.save(); context.filter = getCanvasFilter(); try { @@ -4376,7 +4442,7 @@ window.cancelAnimFrame = (function () { } // Color overlay tint if configured - applyBgColorOverlay(context, cw, ch); + applyBgColorOverlay(context, curCw, curCh); } catch (e) { bgRafId = null; return; @@ -4439,8 +4505,8 @@ window.cancelAnimFrame = (function () { if (bgRafId) window.cancelAnimFrame(bgRafId); animationLoop(); } - // For album videos that haven't started yet, drawOnce with the thumbnail - else if (isAlbumVideo) { + // For album videos that haven't started yet, or Onara videos pending play, drawOnce with the thumbnail + else if (isAlbumVideo || document.body.classList.contains('onara-modal-open')) { drawOnce(); } } @@ -8622,11 +8688,8 @@ window.cancelAnimFrame = (function () { const srcH = innerEyeCanvas.height; const bgScale = cfg.bgCanvasScale !== undefined ? Number(cfg.bgCanvasScale) : 3; - // Measure the sidebar so we center within the content area, not the full viewport - const sidebar = document.querySelector('.global-sidebar-right'); - const sidebarW = (sidebar && !document.body.classList.contains('sidebar-right-hidden')) - ? (sidebar.offsetWidth || 0) * SCALE : 0; - const contentW = bw - sidebarW; + // #bg canvas is already positioned to the free space respecting the sidebar + const contentW = bw; const fitScale = Math.min(contentW / srcW, bh / srcH); const dw = srcW * fitScale * bgScale; @@ -9213,6 +9276,9 @@ window.cancelAnimFrame = (function () { w.style.removeProperty('padding-right'); w.style.removeProperty('right'); }); + if (typeof window.redrawBgCanvas === 'function') { + window.redrawBgCanvas(); + } }); }; mq.addEventListener('change', applyBreakpoint); @@ -10310,12 +10376,20 @@ window.cancelAnimFrame = (function () { document.querySelectorAll('video:not(#gchat-messages video), audio:not(#gchat-messages audio)').forEach(el => { try { el.pause(); } catch {} }); } - // Fade out background canvas for smooth transition + // Fade out background canvas for smooth transition (non-Onara only) const canvas = document.getElementById('bg'); if (canvas) { - canvas.classList.add('fast-fade'); - canvas.classList.remove('fader-in'); - canvas.classList.add('fader-out'); + if (useOnara) { + canvas._bgFadingOut = false; + canvas.classList.remove('fader-out', 'fast-fade'); + canvas.classList.add('fader-in'); + canvas.style.transition = 'none'; + canvas.style.opacity = 'var(--bg-canvas-opacity, 1.0)'; + } else { + canvas.classList.add('fast-fade'); + canvas.classList.remove('fader-in'); + canvas.classList.add('fader-out'); + } } } @@ -10622,7 +10696,14 @@ window.cancelAnimFrame = (function () { if (!options.keepMedia) { setupMedia(); const _canvas = document.getElementById('bg'); - if (_canvas) _canvas.classList.remove('fader-out', 'fast-fade'); + if (_canvas) { + _canvas.classList.remove('fader-out', 'fast-fade'); + _canvas.classList.add('fader-in'); + if (useOnara) { + _canvas.style.transition = 'none'; + _canvas.style.opacity = 'var(--bg-canvas-opacity, 1.0)'; + } + } if (window.initBackground) window.initBackground(); if (window.initVisualizer) window.initVisualizer(); } @@ -10891,6 +10972,11 @@ window.cancelAnimFrame = (function () { const canvas = document.getElementById('bg'); if (canvas) { canvas.classList.remove('fader-out', 'fast-fade'); + canvas.classList.add('fader-in'); + if (useOnara) { + canvas.style.transition = 'none'; + canvas.style.opacity = 'var(--bg-canvas-opacity, 1.0)'; + } } if (window.initBackground) window.initBackground(); if (window.initVisualizer) window.initVisualizer(); @@ -11040,6 +11126,10 @@ window.cancelAnimFrame = (function () { if (document.activeElement && document.activeElement !== thumbnail && typeof document.activeElement.blur === 'function') { document.activeElement.blur(); } + openOnaraModal(); + if (typeof window.paintImmediateBgThumb === 'function') { + window.paintImmediateBgThumb(thumbnail); + } } // Thumbnails inherit context (e.g. from Tag Index) loadItemAjax(thumbnail.href, true); @@ -14075,6 +14165,9 @@ window.cancelAnimFrame = (function () { w.style.removeProperty('right'); }); swipeRT.isDraggingSidebar = false; + if (typeof window.redrawBgCanvas === 'function') { + window.redrawBgCanvas(); + } }); }; @@ -14332,6 +14425,9 @@ window.cancelAnimFrame = (function () { w.style.removeProperty('padding-right'); w.style.removeProperty('right'); }); + if (typeof window.redrawBgCanvas === 'function') { + window.redrawBgCanvas(); + } }); }; @@ -14503,6 +14599,14 @@ window.cancelAnimFrame = (function () { onaraModal.style.setProperty('right', targetModalRight, 'important'); } + // Animate #bg canvas width in sync with sidebar so background stays centered + const bgCanvas = document.getElementById('bg'); + if (bgCanvas && animateWrappers) { + const targetBgWidth = isHidden ? `calc(100vw - ${sidebarWidth}px)` : '100vw'; + bgCanvas.style.setProperty('transition', 'width 0.3s ease-in-out', 'important'); + bgCanvas.style.setProperty('width', targetBgWidth, 'important'); + } + sidebar.style.setProperty('transition', 'transform 0.3s ease-in-out', 'important'); sidebar.style.transform = `translateX(${targetTranslate}px)`; @@ -14515,6 +14619,7 @@ window.cancelAnimFrame = (function () { sidebar.style.setProperty('transition', 'none', 'important'); edgeZone.style.setProperty('transition', 'none', 'important'); if (onaraModal) onaraModal.style.setProperty('transition', 'none', 'important'); + if (bgCanvas) bgCanvas.style.setProperty('transition', 'none', 'important'); const toHidden = !isHidden; document.body.classList.toggle('sidebar-right-hidden', toHidden); localStorage.setItem('sidebarRightHidden', toHidden); @@ -14527,11 +14632,18 @@ window.cancelAnimFrame = (function () { onaraModal.style.removeProperty('transition'); onaraModal.style.removeProperty('right'); } + if (bgCanvas) { + bgCanvas.style.removeProperty('transition'); + bgCanvas.style.removeProperty('width'); + } wrappers.forEach(w => { w.style.removeProperty('transition'); w.style.removeProperty('padding-right'); w.style.removeProperty('right'); }); + if (typeof window.redrawBgCanvas === 'function') { + window.redrawBgCanvas(); + } }); };