diff --git a/src/app/components/with-time-loop/with-time-loop.tsx b/src/app/components/with-time-loop/with-time-loop.tsx deleted file mode 100644 index f8962f74..00000000 --- a/src/app/components/with-time-loop/with-time-loop.tsx +++ /dev/null @@ -1,64 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -import hoistNonReactStatics from 'hoist-non-react-statics'; -import raf from 'raf'; -import React, { - JSXElementConstructor, - ReactElement, - useEffect, - useRef, - useState, -} from 'react'; - -/** - * @param C - * @param root0 - * @param root0.refreshRate - * @see https://github.com/gre/gl-react/blob/master/packages/cookbook/src/HOC/timeLoop.js - */ -export function withTimeLoop(C: JSXElementConstructor, {refreshRate = 60} = {}): JSXElementConstructor { - function TimeLoop({...props}): ReactElement { - const [time, setTime] = useState(0); - const [tick, setTick] = useState(0); - const savedRequestAnimationFrame = useRef(null); - - useEffect(() => { - let startTime; - let lastTime; - - const interval = 1000 / refreshRate; - - lastTime = -interval; - - const loop = (currentTime) => { - savedRequestAnimationFrame.current = raf(loop); - - if (!startTime) { - startTime = currentTime; - } - - if (currentTime - lastTime > interval) { - setTime(currentTime - startTime); - setTick((t) => t + 1); - lastTime = currentTime; - } - }; - - savedRequestAnimationFrame.current = raf(loop); - - return () => { - raf.cancel(savedRequestAnimationFrame.current); - }; - }, []); - - return ( - <> - {/* eslint-disable-next-line react/jsx-props-no-spreading */} - - - ); - } - - hoistNonReactStatics(TimeLoop, C); - - return TimeLoop; -} diff --git a/src/components/texture/plane.component.tsx b/src/components/texture/plane.component.tsx new file mode 100644 index 00000000..a8dbe06e --- /dev/null +++ b/src/components/texture/plane.component.tsx @@ -0,0 +1,45 @@ +import {useFrame} from '@react-three/fiber'; +import React, {useMemo} from 'react'; +import fragmentShader from 'src/components/texture/texture.fragment.glsl'; +import vertexShader from 'src/components/texture/texture.vertex.glsl'; +import {ShaderMaterial, Texture} from 'three'; + +interface Props { + size: number; + texture: Texture; + ratio: number; +} + +export function PlaneComponent({size, texture, ratio}: Props) { + const material = useMemo( + () => + new ShaderMaterial({ + uniforms: { + u_texture: {value: texture}, + u_ratio: {value: ratio}, + u_time: {value: 0}, + }, + vertexShader, + fragmentShader, + }), + // eslint-disable-next-line react-hooks/exhaustive-deps + [], + ); + + useFrame(({clock}) => { + material.uniforms.u_time.value = clock.getElapsedTime(); + material.uniforms.u_ratio.value = ratio; + }); + + return ( + + + + + ); +} diff --git a/src/components/texture/texture.component.tsx b/src/components/texture/texture.component.tsx index 2f4a4232..337050b9 100644 --- a/src/components/texture/texture.component.tsx +++ b/src/components/texture/texture.component.tsx @@ -1,10 +1,9 @@ -import {Canvas, useFrame} from '@react-three/fiber'; +import {Canvas} from '@react-three/fiber'; import React, {ReactElement, useMemo} from 'react'; import {p} from 'src/app/shared.styles'; +import {PlaneComponent} from 'src/components/texture/plane.component'; import {mapRange} from 'src/utils/map-range/map-range'; -import {ShaderMaterial, TextureLoader} from 'three'; - -import fragmentShader from './texture.shaders.fragment.glsl'; +import {TextureLoader} from 'three'; interface Props { image: string; @@ -12,49 +11,6 @@ interface Props { width: number; } -const vertexShader = ` - varying vec2 v_uv; - - void main() { - v_uv = uv; - gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); - } -`; - -function Plane({size, texture, ratio}) { - const material = useMemo( - () => - new ShaderMaterial({ - uniforms: { - u_texture: {value: texture}, - u_ratio: {value: ratio}, - u_time: {value: 0}, - }, - vertexShader, - fragmentShader, - }), - // eslint-disable-next-line react-hooks/exhaustive-deps - [], - ); - - useFrame(({clock}) => { - material.uniforms.u_time.value = clock.getElapsedTime(); - material.uniforms.u_ratio.value = ratio; - }); - - return ( - - - - - ); -} - export function TextureComponent({image, dryWet, width}: Props): ReactElement { const texture = new TextureLoader().load(image); const size = useMemo(() => width / 100 - (p / 100) * 2, [width]); @@ -62,7 +18,7 @@ export function TextureComponent({image, dryWet, width}: Props): ReactElement { return ( - - {isDesktop ? ( - - ) : ( - - )} +