mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 02:37:05 +02:00
fix: screenshot props
This commit is contained in:
1 parent
3861b07aef
commit
b6fd568cc6
2 files changed
+56
-31
No files matched your search
+30
-27
@@ -32,7 +32,6 @@ import { useEquipment } from '../../../../../hooks/useEquipment';
|
||||
import { useFullScreen } from '../../../../../hooks/useFullScreen';
|
||||
import { useFullscreenAvailability } from '../../../../../hooks/useFullscreenAvailability';
|
||||
import { useLocale } from '../../../../../hooks/useLocale';
|
||||
import { App } from '../../../../../stores/app';
|
||||
import { Duel } from '../../../../../stores/duel';
|
||||
import { TankopediaEphemeral } from '../../../../../stores/tankopediaEphemeral';
|
||||
import { TankopediaPersistent } from '../../../../../stores/tankopediaPersistent';
|
||||
@@ -42,6 +41,7 @@ import type { ThicknessRange } from '../../../../Armor/components/StaticArmor';
|
||||
import { ModuleButton } from '../../../../ModuleButtons/ModuleButton';
|
||||
import { SmallTankIcon } from '../../../../SmallTankIcon';
|
||||
import { TankSearch } from '../../../../TankSearch';
|
||||
import { screenshotReadyEvent } from '../TankSandbox/components/SceneProps';
|
||||
import { CustomShellButton } from './components/CustomShellButton';
|
||||
import { DynamicArmorSwitcher } from './components/DynamicArmorSwitcher';
|
||||
import { QuickInputs } from './components/QuickInputs';
|
||||
@@ -58,19 +58,10 @@ export function Options({ thicknessRange, canvas, skeleton }: OptionsProps) {
|
||||
);
|
||||
const display = TankopediaEphemeral.use((state) => state.display);
|
||||
const isFullScreen = useFullScreen();
|
||||
const greenPenetration = TankopediaPersistent.use(
|
||||
(state) => state.greenPenetration,
|
||||
);
|
||||
const hideTankModelUnderArmor = TankopediaPersistent.use(
|
||||
(state) => state.hideTankModelUnderArmor,
|
||||
);
|
||||
const advancedHighlighting = TankopediaPersistent.use(
|
||||
(state) => state.advancedHighlighting,
|
||||
);
|
||||
const wireframe = TankopediaPersistent.use((state) => state.wireframe);
|
||||
const opaque = TankopediaPersistent.use((state) => state.opaque);
|
||||
const fullScreenAvailable = useFullscreenAvailability(true);
|
||||
const developerMode = App.use((state) => state.developerMode);
|
||||
const protagonistTank = Duel.use((state) => state.protagonist.tank);
|
||||
const antagonistGun = Duel.use((state) => state.antagonist.gun);
|
||||
const antagonistShell = Duel.use((state) => state.antagonist.shell);
|
||||
@@ -461,19 +452,25 @@ export function Options({ thicknessRange, canvas, skeleton }: OptionsProps) {
|
||||
<Popover.Close>
|
||||
<Button
|
||||
onClick={() => {
|
||||
if (!canvas.current) return;
|
||||
screenshotReadyEvent.dispatch(true);
|
||||
|
||||
const anchor = document.createElement('a');
|
||||
requestAnimationFrame(() => {
|
||||
if (!canvas.current) return;
|
||||
|
||||
anchor.setAttribute(
|
||||
'download',
|
||||
`${protagonistTank.name}.png`,
|
||||
);
|
||||
anchor.setAttribute(
|
||||
'href',
|
||||
canvas.current.toDataURL('image/png'),
|
||||
);
|
||||
anchor.click();
|
||||
const anchor = document.createElement('a');
|
||||
|
||||
anchor.setAttribute(
|
||||
'download',
|
||||
`${protagonistTank.name}.png`,
|
||||
);
|
||||
anchor.setAttribute(
|
||||
'href',
|
||||
canvas.current.toDataURL('image/png'),
|
||||
);
|
||||
anchor.click();
|
||||
|
||||
screenshotReadyEvent.dispatch(false);
|
||||
});
|
||||
}}
|
||||
>
|
||||
<DownloadIcon />
|
||||
@@ -487,14 +484,20 @@ export function Options({ thicknessRange, canvas, skeleton }: OptionsProps) {
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => {
|
||||
if (!canvas.current) return;
|
||||
screenshotReadyEvent.dispatch(true);
|
||||
|
||||
canvas.current.toBlob((blob) => {
|
||||
if (!blob) return;
|
||||
requestAnimationFrame(() => {
|
||||
if (!canvas.current) return;
|
||||
|
||||
navigator.clipboard.write([
|
||||
new ClipboardItem({ 'image/png': blob }),
|
||||
]);
|
||||
canvas.current.toBlob((blob) => {
|
||||
if (!blob) return;
|
||||
|
||||
navigator.clipboard.write([
|
||||
new ClipboardItem({ 'image/png': blob }),
|
||||
]);
|
||||
});
|
||||
|
||||
screenshotReadyEvent.dispatch(false);
|
||||
});
|
||||
}}
|
||||
>
|
||||
|
||||
+26
-4
@@ -1,11 +1,15 @@
|
||||
import { useFrame } from '@react-three/fiber';
|
||||
import { invalidate, useFrame } from '@react-three/fiber';
|
||||
import { clamp } from 'lodash-es';
|
||||
import { useRef } from 'react';
|
||||
import { MeshStandardMaterial } from 'three';
|
||||
import { Quicklime, type QuicklimeEvent } from 'quicklime';
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { Mesh, MeshStandardMaterial } from 'three';
|
||||
|
||||
const SIZE = 2 ** 5;
|
||||
|
||||
export const screenshotReadyEvent = new Quicklime(false);
|
||||
|
||||
export function SceneProps() {
|
||||
const mesh = useRef<Mesh>(null!);
|
||||
const material = useRef<MeshStandardMaterial>(null);
|
||||
|
||||
useFrame(({ camera }) => {
|
||||
@@ -13,8 +17,26 @@ export function SceneProps() {
|
||||
material.current.opacity = clamp(0.5 * camera.position.y, 0, 1);
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
function handleScreenshotReady(event: QuicklimeEvent<boolean>) {
|
||||
mesh.current.visible = !event.data;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
screenshotReadyEvent.on(handleScreenshotReady);
|
||||
|
||||
return () => {
|
||||
screenshotReadyEvent.off(handleScreenshotReady);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<mesh rotation={[-Math.PI / 2, 0, 0]} receiveShadow>
|
||||
<mesh
|
||||
rotation={[-Math.PI / 2, 0, 0]}
|
||||
receiveShadow
|
||||
visible={!screenshotReadyEvent.last!}
|
||||
ref={mesh}
|
||||
>
|
||||
<planeGeometry args={[SIZE, SIZE]} />
|
||||
<meshStandardMaterial
|
||||
transparent
|
||||
|
||||
Reference in new issue
Block a user