81 lines
2.4 KiB
TypeScript
81 lines
2.4 KiB
TypeScript
import { useEffect } from 'react';
|
|
import { uiState } from '../stores/ui';
|
|
import { $shader, setShaderCode } from '../stores/shader';
|
|
import { $appSettings, cycleValueMode, randomizeVisualSettings } from '../stores/appSettings';
|
|
import { FakeShader } from '../FakeShader';
|
|
|
|
export function useKeyboardShortcuts() {
|
|
useEffect(() => {
|
|
const handleKeyDown = (e: KeyboardEvent) => {
|
|
const activeElement = document.activeElement;
|
|
const isInputFocused = activeElement?.matches('input, textarea, select');
|
|
|
|
if (e.key === 'F11') {
|
|
e.preventDefault();
|
|
if (!document.fullscreenElement) {
|
|
document.documentElement.requestFullscreen();
|
|
} else {
|
|
document.exitFullscreen();
|
|
}
|
|
} else if (!isInputFocused) {
|
|
if (e.key === 'h' || e.key === 'H') {
|
|
const ui = uiState.get();
|
|
uiState.set({ ...ui, uiVisible: !ui.uiVisible });
|
|
} else if (e.key === 'r' || e.key === 'R') {
|
|
const randomCode = FakeShader.generateRandomCode();
|
|
setShaderCode(randomCode);
|
|
} else if (e.key === 's' || e.key === 'S') {
|
|
shareURL();
|
|
} else if (e.key === 'm' || e.key === 'M') {
|
|
cycleValueMode();
|
|
} else if (e.key === '?') {
|
|
const ui = uiState.get();
|
|
uiState.set({ ...ui, helpPopupOpen: true });
|
|
} else if (e.key === 'g' || e.key === 'G') {
|
|
randomizeVisualSettings();
|
|
}
|
|
}
|
|
|
|
if (e.key === 'Escape') {
|
|
const ui = uiState.get();
|
|
uiState.set({
|
|
...ui,
|
|
helpPopupOpen: false,
|
|
uiVisible: true,
|
|
mobileMenuOpen: false,
|
|
});
|
|
}
|
|
};
|
|
|
|
document.addEventListener('keydown', handleKeyDown);
|
|
return () => document.removeEventListener('keydown', handleKeyDown);
|
|
}, []);
|
|
}
|
|
|
|
function shareURL() {
|
|
const shader = $shader.get();
|
|
const settings = $appSettings.get();
|
|
|
|
const shareData = {
|
|
code: shader.code,
|
|
resolution: settings.resolution,
|
|
fps: settings.fps,
|
|
renderMode: settings.renderMode,
|
|
valueMode: settings.valueMode,
|
|
uiOpacity: settings.uiOpacity,
|
|
hueShift: settings.hueShift,
|
|
};
|
|
|
|
const encoded = btoa(JSON.stringify(shareData));
|
|
window.location.hash = encoded;
|
|
|
|
navigator.clipboard
|
|
.writeText(window.location.href)
|
|
.then(() => {
|
|
console.log('URL copied to clipboard');
|
|
})
|
|
.catch(() => {
|
|
console.log('Copy failed');
|
|
});
|
|
}
|