mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-24 20:19:49 +02:00
Compare commits
19
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cb2d795461 | ||
|
|
6e934e0ff1 | ||
|
|
375adadbe5 | ||
|
|
082a756f1b | ||
|
|
9fc8a8e2a2 | ||
|
|
1413475679 | ||
|
|
86504e685e | ||
|
|
9df81044d1 | ||
|
|
c5fd7591ea | ||
|
|
cd8e43f945 | ||
|
|
8df112aab4 | ||
|
|
94c04ce102 | ||
|
|
3a170202ca | ||
|
|
46937693a0 | ||
|
|
b391d0b036 | ||
|
|
1061e003f7 | ||
|
|
a2b573abca | ||
|
|
4571d141e6 | ||
|
|
d70225b03c |
No files matched your search
@@ -0,0 +1,20 @@
|
|||||||
|
# BlitzKit 1.30.7
|
||||||
|
|
||||||
|
Thank you to [Mark Greene](https://github.com/Hitjack007) for your contributions this update.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Dragging items in the Tier List now automatically scrolls the screen if you reach the top/bottom edge of the screen
|
||||||
|
|
||||||
|
## Fixes
|
||||||
|
|
||||||
|
- [Mark Greene] Clicking on the armor multiple times with HE no longer crashes BlitzKit
|
||||||
|
- [Mark Greene] Ricochets that later intersect with external modules no longer falsely claim a successful damaging penetration
|
||||||
|
- The lighting animation no longer stops prematurely when BlitzKit is unfocused
|
||||||
|
- The spot light angle has been increased to more evenly light up larger tanks
|
||||||
|
- BlitzKit once again uses soft shadows, reducing the pixelated shadows
|
||||||
|
- Fixed the weird patterns that formed on the tracks of tanks under self-shadows
|
||||||
|
- Increased the floor size and light decay to create the illusion that the floor is infinite
|
||||||
|
- [Mark Greene] Safari no longer crashes when unloading textures for unloaded tanks
|
||||||
|
- The gun depression transition between two constraints (like often behind tanks) now uses a gentler zoned and can never be 0
|
||||||
|
- [Mark Greene] Armor plate names in Static Armor are now properly capitalized in English and translated to other languages
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "blitzkit",
|
"name": "blitzkit",
|
||||||
"version": "1.30.6",
|
"version": "1.30.7",
|
||||||
"license": "BlitzKit License",
|
"license": "BlitzKit License",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export function ArmorPlateDisplay() {
|
|||||||
const highlightArmor = Tankopedia.use((state) => state.highlightArmor);
|
const highlightArmor = Tankopedia.use((state) => state.highlightArmor);
|
||||||
const developerMode = App.useDeferred((state) => state.developerMode, false);
|
const developerMode = App.useDeferred((state) => state.developerMode, false);
|
||||||
const input = useRef<HTMLInputElement>(null);
|
const input = useRef<HTMLInputElement>(null);
|
||||||
const { locale } = useLocale();
|
const { locale, strings } = useLocale();
|
||||||
|
|
||||||
if (highlightArmor === undefined) return null;
|
if (highlightArmor === undefined) return null;
|
||||||
|
|
||||||
@@ -44,7 +44,10 @@ export function ArmorPlateDisplay() {
|
|||||||
>
|
>
|
||||||
<Flex direction="column">
|
<Flex direction="column">
|
||||||
<Text weight="bold">
|
<Text weight="bold">
|
||||||
{layerTypeNames[highlightArmor.type]}{" "}
|
{
|
||||||
|
strings.website.tools.tankopedia.sandbox.dynamic.shot_card
|
||||||
|
.element[layerTypeNames[highlightArmor.type]]
|
||||||
|
}{" "}
|
||||||
{highlightArmor.thickness.toFixed(0)}
|
{highlightArmor.thickness.toFixed(0)}
|
||||||
<Text size="1" weight="regular">
|
<Text size="1" weight="regular">
|
||||||
mm
|
mm
|
||||||
|
|||||||
@@ -42,10 +42,10 @@ const TRACER_THIN = TRACER_THICK / 2;
|
|||||||
|
|
||||||
export function ShotDisplay() {
|
export function ShotDisplay() {
|
||||||
const shot = Tankopedia.use((state) => state.shot);
|
const shot = Tankopedia.use((state) => state.shot);
|
||||||
const inTracer = useRef<Mesh>(null!);
|
const inTracer = useRef<Mesh>(null);
|
||||||
const outTracer = useRef<Mesh>(null!);
|
const outTracer = useRef<Mesh>(null);
|
||||||
const splashRadiusWrapper = useRef<Group>(null!);
|
const splashRadiusWrapper = useRef<Group>(null);
|
||||||
const splashRadiusMaterial = useRef<MeshBasicMaterial>(null!);
|
const splashRadiusMaterial = useRef<MeshBasicMaterial>(null);
|
||||||
const { locale } = useLocale();
|
const { locale } = useLocale();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -63,10 +63,10 @@ export function ShotDisplay() {
|
|||||||
outlineMaterial,
|
outlineMaterial,
|
||||||
).computeLineDistances();
|
).computeLineDistances();
|
||||||
|
|
||||||
splashRadiusWrapper.current.add(outline);
|
splashRadiusWrapper.current?.add(outline);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
splashRadiusWrapper.current.remove(outline);
|
splashRadiusWrapper.current?.remove(outline);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -255,11 +255,11 @@ export function ShotDisplay() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface AnimatorProps {
|
interface AnimatorProps {
|
||||||
inTracer: RefObject<Mesh>;
|
inTracer: RefObject<Mesh | null>;
|
||||||
outTracer: RefObject<Mesh>;
|
outTracer: RefObject<Mesh | null>;
|
||||||
|
|
||||||
splashRadiusWrapper: RefObject<Group>;
|
splashRadiusWrapper: RefObject<Group | null>;
|
||||||
splashRadiusMaterial: RefObject<MeshBasicMaterial>;
|
splashRadiusMaterial: RefObject<MeshBasicMaterial | null>;
|
||||||
|
|
||||||
inLength: number;
|
inLength: number;
|
||||||
outLength: number;
|
outLength: number;
|
||||||
@@ -283,17 +283,23 @@ function Animator({
|
|||||||
const tracerT1 = t % 1;
|
const tracerT1 = t % 1;
|
||||||
const tracerT2 = (t + 0.5) % 1;
|
const tracerT2 = (t + 0.5) % 1;
|
||||||
|
|
||||||
inTracer.current.scale.set(1, 1 - 2 * Math.abs(tracerT1 - 0.5), 1);
|
if (inTracer.current) {
|
||||||
inTracer.current.position.set(0, (1 - tracerT1) * inLength, 0);
|
inTracer.current.scale.set(1, 1 - 2 * Math.abs(tracerT1 - 0.5), 1);
|
||||||
|
inTracer.current.position.set(0, (1 - tracerT1) * inLength, 0);
|
||||||
|
|
||||||
if (outTracer.current) {
|
if (outTracer.current) {
|
||||||
outTracer.current.scale.set(1, 1 - 2 * Math.abs(tracerT2 - 0.5), 1);
|
outTracer.current.scale.set(1, 1 - 2 * Math.abs(tracerT2 - 0.5), 1);
|
||||||
outTracer.current.position.set(0, tracerT2 * outLength, 0);
|
outTracer.current.position.set(0, tracerT2 * outLength, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
invalidate();
|
if (
|
||||||
|
shot.splashRadius !== undefined &&
|
||||||
if (shot.splashRadius !== undefined) {
|
splashRadiusWrapper.current &&
|
||||||
|
splashRadiusMaterial.current
|
||||||
|
) {
|
||||||
if (animationStartTime === null) animationStartTime = t;
|
if (animationStartTime === null) animationStartTime = t;
|
||||||
|
|
||||||
const scale =
|
const scale =
|
||||||
|
|||||||
+4
-3
@@ -161,9 +161,10 @@ export function SpacedArmorSceneComponent({
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
!allowRicochet &&
|
!allowRicochet &&
|
||||||
noDuplicateIntersections.every((intersection) => {
|
noDuplicateIntersections.every(
|
||||||
intersection.object.userData.type !== ArmorType.Primary;
|
(intersection) =>
|
||||||
})
|
intersection.object.userData.type !== ArmorType.Primary,
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
+28
-18
@@ -1,14 +1,20 @@
|
|||||||
import { useFrame } from "@react-three/fiber";
|
import { useFrame } from "@react-three/fiber";
|
||||||
import { clamp, times } from "lodash-es";
|
import { clamp, times } from "lodash-es";
|
||||||
import { Quicklime } from "quicklime";
|
import { Quicklime } from "quicklime";
|
||||||
import { useEffect, useRef, useState, type RefObject } from "react";
|
import {
|
||||||
|
useCallback,
|
||||||
|
useEffect,
|
||||||
|
useRef,
|
||||||
|
useState,
|
||||||
|
type RefObject,
|
||||||
|
} from "react";
|
||||||
import { HemisphereLight, SpotLight, type Group } from "three";
|
import { HemisphereLight, SpotLight, type Group } from "three";
|
||||||
import { degToRad, lerp } from "three/src/math/MathUtils.js";
|
import { degToRad, lerp } from "three/src/math/MathUtils.js";
|
||||||
import { Tankopedia } from "../../../../../../stores/tankopedia";
|
import { Tankopedia } from "../../../../../../stores/tankopedia";
|
||||||
import { TankopediaPersistent } from "../../../../../../stores/tankopediaPersistent";
|
import { TankopediaPersistent } from "../../../../../../stores/tankopediaPersistent";
|
||||||
import { HelpingSpotLight } from "../../../../../HelpingSpotLight";
|
import { HelpingSpotLight } from "../../../../../HelpingSpotLight";
|
||||||
|
|
||||||
const ANGLE = degToRad(10);
|
const ANGLE = degToRad(12);
|
||||||
const REVEAL_ANIMATION_TIME = 3;
|
const REVEAL_ANIMATION_TIME = 3;
|
||||||
const TRANSITION_ANIMATION_TIME = 0.5;
|
const TRANSITION_ANIMATION_TIME = 0.5;
|
||||||
|
|
||||||
@@ -17,8 +23,8 @@ const THETA_OFFSET = degToRad(180 - 45);
|
|||||||
const LIGHT_DISTANCE = 20;
|
const LIGHT_DISTANCE = 20;
|
||||||
const LIGHT_HEIGHT_0 = 4;
|
const LIGHT_HEIGHT_0 = 4;
|
||||||
const LIGHT_HEIGHT_1 = 6;
|
const LIGHT_HEIGHT_1 = 6;
|
||||||
const INTENSITY_0 = 6;
|
const INTENSITY_0 = 6 * 9;
|
||||||
const INTENSITY_1 = 3;
|
const INTENSITY_1 = 3 * 9;
|
||||||
const HEMISPHERE_INTENSITY = 2;
|
const HEMISPHERE_INTENSITY = 2;
|
||||||
|
|
||||||
export const transitionEvent = new Quicklime<number>(0);
|
export const transitionEvent = new Quicklime<number>(0);
|
||||||
@@ -36,8 +42,6 @@ export function Lighting() {
|
|||||||
|
|
||||||
const [animate, setAnimate] = useState(true);
|
const [animate, setAnimate] = useState(true);
|
||||||
|
|
||||||
console.log(animate);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
Tankopedia.mutate((draft) => {
|
Tankopedia.mutate((draft) => {
|
||||||
draft.revealed = true;
|
draft.revealed = true;
|
||||||
@@ -89,7 +93,7 @@ export function Lighting() {
|
|||||||
intensity={intensity}
|
intensity={intensity}
|
||||||
penumbra={1}
|
penumbra={1}
|
||||||
castShadow={highGraphics}
|
castShadow={highGraphics}
|
||||||
decay={0}
|
decay={1}
|
||||||
color="#ffffff"
|
color="#ffffff"
|
||||||
angle={0}
|
angle={0}
|
||||||
/>
|
/>
|
||||||
@@ -111,17 +115,7 @@ interface AnimatorProps {
|
|||||||
function Animator({ stop, t0, animationTime, wrapper }: AnimatorProps) {
|
function Animator({ stop, t0, animationTime, wrapper }: AnimatorProps) {
|
||||||
const requestedDisplay = Tankopedia.use((state) => state.requestedDisplay);
|
const requestedDisplay = Tankopedia.use((state) => state.requestedDisplay);
|
||||||
|
|
||||||
useFrame(({ invalidate }) => {
|
const apply = useCallback((t: number) => {
|
||||||
const dt = performance.now() / 1e3 - t0.current;
|
|
||||||
const x = clamp(dt / animationTime.current, 0, 2);
|
|
||||||
|
|
||||||
if (x === 2) {
|
|
||||||
stop();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const t = (0.5 * Math.sin(Math.PI * (x + 0.5)) + 0.5) ** 2;
|
|
||||||
|
|
||||||
for (const child of wrapper.current.children) {
|
for (const child of wrapper.current.children) {
|
||||||
if (child instanceof SpotLight) {
|
if (child instanceof SpotLight) {
|
||||||
child.angle = ANGLE * t;
|
child.angle = ANGLE * t;
|
||||||
@@ -131,6 +125,22 @@ function Animator({ stop, t0, animationTime, wrapper }: AnimatorProps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
transitionEvent.dispatch(t);
|
transitionEvent.dispatch(t);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useFrame(({ invalidate }) => {
|
||||||
|
const dt = performance.now() / 1e3 - t0.current;
|
||||||
|
const x = clamp(dt / animationTime.current, 0, 2);
|
||||||
|
|
||||||
|
if (x === 2) {
|
||||||
|
apply(1);
|
||||||
|
stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://www.desmos.com/calculator/awsbahxjku
|
||||||
|
const t = (0.5 * Math.sin(Math.PI * (x + 0.5)) + 0.5) ** 2;
|
||||||
|
|
||||||
|
apply(t);
|
||||||
invalidate();
|
invalidate();
|
||||||
|
|
||||||
if (x >= 1 && Tankopedia.state.display !== requestedDisplay) {
|
if (x >= 1 && Tankopedia.state.display !== requestedDisplay) {
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@ import { Quicklime, type QuicklimeEvent } from "quicklime";
|
|||||||
import { useEffect, useRef } from "react";
|
import { useEffect, useRef } from "react";
|
||||||
import { Mesh, MeshStandardMaterial } from "three";
|
import { Mesh, MeshStandardMaterial } from "three";
|
||||||
|
|
||||||
const SIZE = 14;
|
const SIZE = 2 ** 4;
|
||||||
|
|
||||||
export const screenshotReadyEvent = new Quicklime(false);
|
export const screenshotReadyEvent = new Quicklime(false);
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -156,7 +156,7 @@ export const TankSandbox = forwardRef<HTMLCanvasElement, TankSandboxProps>(
|
|||||||
localClippingEnabled: true,
|
localClippingEnabled: true,
|
||||||
preserveDrawingBuffer: true,
|
preserveDrawingBuffer: true,
|
||||||
}}
|
}}
|
||||||
shadows="basic"
|
shadows="soft"
|
||||||
onPointerDown={handlePointerDown}
|
onPointerDown={handlePointerDown}
|
||||||
onPointerMissed={() => {
|
onPointerMissed={() => {
|
||||||
Tankopedia.mutate((draft) => {
|
Tankopedia.mutate((draft) => {
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
import type { TankDefinition } from '@blitzkit/core';
|
import type { TankDefinition } from "@blitzkit/core";
|
||||||
import { Box } from '@radix-ui/themes';
|
import { Box } from "@radix-ui/themes";
|
||||||
import {
|
import {
|
||||||
useCallback,
|
useCallback,
|
||||||
useEffect,
|
useEffect,
|
||||||
useRef,
|
useRef,
|
||||||
type PointerEvent as ReactPointerEvent,
|
type PointerEvent as ReactPointerEvent,
|
||||||
} from 'react';
|
} from "react";
|
||||||
import { TierList } from '../../stores/tierList';
|
import { TierList } from "../../stores/tierList";
|
||||||
import { TankCard } from '../TankCard';
|
import { TankCard } from "../TankCard";
|
||||||
import { tierListCardElements, tierListRowElements } from './Table/constants';
|
import { tierListCardElements, tierListRowElements } from "./Table/constants";
|
||||||
|
|
||||||
|
const SCROLL_ZONE = 1 / 3;
|
||||||
|
|
||||||
type TierListTileProps = {
|
type TierListTileProps = {
|
||||||
tank: TankDefinition;
|
tank: TankDefinition;
|
||||||
@@ -26,6 +28,33 @@ type TierListTileProps = {
|
|||||||
export function TierListTile(props: TierListTileProps) {
|
export function TierListTile(props: TierListTileProps) {
|
||||||
const card = useRef<HTMLDivElement>(null);
|
const card = useRef<HTMLDivElement>(null);
|
||||||
const lastPosition = useRef({ x: 0, y: 0 });
|
const lastPosition = useRef({ x: 0, y: 0 });
|
||||||
|
const autoScroll = useRef(false);
|
||||||
|
const lastT = useRef(0);
|
||||||
|
|
||||||
|
const autoScrollLoop = useCallback(() => {
|
||||||
|
if (!autoScroll.current) return;
|
||||||
|
|
||||||
|
let scrollSpeed = 0;
|
||||||
|
const v = lastPosition.current.y / window.innerHeight;
|
||||||
|
|
||||||
|
if (v <= SCROLL_ZONE) {
|
||||||
|
scrollSpeed = v / SCROLL_ZONE - 1;
|
||||||
|
} else if (v >= 1 - SCROLL_ZONE) {
|
||||||
|
scrollSpeed = 1 - (1 - v) / SCROLL_ZONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
const t = performance.now();
|
||||||
|
const dt = t - lastT.current;
|
||||||
|
lastT.current = t;
|
||||||
|
|
||||||
|
window.scrollBy({
|
||||||
|
behavior: "instant",
|
||||||
|
top: scrollSpeed * dt,
|
||||||
|
});
|
||||||
|
|
||||||
|
requestAnimationFrame(autoScrollLoop);
|
||||||
|
}, []);
|
||||||
|
|
||||||
const handlePointerDown = useCallback(
|
const handlePointerDown = useCallback(
|
||||||
(event: ReactPointerEvent<HTMLSpanElement>) => {
|
(event: ReactPointerEvent<HTMLSpanElement>) => {
|
||||||
if (!card.current) return;
|
if (!card.current) return;
|
||||||
@@ -34,22 +63,26 @@ export function TierListTile(props: TierListTileProps) {
|
|||||||
|
|
||||||
const rect = card.current.getBoundingClientRect();
|
const rect = card.current.getBoundingClientRect();
|
||||||
|
|
||||||
card.current.style.position = 'fixed';
|
card.current.style.position = "fixed";
|
||||||
card.current.style.cursor = 'grabbing';
|
card.current.style.cursor = "grabbing";
|
||||||
card.current.style.zIndex = '1';
|
card.current.style.zIndex = "1";
|
||||||
card.current.style.left = `${rect.left}px`;
|
card.current.style.left = `${rect.left}px`;
|
||||||
card.current.style.top = `${rect.top}px`;
|
card.current.style.top = `${rect.top}px`;
|
||||||
|
|
||||||
lastPosition.current = { x: event.clientX, y: event.clientY };
|
lastPosition.current = { x: event.clientX, y: event.clientY };
|
||||||
|
|
||||||
window.scrollTo({ behavior: 'smooth', top: 124 });
|
window.scrollTo({ behavior: "instant", top: 124 });
|
||||||
|
|
||||||
window.addEventListener('pointermove', handlePointerMove);
|
window.addEventListener("pointermove", handlePointerMove);
|
||||||
window.addEventListener('pointerup', handlePointerUp);
|
window.addEventListener("pointerup", handlePointerUp);
|
||||||
|
|
||||||
TierList.mutate((draft) => {
|
TierList.mutate((draft) => {
|
||||||
draft.dragging = true;
|
draft.dragging = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
autoScroll.current = true;
|
||||||
|
lastT.current = performance.now();
|
||||||
|
autoScrollLoop();
|
||||||
},
|
},
|
||||||
[],
|
[],
|
||||||
);
|
);
|
||||||
@@ -141,12 +174,14 @@ export function TierListTile(props: TierListTileProps) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
card.current.style.position = 'static';
|
card.current.style.position = "static";
|
||||||
card.current.style.zIndex = 'unset';
|
card.current.style.zIndex = "unset";
|
||||||
card.current.style.cursor = 'grab';
|
card.current.style.cursor = "grab";
|
||||||
|
|
||||||
window.removeEventListener('pointermove', handlePointerMove);
|
window.removeEventListener("pointermove", handlePointerMove);
|
||||||
window.removeEventListener('pointerup', handlePointerUp);
|
window.removeEventListener("pointerup", handlePointerUp);
|
||||||
|
|
||||||
|
autoScroll.current = false;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -168,7 +203,7 @@ export function TierListTile(props: TierListTileProps) {
|
|||||||
data-tile-index={props.isPlaced ? props.tileIndex : undefined}
|
data-tile-index={props.isPlaced ? props.tileIndex : undefined}
|
||||||
data-tile-id={props.tank.id}
|
data-tile-id={props.tank.id}
|
||||||
onPointerDown={handlePointerDown}
|
onPointerDown={handlePointerDown}
|
||||||
style={{ cursor: 'grab', touchAction: 'none' }}
|
style={{ cursor: "grab", touchAction: "none" }}
|
||||||
>
|
>
|
||||||
<TankCard noLink tank={props.tank} />
|
<TankCard noLink tank={props.tank} />
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import {
|
|||||||
import { clamp } from "lodash-es";
|
import { clamp } from "lodash-es";
|
||||||
import { degToRad } from "three/src/math/MathUtils.js";
|
import { degToRad } from "three/src/math/MathUtils.js";
|
||||||
|
|
||||||
export const DEFAULT_PITCH_TRANSITION = 15;
|
export const DEFAULT_PITCH_TRANSITION = 20;
|
||||||
|
|
||||||
export function applyPitchYawLimits(
|
export function applyPitchYawLimits(
|
||||||
pitch: number, // rad
|
pitch: number, // rad
|
||||||
@@ -31,7 +31,7 @@ export function applyPitchYawLimits(
|
|||||||
let lowerPitch = -degToRad(pitchLimits.max) - depressionBuff;
|
let lowerPitch = -degToRad(pitchLimits.max) - depressionBuff;
|
||||||
let upperPitch = -degToRad(pitchLimits.min) + elevationBuff;
|
let upperPitch = -degToRad(pitchLimits.min) + elevationBuff;
|
||||||
const transition = degToRad(
|
const transition = degToRad(
|
||||||
pitchLimits.transition ?? DEFAULT_PITCH_TRANSITION,
|
pitchLimits.transition || DEFAULT_PITCH_TRANSITION,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (pitchLimits.back) {
|
if (pitchLimits.back) {
|
||||||
|
|||||||
@@ -36,7 +36,10 @@ export function useDispose(gltf: GLTF & ObjectMap, path: string) {
|
|||||||
for (const map of maps) {
|
for (const map of maps) {
|
||||||
if (!map) continue;
|
if (!map) continue;
|
||||||
|
|
||||||
map.source.data.close();
|
if (map.source.data instanceof ImageBitmap) {
|
||||||
|
map.source.data.close();
|
||||||
|
}
|
||||||
|
|
||||||
map.dispose();
|
map.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user