This commit is contained in:
parent
d1dee7bc3d
commit
f53aad9a94
4 changed files with 160 additions and 0 deletions
99
site/gradient-bands/main.js
Normal file
99
site/gradient-bands/main.js
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
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();
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue