| 95 | }`; |
| 96 | |
| 97 | export const Plasma: React.FC<PlasmaProps> = ({ |
| 98 | color = "#ffffff", |
| 99 | speed = 1, |
| 100 | direction = "forward", |
| 101 | scale = 1, |
| 102 | opacity = 1, |
| 103 | mouseInteractive = true, |
| 104 | }) => { |
| 105 | const containerRef = useRef<HTMLDivElement | null>(null); |
| 106 | const mousePos = useRef({ x: 0, y: 0 }); |
| 107 | |
| 108 | useEffect(() => { |
| 109 | const container = containerRef.current; |
| 110 | if (!container) return; |
| 111 | |
| 112 | const useCustomColor = color ? 1.0 : 0.0; |
| 113 | const customColorRgb = color ? hexToRgb(color) : [1, 1, 1]; |
| 114 | |
| 115 | const directionMultiplier = direction === "reverse" ? -1.0 : 1.0; |
| 116 | |
| 117 | const canvas = document.createElement("canvas"); |
| 118 | const glContext = |
| 119 | canvas.getContext("webgl2", { |
| 120 | alpha: true, |
| 121 | antialias: false, |
| 122 | preserveDrawingBuffer: true, |
| 123 | }) || |
| 124 | canvas.getContext("webgl", { |
| 125 | alpha: true, |
| 126 | antialias: false, |
| 127 | preserveDrawingBuffer: true, |
| 128 | }); |
| 129 | if (!glContext) return; |
| 130 | |
| 131 | const renderer = new Renderer({ |
| 132 | canvas, |
| 133 | webgl: 2, |
| 134 | alpha: true, |
| 135 | antialias: false, |
| 136 | dpr: Math.min(window.devicePixelRatio || 1, 2), |
| 137 | }); |
| 138 | const gl = renderer.gl; |
| 139 | canvas.style.display = "block"; |
| 140 | canvas.style.width = "100%"; |
| 141 | canvas.style.height = "100%"; |
| 142 | container.appendChild(canvas); |
| 143 | |
| 144 | const geometry = new Triangle(gl); |
| 145 | |
| 146 | const program = new Program(gl, { |
| 147 | vertex: vertex, |
| 148 | fragment: fragment, |
| 149 | uniforms: { |
| 150 | iTime: { value: 0 }, |
| 151 | iResolution: { value: new Float32Array([1, 1]) }, |
| 152 | uCustomColor: { value: new Float32Array(customColorRgb) }, |
| 153 | uUseCustomColor: { value: useCustomColor }, |
| 154 | uSpeed: { value: speed * 0.4 }, |