mirror of
https://github.com/ad044/lainTSX.git
synced 2024-10-22 23:19:06 +00:00
adding words...
This commit is contained in:
parent
813063953a
commit
04bb8972d4
11 changed files with 351 additions and 246 deletions
1
public/3d_fonts/MediaWord.blob
Normal file
1
public/3d_fonts/MediaWord.blob
Normal file
File diff suppressed because one or more lines are too long
|
@ -4,8 +4,8 @@ import "./static/css/hub.css";
|
||||||
import "./static/css/main.css";
|
import "./static/css/main.css";
|
||||||
import { Canvas } from "react-three-fiber";
|
import { Canvas } from "react-three-fiber";
|
||||||
import Boot from "./components/Boot";
|
import Boot from "./components/Boot";
|
||||||
import MediaPlayer from "./components/MediaPlayer";
|
import MediaPlayer from "./components/MediaScene/MediaPlayer";
|
||||||
import MediaOverlay from "./components/MediaOverlay";
|
import MediaScene from "./components/MediaScene/MediaScene";
|
||||||
import EventStateManager from "./components/StateManagers/EventStateManager";
|
import EventStateManager from "./components/StateManagers/EventStateManager";
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
|
@ -27,12 +27,12 @@ const App = () => {
|
||||||
<EventStateManager />
|
<EventStateManager />
|
||||||
<Canvas concurrent>
|
<Canvas concurrent>
|
||||||
<Suspense fallback={null}>
|
<Suspense fallback={null}>
|
||||||
<MediaOverlay />
|
<MediaScene />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
{/*<MainScene />*/}
|
{/*<MainScene />*/}
|
||||||
</Canvas>
|
</Canvas>
|
||||||
</span>
|
</span>
|
||||||
<MediaPlayer />
|
{/*<MediaPlayer />*/}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,241 +0,0 @@
|
||||||
import React, { useCallback, useEffect, useRef, useState } from "react";
|
|
||||||
|
|
||||||
import grayTextureFile from "../static/sprite/gray_box.png";
|
|
||||||
import darkGrayTextureFile from "../static/sprite/dark_gray_box.png";
|
|
||||||
import mediaOverlayHud from "../static/sprite/media_hud.png";
|
|
||||||
|
|
||||||
import { useFrame, useLoader } from "react-three-fiber";
|
|
||||||
import * as THREE from "three";
|
|
||||||
import { OrbitControls } from "drei";
|
|
||||||
import { a, useTrail } from "@react-spring/three";
|
|
||||||
import { useMediaStore } from "../store";
|
|
||||||
import BigLetter from "./TextRenderer/BigLetter";
|
|
||||||
import MediumLetter from "./TextRenderer/MediumLetter";
|
|
||||||
import TextRenderer from "./TextRenderer/TextRenderer";
|
|
||||||
|
|
||||||
type ShapeProps = {
|
|
||||||
position: number[];
|
|
||||||
selectable?: boolean;
|
|
||||||
active?: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
const GrayCube = (props: ShapeProps) => {
|
|
||||||
const grayTex = useLoader(THREE.TextureLoader, grayTextureFile);
|
|
||||||
const darkGrayTex = useLoader(THREE.TextureLoader, darkGrayTextureFile);
|
|
||||||
|
|
||||||
const cubeRef = useRef<THREE.Object3D>();
|
|
||||||
|
|
||||||
useFrame(() => {
|
|
||||||
if (props.selectable && props.active) {
|
|
||||||
cubeRef.current!.rotation.y -= 0.015;
|
|
||||||
} else {
|
|
||||||
cubeRef.current!.rotation.y = 0;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<mesh
|
|
||||||
scale={[0.45, 0.5, 0.45]}
|
|
||||||
position={props.position as [number, number, number]}
|
|
||||||
rotation-y={0.15}
|
|
||||||
rotation-z={-0.02}
|
|
||||||
ref={cubeRef}
|
|
||||||
>
|
|
||||||
<boxBufferGeometry args={[1, 1, 1]} attach="geometry" />
|
|
||||||
<meshLambertMaterial
|
|
||||||
attach="material"
|
|
||||||
map={props.active ? grayTex : darkGrayTex}
|
|
||||||
/>
|
|
||||||
</mesh>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const GrayTriangularPrism = (props: ShapeProps) => {
|
|
||||||
const grayTex = useLoader(THREE.TextureLoader, grayTextureFile);
|
|
||||||
const darkGrayTex = useLoader(THREE.TextureLoader, darkGrayTextureFile);
|
|
||||||
|
|
||||||
const prismRef = useRef<THREE.Object3D>();
|
|
||||||
|
|
||||||
const verts = new Float32Array([
|
|
||||||
// Top
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
|
|
||||||
// Bottom
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
|
|
||||||
// Sides
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
|
|
||||||
// Hypotenuse
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
]);
|
|
||||||
|
|
||||||
useFrame(() => {
|
|
||||||
if (props.selectable && props.active) {
|
|
||||||
prismRef.current!.rotation.y -= 0.015;
|
|
||||||
} else {
|
|
||||||
prismRef.current!.rotation.y = 0;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<mesh
|
|
||||||
scale={[0.45, 0.5, 0.45]}
|
|
||||||
position={props.position as [number, number, number]}
|
|
||||||
rotation-y={0.15}
|
|
||||||
rotation-z={-0.02}
|
|
||||||
ref={prismRef}
|
|
||||||
>
|
|
||||||
<boxBufferGeometry args={[1, 1, 1]} attach="geometry" />
|
|
||||||
<meshLambertMaterial
|
|
||||||
attach="material"
|
|
||||||
map={props.active ? grayTex : darkGrayTex}
|
|
||||||
/>
|
|
||||||
</mesh>
|
|
||||||
|
|
||||||
// <mesh
|
|
||||||
// scale={[0.45, 0.5, 0.45]}
|
|
||||||
// position={props.position as [number, number, number]}
|
|
||||||
// rotation-y={0.15}
|
|
||||||
// rotation-x={-1.45}
|
|
||||||
// ref={prismRef}
|
|
||||||
// >
|
|
||||||
// <bufferGeometry attach="geometry">
|
|
||||||
// <bufferAttribute
|
|
||||||
// array={verts}
|
|
||||||
// itemSize={3}
|
|
||||||
// count={verts.length / 3}
|
|
||||||
// attachObject={["attributes", "position"]}
|
|
||||||
// />
|
|
||||||
// </bufferGeometry>
|
|
||||||
// <meshBasicMaterial
|
|
||||||
// side={THREE.DoubleSide}
|
|
||||||
// attach="material"
|
|
||||||
// map={props.active ? grayTex : darkGrayTex}
|
|
||||||
// />
|
|
||||||
// </mesh>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const MediaOverlay = () => {
|
|
||||||
const [grayCubesActive, setGrayCubesActive] = useState(false);
|
|
||||||
const mediaHudOverlayTex = useLoader(THREE.TextureLoader, mediaOverlayHud);
|
|
||||||
|
|
||||||
const activeMediaElement = useMediaStore((state) => state.activeMediaElement);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<OrbitControls />
|
|
||||||
<sprite scale={[5, 1, 1]} position={[2.65, 2.5, 0]}>
|
|
||||||
<spriteMaterial attach="material" map={mediaHudOverlayTex} />
|
|
||||||
</sprite>
|
|
||||||
<group position={[0.4, -0.3, 0]}>
|
|
||||||
<group position={[0, 0, 13]} scale={[1, 1, 1]}>
|
|
||||||
<TextRenderer />
|
|
||||||
</group>
|
|
||||||
|
|
||||||
<pointLight intensity={1.2} color={0xffffff} position={[-2, 0, 3]} />
|
|
||||||
|
|
||||||
<GrayCube position={[-2.7, -1.6, 0.6]} active={grayCubesActive} />
|
|
||||||
<GrayTriangularPrism
|
|
||||||
position={[-3.5, -1.6, 0.6]}
|
|
||||||
active={!grayCubesActive}
|
|
||||||
/>
|
|
||||||
<GrayCube position={[-3.5, -0.9, 0.6]} active={grayCubesActive} />
|
|
||||||
<GrayTriangularPrism
|
|
||||||
position={[-2.7, -0.9, 0.6]}
|
|
||||||
active={!grayCubesActive}
|
|
||||||
/>
|
|
||||||
<GrayTriangularPrism
|
|
||||||
position={[-3.5, -1.6, 1.2]}
|
|
||||||
active={!grayCubesActive}
|
|
||||||
/>
|
|
||||||
<GrayCube position={[-3.5, -0.9, 1.2]} active={grayCubesActive} />
|
|
||||||
<GrayCube
|
|
||||||
position={[-2.7, -1.6, 1.2]}
|
|
||||||
active={grayCubesActive}
|
|
||||||
selectable={true}
|
|
||||||
/>
|
|
||||||
<GrayTriangularPrism
|
|
||||||
position={[-2.7, -0.9, 1.2]}
|
|
||||||
active={!grayCubesActive}
|
|
||||||
selectable={true}
|
|
||||||
/>
|
|
||||||
</group>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default MediaOverlay;
|
|
39
src/components/MediaScene/LeftSide/Cube.tsx
Normal file
39
src/components/MediaScene/LeftSide/Cube.tsx
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
import { useFrame, useLoader } from "react-three-fiber";
|
||||||
|
import * as THREE from "three";
|
||||||
|
import grayTextureFile from "../../../static/sprite/gray_box.png";
|
||||||
|
import darkGrayTextureFile from "../../../static/sprite/dark_gray_box.png";
|
||||||
|
import React, { useRef } from "react";
|
||||||
|
import { ShapeProps } from "./LeftSide";
|
||||||
|
|
||||||
|
const Cube = (props: ShapeProps) => {
|
||||||
|
const grayTex = useLoader(THREE.TextureLoader, grayTextureFile);
|
||||||
|
const darkGrayTex = useLoader(THREE.TextureLoader, darkGrayTextureFile);
|
||||||
|
|
||||||
|
const cubeRef = useRef<THREE.Object3D>();
|
||||||
|
|
||||||
|
useFrame(() => {
|
||||||
|
if (props.selectable && props.active) {
|
||||||
|
cubeRef.current!.rotation.y -= 0.015;
|
||||||
|
} else {
|
||||||
|
cubeRef.current!.rotation.y = 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<mesh
|
||||||
|
scale={[0.45, 0.5, 0.45]}
|
||||||
|
position={props.position as [number, number, number]}
|
||||||
|
rotation-y={0.15}
|
||||||
|
rotation-z={-0.02}
|
||||||
|
ref={cubeRef}
|
||||||
|
>
|
||||||
|
<boxBufferGeometry args={[1, 1, 1]} attach="geometry" />
|
||||||
|
<meshLambertMaterial
|
||||||
|
attach="material"
|
||||||
|
map={props.active ? grayTex : darkGrayTex}
|
||||||
|
/>
|
||||||
|
</mesh>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Cube;
|
43
src/components/MediaScene/LeftSide/LeftSide.tsx
Normal file
43
src/components/MediaScene/LeftSide/LeftSide.tsx
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
import React from "react";
|
||||||
|
import TriangularPrism from "./TriangularPrism";
|
||||||
|
import Cube from "./Cube";
|
||||||
|
|
||||||
|
type LeftSideShapesProps = {
|
||||||
|
active: "cube" | "triangle" | "";
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ShapeProps = {
|
||||||
|
position: number[];
|
||||||
|
selectable?: boolean;
|
||||||
|
active?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
const LeftSide = (props: LeftSideShapesProps) => {
|
||||||
|
const cubesActive = props.active === "cube";
|
||||||
|
const trianglesActive = props.active === "triangle";
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Cube position={[-2.7, -1.6, 0.6]} active={cubesActive} />
|
||||||
|
<TriangularPrism position={[-3.5, -1.6, 0.6]} active={!trianglesActive} />
|
||||||
|
<Cube position={[-3.5, -0.9, 0.6]} active={cubesActive} />
|
||||||
|
<TriangularPrism position={[-2.7, -0.9, 0.6]} active={trianglesActive} />
|
||||||
|
<Cube position={[-3.5, -0.9, 1.2]} active={cubesActive} />
|
||||||
|
<TriangularPrism position={[-3.5, -1.6, 1.2]} active={trianglesActive} />
|
||||||
|
|
||||||
|
{/*main two*/}
|
||||||
|
<Cube
|
||||||
|
position={[-2.7, -1.6, 1.2]}
|
||||||
|
active={cubesActive}
|
||||||
|
selectable={true}
|
||||||
|
/>
|
||||||
|
<TriangularPrism
|
||||||
|
position={[-2.7, -0.9, 1.2]}
|
||||||
|
active={trianglesActive}
|
||||||
|
selectable={true}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default LeftSide;
|
147
src/components/MediaScene/LeftSide/TriangularPrism.tsx
Normal file
147
src/components/MediaScene/LeftSide/TriangularPrism.tsx
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
import { useFrame, useLoader } from "react-three-fiber";
|
||||||
|
import * as THREE from "three";
|
||||||
|
import grayTextureFile from "../../../static/sprite/gray_box.png";
|
||||||
|
import darkGrayTextureFile from "../../../static/sprite/dark_gray_box.png";
|
||||||
|
import React, { useRef } from "react";
|
||||||
|
import { ShapeProps } from "./LeftSide";
|
||||||
|
|
||||||
|
const TriangularPrism = (props: ShapeProps) => {
|
||||||
|
const grayTex = useLoader(THREE.TextureLoader, grayTextureFile);
|
||||||
|
const darkGrayTex = useLoader(THREE.TextureLoader, darkGrayTextureFile);
|
||||||
|
|
||||||
|
const prismRef = useRef<THREE.Object3D>();
|
||||||
|
|
||||||
|
const verts = new Float32Array([
|
||||||
|
// Top
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
|
||||||
|
// Bottom
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
|
||||||
|
// Sides
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
|
||||||
|
// Hypotenuse
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
]);
|
||||||
|
|
||||||
|
useFrame(() => {
|
||||||
|
if (props.selectable && props.active) {
|
||||||
|
prismRef.current!.rotation.y -= 0.015;
|
||||||
|
} else {
|
||||||
|
prismRef.current!.rotation.y = 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<mesh
|
||||||
|
scale={[0.45, 0.5, 0.45]}
|
||||||
|
position={props.position as [number, number, number]}
|
||||||
|
rotation-y={0.15}
|
||||||
|
rotation-z={-0.02}
|
||||||
|
ref={prismRef}
|
||||||
|
>
|
||||||
|
<boxBufferGeometry args={[1, 1, 1]} attach="geometry" />
|
||||||
|
<meshLambertMaterial
|
||||||
|
attach="material"
|
||||||
|
map={props.active ? grayTex : darkGrayTex}
|
||||||
|
/>
|
||||||
|
</mesh>
|
||||||
|
|
||||||
|
// <mesh
|
||||||
|
// scale={[0.45, 0.5, 0.45]}
|
||||||
|
// position={props.position as [number, number, number]}
|
||||||
|
// rotation-y={0.15}
|
||||||
|
// rotation-x={-1.45}
|
||||||
|
// ref={prismRef}
|
||||||
|
// >
|
||||||
|
// <bufferGeometry attach="geometry">
|
||||||
|
// <bufferAttribute
|
||||||
|
// array={verts}
|
||||||
|
// itemSize={3}
|
||||||
|
// count={verts.length / 3}
|
||||||
|
// attachObject={["attributes", "position"]}
|
||||||
|
// />
|
||||||
|
// </bufferGeometry>
|
||||||
|
// <meshBasicMaterial
|
||||||
|
// side={THREE.DoubleSide}
|
||||||
|
// attach="material"
|
||||||
|
// map={props.active ? grayTex : darkGrayTex}
|
||||||
|
// />
|
||||||
|
// </mesh>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TriangularPrism;
|
|
@ -1,6 +1,6 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import ReactPlayer from "react-player";
|
import ReactPlayer from "react-player";
|
||||||
import test from "../static/movie/test.webm";
|
import test from "../../static/movie/test.webm";
|
||||||
|
|
||||||
const MediaPlayer = () => {
|
const MediaPlayer = () => {
|
||||||
return (
|
return (
|
43
src/components/MediaScene/MediaScene.tsx
Normal file
43
src/components/MediaScene/MediaScene.tsx
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
import React, { useRef, useState } from "react";
|
||||||
|
|
||||||
|
import grayTextureFile from "../../static/sprite/gray_box.png";
|
||||||
|
import darkGrayTextureFile from "../../static/sprite/dark_gray_box.png";
|
||||||
|
import mediaOverlayHud from "../../static/sprite/media_hud.png";
|
||||||
|
|
||||||
|
import { useFrame, useLoader } from "react-three-fiber";
|
||||||
|
import * as THREE from "three";
|
||||||
|
import { OrbitControls } from "drei";
|
||||||
|
import { useMediaStore, useMediaWordStore } from "../../store";
|
||||||
|
import TextRenderer from "../TextRenderer/TextRenderer";
|
||||||
|
import LeftSide from "./LeftSide/LeftSide";
|
||||||
|
import Word from "./Word";
|
||||||
|
|
||||||
|
const MediaScene = () => {
|
||||||
|
const [grayCubesActive, setGrayCubesActive] = useState(false);
|
||||||
|
const mediaHudOverlayTex = useLoader(THREE.TextureLoader, mediaOverlayHud);
|
||||||
|
const words = useMediaWordStore((state) => state.words);
|
||||||
|
|
||||||
|
const activeMediaElement = useMediaStore((state) => state.activeMediaElement);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<OrbitControls />
|
||||||
|
<sprite scale={[5, 1, 1]} position={[2.65, 2.5, 0]}>
|
||||||
|
<spriteMaterial attach="material" map={mediaHudOverlayTex} />
|
||||||
|
</sprite>
|
||||||
|
<group position={[0.4, -0.3, 0]}>
|
||||||
|
<group position={[0, 0, 13]} scale={[1, 1, 1]}>
|
||||||
|
<TextRenderer />
|
||||||
|
</group>
|
||||||
|
|
||||||
|
<pointLight intensity={1.2} color={0xffffff} position={[-2, 0, 3]} />
|
||||||
|
<LeftSide active={"cube"} />
|
||||||
|
<Word word={words[0]} posX={1} posY={1} />
|
||||||
|
<Word word={words[1]} posX={0} posY={0} />
|
||||||
|
<Word word={words[2]} posX={-1} posY={-1} />
|
||||||
|
</group>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default MediaScene;
|
49
src/components/MediaScene/Word.tsx
Normal file
49
src/components/MediaScene/Word.tsx
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
import React, { useMemo } from "react";
|
||||||
|
import * as THREE from "three";
|
||||||
|
import wordInactiveTexture from "../../static/sprite/word_background.png";
|
||||||
|
import wordActiveTexture from "../../static/sprite/word_background_active.png";
|
||||||
|
import { useLoader } from "react-three-fiber";
|
||||||
|
|
||||||
|
type WordProps = {
|
||||||
|
word: string;
|
||||||
|
posX: number;
|
||||||
|
posY: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
const Word = (props: WordProps) => {
|
||||||
|
const wordFont = useLoader(THREE.FontLoader, "/3d_fonts/MediaWord.blob");
|
||||||
|
const config = useMemo(
|
||||||
|
() => ({
|
||||||
|
font: wordFont,
|
||||||
|
size: 1,
|
||||||
|
}),
|
||||||
|
[wordFont]
|
||||||
|
);
|
||||||
|
|
||||||
|
const wordInactiveTex = useLoader(THREE.TextureLoader, wordInactiveTexture);
|
||||||
|
const wordActiveTex = useLoader(THREE.TextureLoader, wordActiveTexture);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<group position-x={props.posX} position-y={props.posY}>
|
||||||
|
<mesh scale={[0.4, 0.4, 0]} position={[-3.9, 1.915, 0]} renderOrder={3}>
|
||||||
|
<planeBufferGeometry attach="geometry" />
|
||||||
|
<textGeometry attach="geometry" args={[props.word, config]} />
|
||||||
|
<meshBasicMaterial
|
||||||
|
attach="material"
|
||||||
|
color={0x000000}
|
||||||
|
transparent={true}
|
||||||
|
/>
|
||||||
|
</mesh>
|
||||||
|
|
||||||
|
<sprite scale={[4.2, 0.45, 1]} position={[-2, 2, 0]} renderOrder={2}>
|
||||||
|
<spriteMaterial
|
||||||
|
attach="material"
|
||||||
|
map={wordInactiveTex}
|
||||||
|
alphaTest={0.01}
|
||||||
|
/>
|
||||||
|
</sprite>
|
||||||
|
</group>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Word;
|
2
src/react-app-env.d.ts
vendored
2
src/react-app-env.d.ts
vendored
|
@ -8,3 +8,5 @@ declare module "threejs-slice-geometry" {
|
||||||
const src: any;
|
const src: any;
|
||||||
export default src;
|
export default src;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare module '*.ttf';
|
||||||
|
|
22
src/store.ts
22
src/store.ts
|
@ -85,6 +85,17 @@ type MiddleRingState = {
|
||||||
setMiddleRingAnimDuration: (to: number) => void;
|
setMiddleRingAnimDuration: (to: number) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type MediaWordState = {
|
||||||
|
words: string[];
|
||||||
|
fstWordPos: number[];
|
||||||
|
sndWordPos: number[];
|
||||||
|
thirdWordPos: number[];
|
||||||
|
setWords: (to: string[]) => void;
|
||||||
|
setFstWordPos: (to: number[]) => void;
|
||||||
|
setSndWordPos: (to: number[]) => void;
|
||||||
|
setThirdWordPos: (to: number[]) => void;
|
||||||
|
};
|
||||||
|
|
||||||
type MediaState = {
|
type MediaState = {
|
||||||
activeMediaElement: string;
|
activeMediaElement: string;
|
||||||
leftColActiveMediaElement: string;
|
leftColActiveMediaElement: string;
|
||||||
|
@ -244,3 +255,14 @@ export const useMediaStore = create<MediaState>((set) => ({
|
||||||
setLeftColActiveMediaElementTextPos: (to) =>
|
setLeftColActiveMediaElementTextPos: (to) =>
|
||||||
set(() => ({ leftColActiveMediaElementTextPos: to })),
|
set(() => ({ leftColActiveMediaElementTextPos: to })),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
export const useMediaWordStore = create<MediaWordState>((set) => ({
|
||||||
|
words: ["eye", "quiet", "hallucination"],
|
||||||
|
fstWordPos: [0, 0, 0],
|
||||||
|
sndWordPos: [0, 0, 0],
|
||||||
|
thirdWordPos: [0, 0, 0],
|
||||||
|
setWords: (to) => set(() => ({ words: to })),
|
||||||
|
setFstWordPos: (to) => set(() => ({ fstWordPos: to })),
|
||||||
|
setSndWordPos: (to) => set(() => ({ sndWordPos: to })),
|
||||||
|
setThirdWordPos: (to) => set(() => ({ thirdWordPos: to })),
|
||||||
|
}));
|
||||||
|
|
Loading…
Reference in a new issue