Skip to content

Commit

Permalink
Adds rolling cube animations
Browse files Browse the repository at this point in the history
  • Loading branch information
dcyoung committed Feb 12, 2024
1 parent c40a9b6 commit 21e299c
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 15 deletions.
45 changes: 32 additions & 13 deletions app/src/components/visualizers/boxes/base.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useEffect, useMemo, useRef } from "react";
import { ScalarMovingAvgEventDetector } from "@/lib/analyzers/eventDetector";
import { usePalette } from "@/lib/appState";
import { clip, easeInOut, lerp } from "@/lib/easing";
import { type IScalarTracker } from "@/lib/mappers/valueTracker/common";
import { ColorPalette } from "@/lib/palettes";
import { useFrame } from "@react-three/fiber";
Expand Down Expand Up @@ -62,35 +63,53 @@ const BaseBoxes = ({

useFrame(() => {
if (detector.step(scalarTracker?.getNormalizedValue() ?? 0)) {
// random jitter
const rowJitter = Math.floor(Math.random() * 3) - 1;
const colJitter = Math.floor(Math.random() * 3) - 1;
// random jitter in one direction or the other
const [rowJitter, colJitter] =
Math.random() > 0.5 ? [true, false] : [false, true];

for (let i = 0; i < nBoxes; i++) {
cellAssignments[i].fromRow = cellAssignments[i].toRow;
cellAssignments[i].fromCol = cellAssignments[i].toCol;
cellAssignments[i].toRow += (Math.random() > 0.5 ? 1 : -1) * colJitter;
cellAssignments[i].toCol += (Math.random() > 0.5 ? 1 : -1) * rowJitter;
if (rowJitter) {
cellAssignments[i].toRow += Math.random() > 0.5 ? 1 : -1;
}
if (colJitter) {
cellAssignments[i].toCol += Math.random() > 0.5 ? 1 : -1;
}
}
}

const alpha = Math.min(
1,
Math.max(0, detector.timeSinceLastEventMs / rotateDurationMs),
// smooth the roll
const alpha = easeInOut(
clip(detector.timeSinceLastEventMs / rotateDurationMs),
);
// roll angle for each cube
const beta = lerp(Math.PI / 4, (3 * Math.PI) / 4, alpha);
// formula for COM of a rolling cube as a fxn of beta
const rollU = (-0.5 * cellSize * Math.cos(beta)) / Math.sqrt(2);
const rollV = (0.5 * cellSize * Math.sin(beta)) / Math.sqrt(2);

let normCubeX, normCubeY, x, y, z;
let normCubeX, normCubeY, x, y, z, deltaRow, deltaCol;
cellAssignments.forEach(
({ fromRow, fromCol, toRow, toCol }, instanceIdx) => {
const row = fromRow + alpha * (toRow - fromRow);
const col = fromCol + alpha * (toCol - fromCol);
deltaRow = toRow - fromRow;
deltaCol = toCol - fromCol;
const row = fromRow + deltaRow * (rollU + 0.5);
const col = fromCol + deltaCol * (rollU + 0.5);

if (deltaRow !== 0) {
tmpMatrix.makeRotationY((beta - Math.PI / 4) * deltaRow);
}
if (deltaCol !== 0) {
tmpMatrix.makeRotationX(-(beta - Math.PI / 4) * deltaCol);
}

// Find a random cell
normCubeX = row / (nRows - 1);
normCubeY = col / (nCols - 1);

x = nRows * cellSize * (normCubeX - 0.5);
y = nCols * cellSize * (normCubeY - 0.5);
z = 0;
z = rollV - cellSize / 4;
// Position
tmpMatrix.setPosition(x, y, z);

Expand Down
4 changes: 2 additions & 2 deletions app/src/components/visualizers/boxes/reactive.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import { Vector3 } from "three";
import BaseBoxes from "./base";

const BoxesVisual = ({ scalarTracker }: VisualProps) => {
const nBoxes = 100;
const nBoxes = 200;
const gridSize = 100;
const cellSize = 0.25;
const cellSize = 1;

return (
<>
Expand Down
53 changes: 53 additions & 0 deletions app/src/lib/easing.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
export const EASING_FUNCTION = {
LINEAR: "LINEAR",
QUADRATIC: "QUADRATIC",
BEZIER: "BEZIER",
PARAMETRIC: "PARAMETRIC",
} as const;
export type EasingFunction = keyof typeof EASING_FUNCTION;

export const easeInOut = (
t: number,
fxn: EasingFunction = EASING_FUNCTION.BEZIER,
) => {
switch (fxn) {
case "LINEAR":
return t;
case "QUADRATIC":
return t <= 0.5 ? 2.0 * t * t : 2.0 * (t - 0.5) * (1.0 - (t - 0.5)) + 0.5;
case "BEZIER":
return t * t * (3.0 - 2.0 * t);
case "PARAMETRIC":
return (t * t) / (2.0 * (t * t - t) + 1.0);
default:
return fxn satisfies never;
}
};

export const easeIn = (
t: number,
fxn: EasingFunction = EASING_FUNCTION.BEZIER,
) => {
if (t >= 0.5) {
return t;
}
return easeInOut(t, fxn);
};

export const easeOut = (
t: number,
fxn: EasingFunction = EASING_FUNCTION.BEZIER,
) => {
if (t <= 0.5) {
return t;
}
return easeInOut(t, fxn);
};

export const clip = (t: number, min = 0, max = 1) => {
return Math.min(max, Math.max(min, t));
};

export const lerp = (from: number, to: number, alpha: number) => {
return from + alpha * (to - from);
};

0 comments on commit 21e299c

Please sign in to comment.