refactor: radians

This commit is contained in:
cha0s 2024-07-14 21:07:46 -05:00
parent 94685e4654
commit 4529d2e8d3
9 changed files with 82 additions and 80 deletions

9
app/context/radians.js Normal file
View File

@ -0,0 +1,9 @@
import {createContext, useContext} from 'react';
const context = createContext();
export default context;
export function useRadians() {
return useContext(context);
}

View File

@ -1,33 +1,32 @@
import {useEffect, useState} from 'react';
import {memo, useEffect, useState} from 'react';
import {useRadians} from '@/context/radians.js';
import {render} from '@/dialogue.js';
import {TAU} from '@/util/math.js';
import styles from './message.module.css';
export default function Message({letters}) {
const [radians, setRadians] = useState(0);
function Message({letters}) {
const radians = useRadians();
const [localRadians, setLocalRadians] = useState(radians);
const [isAnimating, setIsAnimating] = useState(true);
useEffect(() => {
setRadians(0);
let handle;
let last;
const spin = (ts) => {
if ('undefined' === typeof last) {
last = ts;
}
const elapsed = (ts - last) / 1000;
last = ts;
setRadians((radians) => radians + (elapsed * TAU));
handle = requestAnimationFrame(spin);
};
handle = requestAnimationFrame(spin);
const handle = setTimeout(() => {
setIsAnimating(false);
}, 2_000);
return () => {
cancelAnimationFrame(handle);
};
clearTimeout(handle);
}
}, []);
useEffect(() => {
if (isAnimating) {
setLocalRadians(radians)
}
}, [isAnimating, radians]);
return (
<div className={styles.message}>
{render(letters, '')(letters.length - 1, radians)}
{render(letters, '')(letters.length - 1, localRadians)}
</div>
)
}
export default memo(Message);

View File

