mirror of
https://github.com/stronk-dev/SignalRGB_Effects.git
synced 2025-07-04 19:05:09 +02:00
116 lines
3.3 KiB
HTML
116 lines
3.3 KiB
HTML
<head>
|
|
<title>Gradient Rotating Ball</title>
|
|
<meta
|
|
description="Rotates a ball from the center of the canvas, much like the Radar RGB FX. This version has a gradient between the foreground and background to ensure smooth transitions between colours" />
|
|
<meta publisher="stronk" />
|
|
<meta property="speed" label="Speed" type="number" min="0" max="100" default="5">
|
|
<meta property="radius" label="Size" type="number" min="1" max="200" default="100">
|
|
<meta property="distance" label="Offset" type="number" min="0" max="200" default="75">
|
|
<meta property="bg" label="Background Colour" type="color" default="#00141e" min="0" max="360" />
|
|
<meta property="fg" label="Foreground Colour" type="color" default="#2aff5d" min="0" max="360" />
|
|
</head>
|
|
|
|
<body style="margin: 0; padding: 0;">
|
|
<canvas id="exCanvas" width="320" height="200"></canvas>
|
|
</body>
|
|
|
|
<script>
|
|
var c = document.getElementById("exCanvas");
|
|
var ctx = c.getContext("2d");
|
|
var width = 320;
|
|
var height = 200;
|
|
var rotate = 1;
|
|
var h = -1;
|
|
var s = -1;
|
|
var l = -1;
|
|
|
|
function hexToHSL(H) {
|
|
// Convert hex to RGB first
|
|
let r = 0, g = 0, b = 0;
|
|
if (H.length == 4) {
|
|
r = "0x" + H[1] + H[1];
|
|
g = "0x" + H[2] + H[2];
|
|
b = "0x" + H[3] + H[3];
|
|
} else if (H.length == 7) {
|
|
r = "0x" + H[1] + H[2];
|
|
g = "0x" + H[3] + H[4];
|
|
b = "0x" + H[5] + H[6];
|
|
}
|
|
// Then to HSL
|
|
r /= 255;
|
|
g /= 255;
|
|
b /= 255;
|
|
let cmin = Math.min(r, g, b),
|
|
cmax = Math.max(r, g, b),
|
|
delta = cmax - cmin,
|
|
h = 0,
|
|
s = 0,
|
|
l = 0;
|
|
|
|
if (delta == 0)
|
|
h = 0;
|
|
else if (cmax == r)
|
|
h = ((g - b) / delta) % 6;
|
|
else if (cmax == g)
|
|
h = (b - r) / delta + 2;
|
|
else
|
|
h = (r - g) / delta + 4;
|
|
|
|
h = Math.round(h * 60);
|
|
|
|
if (h < 0)
|
|
h += 360;
|
|
|
|
l = (cmax + cmin) / 2;
|
|
s = delta == 0 ? 0 : delta / (1 - Math.abs(2 * l - 1));
|
|
s = +(s * 100).toFixed(1);
|
|
l = +(l * 100).toFixed(1);
|
|
|
|
return [h, s, l];
|
|
}
|
|
|
|
function update() {
|
|
// Extract HSL so that we can add opacity
|
|
if (h == -1 || s == -1 || l == -1) {
|
|
[h, s, l] = hexToHSL(fg);
|
|
}
|
|
// Reset canvas
|
|
ctx.fillStyle = bg;
|
|
ctx.fillRect(0, 0, width, height);
|
|
|
|
// Calculate anchor point
|
|
midPoint = {
|
|
x: (width / 2),
|
|
y: (height / 2) - distance
|
|
};
|
|
|
|
// Increment rotation
|
|
rotate += speed
|
|
|
|
// Define gradient for ball
|
|
var grd = ctx.createRadialGradient(midPoint.x, midPoint.y, 0, midPoint.x, midPoint.y, radius);
|
|
grd.addColorStop(0, `hsla(${h}, ${s}%, ${l}%, 1.0)`);
|
|
grd.addColorStop(0.5, `hsla(${h}, ${s}%, ${l}%, 0.3)`);
|
|
grd.addColorStop(0.65, `hsla(${h}, ${s}%, ${l}%, 0.15)`);
|
|
grd.addColorStop(0.755, `hsla(${h}, ${s}%, ${l}%, 0.075)`);
|
|
grd.addColorStop(0.8285, `hsla(${h}, ${s}%, ${l}%, 0.037)`);
|
|
grd.addColorStop(0.88, `hsla(${h}, ${s}%, ${l}%, 0.019)`);
|
|
grd.addColorStop(1, `hsla(${h}, ${s}%, ${l}%, 0)`);
|
|
|
|
ctx.beginPath();
|
|
// Rotate Ball around center
|
|
ctx.translate(midPoint.x, midPoint.y);
|
|
ctx.translate(0, distance);
|
|
ctx.rotate(0.001 * rotate);
|
|
ctx.translate(-midPoint.x, -midPoint.y);
|
|
ctx.translate(0, -distance);
|
|
// Draw Ball
|
|
ctx.arc(midPoint.x, midPoint.y, midPoint.x - 2, 0, Math.PI * 2, false);
|
|
ctx.fillStyle = grd;
|
|
ctx.fill();
|
|
ctx.closePath();
|
|
|
|
window.requestAnimationFrame(update);
|
|
}
|
|
window.requestAnimationFrame(update);
|
|
</script> |