Skip to content

Instantly share code, notes, and snippets.

@wchargin
Created September 9, 2024 20:10
Show Gist options
  • Save wchargin/0a49246fcb9792904878013c53987d1f to your computer and use it in GitHub Desktop.
Save wchargin/0a49246fcb9792904878013c53987d1f to your computer and use it in GitHub Desktop.
<!doctype html>
<div id="root"></div>
<script type="module">
import React, { useEffect, useState } from "https://esm.sh/[email protected]";
import ReactDOM from "https://esm.sh/[email protected]";
import { animated, useSpring } from "https://esm.sh/@react-spring/[email protected]";
import { usePrevious } from "https://esm.sh/@uidotdev/[email protected]";
const USE_SPRING = true;
const h = React.createElement;
const rescale = (fromMin, fromMax, speed, toMin, toMax) => {
const fromRange = fromMax - fromMin;
const toRange = toMax - toMin;
return toMin + (speed - fromMin) * (toRange / fromRange);
};
const MIN_SPEED = 0;
const MAX_SPEED = 5;
const MIN_ANGLE = -90;
const MAX_ANGLE = 90;
const NEEDLE_WIDTH = 3.72;
const NEEDLE_HEIGHT = 22;
const ROTATION_Y = NEEDLE_HEIGHT - 2;
const getAngle = (speed) => {
return rescale(MIN_SPEED, MAX_SPEED, speed, MIN_ANGLE, MAX_ANGLE);
};
const App = () => {
const [speed, setSpeed] = useState(0);
const prevSpeed = usePrevious(speed);
useEffect(() => {
const id = setInterval(() => {
const delta = 1 / 50;
setSpeed((speed) => {
if (speed > 5) {
clearInterval(id);
}
return speed + delta;
});
}, 20);
}, []);
const springArgs = {
config: {
duration: 50,
},
from: {
transform: `rotate(${getAngle(prevSpeed)}, ${Math.round(NEEDLE_WIDTH / 2)}, ${ROTATION_Y})`,
},
to: {
transform: `rotate(${getAngle(speed)}, ${Math.round(NEEDLE_WIDTH / 2)}, ${ROTATION_Y})`,
},
};
console.log(springArgs.from.transform, springArgs.to.transform);
const animationProps = useSpring(springArgs);
return h(
"svg",
{},
h(
"g",
{ transform: "translate(100,0) scale(5)" },
h(animated.path, {
width: NEEDLE_WIDTH,
height: NEEDLE_HEIGHT,
d: "M1.5,0L1.5,0c0,0,2.3,17.5,2.1,20s-3.1,2.8-3.6,0S1.5,0,1.5,0z",
transform: USE_SPRING
? animationProps.transform
: springArgs.to.transform,
}),
),
);
};
ReactDOM.createRoot(root).render(h(App));
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment