import React, { useEffect, useState, useRef } from "react"; import { assetsPath } from "./Common"; import "./Sheep.css"; const sheepSteps = 12; const useAnimationFrame = (callback: (t: number) => void) => { const requestRef = useRef(null); const animate = (time: number) => { callback(time); requestRef.current = requestAnimationFrame(animate); }; useEffect(() => { requestRef.current = requestAnimationFrame(animate); return () => { if (requestRef.current !== null) { cancelAnimationFrame(requestRef.current); } }; }, []); }; const Sheep: React.FC<{ radius: number; speed: number; size: number; style?: React.CSSProperties }> = ({ radius, speed, size, style, }) => { const [time, setTime] = useState(0); const [direction, setDirection] = useState(Math.random() * 2 * Math.PI); const [y, setY] = useState((Math.random() - 0.5) * radius); const [frame, setFrame] = useState(0); const [x, setX] = useState((Math.random() - 0.5) * radius); const previousTimeRef = useRef(); useAnimationFrame((t) => { if (previousTimeRef.current !== undefined) { const deltaTime = t - previousTimeRef.current; previousTimeRef.current = t; setTime(deltaTime); } else { previousTimeRef.current = t; } }); useEffect(() => { let alpha = time / speed; const sheepSpeed = 0.05; if (alpha > 1.0) alpha = 0.1; let newX = x + sheepSpeed * Math.sin(direction) * alpha; let newY = y + sheepSpeed * Math.cos(direction) * alpha; if (Math.sqrt(newX * newX + newY * newY) > Math.sqrt(radius * radius)) { let newDirection = direction + Math.PI + 0.5 * (Math.random() - 0.5) * Math.PI; while (newDirection >= 2 * Math.PI) newDirection -= 2 * Math.PI; while (newDirection <= -2 * Math.PI) newDirection += 2 * Math.PI; setDirection(newDirection); newX += sheepSpeed * Math.sin(newDirection) * alpha; newY += sheepSpeed * Math.cos(newDirection) * alpha; } setX(newX); setY(newY); setFrame(frame + sheepSteps * alpha); }, [time, speed]); const cell = Math.floor(frame) % sheepSteps; return (
0 ? +1 : -1}, 1)`, ...style, }} /> ); }; const Herd: React.FC<{ count: number; style?: React.CSSProperties }> = ({ count, style }) => { const [sheep, setSheep] = useState([]); useEffect(() => { const tmp: React.ReactNode[] = []; for (let i = 0; i < count; i++) { const scalar = Math.random(); tmp.push(); } setSheep(tmp); }, [count]); return (
{sheep}
); }; export { Sheep, Herd };