summaryrefslogtreecommitdiff
path: root/js
diff options
context:
space:
mode:
authorJohn Bargman2026-04-15 08:23:09 +0000
committerJohn Bargman2026-04-15 08:23:09 +0000
commitdb6b79edbfca3ab7049af2492acd567b099559f5 (patch)
treef54df4a8af70b057032e5af882bd6d1e6be87bf2 /js
parent4f877207787edd592687f338772d95c9ec2c7038 (diff)
downloadnixtaml-website-db6b79edbfca3ab7049af2492acd567b099559f5.tar
nixtaml-website-db6b79edbfca3ab7049af2492acd567b099559f5.tar.gz
nixtaml-website-db6b79edbfca3ab7049af2492acd567b099559f5.tar.bz2
nixtaml-website-db6b79edbfca3ab7049af2492acd567b099559f5.tar.lz
nixtaml-website-db6b79edbfca3ab7049af2492acd567b099559f5.tar.xz
nixtaml-website-db6b79edbfca3ab7049af2492acd567b099559f5.tar.zst
nixtaml-website-db6b79edbfca3ab7049af2492acd567b099559f5.zip
agentic ai; is so; fucking cool; omgmain
Diffstat (limited to 'js')
-rw-r--r--js/parallax.js61
-rw-r--r--js/webgl-bg.js190
2 files changed, 251 insertions, 0 deletions
diff --git a/js/parallax.js b/js/parallax.js
new file mode 100644
index 0000000..9c2c671
--- /dev/null
+++ b/js/parallax.js
@@ -0,0 +1,61 @@
+// Parallax scroll effects for Nixtaml website
+// Vanilla JavaScript implementation with performance optimizations
+
+(function() {
+ // Check for reduced motion preference
+ const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
+
+ // Check if mobile (disable parallax for better performance)
+ const isMobile = window.innerWidth < 768;
+
+ // If reduced motion or mobile, exit early
+ if (prefersReducedMotion || isMobile) {
+ return;
+ }
+
+ // Throttle function for scroll events
+ function throttle(func, limit) {
+ let inThrottle;
+ return function() {
+ const args = arguments;
+ const context = this;
+ if (!inThrottle) {
+ func.apply(context, args);
+ inThrottle = true;
+ setTimeout(() => inThrottle = false, limit);
+ }
+ }
+ }
+
+ // Parallax animation function
+ let ticking = false;
+ function updateParallax() {
+ if (!ticking) {
+ requestAnimationFrame(function() {
+ const scrolled = window.pageYOffset;
+
+ // Get all elements with data-speed
+ const parallaxElements = document.querySelectorAll('[data-speed]');
+
+ parallaxElements.forEach(element => {
+ const speed = parseFloat(element.getAttribute('data-speed')) || 0;
+ const yPos = -(scrolled * speed);
+ element.style.transform = `translateY(${yPos}px)`;
+ });
+
+ ticking = false;
+ });
+ ticking = true;
+ }
+ }
+
+ // Throttled scroll handler
+ const throttledUpdate = throttle(updateParallax, 16); // ~60fps
+
+ // Add scroll listener
+ window.addEventListener('scroll', throttledUpdate, { passive: true });
+
+ // Initial call
+ updateParallax();
+})();</content>
+<parameter name="filePath">js/parallax.js \ No newline at end of file
diff --git a/js/webgl-bg.js b/js/webgl-bg.js
new file mode 100644
index 0000000..081b525
--- /dev/null
+++ b/js/webgl-bg.js
@@ -0,0 +1,190 @@
+// WebGL background effect for Nixtaml website
+// Particle system with subtle animations fitting "crash-over-burn" theme
+
+(function() {
+ // Check for reduced motion preference
+ const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
+
+ // Check if mobile (simplify or disable for performance)
+ const isMobile = window.innerWidth < 768;
+
+ // If reduced motion or mobile, skip WebGL
+ if (prefersReducedMotion || isMobile) {
+ console.log('WebGL background disabled: reduced motion or mobile');
+ return;
+ }
+
+ // Check WebGL support
+ const canvas = document.createElement('canvas');
+ const gl = canvas.getContext('webgl2') || canvas.getContext('webgl');
+ if (!gl) {
+ console.log('WebGL not supported, using fallback');
+ return;
+ }
+
+ // Append canvas to body
+ canvas.id = 'webgl-bg';
+ document.body.insertBefore(canvas, document.body.firstChild);
+
+ // Set canvas size
+ function resizeCanvas() {
+ canvas.width = window.innerWidth;
+ canvas.height = window.innerHeight;
+ gl.viewport(0, 0, canvas.width, canvas.height);
+ }
+ resizeCanvas();
+ window.addEventListener('resize', resizeCanvas);
+
+ // Load shader
+ function loadShader(gl, type, source) {
+ const shader = gl.createShader(type);
+ gl.shaderSource(shader, source);
+ gl.compileShader(shader);
+ if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
+ console.error('Shader compile error:', gl.getShaderInfoLog(shader));
+ gl.deleteShader(shader);
+ return null;
+ }
+ return shader;
+ }
+
+ // Create program
+ const vertexShaderSource = `
+ attribute vec2 a_position;
+ attribute float a_size;
+ attribute vec3 a_color;
+
+ uniform mat4 u_matrix;
+ uniform float u_time;
+
+ varying vec3 v_color;
+
+ void main() {
+ vec4 position = vec4(a_position, 0.0, 1.0);
+ position.x += sin(u_time * 0.001 + a_position.y * 0.01) * 0.05;
+ position.y += cos(u_time * 0.0005 + a_position.x * 0.01) * 0.02;
+
+ gl_Position = u_matrix * position;
+ gl_PointSize = a_size;
+
+ v_color = a_color;
+ }
+ `;
+
+ const fragmentShaderSource = `
+ precision mediump float;
+
+ varying vec3 v_color;
+
+ void main() {
+ vec2 center = gl_PointCoord - vec2(0.5);
+ float dist = length(center);
+
+ if (dist > 0.5) {
+ discard;
+ }
+
+ float alpha = 1.0 - smoothstep(0.0, 0.5, dist);
+ gl_FragColor = vec4(v_color, alpha * 0.2);
+ }
+ `;
+
+ const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
+ const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
+
+ const program = gl.createProgram();
+ gl.attachShader(program, vertexShader);
+ gl.attachShader(program, fragmentShader);
+ gl.linkProgram(program);
+
+ if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
+ console.error('Program link error:', gl.getProgramInfoLog(program));
+ return;
+ }
+
+ gl.useProgram(program);
+
+ // Get attribute locations
+ const positionLocation = gl.getAttribLocation(program, 'a_position');
+ const sizeLocation = gl.getAttribLocation(program, 'a_size');
+ const colorLocation = gl.getAttribLocation(program, 'a_color');
+
+ // Get uniform locations
+ const matrixLocation = gl.getUniformLocation(program, 'u_matrix');
+ const timeLocation = gl.getUniformLocation(program, 'u_time');
+
+ // Create particles
+ const numParticles = 200;
+ const positions = new Float32Array(numParticles * 2);
+ const sizes = new Float32Array(numParticles);
+ const colors = new Float32Array(numParticles * 3);
+
+ for (let i = 0; i < numParticles; i++) {
+ positions[i * 2] = (Math.random() - 0.5) * 4; // Spread across screen
+ positions[i * 2 + 1] = (Math.random() - 0.5) * 4;
+ sizes[i] = Math.random() * 5 + 2; // Size 2-7
+ // Orange/red colors
+ colors[i * 3] = Math.random() * 0.5 + 0.5; // R
+ colors[i * 3 + 1] = Math.random() * 0.3 + 0.2; // G
+ colors[i * 3 + 2] = Math.random() * 0.1; // B
+ }
+
+ // Create buffers
+ const positionBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
+
+ const sizeBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, sizeBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, sizes, gl.STATIC_DRAW);
+
+ const colorBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);
+
+ // Enable blending
+ gl.enable(gl.BLEND);
+ gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
+
+ // Render loop
+ let startTime = Date.now();
+ function render() {
+ const time = Date.now() - startTime;
+
+ // Clear
+ gl.clearColor(0, 0, 0, 0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ // Set uniforms
+ const matrix = new Float32Array([
+ 1, 0, 0, 0,
+ 0, 1, 0, 0,
+ 0, 0, 1, 0,
+ 0, 0, 0, 1
+ ]);
+ gl.uniformMatrix4fv(matrixLocation, false, matrix);
+ gl.uniform1f(timeLocation, time);
+
+ // Bind position buffer
+ gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
+ gl.enableVertexAttribArray(positionLocation);
+ gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
+
+ // Bind size buffer
+ gl.bindBuffer(gl.ARRAY_BUFFER, sizeBuffer);
+ gl.enableVertexAttribArray(sizeLocation);
+ gl.vertexAttribPointer(sizeLocation, 1, gl.FLOAT, false, 0, 0);
+
+ // Bind color buffer
+ gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
+ gl.enableVertexAttribArray(colorLocation);
+ gl.vertexAttribPointer(colorLocation, 3, gl.FLOAT, false, 0, 0);
+
+ // Draw
+ gl.drawArrays(gl.POINTS, 0, numParticles);
+
+ requestAnimationFrame(render);
+ }
+
+ render();
+})(); \ No newline at end of file