mirror of
https://github.com/ad044/lainTSX.git
synced 2024-10-22 23:19:06 +00:00
refactored yellow orb and audio analyser
This commit is contained in:
parent
47c65fd497
commit
403057bb2f
11 changed files with 145 additions and 144 deletions
|
@ -96,20 +96,20 @@ const KeyPressHandler = () => {
|
||||||
mainSubscene !== "level_selection" &&
|
mainSubscene !== "level_selection" &&
|
||||||
scene === "main"
|
scene === "main"
|
||||||
) {
|
) {
|
||||||
if (now > lainIdleCounter.current + 10000) {
|
// if (now > lainIdleCounter.current + 10000) {
|
||||||
lainManager({ event: getRandomIdleLainAnim() });
|
// lainManager({ event: getRandomIdleLainAnim() });
|
||||||
// after one idle animation plays, the second comes sooner than it would after a regular keypress
|
// // after one idle animation plays, the second comes sooner than it would after a regular keypress
|
||||||
lainIdleCounter.current = now - 2500;
|
// lainIdleCounter.current = now - 2500;
|
||||||
}
|
// }
|
||||||
if (now > idleSceneCounter.current + 15000) {
|
// if (now > idleSceneCounter.current + 15000) {
|
||||||
idleManager(getRandomIdleMedia());
|
// idleManager(getRandomIdleMedia());
|
||||||
sceneManager({ event: "play_idle_media" });
|
// sceneManager({ event: "play_idle_media" });
|
||||||
// put it on lock until the next action, since while the idle media plays, the
|
// // put it on lock until the next action, since while the idle media plays, the
|
||||||
// Date.now() value keeps increasing, which can result in another idle media playing right after one finishes
|
// // Date.now() value keeps increasing, which can result in another idle media playing right after one finishes
|
||||||
// one way to work around this would be to modify the value depending on the last played idle media's duration
|
// // one way to work around this would be to modify the value depending on the last played idle media's duration
|
||||||
// but i'm way too lazy for that
|
// // but i'm way too lazy for that
|
||||||
idleSceneCounter.current = -1;
|
// idleSceneCounter.current = -1;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -39,12 +39,12 @@ const LainSpeak = (props: LainTaKProps) => {
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
const analyser = useStore((state) => state.audioAnalyser);
|
|
||||||
|
|
||||||
const mouthRef = useRef<THREE.SpriteMaterial>();
|
const mouthRef = useRef<THREE.SpriteMaterial>();
|
||||||
|
const audioAnalyser = useStore((state) => state.audioAnalyser);
|
||||||
|
|
||||||
useFrame(() => {
|
useFrame(() => {
|
||||||
if (analyser) {
|
if (audioAnalyser) {
|
||||||
const freq = parseInt(String(analyser.getAverageFrequency()));
|
const freq = parseInt(String(audioAnalyser.getAverageFrequency()));
|
||||||
|
|
||||||
if (mouthRef.current) {
|
if (mouthRef.current) {
|
||||||
if (freq >= 50) {
|
if (freq >= 50) {
|
||||||
|
|
|
@ -1,118 +1,111 @@
|
||||||
import React, { memo, useRef, useState } from "react";
|
import React, { memo, useMemo, useRef } from "react";
|
||||||
import { useFrame, useLoader } from "react-three-fiber";
|
import { useFrame, useLoader } from "react-three-fiber";
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
import orbSprite from "../../static/sprite/orb.png";
|
import orbSprite from "../../static/sprite/orb.png";
|
||||||
import { useStore } from "../../store";
|
|
||||||
|
|
||||||
// initialize outside the component otherwise it gets overwritten when it rerenders
|
|
||||||
let orbIdx = 0;
|
|
||||||
let orbDirectionChangeCount = 0;
|
|
||||||
let renderOrder = -1;
|
|
||||||
|
|
||||||
type YellowOrbProps = {
|
type YellowOrbProps = {
|
||||||
visible: boolean;
|
visible: boolean;
|
||||||
}
|
};
|
||||||
|
|
||||||
const YellowOrb = (props: YellowOrbProps) => {
|
const YellowOrb = memo((props: YellowOrbProps) => {
|
||||||
const orbRef = useRef<THREE.Object3D>();
|
const orbRef = useRef<THREE.Object3D>();
|
||||||
const [orbDirection, setOrbDirection] = useState("left");
|
const idxRef = useRef(0);
|
||||||
const [currentCurve, setCurrentCurve] = useState("first");
|
const directionChangeCountRef = useRef(0);
|
||||||
|
// left or right (0/1)
|
||||||
|
const directionRef = useRef(0);
|
||||||
|
// first curve and second curve (0/1)
|
||||||
|
const curveIdxRef = useRef(0);
|
||||||
|
|
||||||
const orbSpriteTexture = useLoader(THREE.TextureLoader, orbSprite);
|
const orbSpriteTexture = useLoader(THREE.TextureLoader, orbSprite);
|
||||||
|
|
||||||
// first one goes from up to down left to right
|
// first one goes from up to down left to right
|
||||||
const firstCurve = new THREE.QuadraticBezierCurve3(
|
// second one goes from down to up left to right
|
||||||
|
const curves = useMemo(
|
||||||
|
() => [
|
||||||
|
new THREE.QuadraticBezierCurve3(
|
||||||
new THREE.Vector3(1.2, 0, 0),
|
new THREE.Vector3(1.2, 0, 0),
|
||||||
new THREE.Vector3(0.5, -0.8, 0),
|
new THREE.Vector3(0.5, -0.8, 0),
|
||||||
new THREE.Vector3(-1.2, 1, 0)
|
new THREE.Vector3(-1.2, 1, 0)
|
||||||
);
|
),
|
||||||
|
new THREE.QuadraticBezierCurve3(
|
||||||
// second one goes from down to up left to right
|
|
||||||
const secondCurve = new THREE.QuadraticBezierCurve3(
|
|
||||||
new THREE.Vector3(-1.2, -0.8, 0),
|
new THREE.Vector3(-1.2, -0.8, 0),
|
||||||
new THREE.Vector3(-0.5, -0.1, 0),
|
new THREE.Vector3(-0.5, -0.1, 0),
|
||||||
new THREE.Vector3(1.2, 0.8, 0)
|
new THREE.Vector3(1.2, 0.8, 0)
|
||||||
|
),
|
||||||
|
],
|
||||||
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
useFrame(() => {
|
useFrame(() => {
|
||||||
if (props.visible) {
|
if (props.visible) {
|
||||||
let orbPosFirst = firstCurve.getPoint(orbIdx / 250);
|
const orbPosFirst = curves[0].getPoint(idxRef.current / 250);
|
||||||
let orbPosSecond = secondCurve.getPoint(orbIdx / 250);
|
const orbPosSecond = curves[1].getPoint(idxRef.current / 250);
|
||||||
|
|
||||||
if (orbPosFirst.x < -1.4) {
|
if (orbPosFirst.x < -1.4) {
|
||||||
switch (currentCurve) {
|
if (curveIdxRef.current === 0) {
|
||||||
case "first":
|
directionRef.current = 1;
|
||||||
setOrbDirection("right");
|
if (orbRef.current) orbRef.current.renderOrder = 0;
|
||||||
renderOrder = 0;
|
} else {
|
||||||
break;
|
directionRef.current = 0;
|
||||||
case "second":
|
|
||||||
setOrbDirection("left");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
orbDirectionChangeCount++;
|
if (directionChangeCountRef.current) directionChangeCountRef.current++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (orbPosFirst.x > 1.4) {
|
if (orbPosFirst.x > 1.4) {
|
||||||
switch (currentCurve) {
|
if (curveIdxRef.current === 0) {
|
||||||
case "first":
|
directionRef.current = 0;
|
||||||
setOrbDirection("left");
|
} else {
|
||||||
break;
|
directionRef.current = 1;
|
||||||
case "second":
|
|
||||||
setOrbDirection("right");
|
if (orbRef.current) orbRef.current.renderOrder = -1;
|
||||||
renderOrder = -1;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
orbDirectionChangeCount++;
|
if (directionChangeCountRef.current) directionChangeCountRef.current++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (orbDirection === "left") {
|
if (directionRef.current === 0) {
|
||||||
switch (currentCurve) {
|
if (curveIdxRef.current === 0) {
|
||||||
case "first":
|
idxRef.current++;
|
||||||
orbIdx++;
|
} else {
|
||||||
break;
|
idxRef.current--;
|
||||||
case "second":
|
|
||||||
orbIdx--;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch (currentCurve) {
|
if (curveIdxRef.current === 0) {
|
||||||
case "first":
|
idxRef.current--;
|
||||||
orbIdx--;
|
|
||||||
break;
|
|
||||||
case "second":
|
|
||||||
orbIdx++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (orbDirectionChangeCount % 6 === 0 && orbDirectionChangeCount !== 0) {
|
|
||||||
orbDirectionChangeCount = 0;
|
|
||||||
switch (currentCurve) {
|
|
||||||
case "first":
|
|
||||||
orbIdx = 250;
|
|
||||||
setCurrentCurve("second");
|
|
||||||
break;
|
|
||||||
case "second":
|
|
||||||
orbIdx = 0;
|
|
||||||
setCurrentCurve("first");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
setOrbDirection("left");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentCurve === "first") {
|
|
||||||
orbRef.current!.position.x = orbPosFirst.x;
|
|
||||||
orbRef.current!.position.y = orbPosFirst.y;
|
|
||||||
} else {
|
} else {
|
||||||
orbRef.current!.position.x = orbPosSecond.x;
|
idxRef.current++;
|
||||||
orbRef.current!.position.y = orbPosSecond.y;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
directionChangeCountRef.current % 6 === 0 &&
|
||||||
|
directionChangeCountRef.current !== 0
|
||||||
|
) {
|
||||||
|
directionChangeCountRef.current = 0;
|
||||||
|
if (curveIdxRef.current === 0) {
|
||||||
|
idxRef.current = 250;
|
||||||
|
curveIdxRef.current = 1;
|
||||||
|
} else {
|
||||||
|
idxRef.current = 0;
|
||||||
|
curveIdxRef.current = 0;
|
||||||
|
}
|
||||||
|
directionRef.current = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (orbRef.current) {
|
||||||
|
if (curveIdxRef.current === 0) {
|
||||||
|
orbRef.current.position.x = orbPosFirst.x;
|
||||||
|
orbRef.current.position.y = orbPosFirst.y;
|
||||||
|
} else {
|
||||||
|
orbRef.current.position.x = orbPosSecond.x;
|
||||||
|
orbRef.current.position.y = orbPosSecond.y;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<group position={[0, -0.1, 1]}>
|
<group position={[0, -0.1, 1]}>
|
||||||
<sprite scale={[0.5, 0.5, 0.5]} ref={orbRef} renderOrder={renderOrder}>
|
<sprite scale={[0.5, 0.5, 0.5]} ref={orbRef}>
|
||||||
<spriteMaterial
|
<spriteMaterial
|
||||||
attach="material"
|
attach="material"
|
||||||
map={orbSpriteTexture}
|
map={orbSpriteTexture}
|
||||||
|
@ -122,6 +115,6 @@ const YellowOrb = (props: YellowOrbProps) => {
|
||||||
</sprite>
|
</sprite>
|
||||||
</group>
|
</group>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
export default YellowOrb;
|
export default YellowOrb;
|
||||||
|
|
|
@ -37,8 +37,6 @@ const MediaPlayer = () => {
|
||||||
|
|
||||||
if (percentageElapsed % 5 === 0 && percentageElapsed !== 0) {
|
if (percentageElapsed % 5 === 0 && percentageElapsed !== 0) {
|
||||||
setPercentageElapsed(percentageElapsed);
|
setPercentageElapsed(percentageElapsed);
|
||||||
if (percentageElapsed === 100 && videoRef.current)
|
|
||||||
videoRef.current.currentTime = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [setPercentageElapsed, videoRef]);
|
}, [setPercentageElapsed, videoRef]);
|
||||||
|
|
|
@ -5,8 +5,7 @@ import AudioVisualizerColumn from "./AudioVisualizerColumn";
|
||||||
import { useStore } from "../../../store";
|
import { useStore } from "../../../store";
|
||||||
|
|
||||||
const AudioVisualizer = memo(() => {
|
const AudioVisualizer = memo(() => {
|
||||||
const analyser = useStore((state) => state.audioAnalyser);
|
const audioAnalyser = useStore(state=> state.audioAnalyser)
|
||||||
|
|
||||||
const columnRefs = useMemo(
|
const columnRefs = useMemo(
|
||||||
() =>
|
() =>
|
||||||
Array.from({ length: 15 }, () => [
|
Array.from({ length: 15 }, () => [
|
||||||
|
@ -19,8 +18,8 @@ const AudioVisualizer = memo(() => {
|
||||||
);
|
);
|
||||||
|
|
||||||
useFrame(() => {
|
useFrame(() => {
|
||||||
if (analyser) {
|
if (audioAnalyser) {
|
||||||
const frequencyData = analyser.getFrequencyData();
|
const frequencyData = audioAnalyser.getFrequencyData();
|
||||||
|
|
||||||
columnRefs.forEach((refArray, idx) => {
|
columnRefs.forEach((refArray, idx) => {
|
||||||
const ref1 = refArray[0];
|
const ref1 = refArray[0];
|
||||||
|
|
|
@ -10,18 +10,13 @@ const mediaManager = (eventState: any) => {
|
||||||
|
|
||||||
const updateRightSide = useStore.getState().updateRightSide;
|
const updateRightSide = useStore.getState().updateRightSide;
|
||||||
|
|
||||||
const setAudioAnalyser = useStore.getState().setAudioAnalyser;
|
const setPercentageElapsed = useStore.getState().setPercentageElapsed;
|
||||||
|
|
||||||
const playMedia = () => {
|
const playMedia = () => {
|
||||||
const mediaElement = document.getElementById("media") as HTMLMediaElement;
|
const mediaElement = document.getElementById("media") as HTMLMediaElement;
|
||||||
|
|
||||||
if (mediaElement && mediaElement.paused) {
|
if (mediaElement && mediaElement.paused) {
|
||||||
const listener = new THREE.AudioListener();
|
setPercentageElapsed(0);
|
||||||
const audio = new THREE.Audio(listener);
|
|
||||||
|
|
||||||
audio.setMediaElementSource(mediaElement);
|
|
||||||
|
|
||||||
setAudioAnalyser(new THREE.AudioAnalyser(audio, 2048));
|
|
||||||
|
|
||||||
mediaElement.play();
|
mediaElement.play();
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,11 +5,7 @@ import { useStore } from "../store";
|
||||||
import EndSelectionScreen from "../components/EndScene/EndSelectionScreen";
|
import EndSelectionScreen from "../components/EndScene/EndSelectionScreen";
|
||||||
|
|
||||||
const EndScene = () => {
|
const EndScene = () => {
|
||||||
const setAudioAnalyser = useStore((state) => state.setAudioAnalyser);
|
const mediaPlayedCount = useStore((state) => state.endMediaPlayedCount);
|
||||||
|
|
||||||
const mediaPlayedCount = useStore(
|
|
||||||
(state) => state.endMediaPlayedCount
|
|
||||||
);
|
|
||||||
|
|
||||||
const mainCylinderRef = useRef<THREE.Object3D>();
|
const mainCylinderRef = useRef<THREE.Object3D>();
|
||||||
|
|
||||||
|
@ -37,13 +33,6 @@ const EndScene = () => {
|
||||||
"media"
|
"media"
|
||||||
) as HTMLMediaElement;
|
) as HTMLMediaElement;
|
||||||
|
|
||||||
const listener = new THREE.AudioListener();
|
|
||||||
const audio = new THREE.Audio(listener);
|
|
||||||
|
|
||||||
audio.setMediaElementSource(mediaElement);
|
|
||||||
|
|
||||||
setAudioAnalyser(new THREE.AudioAnalyser(audio, 2048));
|
|
||||||
|
|
||||||
if (mediaElement) {
|
if (mediaElement) {
|
||||||
mediaElement.play();
|
mediaElement.play();
|
||||||
setIsIntro(false);
|
setIsIntro(false);
|
||||||
|
@ -55,7 +44,7 @@ const EndScene = () => {
|
||||||
setSceneOutro(true);
|
setSceneOutro(true);
|
||||||
}, 4000);
|
}, 4000);
|
||||||
}
|
}
|
||||||
}, [mediaPlayedCount, setAudioAnalyser]);
|
}, [mediaPlayedCount]);
|
||||||
|
|
||||||
// return mediaPlayedCount > 0 ? (
|
// return mediaPlayedCount > 0 ? (
|
||||||
// <>
|
// <>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import React, { useEffect } from "react";
|
import React, { useEffect } from "react";
|
||||||
import { useStore } from "../store";
|
import { createAudioAnalyser, useStore } from "../store";
|
||||||
import LeftSide from "../components/MediaScene/Selectables/LeftSide";
|
import LeftSide from "../components/MediaScene/Selectables/LeftSide";
|
||||||
import RightSide from "../components/MediaScene/Selectables/RightSide";
|
import RightSide from "../components/MediaScene/Selectables/RightSide";
|
||||||
import AudioVisualizer from "../components/MediaScene/AudioVisualizer/AudioVisualizer";
|
import AudioVisualizer from "../components/MediaScene/AudioVisualizer/AudioVisualizer";
|
||||||
|
@ -10,6 +10,8 @@ import GreenTextRenderer from "../components/TextRenderer/GreenTextRenderer";
|
||||||
import MediaYellowTextAnimator from "../components/TextRenderer/MediaYellowTextAnimator";
|
import MediaYellowTextAnimator from "../components/TextRenderer/MediaYellowTextAnimator";
|
||||||
|
|
||||||
const MediaScene = () => {
|
const MediaScene = () => {
|
||||||
|
const setAudioAnalyser = useStore((state) => state.setAudioAnalyser);
|
||||||
|
|
||||||
const activeNodeMedia = useStore((state) => state.activeNode.media_file);
|
const activeNodeMedia = useStore((state) => state.activeNode.media_file);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -29,6 +31,8 @@ const MediaScene = () => {
|
||||||
const trackElement = document.getElementById("track") as HTMLTrackElement;
|
const trackElement = document.getElementById("track") as HTMLTrackElement;
|
||||||
|
|
||||||
if (mediaElement) {
|
if (mediaElement) {
|
||||||
|
setAudioAnalyser(createAudioAnalyser());
|
||||||
|
|
||||||
mediaElement.currentTime = 0;
|
mediaElement.currentTime = 0;
|
||||||
import("../static/webvtt/" + nodeName + ".vtt")
|
import("../static/webvtt/" + nodeName + ".vtt")
|
||||||
.then((vtt) => {
|
.then((vtt) => {
|
||||||
|
@ -49,7 +53,7 @@ const MediaScene = () => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [nodeMedia, nodeName]);
|
}, [nodeMedia, nodeName, setAudioAnalyser]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<perspectiveCamera position-z={3}>
|
<perspectiveCamera position-z={3}>
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import LainSpeak from "../components/LainSpeak";
|
import LainSpeak from "../components/LainSpeak";
|
||||||
import * as THREE from "three";
|
import { createAudioAnalyser, useStore } from "../store";
|
||||||
import { useStore } from "../store";
|
|
||||||
|
|
||||||
const TaKScene = () => {
|
const TaKScene = () => {
|
||||||
const setAudioAnalyser = useStore((state) => state.setAudioAnalyser);
|
|
||||||
const setScene = useStore((state) => state.setScene);
|
const setScene = useStore((state) => state.setScene);
|
||||||
|
const setAudioAnalyser = useStore((state) => state.setAudioAnalyser);
|
||||||
|
|
||||||
|
const nodeMedia = useStore((state) => state.activeNode.media_file);
|
||||||
|
const nodeName = useStore((state) => state.activeNode.node_name);
|
||||||
|
|
||||||
const [isIntro, setIsIntro] = useState(true);
|
const [isIntro, setIsIntro] = useState(true);
|
||||||
const [isOutro, setIsOutro] = useState(false);
|
const [isOutro, setIsOutro] = useState(false);
|
||||||
|
|
||||||
const percentageElapsed = useStore(
|
const percentageElapsed = useStore((state) => state.mediaPercentageElapsed);
|
||||||
(state) => state.mediaPercentageElapsed
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (percentageElapsed === 100) {
|
if (percentageElapsed === 100) {
|
||||||
|
@ -26,21 +26,35 @@ const TaKScene = () => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const mediaElement = document.getElementById("media") as HTMLMediaElement;
|
const mediaElement = document.getElementById("media") as HTMLMediaElement;
|
||||||
|
const trackElement = document.getElementById("track") as HTMLTrackElement;
|
||||||
const listener = new THREE.AudioListener();
|
|
||||||
const audio = new THREE.Audio(listener);
|
|
||||||
|
|
||||||
audio.setMediaElementSource(mediaElement);
|
|
||||||
|
|
||||||
setAudioAnalyser(new THREE.AudioAnalyser(audio, 2048));
|
|
||||||
|
|
||||||
if (mediaElement) {
|
if (mediaElement) {
|
||||||
|
setAudioAnalyser(createAudioAnalyser());
|
||||||
mediaElement.currentTime = 0;
|
mediaElement.currentTime = 0;
|
||||||
|
import("../static/webvtt/" + nodeName + ".vtt")
|
||||||
|
.then((vtt) => {
|
||||||
|
if (vtt) trackElement.src = vtt.default;
|
||||||
|
})
|
||||||
|
// some entries have no spoken words, so the file doesnt exist. we catch that here.
|
||||||
|
.catch((e) => console.log(e));
|
||||||
|
|
||||||
|
if (nodeMedia.includes("XA")) {
|
||||||
|
import("../static/audio/" + nodeMedia + ".ogg").then((media) => {
|
||||||
|
mediaElement.src = media.default;
|
||||||
|
mediaElement.load();
|
||||||
mediaElement.play();
|
mediaElement.play();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
import("../static/movie/" + nodeMedia + "[0].webm").then((media) => {
|
||||||
|
mediaElement.src = media.default;
|
||||||
|
mediaElement.load();
|
||||||
|
mediaElement.play();
|
||||||
|
});
|
||||||
|
}
|
||||||
setIsIntro(false);
|
setIsIntro(false);
|
||||||
}
|
}
|
||||||
}, 3800);
|
}, 3800);
|
||||||
}, [setAudioAnalyser]);
|
}, [nodeMedia, nodeName]);
|
||||||
|
|
||||||
return <LainSpeak intro={isIntro} outro={isOutro} />;
|
return <LainSpeak intro={isIntro} outro={isOutro} />;
|
||||||
};
|
};
|
||||||
|
|
20
src/store.ts
20
src/store.ts
|
@ -6,6 +6,7 @@ import { NodeDataType } from "./components/MainScene/Site";
|
||||||
import { getNodeById } from "./utils/node-utils";
|
import { getNodeById } from "./utils/node-utils";
|
||||||
import site_a from "./resources/site_a.json";
|
import site_a from "./resources/site_a.json";
|
||||||
|
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
currentScene: string;
|
currentScene: string;
|
||||||
|
|
||||||
|
@ -48,7 +49,7 @@ type State = {
|
||||||
permissionDenied: boolean;
|
permissionDenied: boolean;
|
||||||
|
|
||||||
// media/media scene
|
// media/media scene
|
||||||
audioAnalyser: undefined | THREE.AudioAnalyser;
|
audioAnalyser: any;
|
||||||
mediaPercentageElapsed: number;
|
mediaPercentageElapsed: number;
|
||||||
mediaComponentMatrix: [["play", "exit"], ["fstWord", "sndWord", "thirdWord"]];
|
mediaComponentMatrix: [["play", "exit"], ["fstWord", "sndWord", "thirdWord"]];
|
||||||
mediaComponentMatrixIndices: {
|
mediaComponentMatrixIndices: {
|
||||||
|
@ -172,7 +173,7 @@ export const useStore = create(
|
||||||
showingAbout: false,
|
showingAbout: false,
|
||||||
permissionDenied: false,
|
permissionDenied: false,
|
||||||
|
|
||||||
// media / media scene
|
// media scene
|
||||||
audioAnalyser: undefined,
|
audioAnalyser: undefined,
|
||||||
mediaPercentageElapsed: 0,
|
mediaPercentageElapsed: 0,
|
||||||
mediaComponentMatrix: [
|
mediaComponentMatrix: [
|
||||||
|
@ -316,7 +317,8 @@ export const useStore = create(
|
||||||
setPermissionDenied: (to: boolean) =>
|
setPermissionDenied: (to: boolean) =>
|
||||||
set(() => ({ permissionDenied: to })),
|
set(() => ({ permissionDenied: to })),
|
||||||
|
|
||||||
// media/media scene setters
|
// media scene setters
|
||||||
|
setAudioAnalyser: (to: any) => set(() => ({ audioAnalyser: to })),
|
||||||
toggleMediaSide: () =>
|
toggleMediaSide: () =>
|
||||||
set((state) => ({
|
set((state) => ({
|
||||||
mediaComponentMatrixIndices: {
|
mediaComponentMatrixIndices: {
|
||||||
|
@ -343,8 +345,6 @@ export const useStore = create(
|
||||||
})),
|
})),
|
||||||
setPercentageElapsed: (to: number) =>
|
setPercentageElapsed: (to: number) =>
|
||||||
set(() => ({ mediaPercentageElapsed: to })),
|
set(() => ({ mediaPercentageElapsed: to })),
|
||||||
setAudioAnalyser: (to: THREE.AudioAnalyser) =>
|
|
||||||
set(() => ({ audioAnalyser: to })),
|
|
||||||
setWordSelected: (to: boolean) => set(() => ({ wordSelected: to })),
|
setWordSelected: (to: boolean) => set(() => ({ wordSelected: to })),
|
||||||
|
|
||||||
// idle media setters
|
// idle media setters
|
||||||
|
@ -537,3 +537,13 @@ export const playAudio = (audio: HTMLAudioElement) => {
|
||||||
audio.loop = false;
|
audio.loop = false;
|
||||||
audio.play();
|
audio.play();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const createAudioAnalyser = () => {
|
||||||
|
const mediaElement = document.getElementById("media") as HTMLMediaElement;
|
||||||
|
const listener = new THREE.AudioListener();
|
||||||
|
const audio = new THREE.Audio(listener);
|
||||||
|
|
||||||
|
audio.setMediaElementSource(mediaElement);
|
||||||
|
|
||||||
|
return new THREE.AudioAnalyser(audio, 2048);
|
||||||
|
};
|
||||||
|
|
|
@ -67,8 +67,7 @@ export const isNodeVisible = (
|
||||||
? (node.unlocked_by === "" ||
|
? (node.unlocked_by === "" ||
|
||||||
gameProgress[node.unlocked_by as keyof typeof gameProgress]
|
gameProgress[node.unlocked_by as keyof typeof gameProgress]
|
||||||
.is_viewed) &&
|
.is_viewed) &&
|
||||||
gameProgress[node.node_name as keyof typeof gameProgress].is_visible &&
|
gameProgress[node.node_name as keyof typeof gameProgress].is_visible
|
||||||
node.required_final_video_viewcount < 1
|
|
||||||
: false;
|
: false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue