From 8b8ae57b446766d7970b5253d79ed6688fcc9394 Mon Sep 17 00:00:00 2001 From: Til Schmitter Date: Sat, 11 Apr 2026 02:00:08 +0200 Subject: [PATCH] volume slider rework --- copyparty/web/browser.css | 68 ++++++++-------- copyparty/web/browser.js | 161 ++++++++++++++++++++++++++------------ 2 files changed, 144 insertions(+), 85 deletions(-) diff --git a/copyparty/web/browser.css b/copyparty/web/browser.css index 81b71d45..0505c2c9 100644 --- a/copyparty/web/browser.css +++ b/copyparty/web/browser.css @@ -33,15 +33,15 @@ --sel-bg: var(--fg); --a: #fc5; - --a-b: #c90; - --a-hil: #fd9; - --a-dark: #e70; + --a-hil: color-mix(in xyz, var(--a) 70%, var(--fg-max) 30%); + --a-dark: #e70; /* warning text etc */ --a-gray: #666; + accent-color: var(--a); --btn-fg: var(--a); --btn-bg: rgba(128,128,128,0.15); --btn-h-fg: var(--a-hil); - --btn-h-bg: #850; + --btn-h-bg: color-mix(in xyz, var(--a) 30%, var(--bg) 70%); --btn-1-fg: rgb(25, 19, 12); --btn-1-bg: var(--a); --btn-h-bs: var(--btn-bs); @@ -49,7 +49,7 @@ --btn-1-bs: var(--btn-bs); --btn-1-bb: var(--btn-bb); --btn-1h-fg: var(--btn-1-fg); - --btn-1h-bg: #fe8; + --btn-1h-bg: var(--a-hil); --btn-1h-bs: var(--btn-1-bs); --btn-1h-bb: var(--btn-1-bb); --chk-fg: var(--tab-alt); @@ -65,7 +65,7 @@ --u2-txt-bg: var(--bg-u5); --u2-tab-bg: linear-gradient(to bottom, var(--bg), var(--bg-u1)); --u2-tab-b1: rgba(128,128,128,0.8); - --u2-tab-1-fg: #fd7; + --u2-tab-1-fg: var(--a-hil); --u2-tab-1-bg: linear-gradient(to bottom, #353, var(--bg) 80%); --u2-tab-1-b1: #7c5; --u2-tab-1-b2: #583; @@ -81,7 +81,7 @@ --u2-err-b1: #d06; --ud-b1: #888; - --sort-1: #fb0; + --sort-1: var(--a); --sort-2: #d90; --sz-b: #aaa; @@ -166,7 +166,6 @@ html.y { --scroll: #490; --a: #06a; - --a-b: #08b; --a-hil: #058; --a-gray: #bbb; --a-dark: #c0f; @@ -275,8 +274,6 @@ html.bz { --row-alt: #181a27; - --a-b: #fb4; - --btn-bg: #202231; --btn-h-bg: #2d2f45; --btn-1-bg: #eb6; @@ -423,7 +420,6 @@ html.dz { --scroll: #0f0; --a: #9f9; - --a-b: #cfc; --a-hil: #cfc; --a-dark: #afa; --a-gray: #2a2; @@ -487,7 +483,6 @@ html.dy { --scroll: #000; --a: #000; - --a-b: #000; --a-hil: #000; --a-gray: #bbb; --a-dark: #000; @@ -622,7 +617,7 @@ html .ayjump:focus { display: block; margin: 0; /* min-width: 10em; */ - padding: .35em .5em .2em 0; + padding: .35em 0 .2em 0; font-size: 1.4em; } #srch_namev { @@ -1323,6 +1318,7 @@ html.y #widget.open { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; + margin-left: .3em; } #progbar { display: none; @@ -1332,16 +1328,18 @@ html.y #widget.open { } #altprogbar { display: none; - grid-template-columns: max-content auto max-content + grid-template-columns: max-content auto max-content; + max-width: 40vw; + text-align: center; } #altprogbar.vis { display: grid; } -#txtpos, -#txtsongend { +#altprogbar span { font-size: small; color: var(--fg-weak); - margin: .2em; + margin: .3em; + align-self: center; } #sliderpos { width: 100%; @@ -1361,8 +1359,6 @@ html.y #widget.open { box-shadow: -.03em -.03em .7em rgba(0,0,0,0.5) inset; } #pctl { - accent-color: var(--a); - display: grid; grid-template-columns: max-content max-content max-content 20% auto max-content max-content max-content; align-content: center; @@ -1387,15 +1383,20 @@ html.y #widget.open { #pvol { border-radius: 9em; max-width: 9em; - width: 100%; + height: .5em; + aspect-ratio: 8; background: rgba(0,0,0,0.2); } -.vbar { - margin: 0 -.4em; - display: inline-block; - font-weight: bold; - transform: translateY(-.1em); - text-shadow: none; +#pvolbg { + height: 100%; + padding: .3em; + align-content: center; + align-items: center; + display: flex; +} +#pvolbg svg { + height: 1.3em; + margin-right: .3em; } #widget.cmp { height: 1.6em; @@ -1444,7 +1445,7 @@ html.y #widget.open { background: #000; background: var(--op-aa-bg); border-radius: 0 0 .2em .2em; - border-bottom: .3em solid var(--a-b); + border-bottom: .3em solid var(--a); box-shadow: var(--op-aa-sh); margin: -.2em 0 -.6em 0; padding-top: .4em; @@ -1580,7 +1581,6 @@ input.ssconf_v { #audio_drc table, #audio_eq table { border-collapse: collapse; - accent-color: var(--a); } #audio_drc td, #audio_eq td, @@ -1630,7 +1630,7 @@ input.ssconf_v { } #srch_q { white-space: pre; - color: var(--a-b); + color: var(--a); min-height: 1em; margin: .2em 0 -1em 1.6em; } @@ -2500,7 +2500,7 @@ html.y #bbox-overlay figcaption a { #s_content{ display: grid; grid-template-rows: auto auto; - margin: 5%; + margin: 5vh 5vw; border-radius: .5em; border: var(--a) solid 1px; background: var(--bg); @@ -3099,7 +3099,7 @@ html.b #u2conf a.b:hover { } .fsearch_explain { color: var(--a-dark); - padding-left: .7em; + padding: .7em; font-size: 1.1em; line-height: 0; } @@ -3586,7 +3586,6 @@ html.ey { --scroll: var(--silver); --f-sel-sh: transparent; --a: #000; - --a-b: #fff; --a-hil: #fff; --a-h-bg: var(--bg); --a-dark: var(--a); @@ -3687,7 +3686,6 @@ html.ez { --scroll: #555555; --f-sel-sh: transparent; --a: var(--fg); - --a-b: var(--fg); --a-hil: var(--fg); --btn-1h-bg: var(--bg-d3); --a-h-bg: var(--bg); @@ -4449,7 +4447,7 @@ html.e #detree { align-self: center; } #acc_settings{ - background: rgba(0, 0, 0, 0.4); + background: var(--a); position: absolute; align-self: end; right: 0; @@ -4457,7 +4455,7 @@ html.e #detree { font-size: medium; } #acc_settings:hover{ - background: var(--a-hil); + background: var(--btn-h-bg); } .popup.show { diff --git a/copyparty/web/browser.js b/copyparty/web/browser.js index dc884aaa..61514329 100644 --- a/copyparty/web/browser.js +++ b/copyparty/web/browser.js @@ -770,6 +770,7 @@ var svg_prev = svg_box + ''; var svg_play = svg_box + '' var svg_pause = svg_box + '' +var svg_vol = svg_box + '' ebi('widget').innerHTML = ( '
' + @@ -802,19 +803,19 @@ ebi('widget').innerHTML = ( ' ' + svg_prev + '' + ' ' + svg_play + '' + ' ' + svg_next + '' + - ' ' + + ' ' + '
' + ' ' + ' ' + '
' + '
' + - ' 0:00' + + ' 0:00' + ' ' + - ' 0:00' + + ' 0:00' + '
' + ' 🔁' + ' 🔀' + - '
' + + '
' + svg_vol + '
' + '
' + '' + '
' + @@ -1103,7 +1104,7 @@ ebi('op_cfg').innerHTML = ( var s = subSettings.children[ii]; var info = tt.parse(s.getAttribute('tt')); s.removeAttribute('tt'); - s.href = '#' + sId; + //s.href = '#' + sId; section += `
` + s.outerHTML + (info?.length > 0 ? `

