Skip to content

Commit af23db4

Browse files
Update interface
1 parent 6c8dd46 commit af23db4

3 files changed

Lines changed: 1320 additions & 74 deletions

File tree

public/app.mjs

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,16 +170,99 @@ function syncControls(config) {
170170
controls.json.value = JSON.stringify(config, null, 2);
171171
}
172172

173+
// Interpolate between two hex colors
174+
function interpolateColor(color1, color2, factor) {
175+
const c1 = parseInt(color1.slice(1), 16);
176+
const c2 = parseInt(color2.slice(1), 16);
177+
const r1 = (c1 >> 16) & 255, g1 = (c1 >> 8) & 255, b1 = c1 & 255;
178+
const r2 = (c2 >> 16) & 255, g2 = (c2 >> 8) & 255, b2 = c2 & 255;
179+
const r = Math.round(r1 + (r2 - r1) * factor);
180+
const g = Math.round(g1 + (g2 - g1) * factor);
181+
const b = Math.round(b1 + (b2 - b1) * factor);
182+
return `#${((r << 16) | (g << 8) | b).toString(16).padStart(6, '0')}`;
183+
}
184+
185+
// Get color from gradient at a given position (0-1)
186+
function getGradientColor(position, colors, positions) {
187+
if (!colors || colors.length === 0) return '#ffffff';
188+
if (colors.length === 1) return colors[0];
189+
190+
// Normalize position to 0-1
191+
const t = Math.max(0, Math.min(1, position));
192+
193+
// Find the two stops this position falls between
194+
let startIdx = 0;
195+
for (let i = 0; i < positions.length - 1; i++) {
196+
const pos1 = positions[i] / 100;
197+
const pos2 = positions[i + 1] / 100;
198+
if (t >= pos1 && t <= pos2) {
199+
startIdx = i;
200+
break;
201+
}
202+
}
203+
204+
const pos1 = positions[startIdx] / 100;
205+
const pos2 = positions[startIdx + 1] / 100;
206+
const range = pos2 - pos1;
207+
const factor = range === 0 ? 0 : (t - pos1) / range;
208+
209+
return interpolateColor(colors[startIdx], colors[startIdx + 1], factor);
210+
}
211+
173212
function colorFor(value, config, rowIndex, colIndex, channels) {
174-
const palette = config.rendu.palette || ["#07121f", "#ff9d4d", "#53b0ff", "#f5f7ff"];
175213
const visualValue = channels && channels.length > 1 ? channels[1] : value;
176214
const alphabet = config.alphabet_sortie || config.alphabet_entree || [0, 1];
177215
let index = alphabet.findIndex((item) => String(item) === String(visualValue));
216+
217+
// Use gradient if available
218+
const gradient = config.rendu.gradient;
219+
if (gradient && gradient.colors && gradient.colors.length > 0) {
220+
let position = 0;
221+
if (index >= 0) {
222+
position = index / Math.max(1, alphabet.length - 1);
223+
} else {
224+
position = (Math.abs(Number(visualValue) || Number(value) || 0) % 100) / 100;
225+
}
226+
227+
// Apply gradient based on type
228+
if (gradient.type === 'linear') {
229+
position = (colIndex / (config.largeur || 100)) * 0.5 + (rowIndex / (config.hauteur || 100)) * 0.5;
230+
} else if (gradient.type === 'radial') {
231+
const centerX = (config.largeur || 100) / 2;
232+
const centerY = (config.hauteur || 100) / 2;
233+
const dist = Math.sqrt(Math.pow(colIndex - centerX, 2) + Math.pow(rowIndex - centerY, 2));
234+
const maxDist = Math.sqrt(Math.pow(centerX, 2) + Math.pow(centerY, 2));
235+
position = Math.min(1, dist / maxDist);
236+
} else if (gradient.type === 'conic') {
237+
const centerX = (config.largeur || 100) / 2;
238+
const centerY = (config.hauteur || 100) / 2;
239+
const angle = Math.atan2(rowIndex - centerY, colIndex - centerX);
240+
position = ((angle + Math.PI) / (2 * Math.PI));
241+
}
242+
243+
return getGradientColor(position, gradient.colors, gradient.positions);
244+
}
245+
246+
// Fallback to palette if no gradient
247+
const palette = config.rendu.palette || ["#07121f", "#ff9d4d", "#53b0ff", "#f5f7ff"];
178248
if (index < 0) index = Math.abs(Number(visualValue) || Number(value) || 0) % palette.length;
179249
const drift = (rowIndex + colIndex) % Math.max(1, palette.length - 1);
180250
return palette[(index + drift) % palette.length] || palette[0];
181251
}
182252

253+
window.applyGradientToPalette = function(colors, type, positions) {
254+
if (!state.config) return;
255+
state.config.rendu = state.config.rendu || {};
256+
state.config.rendu.gradient = {
257+
colors: colors || ["#07121f", "#ff9d4d", "#53b0ff", "#f5f7ff"],
258+
type: type || 'linear',
259+
positions: positions || [0, 50, 100]
260+
};
261+
// Keep palette as fallback
262+
state.config.rendu.palette = colors || ["#07121f", "#ff9d4d", "#53b0ff", "#f5f7ff"];
263+
render();
264+
};
265+
183266
function drawUniverseToCanvas(targetCanvas, universe, maxWidth = 240, maxHeight = 132) {
184267
const { configuration, lignes, sorties } = universe;
185268
const context = targetCanvas.getContext("2d");

0 commit comments

Comments
 (0)