Flocking birds are animated
Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
This commit is contained in:
parent
4c33dfcdf1
commit
abbbbafad4
BIN
client/public/assets/gfx/birds.png
Executable file
BIN
client/public/assets/gfx/birds.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 107 KiB |
@ -27,6 +27,7 @@ import { Trade } from "./Trade.js";
|
||||
import { Winner } from "./Winner.js";
|
||||
import { HouseRules } from "./HouseRules.js";
|
||||
import { Dice } from "./Dice.js";
|
||||
import { Flock } from "./Bird.js";
|
||||
|
||||
import history from "./history.js";
|
||||
import "./App.css";
|
||||
@ -332,6 +333,7 @@ const Table = () => {
|
||||
return <GlobalContext.Provider value={global}>
|
||||
{ /* <PingPong/> */ }
|
||||
<div className="Table">
|
||||
<Flock count={15}/>
|
||||
<div className="ActivitiesBox">
|
||||
<Activities/>
|
||||
{ dice && dice.length && <div className="DiceRoll">
|
||||
|
16
client/src/Bird.css
Normal file
16
client/src/Bird.css
Normal file
@ -0,0 +1,16 @@
|
||||
.Flock {
|
||||
z-index: 50;
|
||||
position: relative;
|
||||
top: 5rem;
|
||||
left: 10rem;
|
||||
width: 20rem;
|
||||
height: 20rem;
|
||||
border: 1px solid purple;
|
||||
}
|
||||
|
||||
.Bird {
|
||||
z-index: 50; /* Above Tile (5,10), Road (12), Corner (20) */
|
||||
position: absolute;
|
||||
background-size: 1200% auto;
|
||||
background-repeat: no-repeat;
|
||||
}
|
105
client/src/Bird.js
Normal file
105
client/src/Bird.js
Normal file
@ -0,0 +1,105 @@
|
||||
import React, { useEffect, useState, useCallback } from "react";
|
||||
import { assetsPath } from "./Common.js";
|
||||
import "./Bird.css";
|
||||
|
||||
const
|
||||
birdAngles = 12,
|
||||
birdAnimations = 4;
|
||||
const frames = [0, 1, 2, 3, 3, 3, 2, 1, 0, 0, 0];
|
||||
|
||||
const useAnimationFrame = callback => {
|
||||
// Use useRef for mutable variables that we want to persist
|
||||
// without triggering a re-render on their change
|
||||
const requestRef = React.useRef();
|
||||
|
||||
const animate = time => {
|
||||
callback(time)
|
||||
requestRef.current = requestAnimationFrame(animate);
|
||||
}
|
||||
|
||||
React.useEffect(() => {
|
||||
requestRef.current = requestAnimationFrame(animate);
|
||||
return () => cancelAnimationFrame(requestRef.current);
|
||||
}, []); // Make sure the effect runs only once
|
||||
}
|
||||
|
||||
const Bird = ({ origin, radius, speed, angle, size, style }) => {
|
||||
const [time, setTime] = useState(0);
|
||||
const [rotation] = useState(Math.PI * 2 * radius / speed);
|
||||
const [direction] = useState(Math.floor(birdAngles * (angle ? angle : 0) / 360.));
|
||||
const [cell, setCell] = useState(0);
|
||||
|
||||
const previousTimeRef = React.useRef();
|
||||
|
||||
useAnimationFrame(time => {
|
||||
if (previousTimeRef.current !== undefined) {
|
||||
const deltaTime = time - previousTimeRef.current;
|
||||
setTime(deltaTime);
|
||||
} else {
|
||||
previousTimeRef.current = time;
|
||||
}
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const alpha = (time % speed) / speed;
|
||||
const frame = Math.floor(frames.length * alpha);
|
||||
console.log({ alpha, frame });
|
||||
setCell(frames[Math.floor(frame)]);
|
||||
}, [time, setCell, speed]);
|
||||
|
||||
return <div className={`Bird`}
|
||||
style={{
|
||||
//top: ${origin.x + radius * }
|
||||
width: `${size * 64}px`,
|
||||
height: `${size * 64}px`,
|
||||
backgroundImage: `url(${assetsPath}/gfx/birds.png)`,
|
||||
backgroundPositionX: `${100 * direction / 11}%`,
|
||||
backgroundPositionY: `${100 * cell / 3}%`,
|
||||
transform: `translate(-50%, -50%)`,
|
||||
...style
|
||||
}}
|
||||
/>;
|
||||
};
|
||||
|
||||
const Flock = ({count}) => {
|
||||
const [birds, setBirds] = useState([]);
|
||||
useEffect(() => {
|
||||
const tmp = [];
|
||||
for (let i = 0; i < count; i++) {
|
||||
tmp.push(<Bird
|
||||
speed={500 + Math.random() * 1000}
|
||||
size={0.2 + Math.random() * 0.15}
|
||||
angle={Math.random() * 360}
|
||||
key={i}
|
||||
style={{
|
||||
left: `${Math.random() * 100}%`,
|
||||
top: `${ Math.random() * 100}%`,
|
||||
}}/>)
|
||||
}
|
||||
tmp.push(<Bird
|
||||
speed={500 + Math.random() * 1000}
|
||||
size={0.2 + Math.random() * 0.15}
|
||||
angle={Math.random() * 360}
|
||||
key={count+1}
|
||||
style={{
|
||||
left: `0%`,
|
||||
top: `0%`,
|
||||
border: `1px solid orange`
|
||||
}}/>);
|
||||
tmp.push(<Bird
|
||||
speed={500 + Math.random() * 1000}
|
||||
size={0.2 + Math.random() * 0.15}
|
||||
angle={Math.random() * 360}
|
||||
key={count + 2}
|
||||
style={{
|
||||
left: `100%`,
|
||||
top: `100%`,
|
||||
border: `1px solid green`
|
||||
}} />);
|
||||
setBirds(tmp);
|
||||
}, [count, setBirds]);
|
||||
|
||||
return <div className="Flock">{ birds }</div>;
|
||||
};
|
||||
|
||||
export { Bird, Flock };
|
BIN
original/birds.png
Executable file
BIN
original/birds.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 107 KiB |
BIN
original/birds.xcf
Executable file
BIN
original/birds.xcf
Executable file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user