import { useState, useEffect } from 'preact/hooks' import '@/components/settings.css' import { subscribe, unsubscribe, publish } from '@/libs/events' const getPercentage = (value) => parseInt(value.replace("%", "")) const defaultBackgroundImage = getComputedStyle(document.body).backgroundImage export default function Settings({ spinePlayer, setShowSettings, hidden, logoEl }) { const defaultFps = 60 const defaultRatio = 61.8 const defaultOpacity = import.meta.env.VITE_OPACITY const defaultShowLogo = false const defaultInvertFilter = import.meta.env.VITE_INVERT_FILTER === "true" const [defaultLogoImage, setDefaultLogoImage] = useState(null) const defaultPadLeft = getPercentage(`${import.meta.env.VITE_VIEWPORT_LEFT}%`) const defaultPadRight = getPercentage(`${import.meta.env.VITE_VIEWPORT_RIGHT}%`) const defaultPadTop = getPercentage(`${import.meta.env.VITE_VIEWPORT_TOP}%`) const defaultPadBottom = getPercentage(`${import.meta.env.VITE_VIEWPORT_BOTTOM}%`) const defaultViewport = { debugRender: false, padLeft: `${defaultPadLeft}%`, padRight: `${defaultPadRight}%`, padTop: `${defaultPadTop}%`, padBottom: `${defaultPadBottom}%`, x: 0, y: 0, } const [fps, setFps] = useState(defaultFps) const [ratio, setRatio] = useState(defaultRatio) const [opacity, setOpacity] = useState(defaultOpacity) const [padLeft, setPadLeft] = useState(defaultPadLeft) const [padRight, setPadRight] = useState(defaultPadRight) const [padTop, setPadTop] = useState(defaultPadTop) const [padBottom, setPadBottom] = useState(defaultPadBottom) const [showLogo, setShowLogo] = useState(defaultShowLogo) const [hidePositionSettings, setHidePositionSettings] = useState(true) const [backgroundClearDisabled, setBackgroundClearDisabled] = useState(true) const [logoClearDisabled, setLogoClearDisabled] = useState(true) const [isPlaying, setIsPlaying] = useState(true) const resize = (value) => { logoEl.width = window.innerWidth / 2 * (value || ratio) / 100 } const readFile = (e, onload, callback) => { const file = e.target.files[0] if (!file) return const reader = new FileReader() reader.readAsDataURL(file); reader.onload = readerEvent => onload(readerEvent) callback() } const setFPS = (value) => { setFps(value) spinePlayer.setFps(value) } const setLogoDisplay = (flag) => { setShowLogo(flag) logoEl.hidden = flag; } const setLogoImage = (e) => { readFile( e, (readerEvent) => { const content = readerEvent.target.result; logoEl.src = content resize() setLogoInvertFilter(false) }, () => setLogoClearDisabled(false) ) } const resetLogoImage = () => { logoEl.src = defaultLogoImage resize() setLogoInvertFilter(defaultInvertFilter) setLogoClearDisabled(true) } const setLogoRatio = (value) => { setRatio(value) resize(value) } const setLogoOpacity = (value) => { setOpacity(value) logoEl.style.opacity = value / 100 } const setLogoInvertFilter = (flag) => { if (!flag) { logoEl.style.filter = "invert(0)" } else { logoEl.style.filter = "invert(1)" } } const setBackground = (e) => { readFile( e, (readerEvent) => { const content = readerEvent.target.result; document.body.style.backgroundImage = `url("${content}")` }, () => setBackgroundClearDisabled(false) ) } const resetBackground = () => { document.body.style.backgroundImage = defaultBackgroundImage setBackgroundClearDisabled(true) } const positionPadding = (key, value) => { switch (key) { case "left": setPadLeft(value) spinePlayer.updateViewport({ ...defaultViewport, padLeft: `${value}%`, }) break; case "right": setPadRight(value) spinePlayer.updateViewport({ ...defaultViewport, padRight: `${value}%`, }) break; case "top": setPadTop(value) spinePlayer.updateViewport({ ...defaultViewport, padTop: `${value}%`, }) break; case "bottom": setPadBottom(value) spinePlayer.updateViewport({ ...defaultViewport, padBottom: `${value}%`, }) break; } } const positionReset = () => { setPadLeft(defaultPadLeft) setPadRight(defaultPadRight) setPadTop(defaultPadTop) setPadBottom(defaultPadBottom) spinePlayer.updateViewport(defaultViewport) } useEffect(() => { if (logoEl) { resize() setLogoInvertFilter(defaultInvertFilter) setLogoOpacity(defaultOpacity) setDefaultLogoImage(logoEl.src) } }, [logoEl]) useEffect(() => { window.addEventListener("contextmenu", e => e.preventDefault()); document.addEventListener("gesturestart", e => e.preventDefault()); }, []) useEffect(() => { window.addEventListener("resize", resize, true); return () => { window.removeEventListener("resize", resize, true); } }, []) return ( ) }