|
1 | 1 | <script> |
2 | 2 | import { onMount, onDestroy } from 'svelte'; |
3 | 3 | import { browser } from '$app/environment'; |
| 4 | + import ThreeBackgroundFallback from './ThreeBackgroundFallback.svelte'; |
4 | 5 |
|
5 | 6 | let canvas; |
6 | 7 | let scene, camera, renderer; |
7 | 8 | let geometry, material, mesh; |
8 | 9 | let particles, particleGeometry, particleMaterial; |
9 | 10 | let animationId; |
10 | 11 | let mouseX = 0, mouseY = 0; |
| 12 | + let threeFailed = false; |
| 13 | + let showFallback = false; |
11 | 14 |
|
12 | 15 | onMount(async () => { |
13 | 16 | if (!browser) return; |
14 | 17 | |
15 | | - const THREE = await import('three'); |
16 | | - initThree(THREE); |
17 | | - animate(); |
18 | | - window.addEventListener('resize', handleResize); |
19 | | - window.addEventListener('mousemove', handleMouseMove); |
| 18 | + // Check if user prefers reduced motion |
| 19 | + const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches; |
| 20 | + if (prefersReducedMotion) { |
| 21 | + showFallback = true; |
| 22 | + return; |
| 23 | + } |
| 24 | +
|
| 25 | + try { |
| 26 | + // Check for WebGL support |
| 27 | + if (!window.WebGLRenderingContext) { |
| 28 | + throw new Error('WebGL not supported'); |
| 29 | + } |
| 30 | +
|
| 31 | + const canvas = document.createElement('canvas'); |
| 32 | + const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl'); |
| 33 | + if (!gl) { |
| 34 | + throw new Error('WebGL context not available'); |
| 35 | + } |
| 36 | + |
| 37 | + const THREE = await import('three'); |
| 38 | + initThree(THREE); |
| 39 | + animate(); |
| 40 | + window.addEventListener('resize', handleResize); |
| 41 | + window.addEventListener('mousemove', handleMouseMove); |
| 42 | + } catch (error) { |
| 43 | + console.warn('3D background failed to initialize, using fallback:', error); |
| 44 | + threeFailed = true; |
| 45 | + showFallback = true; |
| 46 | + } |
20 | 47 | }); |
21 | 48 |
|
22 | 49 | onDestroy(() => { |
|
130 | 157 | } |
131 | 158 | </script> |
132 | 159 |
|
133 | | -<canvas bind:this={canvas} class="three-canvas"></canvas> |
| 160 | +{#if showFallback} |
| 161 | + <ThreeBackgroundFallback /> |
| 162 | +{:else} |
| 163 | + <canvas bind:this={canvas} class="three-canvas" aria-hidden="true"></canvas> |
| 164 | +{/if} |
134 | 165 |
|
135 | 166 | <style> |
136 | 167 | .three-canvas { |
|
0 commit comments