|
|
|
@@ -421,45 +421,12 @@ function FullscreenViewer({ |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
function playFlipSound(ctx: AudioContext | null) { |
|
|
|
if (!ctx) return; |
|
|
|
const duration = 0.28; |
|
|
|
const sr = ctx.sampleRate; |
|
|
|
const buffer = ctx.createBuffer(1, Math.floor(sr * duration), sr); |
|
|
|
const data = buffer.getChannelData(0); |
|
|
|
for (let i = 0; i < data.length; i++) { |
|
|
|
const t = i / sr; |
|
|
|
const envelope = Math.exp(-t * 14) * (1 - Math.exp(-t * 80)); |
|
|
|
data[i] = (Math.random() * 2 - 1) * envelope * 0.45; |
|
|
|
} |
|
|
|
const src = ctx.createBufferSource(); |
|
|
|
src.buffer = buffer; |
|
|
|
const bp = ctx.createBiquadFilter(); |
|
|
|
bp.type = 'bandpass'; |
|
|
|
bp.frequency.value = 2200; |
|
|
|
bp.Q.value = 0.9; |
|
|
|
const gain = ctx.createGain(); |
|
|
|
gain.gain.value = 0.6; |
|
|
|
src.connect(bp); bp.connect(gain); gain.connect(ctx.destination); |
|
|
|
src.start(); |
|
|
|
} |
|
|
|
|
|
|
|
function FlipBook({ pages, onClose }: { pages: string[]; onClose: () => void }) { |
|
|
|
const containerRef = useRef<HTMLDivElement>(null); |
|
|
|
const flipRef = useRef<import('@/lib/page-flip').PageFlip | null>(null); |
|
|
|
const audioRef = useRef<AudioContext | null>(null); |
|
|
|
const [currentPage, setCurrentPage] = useState(0); |
|
|
|
const [pageCount, setPageCount] = useState(pages.length); |
|
|
|
|
|
|
|
const getCtx = () => { |
|
|
|
if (!audioRef.current) { |
|
|
|
const Ctx = (window as unknown as { AudioContext?: typeof AudioContext; webkitAudioContext?: typeof AudioContext }).AudioContext |
|
|
|
?? (window as unknown as { AudioContext?: typeof AudioContext; webkitAudioContext?: typeof AudioContext }).webkitAudioContext; |
|
|
|
if (Ctx) audioRef.current = new Ctx(); |
|
|
|
} |
|
|
|
return audioRef.current; |
|
|
|
}; |
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
if (!containerRef.current || pages.length === 0) return; |
|
|
|
let cancelled = false; |
|
|
|
@@ -510,7 +477,6 @@ function FlipBook({ pages, onClose }: { pages: string[]; onClose: () => void }) |
|
|
|
flip.on('flip', (e) => { |
|
|
|
const newPage = typeof e.data === 'number' ? e.data : 0; |
|
|
|
setCurrentPage(newPage); |
|
|
|
playFlipSound(getCtx()); |
|
|
|
}); |
|
|
|
flip.on('init', () => { |
|
|
|
setPageCount(flip.getPageCount()); |
|
|
|
|