Zip It
by MusicBar, progress bar
A metal zipper unzips up to the playhead, its pull tab swings on the beat, and a light glows through the opening, pulsing with the music.
How it installs, its SHA-256 and its code
Click Apply: MusicBar downloads it, checks its SHA-256 and puts it on the taskbar, or just puts it on if it already has it. Needs MusicBar 1.8 or newer.
SHA-256 4088abc9da0c7398606777f0458e7e159350a7825c52e04d16b3cb7aa0b998ef
//! name: Zip It
//! author: MusicBar
//! kind: progress
//! description: A metal zipper unzips up to the playhead, its pull tab swinging on the beat and a glowing light pulsing with the music inside the opened part.
// A steady random number for a row or a column.
float hash1(float n) { return frac(sin(n * 12.9898) * 43758.5453); }
// Lays a color over what is there (premultiplied light, and how much of the pixel it covers).
void layer(inout float3 acc, inout float cover, float3 rgb, float a)
{
a = saturate(a);
acc = rgb * a + acc * (1.0 - a);
cover = a + cover * (1.0 - a);
}
// Rounded box: p from its center, b its half size, r the corner radius. Negative inside.
float box(float2 p, float2 b, float r)
{
float2 q = abs(p) - b + r;
return length(max(q, 0.0)) + min(max(q.x, q.y), 0.0) - r;
}
// A trapezoid lying along x: half height h0 at its left end, h1 at its right end, half length L.
float trap(float2 p, float h0, float h1, float L)
{
float2 q = float2(abs(p.y), p.x);
float2 k1 = float2(h1, L);
float2 k2 = float2(h1 - h0, 2.0 * L);
float2 ca = float2(q.x - min(q.x, q.y < 0.0 ? h0 : h1), abs(q.y) - L);
float2 cb = q - k1 + k2 * saturate(dot(k1 - q, k2) / dot(k2, k2));
float s = (cb.x < 0.0 && ca.y < 0.0) ? -1.0 : 1.0;
return s * sqrt(min(dot(ca, ca), dot(cb, cb)));
}
// Brushed metal: a vertical light falloff, fine streaks along the bar and a soft specular band.
float3 metal(float3 tint, float t, float streak, float spec)
{
float3 c = tint * (0.55 + 0.4 * t) * (0.9 + 0.14 * streak);
return c + spec * float3(1.0, 0.98, 0.94);
}
float4 main(float2 uv : TEXCOORD) : COLOR
{
float2 px = float2(uv.x * size.x, rise(uv) * size.y); // pixels: along the bar, up from the screen edge
float H = size.y;
float mid = H * 0.5;
float head = progress * size.x;
float3 steel = lerp(float3(0.80, 0.82, 0.86), colorC.rgb, 0.38);
float streak = hash1(floor(px.y * 1.7) + 0.37);
// Shut ahead of the slider; behind it the two rows part into a V and stay apart.
float back = head - px.x;
float open = 1.0 - exp(-max(back - 0.05 * H, 0.0) / (1.25 * H));
float off = 0.045 * H + 0.215 * H * open;
float yT = mid + off, yB = mid - off;
float th = 0.12 * H;
float3 acc = float3(0, 0, 0);
float cover = 0;
// The fabric tapes the teeth are clamped onto, with a twill weave and a row of stitches.
float3 cloth = lerp(float3(0.09, 0.09, 0.11), colorB.rgb * 0.35, 0.45);
float weave = 0.82 + 0.18 * step(0.5, frac((px.x + px.y) / 3.0));
float tapeT = smoothstep(-0.5, 0.5, px.y - yT) * smoothstep(0.5, -0.5, px.y - (yT + th + 0.1 * H));
float tapeB = smoothstep(0.5, -0.5, px.y - yB) * smoothstep(-0.5, 0.5, px.y - (yB - th - 0.1 * H));
float stitchY = min(abs(px.y - (yT + th + 0.05 * H)), abs(px.y - (yB - th - 0.05 * H)));
float stitch = smoothstep(0.9, 0.2, stitchY) * step(frac(px.x / max(5.0, 0.16 * H)), 0.6);
layer(acc, cover, cloth * weave, (tapeT + tapeB) * 0.92);
layer(acc, cover, lerp(cloth, float3(0.85, 0.85, 0.88), 0.55), stitch * (tapeT + tapeB) * 0.7);
// Inside the open part: a glow, and a dot-matrix equalizer pulsing with the spectrum.
float gap = max(off - th, 0.0);
float inside = smoothstep(yT + th, yT, px.y) * smoothstep(yB - th, yB, px.y) * open;
float g = max(3.0, 0.15 * H);
float2 cell = floor(float2(px.x, px.y - mid) / g);
float2 dotLocal = frac(float2(px.x, px.y - mid) / g) - 0.5;
float fx = 1.0 - abs(frac(cell.x * g / (11.0 * H)) * 2.0 - 1.0);
float spec = spectrum(fx);
float reach = 0.5 * g + (gap + 0.4 * th) * 1.3 * spec;
float tall = abs(cell.y + 0.5) * g;
float lit = smoothstep(reach + 0.5 * g, reach - 0.5 * g, tall) * smoothstep(0.42, 0.24, length(dotLocal));
float pulse = 0.62 + 0.3 * level + 0.35 * beat;
float glow = exp(-abs(px.y - mid) / (0.06 * H + gap * 0.8)) * pulse;
layer(acc, cover, colorA.rgb * 0.85, inside * glow * 0.8);
float3 dotColor = lerp(lerp(colorA.rgb, float3(1, 1, 1), 0.45), lerp(colorA.rgb, colorB.rgb, 0.5), saturate(tall / (gap + th)));
layer(acc, cover, dotColor, inside * lit * (0.45 + 0.55 * spec));
// The teeth: two combs that interlock when shut. Rounded metal, lit from above, a cup at the tip.
float P = 0.3 * H;
float tw = 0.25 * P;
float lxT = px.x - floor(px.x / P + 0.5) * P;
float lxB = px.x - (floor(px.x / P) + 0.5) * P;
float dT = box(float2(lxT, px.y - yT), float2(tw, th), tw * 0.55);
float dB = box(float2(lxB, px.y - yB), float2(tw, th), tw * 0.55);
float onT = step(dT, dB);
float d = min(dT, dB);
float lx = lerp(lxB, lxT, onT) / tw;
float ly = (px.y - lerp(yB, yT, onT)) / th;
float tipSide = lerp(ly, -ly, onT); // 1 at the tip that faces the other row
float bulge = sqrt(saturate(1.0 - lx * lx));
float cup = smoothstep(0.55, 0.2, length(float2(lx * 1.3, (tipSide - 0.55) * 2.2)));
float3 tooth = metal(steel, bulge * (0.75 + 0.25 * ly), 0.5, 0.55 * exp(-pow((lx + 0.35) / 0.25, 2.0)) * (0.5 + 0.5 * ly));
tooth *= (1.0 - 0.3 * cup) * (1.0 - 0.45 * smoothstep(-1.4, 0.0, d)); // dark rim: reads on any taskbar
float rim = smoothstep(-0.12 * H, 0.0, d) * smoothstep(0.2, 0.9, tipSide) * open * pulse;
tooth = lerp(tooth, colorA.rgb * 1.2, saturate(rim * 0.9));
layer(acc, cover, tooth, smoothstep(0.5, -0.5, d));
// A bright flare in the throat of the V, kicked by the beat.
float2 apex = float2(head - 0.75 * H, mid);
float2 fq = (px - apex) / float2(1.6 * H, 0.22 * H);
layer(acc, cover, lerp(colorA.rgb, float3(1, 1, 1), 0.4), exp(-length(fq) * 2.2) * (0.45 + 0.5 * beat) * step(px.x, head));
// The slider: a trapezoid wide where the open rows go in, with a raised bridge on top.
float2 sp = px - float2(head, mid);
float dShadow = trap(sp - float2(0.06 * H, -0.08 * H), 0.42 * H, 0.27 * H, 0.5 * H) - 0.07 * H;
layer(acc, cover, float3(0, 0, 0), smoothstep(0.12 * H, -0.06 * H, dShadow) * 0.5);
float dS = trap(sp, 0.42 * H, 0.27 * H, 0.5 * H) - 0.07 * H;
float ts = saturate(sp.y / (0.48 * H) * 0.5 + 0.5);
float3 body = metal(steel * 0.8, ts * ts, streak, 0.4 * exp(-pow((sp.y - 0.22 * H) / (0.07 * H), 2.0)));
body = lerp(body, body * lerp(0.45, 1.5, ts), smoothstep(-0.1 * H, 0.0, dS)) * (1.0 - 0.5 * smoothstep(-1.2, 0.0, dS));
body = lerp(body, colorA.rgb * 1.3, smoothstep(-0.12 * H, 0.0, dS) * smoothstep(0.0, -0.4 * H, sp.x) * pulse * 0.6);
layer(acc, cover, body, smoothstep(0.5, -0.5, dS));
float dBr = box(sp - float2(0.08 * H, 0.0), float2(0.4 * H, 0.12 * H), 0.11 * H);
float tb = saturate(sp.y / (0.12 * H) * 0.5 + 0.5);
float3 bridge = metal(steel * 0.95, tb, streak, 0.5 * exp(-pow((sp.y - 0.05 * H) / (0.04 * H), 2.0)));
bridge *= 1.0 - 0.45 * smoothstep(-0.04 * H, 0.0, dBr) * (1.0 - tb);
layer(acc, cover, float3(0, 0, 0), smoothstep(0.5, -0.5, dBr - 1.2) * 0.4);
layer(acc, cover, bridge, smoothstep(0.5, -0.5, dBr));
// The pull tab hangs from a pin near the front and swings: a little all the time, a flick on each beat.
float2 pin = float2(head + 0.3 * H, mid);
float a = 0.12 * sin(time * 2.4) * (0.6 + 0.4 * level) + 0.34 * beat - 0.04;
float ca = cos(a), sa = sin(a);
float Lt = H;
float2 dp = px - pin;
float2 q = float2(ca * dp.x + sa * dp.y, -sa * dp.x + ca * dp.y);
float2 dq = dp - float2(0.05 * H, -0.08 * H);
float2 qs = float2(ca * dq.x + sa * dq.y, -sa * dq.x + ca * dq.y);
float dTabS = trap(qs - float2(Lt * 0.5, 0.0), 0.08 * H, 0.18 * H, Lt * 0.5) - 0.04 * H;
layer(acc, cover, float3(0, 0, 0), smoothstep(0.1 * H, -0.05 * H, dTabS) * 0.45);
float dHole = box(q - float2(Lt * 0.74, 0.0), float2(0.15 * H, 0.06 * H), 0.06 * H);
float dTab = max(trap(q - float2(Lt * 0.5, 0.0), 0.08 * H, 0.18 * H, Lt * 0.5) - 0.04 * H, -dHole);
float tt = saturate(q.y / (0.2 * H) * 0.5 + 0.5);
float3 tab = metal(lerp(steel, colorC.rgb, 0.35), tt, streak, 0.45 * exp(-pow((q.y - 0.07 * H) / (0.05 * H), 2.0)));
tab = lerp(tab, tab * lerp(0.5, 1.45, tt), smoothstep(-0.07 * H, 0.0, dTab)); // a bevel round the rim
tab *= (1.0 + 0.4 * beat) * (1.0 - 0.5 * smoothstep(-1.2, 0.0, dTab));
layer(acc, cover, tab, smoothstep(0.5, -0.5, dTab));
float dPin = length(dp) - 0.085 * H;
layer(acc, cover, metal(steel * 0.8, saturate(dp.y / (0.17 * H) + 0.5), 0.5, 0.0), smoothstep(0.5, -0.5, dPin));
return paint(acc / max(cover, 0.001), cover);
}