Skip to content

Commit

Permalink
Adds Treadmill Visual (#33)
Browse files Browse the repository at this point in the history
* Adds WIP treadmill visual

* Updates for speed fxn

* Resolve errors

* Bump action versions

* Bugfix
  • Loading branch information
dcyoung authored Feb 19, 2024
1 parent e11894c commit 20c572a
Show file tree
Hide file tree
Showing 23 changed files with 362 additions and 89 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/pr_staging_deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
git config --global user.name github-actions
git config --global user.email [email protected]
- name: Checkout Repo
uses: actions/checkout@v2
uses: actions/checkout@v4
with:
path: "pr-build"
- uses: pnpm/action-setup@v2
Expand All @@ -45,7 +45,7 @@ jobs:
env:
CI: ""
- name: Checkout temporary deployment target repo
uses: actions/checkout@v2
uses: actions/checkout@v4
with:
repository: dcyoung/${{ env.PR_REPO_NAME }}
fetch-depth: 0
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pr_staging_teardown.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Delete repository for temporary deployment
uses: dcyoung/[email protected]
with:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout 🛎️
uses: actions/checkout@v3
uses: actions/checkout@v4
- uses: pnpm/action-setup@v2
with:
version: 8
Expand Down
1 change: 1 addition & 0 deletions app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"tailwind-merge": "^1.14.0",
"tailwindcss-animate": "^1.0.6",
"three": "^0.161.0",
"three-stdlib": "^2.29.4",
"zod": "^3.22.4",
"zod-fetch": "^0.1.1",
"zustand": "^4.5.0"
Expand Down
3 changes: 3 additions & 0 deletions app/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 21 additions & 7 deletions app/src/components/canvas/AutoOrbitCamera.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { useVisualContext } from "@/context/visual";
import { useFrame, useThree } from "@react-three/fiber";
import { Spherical, type Vector3 } from "three";

import { VISUAL } from "../visualizers/common";

const setFromSphericalZUp = (vec: Vector3, s: Spherical) => {
const sinPhiRadius = Math.sin(s.phi) * s.radius;
vec.x = sinPhiRadius * Math.sin(s.theta);
Expand All @@ -16,7 +18,7 @@ const useSphericalLimits = () => {
// theta is the equator angle
// phi is the polar angle
switch (visual) {
case "ribbons":
case VISUAL.RIBBONS:
return {
rMin: 10,
rMax: 15,
Expand All @@ -28,7 +30,7 @@ const useSphericalLimits = () => {
phiMax: Math.PI / 2.1,
phiSpeed: 0.25,
};
case "sphere":
case VISUAL.SPHERE:
return {
rMin: 10,
rMax: 15,
Expand All @@ -40,7 +42,7 @@ const useSphericalLimits = () => {
phiMax: Math.PI / 2,
phiSpeed: 0.25,
};
case "cube":
case VISUAL.CUBE:
return {
rMin: 12,
rMax: 20,
Expand All @@ -52,7 +54,7 @@ const useSphericalLimits = () => {
phiMax: Math.PI / 2,
phiSpeed: 0.25,
};
case "diffusedRing":
case VISUAL.DIFFUSED_RING:
return {
rMin: 10,
rMax: 18,
Expand All @@ -64,9 +66,21 @@ const useSphericalLimits = () => {
phiMax: Math.PI / 2.25,
phiSpeed: 0.25,
};
case "boxes":
case "dna":
case "grid":
case VISUAL.WALK:
return {
rMin: 15,
rMax: 22,
rSpeed: 0.1,
thetaMin: 0,
thetaMax: 2 * Math.PI,
thetaSpeed: 0.025,
phiMin: Math.PI / 3.5,
phiMax: Math.PI / 2.25,
phiSpeed: 0.25,
};
case VISUAL.BOXES:
case VISUAL.DNA:
case VISUAL.GRID:
return {
rMin: 15,
rMax: 22,
Expand Down
2 changes: 1 addition & 1 deletion app/src/components/controls/dock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export const Dock = ({
return (
<div
className={cn(
"max-w-4/5 sm:max-w-3/5 pointer-events-none h-fit overflow-hidden bg-transparent",
"pointer-events-none h-fit overflow-hidden bg-transparent",
className,
)}
{...props}
Expand Down
4 changes: 3 additions & 1 deletion app/src/components/controls/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ export const ControlsPanel = () => {
</div>
{showUI && (
<div className="pointer-events-none absolute bottom-0 flex w-full items-end justify-center gap-4 p-4">
{mode !== APPLICATION_MODE.AUDIO_SCOPE && <VisualsDock />}
{mode !== APPLICATION_MODE.AUDIO_SCOPE && (
<VisualsDock className="sm:max-w-[60%]" />
)}
<div
className={cn({
"absolute bottom-24 right-0 sm:static sm:bottom-0": true,
Expand Down
1 change: 1 addition & 0 deletions app/src/components/controls/mode/waveform.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const WaveformModeControls = () => {
<div className="flex w-full items-center justify-between">
<Label>Double</Label>
<Switch
checked={waveformFrequenciesHz.length > 1}
defaultChecked={waveformFrequenciesHz.length > 1}
onCheckedChange={(e) => {
setWaveformFrequenciesHz(e ? [2.0, 10.0] : [2.0]);
Expand Down
16 changes: 9 additions & 7 deletions app/src/components/controls/visualSettingsSheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
} from "@/lib/palettes";
import { cn } from "@/lib/utils";

import { VISUAL } from "../visualizers/common";
import { CubeVisualSettingsControls } from "./visual/cube";
import { DiffusedRingVisualSettingsControls } from "./visual/diffusedRing";
import { GridVisualSettingsControls } from "./visual/grid";
Expand Down Expand Up @@ -64,17 +65,18 @@ const PaletteIcon = ({
const VisualSettingsControls = () => {
const { visual } = useVisualContext();
switch (visual) {
case "cube":
case VISUAL.CUBE:
return CubeVisualSettingsControls();
case "grid":
case VISUAL.GRID:
return GridVisualSettingsControls();
case "sphere":
case VISUAL.SPHERE:
return SphereVisualSettingsControls();
case "diffusedRing":
case VISUAL.DIFFUSED_RING:
return DiffusedRingVisualSettingsControls();
case "ribbons":
case "dna":
case "boxes":
case VISUAL.RIBBONS:
case VISUAL.DNA:
case VISUAL.BOXES:
case VISUAL.WALK:
return null;
default:
return visual satisfies never;
Expand Down
21 changes: 13 additions & 8 deletions app/src/components/controls/visualsDock.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { type HTMLAttributes } from "react";
import {
AVAILABLE_VISUALS,
VISUAL,
type VisualType,
} from "@/components/visualizers/common";
import { useVisualContext, useVisualContextSetters } from "@/context/visual";
Expand All @@ -9,31 +10,35 @@ import {
Boxes,
CircleDashed,
Dna,
Footprints,
Globe,
Grid3x3,
HelpCircle,
Ribbon,
} from "lucide-react";

import { Dock, DockItem, DockNav } from "./dock";

const VisualIcon = ({ visual }: { visual: VisualType }) => {
switch (visual) {
case "grid":
case VISUAL.GRID:
return <Grid3x3 />;
case "cube":
case VISUAL.CUBE:
return <Box />;
case "sphere":
case VISUAL.SPHERE:
return <Globe />;
case "diffusedRing":
case VISUAL.DIFFUSED_RING:
return <CircleDashed />;
case "dna":
case VISUAL.DNA:
return <Dna />;
case "boxes":
case VISUAL.BOXES:
return <Boxes />;
case "ribbons":
case VISUAL.RIBBONS:
return <Ribbon />;
case VISUAL.WALK:
return <Footprints />;
default:
return visual satisfies never;
return <HelpCircle />;
}
};

Expand Down
26 changes: 14 additions & 12 deletions app/src/components/visualizers/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,18 @@ export interface MotionVisualProps {
scalarTracker?: IScalarTracker;
}

export const AVAILABLE_VISUALS = [
"grid",
"sphere",
"cube",
"diffusedRing",
"dna",
"boxes",
"ribbons",
// "stencil",
// "swarm",
] as const;
export const VISUAL = {
GRID: "grid",
SPHERE: "sphere",
CUBE: "cube",
DIFFUSED_RING: "diffusedRing",
DNA: "dna",
BOXES: "boxes",
RIBBONS: "ribbons",
WALK: "walk",
// STENCIL: "stencil",
// SWARM: "swarm",
} as const;

export type VisualType = (typeof AVAILABLE_VISUALS)[number];
export const AVAILABLE_VISUALS = Object.values(VISUAL);
export type VisualType = (typeof VISUAL)[keyof typeof VISUAL];
26 changes: 26 additions & 0 deletions app/src/components/visualizers/visual.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Suspense } from "react";
import { useVisualComponent } from "@/hooks/useVisualComponent";
import { type ICoordinateMapper } from "@/lib/mappers/coordinateMappers/common";
import { type IScalarTracker } from "@/lib/mappers/valueTracker/common";

import { type VisualType } from "./common";

export const Visual = ({
visual,
coordinateMapper,
scalarTracker,
}: {
visual: VisualType;
coordinateMapper?: ICoordinateMapper;
scalarTracker?: IScalarTracker;
}) => {
const VisualComponent = useVisualComponent(visual);
return (
<Suspense fallback={null}>
<VisualComponent
coordinateMapper={coordinateMapper}
scalarTracker={scalarTracker}
/>
</Suspense>
);
};
23 changes: 7 additions & 16 deletions app/src/components/visualizers/visualizerAudio.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { lazy, Suspense, useMemo } from "react";
import { type VisualType } from "@/components/visualizers/common";
import { useFFTAnalyzerContext } from "@/context/fftAnalyzer";
import { useEnergyInfo, useVisualSourceDataX } from "@/lib/appState";
import { CoordinateMapper_Data } from "@/lib/mappers/coordinateMappers/data";
import { EnergyTracker } from "@/lib/mappers/valueTracker/energyTracker";

import { Visual } from "./visual";

const AudioVisual = ({ visual }: { visual: VisualType }) => {
const freqData = useVisualSourceDataX();
const energyInfo = useEnergyInfo();
Expand All @@ -14,22 +15,12 @@ const AudioVisual = ({ visual }: { visual: VisualType }) => {
const coordinateMapper = new CoordinateMapper_Data(amplitude, freqData);
const energyTracker = new EnergyTracker(energyInfo);

const VisualComponent = useMemo(
() =>
lazy(
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
async () => await import(`./${visual}/reactive.tsx`),
),
[visual],
);

return (
<Suspense fallback={null}>
<VisualComponent
coordinateMapper={coordinateMapper}
scalarTracker={energyTracker}
/>
</Suspense>
<Visual
visual={visual}
coordinateMapper={coordinateMapper}
scalarTracker={energyTracker}
/>
);
};

Expand Down
20 changes: 3 additions & 17 deletions app/src/components/visualizers/visualizerNoise.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,10 @@
import { lazy, Suspense, useMemo } from "react";
import { type VisualType } from "@/components/visualizers/common";
import { useNoiseGeneratorContext } from "@/context/noiseGenerator";
import { CoordinateMapper_Noise } from "@/lib/mappers/coordinateMappers/noise";

const NoiseVisual = ({ visual }: { visual: VisualType }) => {
const VisualComponent = useMemo(
() =>
lazy(
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
async () => await import(`./${visual}/reactive.tsx`),
),
[visual],
);
import { Visual } from "./visual";

const NoiseVisual = ({ visual }: { visual: VisualType }) => {
const { amplitude, spatialScale, timeScale, nIterations } =
useNoiseGeneratorContext();

Expand All @@ -23,13 +15,7 @@ const NoiseVisual = ({ visual }: { visual: VisualType }) => {
nIterations,
);

return (
<>
<Suspense fallback={null}>
<VisualComponent coordinateMapper={coordinateMapper} />
</Suspense>
</>
);
return <Visual visual={visual} coordinateMapper={coordinateMapper} />;
};

export default NoiseVisual;
Loading

0 comments on commit 20c572a

Please sign in to comment.