Zip It

của MusicBar, thanh tiến trình

Dây kéo kim loại được kéo mở tới chỗ đang phát, tay kéo lắc lư theo nhịp, chỗ hở bên trong sáng lên và nhấp nháy theo nhạc.

5 lượt tải Tải file, 8.3 KB
Cách cài, mã SHA-256 và mã nguồn

Bấm Áp dụng: MusicBar tự tải về, kiểm tra mã SHA-256 rồi mặc lên taskbar; có rồi thì mặc luôn. Cần MusicBar 1.8 trở lên.

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);
}