Add scrolling and pause button

This commit is contained in:
Hayk Martiros 2022-11-23 21:46:32 -08:00
parent 54bc013531
commit e3e9710f7a
8 changed files with 74 additions and 61 deletions

View File

@ -1,20 +1,33 @@
import * as THREE from "three";
import React, { Suspense } from "react";
import { useLoader } from "@react-three/fiber";
import React, { useRef, Suspense } from "react";
import { useLoader, useFrame } from "@react-three/fiber";
interface ImagePlaneProps {
url: string;
};
height: number;
paused: boolean;
}
/**
* Draw an image on a plane geometry.
*/
export default function ImagePlane(props: ImagePlaneProps) {
const texture = useLoader(THREE.TextureLoader, props.url);
const mesh = useRef<THREE.Mesh>(null);
useFrame(() => {
if (props.paused) {
return;
}
mesh.current.position.y += 1 / 30.0;
});
return (
<Suspense fallback={null}>
<mesh rotation-z={-Math.PI / 2}>
<planeBufferGeometry attach="geometry" args={[150, 30]} />
<mesh ref={mesh} rotation-z={-Math.PI / 2} position-y={props.height}>
<planeBufferGeometry attach="geometry" args={[30, 30]} />
<meshBasicMaterial attach="material" map={texture} />
</mesh>
</Suspense>

View File

@ -1,22 +1,23 @@
import { NextComponentType } from 'next'
import { Fragment, useState } from 'react'
import { FiPause, FiPlay } from "react-icons/fi";
const Modal: NextComponentType = () => {
const [paused, SetPause] = useState(false)
interface PauseProps {
paused: boolean;
setPaused: (value: boolean) => void;
}
const Pause = (props: PauseProps) => {
return (
<>
<button
title="Pause"
className="fixed z-90 top-28 right-8 bg-slate-100 w-14 h-14 rounded-full drop-shadow-lg
flex justify-center items-center text-black text-2xl hover:bg-sky-500 hover:drop-shadow-2xl"
onClick={() => SetPause(!paused)}
onClick={() => props.setPaused(!props.paused)}
>
{paused ? <FiPlay /> : <FiPause />}
{props.paused ? <FiPlay /> : <FiPause />}
</button>
</>
)
}
);
};
export default Modal
export default Pause;

View File

@ -1,11 +1,9 @@
import { Dialog, Transition } from '@headlessui/react'
import { NextComponentType } from 'next'
import { Fragment, useState } from 'react'
import { Dialog, Transition } from "@headlessui/react";
import { Fragment, useState } from "react";
import { FiSliders } from "react-icons/fi";
const Modal: NextComponentType = () => {
const [open, setOpen] = useState(false)
const Settings = () => {
const [open, setOpen] = useState(false);
return (
<>
@ -80,7 +78,7 @@ const Modal: NextComponentType = () => {
</Dialog>
</Transition>
</>
)
}
);
};
export default Modal
export default Settings;

View File

@ -3,15 +3,28 @@ import { Canvas } from "@react-three/fiber";
import RotatingBox from "./RotatingBox";
import ImagePlane from "./ImagePlane";
interface CanvasProps {
paused: boolean;
}
/**
* React three fiber canvas with spectrogram drawing.
*/
export default function ThreeCanvas() {
export default function ThreeCanvas(props: CanvasProps) {
// change the image URL
const spectrogram_image = "spectrogram.jpeg";
const height = -30.0;
return (
<Canvas camera={{ position: [0, 0, 35] }}>
<Canvas camera={{ position: [0, 0, 35], rotation: [0.2, 0, 0] }}>
<ambientLight intensity={2} />
<pointLight position={[40, 40, 40]} />
<ImagePlane url={"spectrogram_example.png"} />
<ImagePlane
url={spectrogram_image}
height={height}
paused={props.paused}
/>
<RotatingBox position={[-12, 0, 1]} />
<RotatingBox position={[-4, 0, 1]} />
<RotatingBox position={[4, 0, 1]} />

15
package-lock.json generated
View File

@ -9,7 +9,6 @@
"version": "0.1.0",
"dependencies": {
"@headlessui/react": "^1.5.0",
"@heroicons/react": "^1.0.5",
"@react-three/drei": "^9.41.2",
"@react-three/fiber": "^8.9.1",
"eslint": "8.27.0",
@ -119,14 +118,6 @@
"react-dom": "^16 || ^17 || ^18"
}
},
"node_modules/@heroicons/react": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/@heroicons/react/-/react-1.0.6.tgz",
"integrity": "sha512-JJCXydOFWMDpCP4q13iEplA503MQO3xLoZiKum+955ZCtHINWnx26CUxVxxFQu/uLb4LW3ge15ZpzIkXKkJ8oQ==",
"peerDependencies": {
"react": ">= 16"
}
},
"node_modules/@humanwhocodes/config-array": {
"version": "0.11.7",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz",
@ -4260,12 +4251,6 @@
"client-only": "^0.0.1"
}
},
"@heroicons/react": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/@heroicons/react/-/react-1.0.6.tgz",
"integrity": "sha512-JJCXydOFWMDpCP4q13iEplA503MQO3xLoZiKum+955ZCtHINWnx26CUxVxxFQu/uLb4LW3ge15ZpzIkXKkJ8oQ==",
"requires": {}
},
"@humanwhocodes/config-array": {
"version": "0.11.7",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz",

View File

@ -14,7 +14,6 @@
"eslint": "8.27.0",
"eslint-config-next": "13.0.4",
"@headlessui/react": "^1.5.0",
"@heroicons/react": "^1.0.5",
"next": "13.0.4",
"react": "18.2.0",
"react-dom": "18.2.0",

View File

@ -1,11 +1,15 @@
import Head from "next/head";
import { useState } from "react";
import ThreeCanvas from "../components/ThreeCanvas";
import { FiPause } from "react-icons/fi";
import Settings from '../components/Settings'
import Pause from '../components/Pause'
export default function Home() {
const [paused, setPaused] = useState(false);
return (
<>
<Head>
@ -19,7 +23,7 @@ export default function Home() {
<div className="bg-sky-900 flex flex-row min-h-screen text-white">
<div className="w-1/3 min-h-screen">
<ThreeCanvas />
<ThreeCanvas paused={paused} />
</div>
<main className="w-2/3 min-h-screen p-4">
@ -41,7 +45,7 @@ export default function Home() {
{/* TODO(hayk): Convert into components. */}
<Settings />
<Pause />
<Pause paused={paused} setPaused={setPaused} />
<input
className="fixed z-90 bottom-20 right-40 w-1/2 h-12 pl-3 text-xl text-black"

BIN
public/spectrogram.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB