mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-11-12 12:16:11 +01:00
feat: foggy transition
This commit is contained in:
1 parent
7a18de6650
commit
6d8387fa9d
7 files changed
+109
-40
No files matched your search
+5
-3
@@ -4,14 +4,16 @@ import { Euler } from 'three';
|
||||
import { degToRad } from 'three/src/math/MathUtils.js';
|
||||
import { useModel } from '../../../../../../hooks/useModel';
|
||||
import { Duel } from '../../../../../../stores/duel';
|
||||
import { TankopediaEphemeral } from '../../../../../../stores/tankopediaEphemeral';
|
||||
import { TankopediaDisplay } from '../../../../../../stores/tankopediaPersistent/constants';
|
||||
|
||||
const LIGHTS_COUNT = 5;
|
||||
|
||||
export function Lighting() {
|
||||
interface LightingProps {
|
||||
display: TankopediaDisplay;
|
||||
}
|
||||
|
||||
export function Lighting({ display }: LightingProps) {
|
||||
const protagonist = Duel.use((state) => state.protagonist);
|
||||
const display = TankopediaEphemeral.use((state) => state.display);
|
||||
const { hasPbr } = useModel(protagonist.tank.id);
|
||||
const isBrighterLighting =
|
||||
!hasPbr && display !== TankopediaDisplay.StaticArmor;
|
||||
|
||||
+44
-4
@@ -1,12 +1,14 @@
|
||||
import { BLITZKIT_TANK_ICON_SIZE } from '@blitzkit/core';
|
||||
import { Canvas } from '@react-three/fiber';
|
||||
import { Canvas, invalidate } from '@react-three/fiber';
|
||||
import {
|
||||
forwardRef,
|
||||
Suspense,
|
||||
useEffect,
|
||||
useImperativeHandle,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react';
|
||||
import { Fog } from 'three';
|
||||
import { applyPitchYawLimits } from '../../../../../core/blitz/applyPitchYawLimits';
|
||||
import { modelTransformEvent } from '../../../../../core/blitzkit/modelTransform';
|
||||
import { Pose, poseEvent } from '../../../../../core/blitzkit/pose';
|
||||
@@ -36,8 +38,15 @@ interface TankSandboxProps {
|
||||
naked?: boolean;
|
||||
}
|
||||
|
||||
const near0 = 15;
|
||||
const far0 = 25;
|
||||
const near1 = 0;
|
||||
const far1 = 0;
|
||||
const animationTime = 0.5;
|
||||
|
||||
export const TankSandbox = forwardRef<HTMLCanvasElement, TankSandboxProps>(
|
||||
({ thicknessRange, naked }, ref) => {
|
||||
const fog = useRef(new Fog('black', near0, far0));
|
||||
const mutateTankopediaEphemeral = TankopediaEphemeral.useMutation();
|
||||
const canvas = useRef<HTMLCanvasElement>(null);
|
||||
const hasImprovedVerticalStabilizer = useEquipment(122);
|
||||
@@ -50,12 +59,42 @@ export const TankSandbox = forwardRef<HTMLCanvasElement, TankSandboxProps>(
|
||||
tankModelDefinition.turrets[protagonistTurret.id];
|
||||
const gunModelDefinition =
|
||||
turretModelDefinition.guns[protagonistGun.gun_type!.value.base.id];
|
||||
const display = TankopediaEphemeral.use((state) => state.display);
|
||||
const rawDisplay = TankopediaEphemeral.use((state) => state.display);
|
||||
const [display, setDisplay] = useState(rawDisplay);
|
||||
const hideTankModelUnderArmor = TankopediaPersistent.use(
|
||||
(state) => state.hideTankModelUnderArmor,
|
||||
);
|
||||
const onScreen = useOnScreen(canvas);
|
||||
|
||||
useEffect(() => {
|
||||
if (rawDisplay === display) return;
|
||||
|
||||
const t0 = Date.now();
|
||||
|
||||
const interval = setInterval((e) => {
|
||||
const t = (Date.now() - t0) / 1000;
|
||||
const x = t / animationTime;
|
||||
const y = Math.cbrt(-2 * Math.abs(x - 0.5)) + 1;
|
||||
|
||||
const near = near0 + (near1 - near0) * y;
|
||||
const far = far0 + (far1 - far0) * y;
|
||||
|
||||
fog.current.near = near;
|
||||
fog.current.far = far;
|
||||
|
||||
invalidate();
|
||||
|
||||
if (rawDisplay !== display && x >= 0.5) setDisplay(rawDisplay);
|
||||
if (x >= 1) {
|
||||
fog.current.near = near0;
|
||||
fog.current.far = far0;
|
||||
clearInterval(interval);
|
||||
}
|
||||
}, 1000 / 60);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, [rawDisplay]);
|
||||
|
||||
useImperativeHandle(ref, () => canvas.current!, []);
|
||||
|
||||
function handlePointerDown() {
|
||||
@@ -166,6 +205,8 @@ export const TankSandbox = forwardRef<HTMLCanvasElement, TankSandboxProps>(
|
||||
|
||||
return (
|
||||
<Canvas
|
||||
ref={canvas}
|
||||
scene={{ fog: naked ? undefined : fog.current }}
|
||||
frameloop={
|
||||
onScreen
|
||||
? display === TankopediaDisplay.ShootingRange
|
||||
@@ -179,7 +220,6 @@ export const TankSandbox = forwardRef<HTMLCanvasElement, TankSandboxProps>(
|
||||
preserveDrawingBuffer: true,
|
||||
}}
|
||||
shadows
|
||||
ref={canvas}
|
||||
onPointerDown={handlePointerDown}
|
||||
onPointerMissed={() => {
|
||||
mutateTankopediaEphemeral((draft) => {
|
||||
@@ -208,7 +248,7 @@ export const TankSandbox = forwardRef<HTMLCanvasElement, TankSandboxProps>(
|
||||
{display === TankopediaDisplay.StaticArmor && (
|
||||
<StaticArmor thicknessRange={thicknessRange} />
|
||||
)}
|
||||
<Lighting />
|
||||
<Lighting display={display} />
|
||||
</Suspense>
|
||||
</Canvas>
|
||||
);
|
||||
|
||||
@@ -4,7 +4,6 @@ import { times } from 'lodash-es';
|
||||
import { Suspense, useEffect, useMemo, useRef } from 'react';
|
||||
import { NAVBAR_HEIGHT } from '../../../constants/navbar';
|
||||
import { awaitableTankDefinitions } from '../../../core/awaitables/tankDefinitions';
|
||||
import { Var } from '../../../core/radix/var';
|
||||
import { useFullScreen } from '../../../hooks/useFullScreen';
|
||||
import { useLocale } from '../../../hooks/useLocale';
|
||||
import { Duel } from '../../../stores/duel';
|
||||
@@ -74,15 +73,10 @@ export function HeroSection({ skeleton }: MaybeSkeletonComponentProps) {
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Flex justify="center" style={{ backgroundColor: Var('color-surface') }}>
|
||||
<Flex justify="center" style={{ backgroundColor: 'black' }}>
|
||||
<Flex
|
||||
direction={{ initial: 'column', md: 'row' }}
|
||||
style={{
|
||||
backgroundColor: isFullScreen
|
||||
? Var('color-background')
|
||||
: Var('color-surface'),
|
||||
zIndex: isFullScreen ? 2 : undefined,
|
||||
}}
|
||||
style={{ zIndex: isFullScreen ? 2 : undefined }}
|
||||
height={
|
||||
isFullScreen ? '100vh' : `calc(100vh - ${NAVBAR_HEIGHT}px - 8rem)`
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user