https://motioncanvas.online/preview/midnight-jdm-street-race
Scroll Down

Loading Canvas Shader...

Next-Gen Scroll Mechanics

Experience Beautiful Ambient Depth

This browser window is simulating a production webpage. As you scroll down, the ambient Midnight JDM Street Race background dynamically zooms and pulls focus in real-time, creating beautiful, cinematic parallax depth.

Built for Ultra Performance

Modern web layouts require buttery-smooth animations. Our styles run completely on the GPU, avoiding CPU reflow and main-thread layout jank.

Focus Pull Parallax

Scroll depth controls blur intensity and lens scaling simultaneously to guide focus elegantly.

GPU-Accelerated

Uses hardware transforms and native filters, optimized for stable 120fps scrolling.

Highly Customizable

Adjust speed, maximum blur limit, zoom multipliers, and filters in real-time.

© 2026 MOTIONCANVAS. ALL RIGHTS RESERVED.ACTIVE BACKGROUND: MIDNIGHT JDM STREET RACE

Midnight JDM Street Race

🟠 WebGL

A deeply motion-blurred late-night street race simulation. Glowing red and white headlights and taillights continuously warp past with responsive speed-boosting scroll wheel and immersive camera shake.

#WebGL#street-race#shader#interactive#motion-blur
Advertisement
Sponsor Advertisement
728 × 90 | Responsive Banner

Responsive Horizontal Leaderboard

Slot ID: ca-pub-detail-below-preview

Google AdSense Placeholder

Interactive Settings

Motion PresetsCustom Tuning
Animation Speed1.0x
Blur (Aesthetic diffusion)0px
Layer Opacity100%
Scale Zoom1.0x
Rotation Angle0°
Advertisement
Sponsor Advertisement
300 × 250 | Rectangle

Medium Rectangle Block

Slot ID: ca-pub-detail-after-customization

Google AdSense Placeholder

Quick Copy Actions

Download File Packages

Keyboard Shortcuts

Space Play/Pause
F Fullscreen
R Reset Slider
C Copy Code
Advertisement
Sponsor Advertisement
728 × 90 | Responsive Banner

Responsive Horizontal Leaderboard

Slot ID: ca-pub-detail-before-related

Google AdSense Placeholder

More in WebGL

Midnight JDM Street Race - WebGL 3D GPU WebGL background for React & Tailwind

Integrate the Midnight JDM Street Race directly into your website. This asset is rendered using raw WebGL shader context. It is optimized for zero layout-shifts and runs with high-performance hardware-accelerated processing.

Performance Specifications

  • Render Mode: WEBGL (WebGL 3D GPU)
  • Fluidity: Locked at 60fps dynamic loop
  • Bundle Footprint: Zero external NPM dependencies
  • SEO Indexing status: 100% Crawlable static semantic HTML

🛠️ Integration Capabilities

Our templates expose inline design tokens like --color-1 and --color-2 for infinite color palettes. This template is designed to fit inside hero elements, full-screen landing pages, and interactive presentation cards.

Technical Code Reference & Syntaxes for Googlebot & Crawlers

The snippets below display the direct, unminified source code utilized for rendering this background.

HTML & Inline CSS Snippet (Vanilla)

<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Midnight JDM Street Race</title>
  <style>
    html, body {
      margin: 0;
      padding: 0;
      width: 100%;
      height: 100%;
      overflow: hidden;
      background: #09090b;
    }
    
    #canvas-webgl-jdm-street-race {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      border: none;
    }
  </style>
