Compare commits

..

No commits in common. "6f423370081669a34003cfdec1050fe6d30636ec" and "4c90b4a9a28928f782c9047c36b438f41c532225" have entirely different histories.

View file

@ -40,39 +40,68 @@ PanelWindow {
ctx.clearRect(0, 0, w, h);
// Horizontal gradient for the border
// Opaque backing behind the stroke
ctx.fillStyle = M.Theme.base00.toString();
ctx.beginPath();
if (r > lw) {
ctx.moveTo(0, r);
ctx.arc(r, r, r, Math.PI, -Math.PI / 2);
ctx.lineTo(w - r, 0);
ctx.arc(w - r, r, r, -Math.PI / 2, 0);
ctx.lineTo(w, lw);
ctx.lineTo(0, lw);
} else {
ctx.rect(0, 0, w, lw);
}
ctx.fill();
// Glow below the stroke fades from gradient color to transparent
const glowH = h - lw;
if (glowH > 0) {
const glowGrad = ctx.createLinearGradient(0, lw, 0, h);
glowGrad.addColorStop(0, "rgba(255,255,255,0.06)");
glowGrad.addColorStop(1, "transparent");
// Use the horizontal gradient as a mask via compositing
const hGrad = ctx.createLinearGradient(0, 0, w, 0);
hGrad.addColorStop(0, M.Theme.base0C.toString());
hGrad.addColorStop(1, M.Theme.base09.toString());
// Draw vertical fade strip
ctx.globalAlpha = 0.12;
ctx.fillStyle = hGrad;
ctx.fillRect(0, lw, w, glowH);
// Erase bottom portion with transparent fade
ctx.globalAlpha = 1;
ctx.globalCompositeOperation = "destination-out";
const eraseGrad = ctx.createLinearGradient(0, lw, 0, h);
eraseGrad.addColorStop(0, "transparent");
eraseGrad.addColorStop(1, "black");
ctx.fillStyle = eraseGrad;
ctx.fillRect(0, lw, w, glowH);
ctx.globalCompositeOperation = "source-over";
}
// Gradient stroke
ctx.globalAlpha = 1;
const grad = ctx.createLinearGradient(0, 0, w, 0);
grad.addColorStop(0, M.Theme.base0C.toString());
grad.addColorStop(1, M.Theme.base09.toString());
ctx.strokeStyle = grad;
ctx.lineWidth = lw;
// Stroke: top + left side + right side (open bottom)
// Left side down, curve, across top, curve, right side down
ctx.beginPath();
if (r > lw) {
ctx.moveTo(hw, h);
ctx.lineTo(hw, r);
ctx.moveTo(0, r);
ctx.arc(r, r, r - hw, Math.PI, -Math.PI / 2);
ctx.lineTo(w - r, hw);
ctx.arc(w - r, r, r - hw, -Math.PI / 2, 0);
ctx.lineTo(w - hw, h);
} else {
ctx.moveTo(hw, h);
ctx.lineTo(hw, hw);
ctx.lineTo(w - hw, hw);
ctx.lineTo(w - hw, h);
ctx.moveTo(0, hw);
ctx.lineTo(w, hw);
}
ctx.stroke();
// Fade out the bottom of the side borders
ctx.globalCompositeOperation = "destination-out";
const fadeGrad = ctx.createLinearGradient(0, h * 0.5, 0, h);
fadeGrad.addColorStop(0, "transparent");
fadeGrad.addColorStop(1, "black");
ctx.fillStyle = fadeGrad;
ctx.fillRect(0, h * 0.5, w, h * 0.5);
ctx.globalCompositeOperation = "source-over";
}
}