webtools/site/gradient-bands/main.js
Leon Mika f53aad9a94
All checks were successful
/ publish (push) Successful in 45s
Added Gradient bands
2025-09-27 10:57:14 +10:00

99 lines
2.9 KiB
JavaScript

function hexToRgb(hex) {
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
}
function interpolateColor(startRgb, endRgb, t) {
return {
r: Math.round(startRgb.r + (endRgb.r - startRgb.r) * t),
g: Math.round(startRgb.g + (endRgb.g - startRgb.g) * t),
b: Math.round(startRgb.b + (endRgb.b - startRgb.b) * t)
};
}
function rgbToString(rgb) {
return `rgb(${rgb.r}, ${rgb.g}, ${rgb.b})`;
}
function getBandColorAtT(startRgb, endRgb, bands, t) {
const bandIndex = Math.floor(t * bands);
const bandT = bandIndex / (bands - 1);
const clampedBandT = Math.max(0, Math.min(1, bandT));
return interpolateColor(startRgb, endRgb, clampedBandT);
}
function applyFunction(t, funcType) {
switch ( funcType) {
case 'linear':
return t;
case 'quad':
return t * t;
case 'cubic':
return t * t * t;
case 'sin':
return -Math.cos(t * Math.PI) / 2.0 + 0.5;
}
}
function renderGradient() {
const canvas = document.getElementById('gradient-canvas');
const ctx = canvas.getContext('2d');
const startColor = document.getElementById('start-color').value;
const endColor = document.getElementById('end-color').value;
const bands = parseInt(document.getElementById('bands').value);
const funcType = document.getElementById('func').value;
const startRgb = hexToRgb(startColor);
const endRgb = hexToRgb(endColor);
if (!startRgb || !endRgb || bands < 1) {
return;
}
const width = canvas.width;
const height = canvas.height;
const imageData = ctx.createImageData(width, height);
const data = imageData.data;
for (let y = 0; y < height; y++) {
const t = y / (height - 1);
const u = applyFunction(t, funcType);
const color = getBandColorAtT(startRgb, endRgb, bands, u);
for (let x = 0; x < width; x++) {
const index = (y * width + x) * 4;
data[index] = color.r;
data[index + 1] = color.g;
data[index + 2] = color.b;
data[index + 3] = 255;
}
}
ctx.putImageData(imageData, 0, 0);
}
function downloadCanvas() {
const canvas = document.getElementById('gradient-canvas');
const link = document.createElement('a');
link.download = 'gradient-bands.png';
link.href = canvas.toDataURL();
link.click();
}
function initializeEventListeners() {
document.getElementById('start-color').addEventListener('input', renderGradient);
document.getElementById('end-color').addEventListener('input', renderGradient);
document.getElementById('bands').addEventListener('input', renderGradient);
document.getElementById('func').addEventListener('input', renderGradient);
document.getElementById('download-btn').addEventListener('click', downloadCanvas);
}
document.addEventListener('DOMContentLoaded', () => {
initializeEventListeners();
renderGradient();
});