${info}

` : '') + @@ -2159,11 +2160,50 @@ function glossy_grad(can, h, s, l) { p = [0, 0.49, 0.50, 1]; for (var a = 0; a < p.length; a++) - g.addColorStop(p[a], 'hsl(' + h + ',' + s[a] + '%,' + l[a] + '%)'); + g.addColorStop(p[a], 'hsl(' + h + ',' + (Array.isArray(s) ? s[a] : s) + '%,' + (Array.isArray(l) ? l[a] : l) + '%)'); return g; } +function hexToRgb(hex){ + var long = hex.length >= 6; + var _r = long ? hex.substr(1,2) : hex.substr(1,1) + var _g = long ? hex.substr(3,2) : hex.substr(2,1) + var _b = long ? hex.substr(5,2) : hex.substr(3,1) + + if(!long){ + _r += _r; + _g += _g; + _b += _b; + } + + return [ + parseInt(_r, 16), + parseInt(_g, 16), + parseInt(_b, 16) + ]; +} +function rgbToHsl(r, g, b){ + r /= 255, g /= 255, b /= 255; + var max = Math.max(r, g, b), min = Math.min(r, g, b); + var h, s, l = (max + min) / 2; + + if(max == min){ + h = s = 0; // achromatic + }else{ + var d = max - min; + s = l > 0.5 ? d / (2 - max - min) : d / (max + min); + h = Math.atan2(Math.sqrt(3) * (g - b), 2 * r - g - b) + switch(max){ + case r: h = (g - b) / d + (g < b ? 6 : 0); break; + case g: h = (b - r) / d + 2; break; + case b: h = (r - g) / d + 4; break; + } + h /= 6; + } + + return [h, s, l]; +} // buffer/position bar var pbar = (function () { @@ -2256,11 +2296,20 @@ var pbar = (function () { dz = themen == 'dz', dy = themen == 'dy'; + var accentRgb = hexToRgb(getComputedStyle(document.body).getPropertyValue('--a')); + var accentHsl = rgbToHsl(accentRgb[0], accentRgb[1], accentRgb[2]); + accentHsl[0] *= 360; + accentHsl[1] *= 100; + accentHsl[2] *= 100; + if (gradh != gk) { gradh = gk; - grad = glossy_grad(bc, dz ? 120 : 85, - dy ? [0, 0, 0, 0] : [35, 40, 37, 35], - dy ? [20, 24, 22, 20] : light ? [45, 56, 50, 45] : [42, 51, 47, 42]); + var l = accentHsl[2] + var lArr = [l*.7, l, l*.9, l*.7] + grad = glossy_grad(bc, + accentHsl[0], + accentHsl[1], + lArr); } bctx.fillStyle = grad; for (var a = 0; a < mp.au.buffered.length; a++) { @@ -2277,20 +2326,22 @@ var pbar = (function () { bctx.globalAlpha = 1; } - var step = sm > 1 ? 1 : sm > 0.4 ? 3 : sm > 0.05 ? 30 : 720; - bctx.fillStyle = light && !dy ? 'rgba(0,64,0,0.15)' : 'rgba(204,255,128,0.15)'; - for (var p = step, mins = adur / 10; p <= mins; p += step) - bctx.fillRect(Math.floor(sm * p * 10), 0, 2, pc.h); + if(false){ + var step = sm > 1 ? 1 : sm > 0.4 ? 3 : sm > 0.05 ? 30 : 720; + bctx.fillStyle = light && !dy ? 'rgba(0,0,0,0.15)' : 'rgba(255, 255, 255, 0.15)'; + for (var p = step, mins = adur / 10; p <= mins; p += step) + bctx.fillRect(Math.floor(sm * p * 10), 0, 2, pc.h); - step = sm > 0.15 ? 1 : sm > 0.05 ? 10 : 360; - bctx.fillStyle = light && !dy ? 'rgba(0,64,0,0.5)' : 'rgba(192,255,96,0.5)'; - for (var p = step, mins = adur / 60; p <= mins; p += step) - bctx.fillRect(Math.floor(sm * p * 60), 0, 2, pc.h); + step = sm > 0.15 ? 1 : sm > 0.05 ? 10 : 360; + bctx.fillStyle = light && !dy ? 'rgba(0, 0, 0, 0.5)' : 'rgba(255, 255, 255, 0.5)'; + for (var p = step, mins = adur / 60; p <= mins; p += step) + bctx.fillRect(Math.floor(sm * p * 60), 0, 2, pc.h); - step = sm > 0.33 ? 1 : sm > 0.15 ? 5 : sm > 0.05 ? 10 : sm > 0.01 ? 60 : 720; - bctx.fillStyle = dz ? '#0f0' : dy ? '#999' : light ? 'rgba(0,64,0,0.9)' : 'rgba(192,255,96,1)'; - for (var p = step, mins = adur / 60; p <= mins; p += step) { - bctx.fillText(p, Math.floor(sm * p * 60 + 3), pc.h / 3); + step = sm > 0.33 ? 1 : sm > 0.15 ? 5 : sm > 0.05 ? 10 : sm > 0.01 ? 60 : 720; + bctx.fillStyle = dz ? '#0f0' : dy ? '#999' : light ? 'rgba(0, 0, 0, 0.9)' : 'rgb(255, 255, 255)'; + for (var p = step, mins = adur / 60; p <= mins; p += step) { + bctx.fillText(p, Math.floor(sm * p * 60 + 3), pc.h / 3); + } } step = sm > 0.2 ? 10 : sm > 0.1 ? 30 : sm > 0.01 ? 60 : sm > 0.005 ? 720 : 1440; @@ -2303,7 +2354,7 @@ var pbar = (function () { var bc = r.buf, pc = r.pos, pctx = pc.ctx, - w = 8, + w = 2, apos, adur; if (t_redraw) { @@ -2359,8 +2410,8 @@ var pbar = (function () { if (!widget.is_open) return; - pctx.fillStyle = '#573'; pctx.fillRect((x - w / 2) - 1, 0, w + 2, pc.h); - pctx.fillStyle = '#dfc'; pctx.fillRect((x - w / 2), 0, w, pc.h); + pctx.fillStyle = '#bbb'; pctx.fillRect((x - w / 2) - 1, 0, w + 2, pc.h); + pctx.fillStyle = '#fff'; pctx.fillRect((x - w / 2), 0, w, pc.h); pctx.lineWidth = 2.5; pctx.fillStyle = '#fff'; @@ -2368,7 +2419,7 @@ var pbar = (function () { var m1 = pctx.measureText(t1), m1b = pctx.measureText(t1 + ":88"), m2 = pctx.measureText(t2), - yt = pc.h * 0.94, + yt = pc.h * 0.65, xt1 = pc.w - (m1.width + 12), xt2 = x < m1.width * 1.4 ? (x + 12) : (Math.min(pc.w - m1b.width, x - 12) - m2.width); @@ -2418,31 +2469,41 @@ var vbar = (function () { dz = themen == 'dz', dy = themen == 'dy'; + var accentRgb = hexToRgb(getComputedStyle(document.body).getPropertyValue('--a')); + var accentHsl = rgbToHsl(accentRgb[0], accentRgb[1], accentRgb[2]); + accentHsl[0] *= 360; + accentHsl[1] *= 100; + accentHsl[2] *= 100; + if (gradh != gh) { gradh = gh; - grad1 = glossy_grad(r.can, dz ? 120 : 50, - dy ? [0, 0, 0, 0] : light ? [50, 55, 52, 48] : [45, 52, 47, 43], - dy ? [20, 24, 22, 20] : light ? [54, 60, 52, 47] : [42, 51, 47, 42]); - grad2 = glossy_grad(r.can, dz ? 120 : 205, - dz ? [100, 100, 100, 100] : dy ? [0, 0, 0, 0] : [10, 15, 13, 10], - dz ? [10, 14, 12, 10] : dy ? [90, 90, 90, 90] : [16, 20, 18, 16]); + grad1 = glossy_grad(r.can, + accentHsl[0], + accentHsl[1], + accentHsl[2]); + grad2 = glossy_grad(r.can, + accentHsl[0], + 0, + (accentHsl[2] > 0.5 ? accentHsl[2] * 0.35 : accentHsl[2] + 50)); } ctx.fillStyle = grad2; ctx.fillRect(0, 0, w, h); ctx.fillStyle = grad1; ctx.fillRect(0, 0, w * mp.vol, h); + + if(false){ + var vt = Math.floor(mp.vol * 100) + '%', + tw = ctx.measureText(vt).width, + x = w * mp.vol - tw - 8, + li = dy; - var vt = Math.floor(mp.vol * 100) + '%', - tw = ctx.measureText(vt).width, - x = w * mp.vol - tw - 8, - li = dy; + if (mp.vol < 0.5) { + x += tw + 16; + li = !li; + } - if (mp.vol < 0.5) { - x += tw + 16; - li = !li; + ctx.fillStyle = li ? '#fff' : '#210'; + ctx.fillText(vt, x, h / 3 * 2); } - ctx.fillStyle = li ? '#fff' : '#210'; - ctx.fillText(vt, x, h / 3 * 2); - clearTimeout(untext); untext = setTimeout(r.draw, 1000); }; @@ -2477,20 +2538,20 @@ var vbar = (function () { toast.inf(6, 'volume doesnt work because apple says no'); }, 1); } - can.onmousedown = function (e) { + ebi('pvolbg').onmousedown = can.onmousedown = function (e) { if (e.button !== 0) return; - can.onmousemove = mousemove; + ebi('pvolbg').onmousemove = can.onmousemove = mousemove; mousedown(e); }; - can.onmouseup = function (e) { + ebi('pvolbg').onmouseup = can.onmouseup = function (e) { if (e.button === 0) - can.onmousemove = null; + ebi('pvolbg').onmousemove = can.onmousemove = null; }; if (TOUCH) { - can.ontouchstart = mousedown; - can.ontouchmove = mousemove; + ebi('pvolbg').ontouchstart = can.ontouchstart = mousedown; + ebi('pvolbg').ontouchmove = can.ontouchmove = mousemove; } return r; })(); @@ -2683,16 +2744,16 @@ function mpause(e) { seek_au_rel(dist); ev(e); }; - ebi('pvol').onwheel = function (e) { + ebi('pvolbg').onwheel = function (e) { var dist = Math.sign(e.deltaY) * 10; if (Math.abs(e.deltaY) < 30 && !e.deltaMode) dist = e.deltaY; - if (!dist || !mp.au) + if (!dist) return true; dist *= -1; - mp.setvol(Math.round((mp.vol + dist / 500) * 100) / 100 ); + mp.setvol(Math.round((mp.vol + dist / 250) * 100) / 100 ); vbar.draw(); ev(e); };