</head>
<body>

  <canvas id="canvas-webgl-jdm-street-race"></canvas>
  <script>
  (function() {
    const canvas = document.getElementById('canvas-webgl-jdm-street-race');
    const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
    if (!gl) return;
  
    const vertices = new Float32Array([
      -1, -1,  1, -1, -1,  1,
      -1,  1,  1, -1,  1,  1
    ]);
  
    const buffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
    gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
  
    function createShader(gl, type, source) {
      const shader = gl.createShader(type);
      gl.shaderSource(shader, source);
      gl.compileShader(shader);
      if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
        console.error(gl.getShaderInfoLog(shader));
        gl.deleteShader(shader);
        return null;
      }
      return shader;
    }
  
    const vsSource = `
      attribute vec2 position;
      void main() {
        gl_Position = vec4(position, 0.0, 1.0);
      }
    `;
  
    const fsSource = `
      precision mediump float;
      uniform vec2 u_resolution;
      uniform float u_time;
      uniform float u_displacement;
      uniform float u_speed;
      uniform vec2 u_mouse;
      uniform vec2 u_shake;
  
      float hash(vec2 p) {
        p = fract(p * vec2(123.34, 456.21));
        p += dot(p, p + 45.32);
        return fract(p.x * p.y);
      }
  
      float hash1(float n) {
        return fract(sin(n) * 43758.5453);
      }
  
      vec3 getLightTrails(vec2 p, float displacement, float sideColorSign) {
        float r = length(p);
        float angle = atan(p.y, p.x);
        float z = 1.0 / (r + 0.015);
        
        float numLanes = 18.0;
        float angleScaled = angle * numLanes / 3.14159265;
        float laneId = floor(angleScaled);
        float laneFract = fract(angleScaled);
        
        float laneSeed = hash1(laneId * 17.43);
        
        vec3 trailColor = vec3(0.0);
        if (p.x + p.y * 0.1 < 0.0) {
          if (laneSeed < 0.3) {
            trailColor = vec3(1.0, 0.95, 0.85);
          } else if (laneSeed < 0.6) {
            trailColor = vec3(0.85, 0.95, 1.0);
          } else {
            trailColor = vec3(1.0, 0.8, 0.4);
          }
        } else {
          if (laneSeed < 0.5) {
            trailColor = vec3(1.0, 0.1, 0.15);
          } else if (laneSeed < 0.8) {
            trailColor = vec3(1.0, 0.35, 0.05);
          } else {
            trailColor = vec3(0.95, 0.05, 0.5);
          }
        }
        
        float activeLane = step(0.35, hash1(laneId * 31.89 + 12.4));
        if (activeLane < 0.5) return vec3(0.0);
        
        float laneSpeed = 0.5 + 1.5 * hash1(laneId * 7.51);
        
        float cellZ = z * 0.15 - displacement * 0.25 * laneSpeed;
        float cellIdZ = floor(cellZ);
        float cellFractZ = fract(cellZ);
        
        float cellSeed = hash(vec2(laneId, cellIdZ));
        
        float activeStreak = step(0.4, cellSeed);
        if (activeStreak < 0.5) return vec3(0.0);
        
        float streakWidth = 0.04 + 0.08 * hash1(laneId * 41.2 + cellIdZ * 13.7);
        float centerOffset = 0.3 + 0.4 * hash1(laneId * 2.3 + cellIdZ * 9.1);
        
        float distToCenter = abs(laneFract - centerOffset);
        float horizGlow = exp(-distToCenter * distToCenter / (2.0 * streakWidth * streakWidth));
        float vertGlow = smoothstep(0.0, 0.15, cellFractZ) * smoothstep(1.0, 0.85, cellFractZ);
        float radialFade = smoothstep(0.02, 0.15, r) * smoothstep(2.2, 0.6, r);
        float speedBrightness = 1.0 + (u_speed - 1.0) * 0.3;
        
        float intensity = horizGlow * vertGlow * radialFade * speedBrightness;
        
        float sparks = 0.0;
        if (hash1(laneId * 51.2 + cellIdZ * 19.3) > 0.85) {
          float sparkZ = fract(cellZ * 10.0);
          sparks = smoothstep(0.02, 0.0, abs(laneFract - centerOffset)) * 
                   smoothstep(0.1, 0.0, abs(sparkZ - 0.5)) * 
                   smoothstep(0.1, 0.4, r);
        }
        
        return trailColor * intensity * 2.2 + vec3(1.0) * sparks * intensity * 1.5;
      }
  
      void main() {
        vec2 p = (gl_FragCoord.xy - 0.5 * u_resolution) / u_resolution.y;
        p += u_shake;
        
        vec2 mouse = (u_mouse - 0.5 * u_resolution) / u_resolution.y;
        p -= mouse * 0.12;
        
        float r = length(p);
        
        vec3 baseColor = vec3(0.004, 0.003, 0.008);
        float vignette = smoothstep(2.0, 0.4, r);
        baseColor *= vignette;
        
        vec3 trails = vec3(0.0);
        trails += getLightTrails(p, u_displacement, p.x);
        trails += getLightTrails(p * 1.6, u_displacement * 1.3 + 4.5, p.x) * 0.45;
        trails += getLightTrails(p * 0.6, u_displacement * 0.8 - 9.1, p.x) * 0.7;
        
        float roadGlow = smoothstep(0.8, 0.0, length(p - vec2(0.3, -0.6))) * 0.07;
        vec3 roadGlowColor = vec3(0.9, 0.1, 0.4) * roadGlow;
        
        float lightGlow = smoothstep(1.0, 0.0, length(p - vec2(-0.4, -0.5))) * 0.06;
        vec3 lightGlowColor = vec3(0.5, 0.8, 1.0) * lightGlow;
        
        vec3 finalColor = baseColor + trails + roadGlowColor + lightGlowColor;
        finalColor = smoothstep(-0.02, 1.02, finalColor);
        
        float scanline = sin(gl_FragCoord.y * 1.5) * 0.04;
        finalColor -= vec3(scanline) * vignette;
        
        gl_FragColor = vec4(finalColor, 1.0);
      }
    `;
  
    const vs = createShader(gl, gl.VERTEX_SHADER, vsSource);
    const fs = createShader(gl, gl.FRAGMENT_SHADER, fsSource);
    if (!vs || !fs) return;
  
    const program = gl.createProgram();
    gl.attachShader(program, vs);
    gl.attachShader(program, fs);
    gl.linkProgram(program);
    if (!gl.getProgramParameter(program, gl.LINK_STATUS)) return;
  
    gl.useProgram(program);
  
    const positionLoc = gl.getAttribLocation(program, 'position');
    gl.enableVertexAttribArray(positionLoc);
    gl.vertexAttribPointer(positionLoc, 2, gl.FLOAT, false, 0, 0);
  
    const uResolution = gl.getUniformLocation(program, 'u_resolution');
    const uTime = gl.getUniformLocation(program, 'u_time');
    const uDisplacement = gl.getUniformLocation(program, 'u_displacement');
    const uSpeed = gl.getUniformLocation(program, 'u_speed');
    const uMouse = gl.getUniformLocation(program, 'u_mouse');
    const uShake = gl.getUniformLocation(program, 'u_shake');
  
    let mouseX = 0, mouseY = 0;
    window.addEventListener('mousemove', (e) => {
      const rect = canvas.getBoundingClientRect();
      mouseX = e.clientX - rect.left;
      mouseY = rect.height - (e.clientY - rect.top);
    });
  
    window.addEventListener('touchmove', (e) => {
      if (e.touches.length > 0) {
        const touch = e.touches[0];
        const rect = canvas.getBoundingClientRect();
        mouseX = touch.clientX - rect.left;
        mouseY = rect.height - (touch.clientY - rect.top);
      }
    });
  
    let scrollSpeed = 1.0;
    let targetScrollSpeed = 1.0;
    window.addEventListener('wheel', (e) => {
      targetScrollSpeed += Math.abs(e.deltaY) * 0.012;
      targetScrollSpeed = Math.min(targetScrollSpeed, 10.0);
    });
  
    function resize() {
      const rect = canvas.parentNode ? canvas.parentNode.getBoundingClientRect() : null;
      const width = rect ? rect.width : window.innerWidth;
      const height = rect ? rect.height : window.innerHeight;
      if (canvas.width !== width || canvas.height !== height) {
        canvas.width = width;
        canvas.height = height;
        gl.viewport(0, 0, width, height);
      }
    }
    window.addEventListener('resize', resize);
    
    if (canvas.parentNode) {
      const observer = new MutationObserver(resize);
      observer.observe(canvas.parentNode, { attributes: true });
    }
  
    resize();
  
    let startTime = Date.now();
    let lastTime = Date.now();
    let displacement = 0;
  
    function render() {
      const now = Date.now();
      const dt = (now - lastTime) / 1000.0;
      lastTime = now;
  
      scrollSpeed += (targetScrollSpeed - scrollSpeed) * 0.12;
      targetScrollSpeed += (1.0 - targetScrollSpeed) * 0.05;
  
      displacement += scrollSpeed * dt * 4.5;
  
      let shakeX = 0.0;
      let shakeY = 0.0;
      if (scrollSpeed > 1.05) {
        const shakeFactor = (scrollSpeed - 1.0) * 0.0035;
        shakeX = (Math.random() - 0.5) * shakeFactor;
        shakeY = (Math.random() - 0.5) * shakeFactor;
      }
  
      let elapsed = (now - startTime) / 1000.0;
      
      gl.uniform2f(uResolution, canvas.width, canvas.height);
      gl.uniform1f(uTime, elapsed);
      gl.uniform1f(uDisplacement, displacement);
      gl.uniform1f(uSpeed, scrollSpeed);
      gl.uniform2f(uMouse, mouseX, mouseY);
      gl.uniform2f(uShake, shakeX, shakeY);
  
      gl.drawArrays(gl.TRIANGLES, 0, 6);
      requestAnimationFrame(render);
    }
    requestAnimationFrame(render);
  })();
  </script>

  
