| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Advanced Mathematical Gradient Simulator</title> |
| <script src="https://cdn.tailwindcss.com"></script> |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script> |
| <script src="https://cdn.jsdelivr.net/npm/dat.gui@0.7.7/build/dat.gui.min.js"></script> |
| <style> |
| body { |
| margin: 0; |
| overflow: hidden; |
| font-family: 'Inter', sans-serif; |
| } |
| canvas { |
| display: block; |
| } |
| #control-panel { |
| position: absolute; |
| top: 20px; |
| right: 20px; |
| background: rgba(0,0,0,0.7); |
| color: white; |
| padding: 15px; |
| border-radius: 10px; |
| max-width: 300px; |
| backdrop-filter: blur(5px); |
| max-height: 90vh; |
| overflow-y: auto; |
| } |
| #title { |
| position: absolute; |
| top: 20px; |
| left: 20px; |
| color: white; |
| font-size: 2rem; |
| text-shadow: 0 0 10px rgba(0,0,0,0.5); |
| z-index: 100; |
| } |
| .control-group { |
| margin-bottom: 15px; |
| border-bottom: 1px solid rgba(255,255,255,0.1); |
| padding-bottom: 10px; |
| } |
| .control-group h3 { |
| margin-top: 0; |
| margin-bottom: 10px; |
| font-weight: 600; |
| } |
| .gradient-control { |
| display: flex; |
| align-items: center; |
| margin-bottom: 8px; |
| } |
| .gradient-control label { |
| min-width: 120px; |
| font-size: 0.9rem; |
| } |
| .gradient-control input[type="color"] { |
| margin-right: 10px; |
| width: 30px; |
| height: 30px; |
| border: none; |
| border-radius: 50%; |
| cursor: pointer; |
| } |
| .gradient-control input[type="range"] { |
| flex-grow: 1; |
| } |
| select { |
| width: 100%; |
| padding: 5px; |
| border-radius: 4px; |
| background: rgba(255,255,255,0.1); |
| color: white; |
| border: 1px solid rgba(255,255,255,0.2); |
| } |
| button { |
| width: 100%; |
| padding: 8px; |
| margin-top: 5px; |
| background: rgba(59, 130, 246, 0.7); |
| color: white; |
| border: none; |
| border-radius: 4px; |
| cursor: pointer; |
| transition: background 0.2s; |
| } |
| button:hover { |
| background: rgba(59, 130, 246, 1); |
| } |
| .tab-content { |
| display: none; |
| } |
| .tab-content.active { |
| display: block; |
| } |
| .tabs { |
| display: flex; |
| margin-bottom: 10px; |
| } |
| .tab { |
| padding: 5px 10px; |
| cursor: pointer; |
| background: rgba(255,255,255,0.1); |
| margin-right: 5px; |
| border-radius: 4px 4px 0 0; |
| font-size: 0.8rem; |
| } |
| .tab.active { |
| background: rgba(59, 130, 246, 0.7); |
| } |
| </style> |
| </head> |
| <body class="bg-gray-900"> |
| <div id="title" class="font-bold">Math Gradient Simulator</div> |
| |
| <div id="control-panel"> |
| <div class="tabs"> |
| <div class="tab active" onclick="switchTab('gradient-tab')">Gradient</div> |
| <div class="tab" onclick="switchTab('math-tab')">Math</div> |
| <div class="tab" onclick="switchTab('physics-tab')">Physics</div> |
| </div> |
| |
| <div id="gradient-tab" class="tab-content active"> |
| <div class="control-group"> |
| <h3>Color Gradient</h3> |
| <div class="gradient-control"> |
| <label for="color1">Color 1</label> |
| <input type="color" id="color1" value="#ff0000"> |
| <input type="range" id="color1Pos" min="0" max="1" step="0.01" value="0"> |
| </div> |
| <div class="gradient-control"> |
| <label for="color2">Color 2</label> |
| <input type="color" id="color2" value="#00ff00"> |
| <input type="range" id="color2Pos" min="0" max="1" step="0.01" value="0.5"> |
| </div> |
| <div class="gradient-control"> |
| <label for="color3">Color 3</label> |
| <input type="color" id="color3" value="#0000ff"> |
| <input type="range" id="color3Pos" min="0" max="1" step="0.01" value="1"> |
| </div> |
| <button id="randomize">Randomize Colors</button> |
| </div> |
| |
| <div class="control-group"> |
| <h3>Gradient Type</h3> |
| <select id="gradientType"> |
| <option value="linear">Linear</option> |
| <option value="radial">Radial</option> |
| <option value="angular">Angular</option> |
| <option value="spiral">Spiral</option> |
| </select> |
| </div> |
| </div> |
| |
| <div id="math-tab" class="tab-content"> |
| <div class="control-group"> |
| <h3>Mathematical Functions</h3> |
| <select id="mathFunction"> |
| <option value="sine">Sine Waves</option> |
| <option value="fractal">Fractal Noise</option> |
| <option value="mandelbrot">Mandelbrot</option> |
| <option value="julia">Julia Set</option> |
| <option value="lorenz">Lorenz Attractor</option> |
| <option value="quantum">Quantum Interference</option> |
| </select> |
| </div> |
| |
| <div class="control-group"> |
| <h3>Sine Wave Parameters</h3> |
| <div class="gradient-control"> |
| <label for="waveFrequency">Frequency</label> |
| <input type="range" id="waveFrequency" min="0.1" max="20" step="0.1" value="5"> |
| </div> |
| <div class="gradient-control"> |
| <label for="waveAmplitude">Amplitude</label> |
| <input type="range" id="waveAmplitude" min="0" max="1" step="0.01" value="0.2"> |
| </div> |
| </div> |
| |
| <div class="control-group"> |
| <h3>Fractal Parameters</h3> |
| <div class="gradient-control"> |
| <label for="fractalOctaves">Octaves</label> |
| <input type="range" id="fractalOctaves" min="1" max="8" step="1" value="4"> |
| </div> |
| <div class="gradient-control"> |
| <label for="fractalLacunarity">Lacunarity</label> |
| <input type="range" id="fractalLacunarity" min="1" max="4" step="0.1" value="2"> |
| </div> |
| <div class="gradient-control"> |
| <label for="fractalGain">Gain</label> |
| <input type="range" id="fractalGain" min="0" max="1" step="0.05" value="0.5"> |
| </div> |
| </div> |
| |
| <div class="control-group"> |
| <h3>Complex System Parameters</h3> |
| <div class="gradient-control"> |
| <label for="complexReal">Real Constant</label> |
| <input type="range" id="complexReal" min="-2" max="2" step="0.01" value="-0.7"> |
| </div> |
| <div class="gradient-control"> |
| <label for="complexImag">Imaginary Constant</label> |
| <input type="range" id="complexImag" min="-2" max="2" step="0.01" value="0.27"> |
| </div> |
| <div class="gradient-control"> |
| <label for="complexIterations">Iterations</label> |
| <input type="range" id="complexIterations" min="10" max="200" step="1" value="100"> |
| </div> |
| </div> |
| </div> |
| |
| <div id="physics-tab" class="tab-content"> |
| <div class="control-group"> |
| <h3>Physics Simulation</h3> |
| <select id="physicsType"> |
| <option value="fluid">Fluid Dynamics</option> |
| <option value="particles">Particle System</option> |
| <option value="gravity">Gravity Well</option> |
| <option value="magnetic">Magnetic Field</option> |
| <option value="quantum">Quantum Field</option> |
| </select> |
| </div> |
| |
| <div class="control-group"> |
| <h3>Fluid Parameters</h3> |
| <div class="gradient-control"> |
| <label for="fluidViscosity">Viscosity</label> |
| <input type="range" id="fluidViscosity" min="0" max="1" step="0.01" value="0.5"> |
| </div> |
| <div class="gradient-control"> |
| <label for="fluidVelocity">Velocity</label> |
| <input type="range" id="fluidVelocity" min="0" max="2" step="0.05" value="0.8"> |
| </div> |
| </div> |
| |
| <div class="control-group"> |
| <h3>Particle Parameters</h3> |
| <div class="gradient-control"> |
| <label for="particleCount">Count</label> |
| <input type="range" id="particleCount" min="10" max="1000" step="10" value="200"> |
| </div> |
| <div class="gradient-control"> |
| <label for="particleSize">Size</label> |
| <input type="range" id="particleSize" min="0.1" max="5" step="0.1" value="1"> |
| </div> |
| </div> |
| |
| <div class="control-group"> |
| <h3>Field Parameters</h3> |
| <div class="gradient-control"> |
| <label for="fieldStrength">Strength</label> |
| <input type="range" id="fieldStrength" min="0" max="2" step="0.05" value="1"> |
| </div> |
| <div class="gradient-control"> |
| <label for="fieldFalloff">Falloff</label> |
| <input type="range" id="fieldFalloff" min="0.1" max="3" step="0.1" value="1.5"> |
| </div> |
| </div> |
| |
| <div class="control-group"> |
| <h3>Quantum Parameters</h3> |
| <div class="gradient-control"> |
| <label for="quantumProbability">Probability</label> |
| <input type="range" id="quantumProbability" min="0" max="1" step="0.01" value="0.5"> |
| </div> |
| <div class="gradient-control"> |
| <label for="quantumEntanglement">Entanglement</label> |
| <input type="range" id="quantumEntanglement" min="0" max="1" step="0.01" value="0.3"> |
| </div> |
| </div> |
| </div> |
| </div> |
|
|
| <script> |
| |
| const scene = new THREE.Scene(); |
| const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); |
| const renderer = new THREE.WebGLRenderer({ antialias: true }); |
| renderer.setSize(window.innerWidth, window.innerHeight); |
| renderer.setPixelRatio(window.devicePixelRatio); |
| document.body.appendChild(renderer.domElement); |
| |
| |
| const geometry = new THREE.PlaneGeometry(2, 2); |
| |
| |
| const shaderMaterial = new THREE.ShaderMaterial({ |
| uniforms: { |
| time: { value: 0 }, |
| resolution: { value: new THREE.Vector2(window.innerWidth, window.innerHeight) }, |
| mouse: { value: new THREE.Vector2(0, 0) }, |
| color1: { value: new THREE.Color(0xff0000) }, |
| color2: { value: new THREE.Color(0x00ff00) }, |
| color3: { value: new THREE.Color(0x0000ff) }, |
| pos1: { value: 0 }, |
| pos2: { value: 0.5 }, |
| pos3: { value: 1 }, |
| |
| |
| gradientType: { value: 0 }, |
| |
| |
| waveFrequency: { value: 5.0 }, |
| waveAmplitude: { value: 0.2 }, |
| |
| |
| fractalOctaves: { value: 4 }, |
| fractalLacunarity: { value: 2.0 }, |
| fractalGain: { value: 0.5 }, |
| |
| |
| complexReal: { value: -0.7 }, |
| complexImag: { value: 0.27 }, |
| complexIterations: { value: 100 }, |
| |
| |
| physicsType: { value: 0 }, |
| fluidViscosity: { value: 0.5 }, |
| fluidVelocity: { value: 0.8 }, |
| particleCount: { value: 200 }, |
| particleSize: { value: 1.0 }, |
| fieldStrength: { value: 1.0 }, |
| fieldFalloff: { value: 1.5 }, |
| quantumProbability: { value: 0.5 }, |
| quantumEntanglement: { value: 0.3 } |
| }, |
| vertexShader: ` |
| varying vec2 vUv; |
| void main() { |
| vUv = uv; |
| gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); |
| } |
| `, |
| fragmentShader: ` |
| #define PI 3.14159265358979323846 |
| |
| uniform float time; |
| uniform vec2 resolution; |
| uniform vec2 mouse; |
| uniform vec3 color1; |
| uniform vec3 color2; |
| uniform vec3 color3; |
| uniform float pos1; |
| uniform float pos2; |
| uniform float pos3; |
| |
| uniform int gradientType; |
| |
| uniform float waveFrequency; |
| uniform float waveAmplitude; |
| |
| uniform int fractalOctaves; |
| uniform float fractalLacunarity; |
| uniform float fractalGain; |
| |
| uniform float complexReal; |
| uniform float complexImag; |
| uniform int complexIterations; |
| |
| uniform int physicsType; |
| uniform float fluidViscosity; |
| uniform float fluidVelocity; |
| uniform float particleCount; |
| uniform float particleSize; |
| uniform float fieldStrength; |
| uniform float fieldFalloff; |
| uniform float quantumProbability; |
| uniform float quantumEntanglement; |
| |
| varying vec2 vUv; |
| |
| // Hash function for random numbers |
| float hash(vec2 p) { |
| return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453); |
| } |
| |
| // Simplex noise function |
| vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } |
| vec4 mod289(vec4 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; } |
| vec4 permute(vec4 x) { return mod289(((x*34.0)+1.0)*x); } |
| vec4 taylorInvSqrt(vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; } |
| |
| float snoise(vec3 v) { |
| const vec2 C = vec2(1.0/6.0, 1.0/3.0); |
| const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); |
| |
| vec3 i = floor(v + dot(v, C.yyy)); |
| vec3 x0 = v - i + dot(i, C.xxx); |
| |
| vec3 g = step(x0.yzx, x0.xyz); |
| vec3 l = 1.0 - g; |
| vec3 i1 = min(g.xyz, l.zxy); |
| vec3 i2 = max(g.xyz, l.zxy); |
| |
| vec3 x1 = x0 - i1 + C.xxx; |
| vec3 x2 = x0 - i2 + C.yyy; |
| vec3 x3 = x0 - D.yyy; |
| |
| i = mod289(i); |
| vec4 p = permute(permute(permute( |
| i.z + vec4(0.0, i1.z, i2.z, 1.0)) |
| + i.y + vec4(0.0, i1.y, i2.y, 1.0)) |
| + i.x + vec4(0.0, i1.x, i2.x, 1.0)); |
| |
| float n_ = 0.142857142857; |
| vec3 ns = n_ * D.wyz - D.xzx; |
| |
| vec4 j = p - 49.0 * floor(p * ns.z * ns.z); |
| |
| vec4 x_ = floor(j * ns.z); |
| vec4 y_ = floor(j - 7.0 * x_); |
| |
| vec4 x = x_ * ns.x + ns.yyyy; |
| vec4 y = y_ * ns.x + ns.yyyy; |
| vec4 h = 1.0 - abs(x) - abs(y); |
| |
| vec4 b0 = vec4(x.xy, y.xy); |
| vec4 b1 = vec4(x.zw, y.zw); |
| |
| vec4 s0 = floor(b0)*2.0 + 1.0; |
| vec4 s1 = floor(b1)*2.0 + 1.0; |
| vec4 sh = -step(h, vec4(0.0)); |
| |
| vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy; |
| vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww; |
| |
| vec3 p0 = vec3(a0.xy, h.x); |
| vec3 p1 = vec3(a0.zw, h.y); |
| vec3 p2 = vec3(a1.xy, h.z); |
| vec3 p3 = vec3(a1.zw, h.w); |
| |
| vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2,p2), dot(p3,p3))); |
| p0 *= norm.x; |
| p1 *= norm.y; |
| p2 *= norm.z; |
| p3 *= norm.w; |
| |
| vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); |
| m = m * m; |
| return 42.0 * dot(m*m, vec4(dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3))); |
| } |
| |
| // Fractional Brownian Motion (fBm) |
| float fbm(vec3 p) { |
| float value = 0.0; |
| float amplitude = 0.5; |
| float frequency = 1.0; |
| |
| for (int i = 0; i < 8; i++) { |
| if (i >= fractalOctaves) break; |
| |
| value += amplitude * snoise(p * frequency); |
| frequency *= fractalLacunarity; |
| amplitude *= fractalGain; |
| } |
| |
| return value; |
| } |
| |
| // Complex number operations |
| vec2 complexMul(vec2 a, vec2 b) { |
| return vec2(a.x*b.x - a.y*b.y, a.x*b.y + a.y*b.x); |
| } |
| |
| // Mandelbrot/Julia set calculation |
| float mandelbrot(vec2 c, vec2 offset, int maxIter) { |
| vec2 z = c; |
| float iter = 0.0; |
| |
| for (int i = 0; i < 200; i++) { |
| if (i >= maxIter) break; |
| |
| z = complexMul(z, z) + offset; |
| if (dot(z, z) > 4.0) { |
| return float(i) / float(maxIter); |
| } |
| iter += 1.0; |
| } |
| |
| return 0.0; |
| } |
| |
| // Quantum probability wave function |
| float quantumWave(vec2 p, float prob, float ent) { |
| float wave1 = sin(p.x * 10.0 + time) * 0.5 + 0.5; |
| float wave2 = sin(p.y * 10.0 + time * 1.3) * 0.5 + 0.5; |
| float interference = wave1 * wave2; |
| |
| float collapse = step(prob, interference); |
| float entangled = mix(interference, collapse, ent); |
| |
| return entangled; |
| } |
| |
| // Fluid simulation function |
| float fluidSim(vec2 p, float visc, float vel) { |
| vec2 coord = p * 5.0 + vec2(time * vel, time * vel * 0.7); |
| float f1 = fbm(vec3(coord, time * 0.1)); |
| |
| coord = p * 3.0 + vec2(time * vel * 0.7, time * vel * 0.3); |
| float f2 = fbm(vec3(coord, time * 0.2)); |
| |
| float f = mix(f1, f2, visc); |
| return f * 0.5 + 0.5; |
| } |
| |
| // Particle system simulation |
| float particleSystem(vec2 p, float count, float size) { |
| float particleEffect = 0.0; |
| float particleScale = count / 1000.0; |
| |
| for (float i = 1.0; i <= 10.0; i++) { |
| if (i > count / 100.0) break; |
| |
| vec2 pos = vec2( |
| sin(time * 0.2 * i) * 0.5 + 0.5, |
| cos(time * 0.3 * i) * 0.5 + 0.5 |
| ); |
| |
| float dist = distance(p, pos); |
| float particle = smoothstep(size * 0.1, 0.0, dist); |
| particleEffect += particle * particleScale; |
| } |
| |
| return clamp(particleEffect, 0.0, 1.0); |
| } |
| |
| // Gravity well simulation |
| float gravityWell(vec2 p, float strength, float falloff) { |
| vec2 center = vec2(0.5, 0.5); |
| vec2 mousePos = mouse; |
| |
| float dist = distance(p, center); |
| float mouseDist = distance(p, mousePos); |
| |
| float gravity = 1.0 - pow(dist, falloff); |
| float mouseGravity = 1.0 - pow(mouseDist, falloff); |
| |
| return (gravity + mouseGravity) * strength * 0.5; |
| } |
| |
| void main() { |
| vec2 uv = vUv; |
| vec2 p = uv * 2.0 - 1.0; |
| p.x *= resolution.x / resolution.y; |
| |
| // Mouse influence |
| vec2 mousePos = (mouse * 2.0 - 1.0); |
| mousePos.x *= resolution.x / resolution.y; |
| float mouseDist = length(p - mousePos); |
| float mouseInfluence = smoothstep(0.5, 0.0, mouseDist) * 0.5; |
| |
| // Base position for gradient |
| vec2 gradientPos = uv; |
| |
| // Apply gradient type |
| if (gradientType == 1) { // Radial |
| gradientPos = vec2(length(uv - 0.5), 0.0); |
| } else if (gradientType == 2) { // Angular |
| gradientPos = vec2(atan(uv.y - 0.5, uv.x - 0.5) / (2.0 * PI) + 0.5, 0.0); |
| } else if (gradientType == 3) { // Spiral |
| float angle = atan(uv.y - 0.5, uv.x - 0.5) / (2.0 * PI); |
| float radius = length(uv - 0.5); |
| gradientPos = vec2(angle + radius * 2.0, 0.0); |
| } |
| |
| // Apply mathematical functions |
| float mathEffect = 0.0; |
| float mathFunction = 0.0; |
| |
| if (mathFunction == 0) { // Sine waves |
| mathEffect = sin(uv.x * waveFrequency * 10.0 + time) * |
| sin(uv.y * waveFrequency * 10.0 + time * 1.3) * |
| waveAmplitude; |
| } else if (mathFunction == 1) { // Fractal noise |
| mathEffect = fbm(vec3(uv * 5.0, time * 0.5)) * 0.5; |
| } else if (mathFunction == 2) { // Mandelbrot |
| vec2 c = (uv - 0.5) * 4.0; |
| mathEffect = mandelbrot(c, c, complexIterations); |
| } else if (mathFunction == 3) { // Julia set |
| vec2 c = (uv - 0.5) * 4.0; |
| mathEffect = mandelbrot(c, vec2(complexReal, complexImag), complexIterations); |
| } else if (mathFunction == 4) { // Lorenz attractor |
| // Simplified Lorenz attractor effect |
| mathEffect = fbm(vec3(uv * 10.0, time * 0.2)) * 0.5; |
| } else if (mathFunction == 5) { // Quantum interference |
| mathEffect = quantumWave(uv, quantumProbability, quantumEntanglement); |
| } |
| |
| // Apply physics simulation |
| float physicsEffect = 0.0; |
| |
| if (physicsType == 0) { // Fluid dynamics |
| physicsEffect = fluidSim(uv, fluidViscosity, fluidVelocity); |
| } else if (physicsType == 1) { // Particle system |
| physicsEffect = particleSystem(uv, particleCount, particleSize); |
| } else if (physicsType == 2) { // Gravity well |
| physicsEffect = gravityWell(uv, fieldStrength, fieldFalloff); |
| } else if (physicsType == 3) { // Magnetic field |
| // Simplified magnetic field effect |
| physicsEffect = sin(uv.x * 10.0 + time) * 0.5 + 0.5; |
| } else if (physicsType == 4) { // Quantum field |
| physicsEffect = quantumWave(uv, quantumProbability, quantumEntanglement); |
| } |
| |
| // Combine effects |
| float combinedEffect = gradientPos.x + mathEffect * 0.3 + physicsEffect * 0.3 + mouseInfluence * 0.2; |
| |
| // Three-color gradient |
| vec3 color; |
| if (combinedEffect < pos2) { |
| float t = (combinedEffect - pos1) / (pos2 - pos1); |
| color = mix(color1, color2, t); |
| } else { |
| float t = (combinedEffect - pos2) / (pos3 - pos2); |
| color = mix(color2, color3, t); |
| } |
| |
| // Add highlights from effects |
| color += vec3(mathEffect * 0.2, physicsEffect * 0.2, mouseInfluence * 0.2); |
| |
| gl_FragColor = vec4(color, 1.0); |
| } |
| ` |
| }); |
| |
| const plane = new THREE.Mesh(geometry, shaderMaterial); |
| scene.add(plane); |
| |
| camera.position.z = 1; |
| |
| |
| const mouse = new THREE.Vector2(); |
| document.addEventListener('mousemove', (event) => { |
| mouse.x = (event.clientX / window.innerWidth); |
| mouse.y = 1 - (event.clientY / window.innerHeight); |
| shaderMaterial.uniforms.mouse.value = mouse; |
| }); |
| |
| |
| window.addEventListener('resize', () => { |
| camera.aspect = window.innerWidth / window.innerHeight; |
| camera.updateProjectionMatrix(); |
| renderer.setSize(window.innerWidth, window.innerHeight); |
| shaderMaterial.uniforms.resolution.value.set(window.innerWidth, window.innerHeight); |
| }); |
| |
| |
| function switchTab(tabId) { |
| document.querySelectorAll('.tab-content').forEach(tab => { |
| tab.classList.remove('active'); |
| }); |
| document.querySelectorAll('.tab').forEach(tab => { |
| tab.classList.remove('active'); |
| }); |
| |
| document.getElementById(tabId).classList.add('active'); |
| event.target.classList.add('active'); |
| } |
| |
| |
| const color1Input = document.getElementById('color1'); |
| const color2Input = document.getElementById('color2'); |
| const color3Input = document.getElementById('color3'); |
| const pos1Input = document.getElementById('color1Pos'); |
| const pos2Input = document.getElementById('color2Pos'); |
| const pos3Input = document.getElementById('color3Pos'); |
| const randomizeBtn = document.getElementById('randomize'); |
| const gradientTypeSelect = document.getElementById('gradientType'); |
| |
| color1Input.addEventListener('input', () => { |
| shaderMaterial.uniforms.color1.value.set(color1Input.value); |
| }); |
| |
| color2Input.addEventListener('input', () => { |
| shaderMaterial.uniforms.color2.value.set(color2Input.value); |
| }); |
| |
| color3Input.addEventListener('input', () => { |
| shaderMaterial.uniforms.color3.value.set(color3Input.value); |
| }); |
| |
| pos1Input.addEventListener('input', () => { |
| shaderMaterial.uniforms.pos1.value = parseFloat(pos1Input.value); |
| }); |
| |
| pos2Input.addEventListener('input', () => { |
| shaderMaterial.uniforms.pos2.value = parseFloat(pos2Input.value); |
| }); |
| |
| pos3Input.addEventListener('input', () => { |
| shaderMaterial.uniforms.pos3.value = parseFloat(pos3Input.value); |
| }); |
| |
| gradientTypeSelect.addEventListener('change', () => { |
| const types = ['linear', 'radial', 'angular', 'spiral']; |
| shaderMaterial.uniforms.gradientType.value = types.indexOf(gradientTypeSelect.value); |
| }); |
| |
| |
| const mathFunctionSelect = document.getElementById('mathFunction'); |
| const waveFrequencyInput = document.getElementById('waveFrequency'); |
| const waveAmplitudeInput = document.getElementById('waveAmplitude'); |
| const fractalOctavesInput = document.getElementById('fractalOctaves'); |
| const fractalLacunarityInput = document.getElementById('fractalLacunarity'); |
| const fractalGainInput = document.getElementById('fractalGain'); |
| const complexRealInput = document.getElementById('complexReal'); |
| const complexImagInput = document.getElementById('complexImag'); |
| const complexIterationsInput = document.getElementById('complexIterations'); |
| |
| mathFunctionSelect.addEventListener('change', () => { |
| shaderMaterial.uniforms.mathFunction.value = mathFunctionSelect.selectedIndex; |
| }); |
| |
| waveFrequencyInput.addEventListener('input', () => { |
| shaderMaterial.uniforms.waveFrequency.value = parseFloat(waveFrequencyInput.value); |
| }); |
| |
| waveAmplitudeInput.addEventListener('input', () => { |
| shaderMaterial.uniforms.waveAmplitude.value = parseFloat(waveAmplitudeInput.value); |
| }); |
| |
| fractalOctavesInput.addEventListener('input', () => { |
| shaderMaterial.uniforms.fractalOctaves.value = parseInt(fractalOctavesInput.value); |
| }); |
| |
| fractalLacunarityInput.addEventListener('input', () => { |
| shaderMaterial.uniforms.fractalLacunarity.value = parseFloat(fractalLacunarityInput.value); |
| }); |
| |
| fractalGainInput.addEventListener('input', () => { |
| shaderMaterial.uniforms.fractalGain.value = parseFloat(fractalGainInput.value); |
| }); |
| |
| complexRealInput.addEventListener('input', () => { |
| shaderMaterial.uniforms.complexReal.value = parseFloat(complexRealInput.value); |
| }); |
| |
| complexImagInput.addEventListener('input', () => { |
| shaderMaterial.uniforms.complexImag.value = parseFloat(complexImagInput.value); |
| }); |
| |
| complexIterationsInput.addEventListener('input', () => { |
| shaderMaterial.uniforms.complexIterations.value = parseInt(complexIterationsInput.value); |
| }); |
| |
| |
| const physicsTypeSelect = document.getElementById('physicsType'); |
| const fluidViscosityInput = document.getElementById('fluidViscosity'); |
| const fluidVelocityInput = document.getElementById('fluidVelocity'); |
| const particleCountInput = document.getElementById('particleCount'); |
| const particleSizeInput = document.getElementById('particleSize'); |
| const fieldStrengthInput = document.getElementById('fieldStrength'); |
| const fieldFalloffInput = document.getElementById('fieldFalloff'); |
| const quantumProbabilityInput = document.getElementById('quantumProbability'); |
| const quantumEntanglementInput = document.getElementById('quantumEntanglement'); |
| |
| physicsTypeSelect.addEventListener('change', () => { |
| shaderMaterial.uniforms.physicsType.value = physicsTypeSelect.selectedIndex; |
| }); |
| |
| fluidViscosityInput.addEventListener('input', () => { |
| shaderMaterial.uniforms.fluidViscosity.value = parseFloat(fluidViscosityInput.value); |
| }); |
| |
| fluidVelocityInput.addEventListener('input', () => { |
| shaderMaterial.uniforms.fluidVelocity.value = parseFloat(fluidVelocityInput.value); |
| }); |
| |
| particleCountInput.addEventListener('input', () => { |
| shaderMaterial.uniforms.particleCount.value = parseFloat(particleCountInput.value); |
| }); |
| |
| particleSizeInput.addEventListener('input', () => { |
| shaderMaterial.uniforms.particleSize.value = parseFloat(particleSizeInput.value); |
| }); |
| |
| fieldStrengthInput.addEventListener('input', () => { |
| shaderMaterial.uniforms.fieldStrength.value = parseFloat(fieldStrengthInput.value); |
| }); |
| |
| fieldFalloffInput.addEventListener('input', () => { |
| shaderMaterial.uniforms.fieldFalloff.value = parseFloat(fieldFalloffInput.value); |
| }); |
| |
| quantumProbabilityInput.addEventListener('input', () => { |
| shaderMaterial.uniforms.quantumProbability.value = parseFloat(quantumProbabilityInput.value); |
| }); |
| |
| quantumEntanglementInput.addEventListener('input', () => { |
| shaderMaterial.uniforms.quantumEntanglement.value = parseFloat(quantumEntanglementInput.value); |
| }); |
| |
| |
| randomizeBtn.addEventListener('click', () => { |
| const randomColor = () => { |
| return '#' + Math.floor(Math.random()*16777215).toString(16); |
| }; |
| |
| color1Input.value = randomColor(); |
| color2Input.value = randomColor(); |
| color3Input.value = randomColor(); |
| |
| shaderMaterial.uniforms.color1.value.set(color1Input.value); |
| shaderMaterial.uniforms.color2.value.set(color2Input.value); |
| shaderMaterial.uniforms.color3.value.set(color3Input.value); |
| }); |
| |
| |
| function animate() { |
| requestAnimationFrame(animate); |
| shaderMaterial.uniforms.time.value += 0.01; |
| renderer.render(scene, camera); |
| } |
| animate(); |
| </script> |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=arirajuns/gradient-simulator-glsl" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> |
| </html> |