new features
This commit is contained in:
@ -6,6 +6,7 @@ interface WorkerMessage {
|
||||
width?: number;
|
||||
height?: number;
|
||||
time?: number;
|
||||
renderMode?: string;
|
||||
}
|
||||
|
||||
interface WorkerResponse {
|
||||
@ -33,7 +34,7 @@ class ShaderWorker {
|
||||
this.compileShader(message.id, message.code!);
|
||||
break;
|
||||
case 'render':
|
||||
this.renderShader(message.id, message.width!, message.height!, message.time!);
|
||||
this.renderShader(message.id, message.width!, message.height!, message.time!, message.renderMode || 'classic');
|
||||
break;
|
||||
}
|
||||
} catch (error) {
|
||||
@ -75,7 +76,7 @@ class ShaderWorker {
|
||||
}
|
||||
}
|
||||
|
||||
private renderShader(id: string, width: number, height: number, time: number): void {
|
||||
private renderShader(id: string, width: number, height: number, time: number, renderMode: string): void {
|
||||
if (!this.compiledFunction) {
|
||||
this.postError(id, 'No compiled shader');
|
||||
return;
|
||||
@ -110,12 +111,12 @@ class ShaderWorker {
|
||||
try {
|
||||
const value = this.compiledFunction(x, y, time, pixelIndex);
|
||||
const safeValue = isFinite(value) ? value : 0;
|
||||
const color = Math.abs(safeValue) % 256;
|
||||
const [r, g, b] = this.calculateColor(safeValue, renderMode);
|
||||
|
||||
data[i] = color; // R
|
||||
data[i + 1] = (color * 2) % 256; // G
|
||||
data[i + 2] = (color * 3) % 256; // B
|
||||
data[i + 3] = 255; // A
|
||||
data[i] = r; // R
|
||||
data[i + 1] = g; // G
|
||||
data[i + 2] = b; // B
|
||||
data[i + 3] = 255; // A
|
||||
} catch (error) {
|
||||
data[i] = 0; // R
|
||||
data[i + 1] = 0; // G
|
||||
@ -131,6 +132,93 @@ class ShaderWorker {
|
||||
}
|
||||
}
|
||||
|
||||
private calculateColor(value: number, renderMode: string): [number, number, number] {
|
||||
const absValue = Math.abs(value) % 256;
|
||||
|
||||
switch (renderMode) {
|
||||
case 'classic':
|
||||
return [
|
||||
absValue,
|
||||
(absValue * 2) % 256,
|
||||
(absValue * 3) % 256
|
||||
];
|
||||
|
||||
case 'grayscale':
|
||||
return [absValue, absValue, absValue];
|
||||
|
||||
case 'red':
|
||||
return [absValue, 0, 0];
|
||||
|
||||
case 'green':
|
||||
return [0, absValue, 0];
|
||||
|
||||
case 'blue':
|
||||
return [0, 0, absValue];
|
||||
|
||||
case 'rgb':
|
||||
return [
|
||||
(absValue * 255 / 256) | 0,
|
||||
((absValue * 2) % 256 * 255 / 256) | 0,
|
||||
((absValue * 3) % 256 * 255 / 256) | 0
|
||||
];
|
||||
|
||||
case 'hsv':
|
||||
return this.hsvToRgb(absValue / 255.0, 1.0, 1.0);
|
||||
|
||||
case 'rainbow':
|
||||
return this.rainbowColor(absValue);
|
||||
|
||||
default:
|
||||
return [absValue, absValue, absValue];
|
||||
}
|
||||
}
|
||||
|
||||
private hsvToRgb(h: number, s: number, v: number): [number, number, number] {
|
||||
const c = v * s;
|
||||
const x = c * (1 - Math.abs((h * 6) % 2 - 1));
|
||||
const m = v - c;
|
||||
|
||||
let r = 0, g = 0, b = 0;
|
||||
|
||||
if (h < 1/6) {
|
||||
r = c; g = x; b = 0;
|
||||
} else if (h < 2/6) {
|
||||
r = x; g = c; b = 0;
|
||||
} else if (h < 3/6) {
|
||||
r = 0; g = c; b = x;
|
||||
} else if (h < 4/6) {
|
||||
r = 0; g = x; b = c;
|
||||
} else if (h < 5/6) {
|
||||
r = x; g = 0; b = c;
|
||||
} else {
|
||||
r = c; g = 0; b = x;
|
||||
}
|
||||
|
||||
return [
|
||||
Math.round((r + m) * 255),
|
||||
Math.round((g + m) * 255),
|
||||
Math.round((b + m) * 255)
|
||||
];
|
||||
}
|
||||
|
||||
private rainbowColor(value: number): [number, number, number] {
|
||||
const phase = (value / 255.0) * 6;
|
||||
const segment = Math.floor(phase);
|
||||
const remainder = phase - segment;
|
||||
const t = remainder;
|
||||
const q = 1 - t;
|
||||
|
||||
switch (segment % 6) {
|
||||
case 0: return [255, Math.round(t * 255), 0];
|
||||
case 1: return [Math.round(q * 255), 255, 0];
|
||||
case 2: return [0, 255, Math.round(t * 255)];
|
||||
case 3: return [0, Math.round(q * 255), 255];
|
||||
case 4: return [Math.round(t * 255), 0, 255];
|
||||
case 5: return [255, 0, Math.round(q * 255)];
|
||||
default: return [255, 255, 255];
|
||||
}
|
||||
}
|
||||
|
||||
private sanitizeCode(code: string): string {
|
||||
// Strict whitelist approach
|
||||
const allowedPattern = /^[0-9a-zA-Z\s\+\-\*\/\%\^\&\|\(\)\<\>\~\?:,\.xyti]+$/;
|
||||
|
||||
Reference in New Issue
Block a user