</body>
</html>

React Component Wrapper (TSX)

import React from 'react';

export default function MidnightJDMStreetRaceBackground() {
  

  return (
    <div 
       
      style={{ width: '100%', height: '100%', position: 'relative', overflow: 'hidden' }}
    >
      <style dangerouslySetInnerHTML={{ __html: `
        #canvas-webgl-jdm-street-race {
          position: absolute;
          top: 0;
          left: 0;
          width: 100%;
          height: 100%;
          border: none;
        }
      ` }} />
      
      {/* HTML Structure */}
      <div 
        style={{ width: '100%', height: '100%' }}
        dangerouslySetInnerHTML={{ __html: `
          <canvas id="canvas-webgl-jdm-street-race"></canvas>
          <script>
          (function() {
            const canvas = document.getElementById('canvas-webgl-jdm-street-race');
            const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
            if (!gl) return;
          
            const vertices = new Float32Array([
              -1, -1,  1, -1, -1,  1,
              -1,  1,  1, -1,  1,  1
            ]);
          
            const buffer = gl.createBuffer();
            gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
            gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
          
            function createShader(gl, type, source) {
              const shader = gl.createShader(type);
              gl.shaderSource(shader, source);
              gl.compileShader(shader);
              if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
                console.error(gl.getShaderInfoLog(shader));
                gl.deleteShader(shader);
                return null;
              }
              return shader;
            }
          
            const vsSource = \`
              attribute vec2 position;
              void main() {
                gl_Position = vec4(position, 0.0, 1.0);
              }
            \`;
          
            const fsSource = \`
              precision mediump float;
              uniform vec2 u_resolution;
              uniform float u_time;
              uniform float u_displacement;
              uniform float u_speed;
              uniform vec2 u_mouse;
              uniform vec2 u_shake;
          
              float hash(vec2 p) {
                p = fract(p * vec2(123.34, 456.21));
                p += dot(p, p + 45.32);
                return fract(p.x * p.y);
              }
          
              float hash1(float n) {
                return fract(sin(n) * 43758.5453);
              }
          
              vec3 getLightTrails(vec2 p, float displacement, float sideColorSign) {
                float r = length(p);
                float angle = atan(p.y, p.x);
                float z = 1.0 / (r + 0.015);
                
                float numLanes = 18.0;
                float angleScaled = angle * numLanes / 3.14159265;
                float laneId = floor(angleScaled);
                float laneFract = fract(angleScaled);
                
                float laneSeed = hash1(laneId * 17.43);
                
                vec3 trailColor = vec3(0.0);
                if (p.x + p.y * 0.1 < 0.0) {
                  if (laneSeed < 0.3) {
                    trailColor = vec3(1.0, 0.95, 0.85);
                  } else if (laneSeed < 0.6) {
                    trailColor = vec3(0.85, 0.95, 1.0);
                  } else {
                    trailColor = vec3(1.0, 0.8, 0.4);
                  }
                } else {
                  if (laneSeed < 0.5) {
                    trailColor = vec3(1.0, 0.1, 0.15);
                  } else if (laneSeed < 0.8) {
                    trailColor = vec3(1.0, 0.35, 0.05);
                  } else {
                    trailColor = vec3(0.95, 0.05, 0.5);
                  }
                }
                
                float activeLane = step(0.35, hash1(laneId * 31.89 + 12.4));
                if (activeLane < 0.5) return vec3(0.0);
                
                float laneSpeed = 0.5 + 1.5 * hash1(laneId * 7.51);
                
                float cellZ = z * 0.15 - displacement * 0.25 * laneSpeed;
                float cellIdZ = floor(cellZ);
                float cellFractZ = fract(cellZ);
                
                float cellSeed = hash(vec2(laneId, cellIdZ));
                
                float activeStreak = step(0.4, cellSeed);
                if (activeStreak < 0.5) return vec3(0.0);
                
                float streakWidth = 0.04 + 0.08 * hash1(laneId * 41.2 + cellIdZ * 13.7);
                float centerOffset = 0.3 + 0.4 * hash1(laneId * 2.3 + cellIdZ * 9.1);
                
                float distToCenter = abs(laneFract - centerOffset);
                float horizGlow = exp(-distToCenter * distToCenter / (2.0 * streakWidth * streakWidth));
                float vertGlow = smoothstep(0.0, 0.15, cellFractZ) * smoothstep(1.0, 0.85, cellFractZ);
                float radialFade = smoothstep(0.02, 0.15, r) * smoothstep(2.2, 0.6, r);
                float speedBrightness = 1.0 + (u_speed - 1.0) * 0.3;
                
                float intensity = horizGlow * vertGlow * radialFade * speedBrightness;
                
                float sparks = 0.0;
                if (hash1(laneId * 51.2 + cellIdZ * 19.3) > 0.85) {
                  float sparkZ = fract(cellZ * 10.0);
                  sparks = smoothstep(0.02, 0.0, abs(laneFract - centerOffset)) * 
                           smoothstep(0.1, 0.0, abs(sparkZ - 0.5)) * 
                           smoothstep(0.1, 0.4, r);
                }
                
                return trailColor * intensity * 2.2 + vec3(1.0) * sparks * intensity * 1.5;
              }
          
              void main() {
                vec2 p = (gl_FragCoord.xy - 0.5 * u_resolution) / u_resolution.y;
                p += u_shake;
                
                vec2 mouse = (u_mouse - 0.5 * u_resolution) / u_resolution.y;
                p -= mouse * 0.12;
                
                float r = length(p);
                
                vec3 baseColor = vec3(0.004, 0.003, 0.008);
                float vignette = smoothstep(2.0, 0.4, r);
                baseColor *= vignette;
                
                vec3 trails = vec3(0.0);
                trails += getLightTrails(p, u_displacement, p.x);
                trails += getLightTrails(p * 1.6, u_displacement * 1.3 + 4.5, p.x) * 0.45;
                trails += getLightTrails(p * 0.6, u_displacement * 0.8 - 9.1, p.x) * 0.7;
                
                float roadGlow = smoothstep(0.8, 0.0, length(p - vec2(0.3, -0.6))) * 0.07;
                vec3 roadGlowColor = vec3(0.9, 0.1, 0.4) * roadGlow;
                
                float lightGlow = smoothstep(1.0, 0.0, length(p - vec2(-0.4, -0.5))) * 0.06;
                vec3 lightGlowColor = vec3(0.5, 0.8, 1.0) * lightGlow;
                
                vec3 finalColor = baseColor + trails + roadGlowColor + lightGlowColor;
                finalColor = smoothstep(-0.02, 1.02, finalColor);
                
                float scanline = sin(gl_FragCoord.y * 1.5) * 0.04;
                finalColor -= vec3(scanline) * vignette;
                
                gl_FragColor = vec4(finalColor, 1.0);
              }
            \`;
          
            const vs = createShader(gl, gl.VERTEX_SHADER, vsSource);
            const fs = createShader(gl, gl.FRAGMENT_SHADER, fsSource);
            if (!vs || !fs) return;
          
            const program = gl.createProgram();
            gl.attachShader(program, vs);
            gl.attachShader(program, fs);
            gl.linkProgram(program);
            if (!gl.getProgramParameter(program, gl.LINK_STATUS)) return;
          
            gl.useProgram(program);
          
            const positionLoc = gl.getAttribLocation(program, 'position');
            gl.enableVertexAttribArray(positionLoc);
            gl.vertexAttribPointer(positionLoc, 2, gl.FLOAT, false, 0, 0);
          
            const uResolution = gl.getUniformLocation(program, 'u_resolution');
            const uTime = gl.getUniformLocation(program, 'u_time');
            const uDisplacement = gl.getUniformLocation(program, 'u_displacement');
            const uSpeed = gl.getUniformLocation(program, 'u_speed');
            const uMouse = gl.getUniformLocation(program, 'u_mouse');
            const uShake = gl.getUniformLocation(program, 'u_shake');
          
            let mouseX = 0, mouseY = 0;
            window.addEventListener('mousemove', (e) => {
              const rect = canvas.getBoundingClientRect();
              mouseX = e.clientX - rect.left;
              mouseY = rect.height - (e.clientY - rect.top);
            });
          
            window.addEventListener('touchmove', (e) => {
              if (e.touches.length > 0) {
                const touch = e.touches[0];
                const rect = canvas.getBoundingClientRect();
                mouseX = touch.clientX - rect.left;
                mouseY = rect.height - (touch.clientY - rect.top);
              }
            });
          
            let scrollSpeed = 1.0;
            let targetScrollSpeed = 1.0;
            window.addEventListener('wheel', (e) => {
              targetScrollSpeed += Math.abs(e.deltaY) * 0.012;
              targetScrollSpeed = Math.min(targetScrollSpeed, 10.0);
            });
          
            function resize() {
              const rect = canvas.parentNode ? canvas.parentNode.getBoundingClientRect() : null;
              const width = rect ? rect.width : window.innerWidth;
              const height = rect ? rect.height : window.innerHeight;
              if (canvas.width !== width || canvas.height !== height) {
                canvas.width = width;
                canvas.height = height;
                gl.viewport(0, 0, width, height);
              }
            }
            window.addEventListener('resize', resize);
            
            if (canvas.parentNode) {
              const observer = new MutationObserver(resize);
              observer.observe(canvas.parentNode, { attributes: true });
            }
          
            resize();
          
            let startTime = Date.now();
            let lastTime = Date.now();
            let displacement = 0;
          
            function render() {
              const now = Date.now();
              const dt = (now - lastTime) / 1000.0;
              lastTime = now;
          
              scrollSpeed += (targetScrollSpeed - scrollSpeed) * 0.12;
              targetScrollSpeed += (1.0 - targetScrollSpeed) * 0.05;
          
              displacement += scrollSpeed * dt * 4.5;
          
              let shakeX = 0.0;
              let shakeY = 0.0;
              if (scrollSpeed > 1.05) {
                const shakeFactor = (scrollSpeed - 1.0) * 0.0035;
                shakeX = (Math.random() - 0.5) * shakeFactor;
                shakeY = (Math.random() - 0.5) * shakeFactor;
              }
          
              let elapsed = (now - startTime) / 1000.0;
              
              gl.uniform2f(uResolution, canvas.width, canvas.height);
              gl.uniform1f(uTime, elapsed);
              gl.uniform1f(uDisplacement, displacement);
              gl.uniform1f(uSpeed, scrollSpeed);
              gl.uniform2f(uMouse, mouseX, mouseY);
              gl.uniform2f(uShake, shakeX, shakeY);
          
              gl.drawArrays(gl.TRIANGLES, 0, 6);
              requestAnimationFrame(render);
            }
            requestAnimationFrame(render);
          })();
          </script>
        ` }}
      />
    </div>
  );
}