@ -2,8 +2,8 @@ import {useEffect, useMemo, useRef, useState} from 'react';
import {RESOLUTION} from '@/constants.js';
import {useDomScale} from '@/context/dom-scale.js';
import {useRadians} from '@/context/radians.js';
import {render} from '@/dialogue.js';
import {TAU} from '@/util/math.js';
import styles from './dialogue.module.css';
@ -18,7 +18,7 @@ export default function Dialogue({
const ref = useRef();
const [dimensions, setDimensions] = useState({h: 0, w: 0});
const [caret, setCaret] = useState(0);
const [radians, setRadians] = useState(0);
const radians = useRadians();
useEffect(() => {
return dialogue.addSkipListener(() => {
if (caret >= dialogue.letters.length - 1) {
@ -29,24 +29,6 @@ export default function Dialogue({
}
});
}, [caret, dialogue]);
useEffect(() => {
setRadians(0);
let handle;
let last;
const spin = (ts) => {
if ('undefined' === typeof last) {
last = ts;
}
const elapsed = (ts - last) / 1000;
last = ts;
setRadians((radians) => radians + (elapsed * TAU));
handle = requestAnimationFrame(spin);
};
handle = requestAnimationFrame(spin);
return () => {
cancelAnimationFrame(handle);
};
}, []);
useEffect(() => {
const {params} = dialogue.letters[caret];
let handle;

View File

@ -1,11 +1,12 @@
import {AdjustmentFilter} from '@pixi/filter-adjustment';
import {GlowFilter} from '@pixi/filter-glow';
import {Container} from '@pixi/react';
import {useEffect, useState} from 'react';
import {useState} from 'react';
import {usePacket} from '@/context/client.js';
import {useEcs, useEcsTick} from '@/context/ecs.js';
import {useMainEntity} from '@/context/main-entity.js';
import {useRadians} from '@/context/radians.js';
import Entity from './entity.jsx';
@ -13,10 +14,13 @@ export default function Entities({filters, monopolizers}) {
const [ecs] = useEcs();
const [entities, setEntities] = useState({});
const [mainEntity] = useMainEntity();
const [radians, setRadians] = useState(0);
const radians = useRadians();
const [willInteractWith, setWillInteractWith] = useState(0);
const [interactionFilters] = useState([new AdjustmentFilter(), new GlowFilter({color: 0x0})]);
const pulse = (Math.cos(radians) + 1) * 0.5;
const [interactionFilters] = useState([
new AdjustmentFilter(),
new GlowFilter({color: 0x0}),
]);
const pulse = (Math.cos(radians / 4) + 1) * 0.5;
interactionFilters[0].brightness = (pulse * 0.75) + 1;
interactionFilters[1].outerStrength = pulse * 0.5;
usePacket('EcsChange', async () => {
@ -64,15 +68,6 @@ export default function Entities({filters, monopolizers}) {
setWillInteractWith(main.Interacts.willInteractWith);
}
}, [ecs, mainEntity]);
useEffect(() => {
setRadians(0);
const handle = setInterval(() => {
setRadians((radians) => (radians + 0.1) % (Math.PI * 2))
}, 50);
return () => {
clearInterval(handle);
};
}, []);
const renderables = [];
for (const id in entities) {
const isHighlightedInteraction = 0 === monopolizers.length && id == willInteractWith;

View File

@ -11,13 +11,21 @@ import ClientContext from '@/context/client.js';
import DebugContext from '@/context/debug.js';
import EcsContext from '@/context/ecs.js';
import MainEntityContext from '@/context/main-entity.js';
import RadiansContext from '@/context/radians.js';
import Ecs from './ecs.jsx';
import styles from './pixi.module.css';
BaseTexture.defaultOptions.scaleMode = SCALE_MODES.NEAREST;
const Contexts = [AssetsContext, ClientContext, DebugContext, EcsContext, MainEntityContext];
const Contexts = [
AssetsContext,
ClientContext,
DebugContext,
EcsContext,
MainEntityContext,
RadiansContext,
];
const ContextBridge = ({children, render}) => {
const contexts = Contexts.map(useContext);

View File

@ -1,7 +1,8 @@
import {Container} from '@pixi/display';
import {Graphics} from '@pixi/graphics';
import {PixiComponent} from '@pixi/react';
import {useEffect, useState} from 'react';
import {useRadians} from '@/context/radians.js';
const tileSize = {x: 16, y: 16};
@ -34,15 +35,7 @@ const TargetingGhostInternal = PixiComponent('TargetingGhost', {
})
export default function TargetingGhost({projected, tileLayer}) {
const [radians, setRadians] = useState(0);
useEffect(() => {
const handle = setInterval(() => {
setRadians((radians) => (radians + 0.2) % (Math.PI * 2))
}, 50);
return () => {
clearInterval(handle);
};
}, []);
const radians = useRadians();
const ghosts = [];
const {area} = tileLayer;
for (const {x, y} of projected) {
@ -54,7 +47,7 @@ export default function TargetingGhost({projected, tileLayer}) {
key={JSON.stringify({x, y})}
x={x * tileSize.x + tileSize.x * 0.5}
y={y * tileSize.y + tileSize.y * 0.5}
radians={radians}
radians={radians / 2}
/>
);
}

View File

@ -4,7 +4,8 @@ import {BlurFilter} from '@pixi/filter-blur';
import {Graphics} from '@pixi/graphics';
import {PixiComponent, useApp} from '@pixi/react';
import {Sprite} from '@pixi/sprite';
import {useEffect, useState} from 'react';
import {useRadians} from '@/context/radians.js';
const tileSize = {x: 16, y: 16};
const radius = 9;
@ -86,19 +87,11 @@ const TargetingGridInternal = PixiComponent('TargetingGrid', {
export default function TargetingGrid({tileLayer, x, y}) {
const app = useApp();
const [radians, setRadians] = useState(0);
useEffect(() => {
const handle = setInterval(() => {
setRadians((radians) => (radians + 0.1) % (Math.PI * 2))
}, 50);
return () => {
clearInterval(handle);
};
}, []);
const radians = useRadians();
return (
<TargetingGridInternal
app={app}
radians={radians}
radians={radians / 4}
tileLayer={tileLayer}
x={x}
y={y}

View File

@ -1,4 +1,4 @@
import {useEffect, useRef, useState} from 'react';
import {memo, useEffect, useRef, useState} from 'react';
import addKeyListener from '@/add-key-listener.js';
import ClientEcs from '@/client-ecs';
@ -47,7 +47,7 @@ const devEventsChannel = {
},
};
export default function Ui({disconnected}) {
function Ui({disconnected}) {
// Key input.
const client = useClient();
const chatInputRef = useRef();
@ -483,3 +483,4 @@ export default function Ui({disconnected}) {
);
}
export default memo(Ui);

View File

@ -7,8 +7,10 @@ import ClientContext from '@/context/client.js';
import DebugContext from '@/context/debug.js';
import EcsContext from '@/context/ecs.js';
import MainEntityContext from '@/context/main-entity.js';
import RadiansContext from '@/context/radians.js';
import Ui from '@/react-components/ui.jsx';
import {juggleSession} from '@/session.server';
import {TAU} from '@/util/math.js';
export async function loader({request}) {
await juggleSession(request);
@ -26,6 +28,24 @@ export default function PlaySpecific() {
const [disconnected, setDisconnected] = useState(false);
const params = useParams();
const [type, url] = params['*'].split('/');
const [radians, setRadians] = useState(0);
useEffect(() => {
let handle;
let last;
const spin = (ts) => {
if ('undefined' === typeof last) {
last = ts;
}
const elapsed = (ts - last) / 1000;
last = ts;
setRadians((radians) => radians + (elapsed * TAU));
handle = requestAnimationFrame(spin);
};
handle = requestAnimationFrame(spin);
return () => {
cancelAnimationFrame(handle);
};
}, []);
useEffect(() => {
if (!Client) {
return;
@ -121,7 +141,9 @@ export default function PlaySpecific() {
<EcsContext.Provider value={ecsTuple}>
<DebugContext.Provider value={debugTuple}>
<AssetsContext.Provider value={assetsTuple}>
<RadiansContext.Provider value={radians}>
<Ui disconnected={disconnected} />
</RadiansContext.Provider>
</AssetsContext.Provider>
</DebugContext.Provider>
</EcsContext.Provider>