mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-30 05:59:51 +01:00
feat: optimize rendering
This commit is contained in:
1 parent
b2ee97b3d4
commit
9f15ded0c9
6 files changed
+40
-50
No files matched your search
@@ -1,6 +1,6 @@
|
|||||||
import { Canvas } from '@react-three/fiber';
|
|
||||||
import { GuessEphemeral } from '../stores/guessEphemeral';
|
import { GuessEphemeral } from '../stores/guessEphemeral';
|
||||||
import { TankopediaDisplay } from '../stores/tankopediaPersistent/constants';
|
import { TankopediaDisplay } from '../stores/tankopediaPersistent/constants';
|
||||||
|
import { SmartCanvas } from './SmartCanvas';
|
||||||
import { Controls } from './Tankopedia/HeroSection/components/TankSandbox/components/Control';
|
import { Controls } from './Tankopedia/HeroSection/components/TankSandbox/components/Control';
|
||||||
import { Lighting } from './Tankopedia/HeroSection/components/TankSandbox/components/Lighting';
|
import { Lighting } from './Tankopedia/HeroSection/components/TankSandbox/components/Lighting';
|
||||||
import { TankModel } from './Tankopedia/HeroSection/components/TankSandbox/components/TankModel';
|
import { TankModel } from './Tankopedia/HeroSection/components/TankSandbox/components/TankModel';
|
||||||
@@ -13,7 +13,7 @@ export function GuessRenderer() {
|
|||||||
const isRevealed = guessState !== null;
|
const isRevealed = guessState !== null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Canvas
|
<SmartCanvas
|
||||||
style={{
|
style={{
|
||||||
filter: `grayscale(${isRevealed ? 0 : 1}) contrast(${isRevealed ? 1 : CONTRAST}) brightness(${isRevealed ? 1 : BRIGHTNESS})`,
|
filter: `grayscale(${isRevealed ? 0 : 1}) contrast(${isRevealed ? 1 : CONTRAST}) brightness(${isRevealed ? 1 : BRIGHTNESS})`,
|
||||||
// filter: `drop-shadow(0 0 1rem ${Var('black-a11')})`,
|
// filter: `drop-shadow(0 0 1rem ${Var('black-a11')})`,
|
||||||
@@ -25,6 +25,6 @@ export function GuessRenderer() {
|
|||||||
<Controls distanceScale={2} zoomable={false} />
|
<Controls distanceScale={2} zoomable={false} />
|
||||||
<Lighting display={TankopediaDisplay.Model} />
|
<Lighting display={TankopediaDisplay.Model} />
|
||||||
<TankModel />
|
<TankModel />
|
||||||
</Canvas>
|
</SmartCanvas>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import { Canvas, type CanvasProps } from '@react-three/fiber';
|
||||||
|
import { forwardRef, useImperativeHandle, useRef } from 'react';
|
||||||
|
import { useOnScreen } from '../hooks/useOnScreen';
|
||||||
|
|
||||||
|
export const SmartCanvas = forwardRef<HTMLCanvasElement, CanvasProps>(
|
||||||
|
(props, ref) => {
|
||||||
|
const canvas = useRef<HTMLCanvasElement>(null);
|
||||||
|
const onScreen = useOnScreen(canvas);
|
||||||
|
|
||||||
|
useImperativeHandle(ref, () => canvas.current!, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Canvas
|
||||||
|
frameloop={onScreen ? 'demand' : 'never'}
|
||||||
|
ref={canvas}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
-3
@@ -1,4 +1,3 @@
|
|||||||
import { invalidate } from '@react-three/fiber';
|
|
||||||
import type { QuicklimeEvent } from 'quicklime';
|
import type { QuicklimeEvent } from 'quicklime';
|
||||||
import { useEffect, useRef } from 'react';
|
import { useEffect, useRef } from 'react';
|
||||||
import type { Group } from 'three';
|
import type { Group } from 'three';
|
||||||
@@ -19,8 +18,6 @@ export function CanvasContent() {
|
|||||||
if (!gun.current) return;
|
if (!gun.current) return;
|
||||||
|
|
||||||
gun.current.rotation.x = event.data.pitch;
|
gun.current.rotation.x = event.data.pitch;
|
||||||
|
|
||||||
invalidate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
modelTransformEvent.on(handleModelTransformEvent);
|
modelTransformEvent.on(handleModelTransformEvent);
|
||||||
|
|||||||
+3
-10
@@ -1,19 +1,12 @@
|
|||||||
import { Canvas } from '@react-three/fiber';
|
import { SmartCanvas } from '../../../../../../../SmartCanvas';
|
||||||
import { CameraPositioner, zoom } from './CameraPositioner';
|
import { CameraPositioner, zoom } from './CameraPositioner';
|
||||||
import { CanvasContent } from './CanvasContent';
|
import { CanvasContent } from './CanvasContent';
|
||||||
|
|
||||||
export function FlexibilityCanvas() {
|
export function FlexibilityCanvas() {
|
||||||
return (
|
return (
|
||||||
<Canvas
|
<SmartCanvas orthographic camera={{ zoom, rotation: [0, Math.PI / 2, 0] }}>
|
||||||
frameloop="demand"
|
|
||||||
orthographic
|
|
||||||
camera={{
|
|
||||||
zoom,
|
|
||||||
rotation: [0, Math.PI / 2, 0],
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<CanvasContent />
|
<CanvasContent />
|
||||||
<CameraPositioner />
|
<CameraPositioner />
|
||||||
</Canvas>
|
</SmartCanvas>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
+10
-28
@@ -1,6 +1,6 @@
|
|||||||
import { I_HAT, J_HAT } from '@blitzkit/core';
|
import { I_HAT, J_HAT } from '@blitzkit/core';
|
||||||
import { OrbitControls } from '@react-three/drei';
|
import { OrbitControls } from '@react-three/drei';
|
||||||
import { invalidate, useThree } from '@react-three/fiber';
|
import { invalidate, useFrame, useThree } from '@react-three/fiber';
|
||||||
import { useEffect, useRef } from 'react';
|
import { useEffect, useRef } from 'react';
|
||||||
import { PerspectiveCamera, Vector3 } from 'three';
|
import { PerspectiveCamera, Vector3 } from 'three';
|
||||||
import { OrbitControls as OrbitControlsClass } from 'three-stdlib';
|
import { OrbitControls as OrbitControlsClass } from 'three-stdlib';
|
||||||
@@ -90,32 +90,16 @@ export function Controls({
|
|||||||
-13,
|
-13,
|
||||||
).multiplyScalar(distanceScale);
|
).multiplyScalar(distanceScale);
|
||||||
|
|
||||||
useEffect(() => {
|
const t0 = useRef(Date.now() / 1000);
|
||||||
if (!orbitControls.current || !doAutoRotate) return;
|
useFrame(() => {
|
||||||
|
const now = Date.now() / 1000;
|
||||||
|
const t = now - t0.current;
|
||||||
|
|
||||||
const t0 = Date.now() / 1000;
|
camera.position
|
||||||
let cancel = false;
|
.copy(inspectModeInitialPosition)
|
||||||
|
.applyAxisAngle(I_HAT, (Math.PI / 32) * Math.sin(t / 9))
|
||||||
function frame() {
|
.applyAxisAngle(J_HAT, (-Math.PI / 16) * Math.sin(t / 7));
|
||||||
if (!cancel) requestAnimationFrame(frame);
|
});
|
||||||
|
|
||||||
const now = Date.now() / 1000;
|
|
||||||
const t = now - t0;
|
|
||||||
|
|
||||||
camera.position
|
|
||||||
.copy(inspectModeInitialPosition)
|
|
||||||
.applyAxisAngle(I_HAT, (Math.PI / 32) * Math.sin(t / 9))
|
|
||||||
.applyAxisAngle(J_HAT, (-Math.PI / 16) * Math.sin(t / 7));
|
|
||||||
|
|
||||||
invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
frame();
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
cancel = true;
|
|
||||||
};
|
|
||||||
}, [doAutoRotate, camera]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const unsubscribeTankopediaEphemeral = tankopediaEphemeralStore.subscribe(
|
const unsubscribeTankopediaEphemeral = tankopediaEphemeralStore.subscribe(
|
||||||
@@ -229,8 +213,6 @@ export function Controls({
|
|||||||
}, [camera, protagonistTank.id, antagonistTank.id]);
|
}, [camera, protagonistTank.id, antagonistTank.id]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let isInitialIteration = true;
|
|
||||||
|
|
||||||
function handleWheel(event: WheelEvent) {
|
function handleWheel(event: WheelEvent) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-6
@@ -1,5 +1,5 @@
|
|||||||
import { BLITZKIT_TANK_ICON_SIZE } from '@blitzkit/core';
|
import { BLITZKIT_TANK_ICON_SIZE } from '@blitzkit/core';
|
||||||
import { Canvas, invalidate } from '@react-three/fiber';
|
import { invalidate } from '@react-three/fiber';
|
||||||
import {
|
import {
|
||||||
forwardRef,
|
forwardRef,
|
||||||
Suspense,
|
Suspense,
|
||||||
@@ -13,7 +13,6 @@ import { applyPitchYawLimits } from '../../../../../core/blitz/applyPitchYawLimi
|
|||||||
import { modelTransformEvent } from '../../../../../core/blitzkit/modelTransform';
|
import { modelTransformEvent } from '../../../../../core/blitzkit/modelTransform';
|
||||||
import { Pose, poseEvent } from '../../../../../core/blitzkit/pose';
|
import { Pose, poseEvent } from '../../../../../core/blitzkit/pose';
|
||||||
import { useEquipment } from '../../../../../hooks/useEquipment';
|
import { useEquipment } from '../../../../../hooks/useEquipment';
|
||||||
import { useOnScreen } from '../../../../../hooks/useOnScreen';
|
|
||||||
import { useTankModelDefinition } from '../../../../../hooks/useTankModelDefinition';
|
import { useTankModelDefinition } from '../../../../../hooks/useTankModelDefinition';
|
||||||
import { Duel } from '../../../../../stores/duel';
|
import { Duel } from '../../../../../stores/duel';
|
||||||
import { TankopediaEphemeral } from '../../../../../stores/tankopediaEphemeral';
|
import { TankopediaEphemeral } from '../../../../../stores/tankopediaEphemeral';
|
||||||
@@ -26,6 +25,7 @@ import {
|
|||||||
StaticArmor,
|
StaticArmor,
|
||||||
type ThicknessRange,
|
type ThicknessRange,
|
||||||
} from '../../../../Armor/components/StaticArmor';
|
} from '../../../../Armor/components/StaticArmor';
|
||||||
|
import { SmartCanvas } from '../../../../SmartCanvas';
|
||||||
import { AutoClear } from './components/AutoClear';
|
import { AutoClear } from './components/AutoClear';
|
||||||
import { Controls } from './components/Control';
|
import { Controls } from './components/Control';
|
||||||
import { InitialFogReveal } from './components/InitialFogReveal';
|
import { InitialFogReveal } from './components/InitialFogReveal';
|
||||||
@@ -65,7 +65,6 @@ export const TankSandbox = forwardRef<HTMLCanvasElement, TankSandboxProps>(
|
|||||||
const hideTankModelUnderArmor = TankopediaPersistent.use(
|
const hideTankModelUnderArmor = TankopediaPersistent.use(
|
||||||
(state) => state.hideTankModelUnderArmor,
|
(state) => state.hideTankModelUnderArmor,
|
||||||
);
|
);
|
||||||
const onScreen = useOnScreen(canvas);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (rawDisplay === display) return;
|
if (rawDisplay === display) return;
|
||||||
@@ -204,10 +203,9 @@ export const TankSandbox = forwardRef<HTMLCanvasElement, TankSandboxProps>(
|
|||||||
}, [display]);
|
}, [display]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Canvas
|
<SmartCanvas
|
||||||
ref={canvas}
|
ref={canvas}
|
||||||
scene={{ fog: naked ? undefined : fog.current }}
|
scene={{ fog: naked ? undefined : fog.current }}
|
||||||
frameloop={onScreen ? 'demand' : 'never'}
|
|
||||||
gl={{
|
gl={{
|
||||||
clippingPlanes: [],
|
clippingPlanes: [],
|
||||||
localClippingEnabled: true,
|
localClippingEnabled: true,
|
||||||
@@ -248,7 +246,7 @@ export const TankSandbox = forwardRef<HTMLCanvasElement, TankSandboxProps>(
|
|||||||
)}
|
)}
|
||||||
<Lighting display={display} />
|
<Lighting display={display} />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</Canvas>
|
</SmartCanvas>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
Reference in new issue
Block a user