Next.js App Router Component (use client)

'use client';

import React from 'react';

export default function MidnightJDMStreetRaceBackground() {
  

  return (
    <div 
       
      className="w-full h-full relative overflow-hidden"
    >
      <style dangerouslySetInnerHTML={{ __html: `
        #canvas-webgl-jdm-street-race {
          position: absolute;
          top: 0;
          left: 0;
          width: 100%;
          height: 100%;
          border: none;
        }
      ` }} />
      
      {/* HTML Structure */}
      <div 
        className="w-full h-full"
        dangerouslySetInnerHTML={{ __html: `
          <canvas id="canvas-webgl-jdm-street-race"></canvas>
          <script>
          (function() {
            const canvas = document.getElementById('canvas-webgl-jdm-street-race');
            const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
            if (!gl) return;
          
            const vertices = new Float32Array([
              -1, -1,  1, -1, -1,  1,
              -1,  1,  1, -1,  1,  1
            ]);
          
            const buffer = gl.createBuffer();
            gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
            gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
          
            function createShader(gl, type, source) {
              const shader = gl.createShader(type);
              gl.shaderSource(shader, source);
              gl.compileShader(shader);
              if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
                console.error(gl.getShaderInfoLog(shader));
                gl.deleteShader(shader);
                return null;
              }
              return shader;
            }
          
            const vsSource = \`
              attribute vec2 position;
              void main() {
                gl_Position = vec4(position, 0.0, 1.0);
              }
            \`;
          
            const fsSource = \`
              precision mediump float;
              uniform vec2 u_resolution;
              uniform float u_time;
              uniform float u_displacement;
              uniform float u_speed;
              uniform vec2 u_mouse;
              uniform vec2 u_shake;
          
              float hash(vec2 p) {
                p = fract(p * vec2(123.34, 456.21));
                p += dot(p, p + 45.32);
                return fract(p.x * p.y);
              }
          
              float hash1(float n) {
                return fract(sin(n) * 43758.5453);
              }
          
              vec3 getLightTrails(vec2 p, float displacement, float sideColorSign) {
                float r = length(p);
                float angle = atan(p.y, p.x);
                float z = 1.0 / (r + 0.015);
                
                float numLanes = 18.0;
                float angleScaled = angle * numLanes / 3.14159265;
                float laneId = floor(angleScaled);
                float laneFract = fract(angleScaled);
                
                float laneSeed = hash1(laneId * 17.43);
                
                vec3 trailColor = vec3(0.0);
                if (p.x + p.y * 0.1 < 0.0) {
                  if (laneSeed < 0.3) {
                    trailColor = vec3(1.0, 0.95, 0.85);
                  } else if (laneSeed < 0.6) {
                    trailColor = vec3(0.85, 0.95, 1.0);
                  } else {
                    trailColor = vec3(1.0, 0.8, 0.4);
                  }
                } else {
                  if (laneSeed < 0.5) {
                    trailColor = vec3(1.0, 0.1, 0.15);
                  } else if (laneSeed < 0.8) {
                    trailColor = vec3(1.0, 0.35, 0.05);
                  } else {
                    trailColor = vec3(0.95, 0.05, 0.5);
                  }
                }
                
                float activeLane = step(0.35, hash1(laneId * 31.89 + 12.4));
                if (activeLane < 0.5) return vec3(0.0);
                
                float laneSpeed = 0.5 + 1.5 * hash1(laneId * 7.51);
                
                float cellZ = z * 0.15 - displacement * 0.25 * laneSpeed;
                float cellIdZ = floor(cellZ);
                float cellFractZ = fract(cellZ);
                
                float cellSeed = hash(vec2(laneId, cellIdZ));
                
                float activeStreak = step(0.4, cellSeed);
                if (activeStreak < 0.5) return vec3(0.0);
                
                float streakWidth = 0.04 + 0.08 * hash1(laneId * 41.2 + cellIdZ * 13.7);
                float centerOffset = 0.3 + 0.4 * hash1(laneId * 2.3 + cellIdZ * 9.1);
                
                float distToCenter = abs(laneFract - centerOffset);
                float horizGlow = exp(-distToCenter * distToCenter / (2.0 * streakWidth * streakWidth));
                float vertGlow = smoothstep(0.0, 0.15, cellFractZ) * smoothstep(1.0, 0.85, cellFractZ);
                float radialFade = smoothstep(0.02, 0.15, r) * smoothstep(2.2, 0.6, r);
                float speedBrightness = 1.0 + (u_speed - 1.0) * 0.3;
                
                float intensity = horizGlow * vertGlow * radialFade * speedBrightness;
                
                float sparks = 0.0;
                if (hash1(laneId * 51.2 + cellIdZ * 19.3) > 0.85) {
                  float sparkZ = fract(cellZ * 10.0);
                  sparks = smoothstep(0.02, 0.0, abs(laneFract - centerOffset)) * 
                           smoothstep(0.1, 0.0, abs(sparkZ - 0.5)) * 
                           smoothstep(0.1, 0.4, r);
                }
                
                return trailColor * intensity * 2.2 + vec3(1.0) * sparks * intensity * 1.5;
              }
          
              void main() {
                vec2 p = (gl_FragCoord.xy - 0.5 * u_resolution) / u_resolution.y;
                p += u_shake;
                
                vec2 mouse = (u_mouse - 0.5 * u_resolution) / u_resolution.y;
                p -= mouse * 0.12;
                
                float r = length(p);
                
                vec3 baseColor = vec3(0.004, 0.003, 0.008);
                float vignette = smoothstep(2.0, 0.4, r);
                baseColor *= vignette;
                
                vec3 trails = vec3(0.0);
                trails += getLightTrails(p, u_displacement, p.x);
                trails += getLightTrails(p * 1.6, u_displacement * 1.3 + 4.5, p.x) * 0.45;
                trails += getLightTrails(p * 0.6, u_displacement * 0.8 - 9.1, p.x) * 0.7;
                
                float roadGlow = smoothstep(0.8, 0.0, length(p - vec2(0.3, -0.6))) * 0.07;
                vec3 roadGlowColor = vec3(0.9, 0.1, 0.4) * roadGlow;
                
                float lightGlow = smoothstep(1.0, 0.0, length(p - vec2(-0.4, -0.5))) * 0.06;
                vec3 lightGlowColor = vec3(0.5, 0.8, 1.0) * lightGlow;
                
                vec3 finalColor = baseColor + trails + roadGlowColor + lightGlowColor;
                finalColor = smoothstep(-0.02, 1.02, finalColor);
                
                float scanline = sin(gl_FragCoord.y * 1.5) * 0.04;
                finalColor -= vec3(scanline) * vignette;
                
                gl_FragColor = vec4(finalColor, 1.0);
              }
            \`;
          
            const vs = createShader(gl, gl.VERTEX_SHADER, vsSource);
            const fs = createShader(gl, gl.FRAGMENT_SHADER, fsSource);
            if (!vs || !fs) return;
          
            const program = gl.createProgram();
            gl.attachShader(program, vs);
            gl.attachShader(program, fs);
            gl.linkProgram(program);
            if (!gl.getProgramParameter(program, gl.LINK_STATUS)) return;
          
            gl.useProgram(program);
          
            const positionLoc = gl.getAttribLocation(program, 'position');
            gl.enableVertexAttribArray(positionLoc);
            gl.vertexAttribPointer(positionLoc, 2, gl.FLOAT, false, 0, 0);
          
            const uResolution = gl.getUniformLocation(program, 'u_resolution');
            const uTime = gl.getUniformLocation(program, 'u_time');
            const uDisplacement = gl.getUniformLocation(program, 'u_displacement');
            const uSpeed = gl.getUniformLocation(program, 'u_speed');
            const uMouse = gl.getUniformLocation(program, 'u_mouse');
            const uShake = gl.getUniformLocation(program, 'u_shake');
          
            let mouseX = 0, mouseY = 0;
            window.addEventListener('mousemove', (e) => {
              const rect = canvas.getBoundingClientRect();
              mouseX = e.clientX - rect.left;
              mouseY = rect.height - (e.clientY - rect.top);
            });
          
            window.addEventListener('touchmove', (e) => {
              if (e.touches.length > 0) {
                const touch = e.touches[0];
                const rect = canvas.getBoundingClientRect();
                mouseX = touch.clientX - rect.left;
                mouseY = rect.height - (touch.clientY - rect.top);
              }
            });
          
            let scrollSpeed = 1.0;
            let targetScrollSpeed = 1.0;
            window.addEventListener('wheel', (e) => {
              targetScrollSpeed += Math.abs(e.deltaY) * 0.012;
              targetScrollSpeed = Math.min(targetScrollSpeed, 10.0);
            });
          
            function resize() {
              const rect = canvas.parentNode ? canvas.parentNode.getBoundingClientRect() : null;
              const width = rect ? rect.width : window.innerWidth;
              const height = rect ? rect.height : window.innerHeight;
              if (canvas.width !== width || canvas.height !== height) {
                canvas.width = width;
                canvas.height = height;
                gl.viewport(0, 0, width, height);
              }
            }
            window.addEventListener('resize', resize);
            
            if (canvas.parentNode) {
              const observer = new MutationObserver(resize);
              observer.observe(canvas.parentNode, { attributes: true });
            }
          
            resize();
          
            let startTime = Date.now();
            let lastTime = Date.now();
            let displacement = 0;
          
            function render() {
              const now = Date.now();
              const dt = (now - lastTime) / 1000.0;
              lastTime = now;
          
              scrollSpeed += (targetScrollSpeed - scrollSpeed) * 0.12;
              targetScrollSpeed += (1.0 - targetScrollSpeed) * 0.05;
          
              displacement += scrollSpeed * dt * 4.5;
          
              let shakeX = 0.0;
              let shakeY = 0.0;
              if (scrollSpeed > 1.05) {
                const shakeFactor = (scrollSpeed - 1.0) * 0.0035;
                shakeX = (Math.random() - 0.5) * shakeFactor;
                shakeY = (Math.random() - 0.5) * shakeFactor;
              }
          
              let elapsed = (now - startTime) / 1000.0;
              
              gl.uniform2f(uResolution, canvas.width, canvas.height);
              gl.uniform1f(uTime, elapsed);
              gl.uniform1f(uDisplacement, displacement);
              gl.uniform1f(uSpeed, scrollSpeed);
              gl.uniform2f(uMouse, mouseX, mouseY);
              gl.uniform2f(uShake, shakeX, shakeY);
          
              gl.drawArrays(gl.TRIANGLES, 0, 6);
              requestAnimationFrame(render);
            }
            requestAnimationFrame(render);
          })();
          </script>
        ` }}
      />
    </div>
  );
}

Raw CSS Stylesheet Snippet

#canvas-webgl-jdm-street-race {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  border: none;
}