pixi-effects 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +89 -0
- package/dist/Controller.cjs +940 -0
- package/dist/Controller.cjs.map +1 -0
- package/dist/Controller.d.cts +109 -0
- package/dist/Controller.d.ts +109 -0
- package/dist/Controller.js +933 -0
- package/dist/Controller.js.map +1 -0
- package/dist/Movie-Bp66rkaC.d.cts +364 -0
- package/dist/Movie-Bp66rkaC.d.ts +364 -0
- package/dist/index.cjs +3045 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +79 -0
- package/dist/index.d.ts +79 -0
- package/dist/index.js +3023 -0
- package/dist/index.js.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/Controller.ts"],"names":[],"mappings":"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","file":"Controller.cjs","sourcesContent":["import type { Movie } from './core/Movie';\n\nconst ICONS = {\n play: '<svg viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\"><path d=\"M3 2 L13 8 L3 14 Z\"/></svg>',\n pause: '<svg viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\"><rect x=\"3\" y=\"2\" width=\"3.5\" height=\"12\"/><rect x=\"9.5\" y=\"2\" width=\"3.5\" height=\"12\"/></svg>',\n volumeOn: '<svg viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\"><path d=\"M2 6 H5 L9 2 V14 L5 10 H2 Z\"/><path d=\"M11 5 Q13 8 11 11\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.2\"/><path d=\"M12.5 3.5 Q15.5 8 12.5 12.5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.2\"/></svg>',\n volumeOff: '<svg viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"currentColor\"><path d=\"M2 6 H5 L9 2 V14 L5 10 H2 Z\"/><path d=\"M11 5 L15 11 M15 5 L11 11\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.4\"/></svg>',\n download: '<svg viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M8 2 V11 M4 7 L8 11 L12 7 M3 13 H13\"/></svg>',\n fullscreenEnter: '<svg viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M2 6 V2 H6 M14 6 V2 H10 M2 10 V14 H6 M14 10 V14 H10\"/></svg>',\n fullscreenExit: '<svg viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M6 2 V6 H2 M10 2 V6 H14 M6 14 V10 H2 M10 14 V10 H14\"/></svg>',\n} as const;\n\nconst STYLE_ATTR = 'data-movie-controller';\n\nconst STYLE_CSS = `\n.movie-controller-wrap { position: relative; display: inline-block; line-height: 0; }\n.movie-controller {\n position: absolute;\n pointer-events: none;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n display: flex;\n flex-direction: column;\n justify-content: flex-end;\n opacity: 1;\n transition: opacity 200ms ease;\n}\n.movie-controller[data-state=\"hidden\"] { opacity: 0; }\n.movie-controller > * { pointer-events: auto; }\n\n.mc-progress {\n position: relative;\n width: 100%;\n height: 16px;\n cursor: pointer;\n display: flex;\n align-items: center;\n outline: none;\n}\n.mc-progress:focus-visible {\n outline: 2px solid #007AFF;\n outline-offset: 2px;\n}\n.mc-progress::before {\n content: \"\"; position: absolute; left: 12px; right: 12px;\n height: 3px; background: rgba(255,255,255,0.25);\n transition: height 120ms ease;\n}\n.mc-progress:hover::before, .mc-progress.mc-scrubbing::before { height: 5px; }\n.mc-progress-fill {\n position: absolute; left: 12px; top: 50%;\n height: 3px;\n width: calc((100% - 24px) * var(--mc-fill, 0));\n background: #007AFF;\n transform: translateY(-50%);\n transition: height 120ms ease;\n pointer-events: none;\n}\n.mc-progress:hover .mc-progress-fill,\n.mc-progress.mc-scrubbing .mc-progress-fill { height: 5px; }\n.mc-progress-thumb {\n position: absolute; top: 50%;\n left: calc(12px + (100% - 24px) * var(--mc-fill, 0));\n width: 12px; height: 12px; border-radius: 50%;\n background: #007AFF;\n transform: translate(-50%, -50%) scale(0);\n transition: transform 120ms ease;\n pointer-events: none;\n}\n.mc-progress:hover .mc-progress-thumb,\n.mc-progress.mc-scrubbing .mc-progress-thumb { transform: translate(-50%, -50%) scale(1); }\n\n.mc-bar {\n position: relative;\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 6px 12px 8px 12px;\n background: linear-gradient(to top, rgba(0,0,0,0.75) 0%, rgba(0,0,0,0) 100%);\n color: #fff;\n line-height: 1;\n}\n.mc-btn {\n background: none; border: 0; padding: 0; margin: 0;\n width: 28px; height: 28px;\n display: inline-flex; align-items: center; justify-content: center;\n color: #fff; opacity: 0.85; cursor: pointer;\n transition: opacity 120ms ease;\n}\n.mc-btn:hover { opacity: 1; }\n.mc-btn:disabled { opacity: 0.4; cursor: not-allowed; }\n.mc-time {\n font-size: 12px; font-family: Menlo, Monaco, monospace;\n color: #fff; opacity: 0.85;\n min-width: 90px;\n}\n.mc-spacer { flex: 1; }\n\n.mc-volume { display: flex; align-items: center; }\n.mc-vol-slider {\n position: relative;\n width: 0;\n height: 28px;\n display: flex;\n align-items: center;\n cursor: pointer;\n margin-left: 0;\n outline: none;\n transition: width 200ms ease, margin-left 200ms ease;\n overflow: hidden;\n}\n.mc-volume:hover .mc-vol-slider,\n.mc-volume:focus-within .mc-vol-slider,\n.mc-vol-slider.mc-scrubbing {\n width: 70px;\n margin-left: 6px;\n}\n.mc-vol-slider:focus-visible { outline: 2px solid #007AFF; outline-offset: 2px; }\n.mc-vol-slider::before {\n content: \"\"; position: absolute; left: 4px; right: 4px;\n height: 3px; background: rgba(255,255,255,0.25); border-radius: 2px;\n}\n.mc-vol-fill {\n position: absolute; left: 4px; top: 50%;\n height: 3px;\n width: calc((100% - 8px) * var(--mc-volume, 1));\n background: #fff;\n transform: translateY(-50%);\n border-radius: 2px;\n pointer-events: none;\n}\n.mc-vol-thumb {\n position: absolute; top: 50%;\n left: calc(4px + (100% - 8px) * var(--mc-volume, 1));\n width: 10px; height: 10px; border-radius: 50%;\n background: #fff;\n transform: translate(-50%, -50%);\n pointer-events: none;\n}\n\n[data-mc-wrap]:fullscreen {\n width: 100vw; height: 100vh;\n display: flex; align-items: center; justify-content: center;\n background: #000;\n}\n[data-mc-wrap]:fullscreen > canvas {\n width: 100% !important;\n height: 100% !important;\n max-width: none !important;\n max-height: none !important;\n object-fit: contain;\n border-radius: 0;\n}\n\n.mc-settings-popover {\n position: absolute;\n bottom: calc(100% + 8px);\n right: 12px;\n background: rgba(20, 20, 20, 0.96);\n border-radius: 8px;\n padding: 10px 12px;\n min-width: 180px;\n color: #fff;\n font-size: 12px;\n box-shadow: 0 4px 16px rgba(0,0,0,0.4);\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.mc-settings-popover[data-open=\"false\"] { display: none; }\n.mc-settings-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n}\n.mc-settings-row > span { color: rgba(255,255,255,0.85); }\n.mc-settings-row > select {\n font: inherit;\n background: rgba(255,255,255,0.1);\n color: #fff;\n border: 1px solid rgba(255,255,255,0.18);\n border-radius: 4px;\n padding: 2px 6px;\n cursor: pointer;\n}\n.mc-export-confirm {\n margin-top: 4px;\n width: 100%;\n background: #007AFF;\n color: #fff;\n border: 0;\n border-radius: 4px;\n padding: 6px 10px;\n font: inherit;\n font-weight: 600;\n cursor: pointer;\n transition: background 120ms ease;\n}\n.mc-export-confirm:hover { background: #0066d6; }\n.mc-export-confirm:disabled { background: rgba(255,255,255,0.18); cursor: not-allowed; }\n\n.mc-export-overlay {\n position: absolute; inset: 0;\n background: rgba(0,0,0,0.7);\n display: flex; justify-content: center; align-items: center;\n z-index: 2;\n}\n.mc-export-panel {\n background: rgba(20,20,20,0.96); color: #fff;\n border-radius: 8px; padding: 16px 20px;\n text-align: center; min-width: 200px; max-width: 80%;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n}\n.mc-export-title { font-size: 13px; margin-bottom: 10px; opacity: 0.9; }\n.mc-export-track {\n width: 100%; height: 6px;\n background: rgba(255,255,255,0.15); border-radius: 3px;\n margin-bottom: 8px; overflow: hidden;\n}\n.mc-export-fill {\n height: 100%; width: 0%;\n background: linear-gradient(90deg, #007AFF, #0056CC);\n transition: width 0.3s ease; border-radius: 3px;\n}\n.mc-export-text {\n color: rgba(255,255,255,0.7); font-size: 11px;\n font-family: Menlo, Monaco, monospace;\n}\n`;\n\nlet styleRefCount = 0;\n\nfunction installStyles(): void {\n if (styleRefCount === 0) {\n const el = document.createElement('style');\n el.setAttribute(STYLE_ATTR, '');\n el.textContent = STYLE_CSS;\n document.head.appendChild(el);\n }\n styleRefCount++;\n}\n\nfunction uninstallStyles(): void {\n styleRefCount = Math.max(0, styleRefCount - 1);\n if (styleRefCount === 0) {\n document.head.querySelectorAll(`style[${STYLE_ATTR}]`).forEach((n) => n.remove());\n }\n}\n\nexport function formatTime(seconds: number): string {\n const s = Math.max(0, Math.floor(seconds));\n const m = Math.floor(s / 60);\n const r = s % 60;\n return `${m}:${r.toString().padStart(2, '0')}`;\n}\n\nexport function frameToPercent(frame: number, totalFrames: number): number {\n if (totalFrames <= 0) return 0;\n const f = Math.min(Math.max(frame, 0), totalFrames);\n return (f / totalFrames) * 100;\n}\n\nexport function pxToFrame(clientX: number, rect: { left: number; width: number }, totalFrames: number): number {\n if (rect.width <= 0 || totalFrames <= 0) return 0;\n const ratio = (clientX - rect.left) / rect.width;\n const clamped = Math.min(Math.max(ratio, 0), 1);\n return Math.round(clamped * totalFrames);\n}\n\nexport function pxToFraction(clientX: number, rect: { left: number; width: number }, inset = 0): number {\n const innerLeft = rect.left + inset;\n const innerWidth = Math.max(0, rect.width - 2 * inset);\n if (innerWidth <= 0) return 0;\n const ratio = (clientX - innerLeft) / innerWidth;\n return Math.min(Math.max(ratio, 0), 1);\n}\n\nexport function extensionForMimeType(mime: string): string {\n const t = (mime || '').toLowerCase();\n if (t.includes('webm')) return 'webm';\n if (t.includes('quicktime') || t.includes('mov')) return 'mov';\n if (t.includes('matroska') || t.includes('mkv')) return 'mkv';\n return 'mp4';\n}\n\nexport interface ControllerOptions {\n canvas: HTMLCanvasElement;\n showExportButton?: boolean;\n enableKeyboardShortcuts?: boolean;\n className?: string;\n}\n\ninterface ResolvedOptions {\n canvas: HTMLCanvasElement;\n showExportButton: boolean;\n enableKeyboardShortcuts: boolean;\n className: string;\n}\n\nexport class Controller {\n movie: Movie;\n options: ResolvedOptions;\n\n private root: HTMLDivElement;\n private wrapper: HTMLDivElement;\n private wrappedHere = false;\n private destroyed = false;\n\n private progressEl!: HTMLDivElement;\n private progressFillEl!: HTMLDivElement;\n private progressThumbEl!: HTMLDivElement;\n private playBtn!: HTMLButtonElement;\n private muteBtn!: HTMLButtonElement;\n private timeEl!: HTMLSpanElement;\n private exportBtn: HTMLButtonElement | null = null;\n private settingsPopoverEl: HTMLDivElement | null = null;\n private settingsFormatSelect: HTMLSelectElement | null = null;\n private settingsQualitySelect: HTMLSelectElement | null = null;\n private exportConfirmBtn: HTMLButtonElement | null = null;\n private exportFormat: 'mp4' | 'webm' | 'mov' = 'mp4';\n private exportQuality: 'low' | 'medium' | 'high' | 'very-high' = 'high';\n private settingsOpen = false;\n private hideTimer: ReturnType<typeof setTimeout> | null = null;\n private static readonly HIDE_DELAY_MS = 2500;\n private static readonly PROGRESS_INSET_PX = 12;\n private isScrubbing = false;\n private wasPlayingBeforeScrub = false;\n private activePointerId: number | null = null;\n private isExporting = false;\n private exportOverlay: HTMLDivElement | null = null;\n private exportFillEl: HTMLDivElement | null = null;\n private exportTextEl: HTMLDivElement | null = null;\n private keyHandler: ((e: KeyboardEvent) => void) | null = null;\n private settingsKeyHandler: ((e: KeyboardEvent) => void) | null = null;\n private settingsOutsideHandler: ((e: PointerEvent) => void) | null = null;\n private onReady: (() => void) | null = null;\n private onFrame: ((e: { frame: number; totalFrames: number }) => void) | null = null;\n private onPause: (() => void) | null = null;\n private onProgress: ((e: { progress: number; frame: number; totalFrames: number }) => void) | null = null;\n private onWrapPointerMove: (() => void) | null = null;\n private onWrapMouseLeave: (() => void) | null = null;\n private resizeObserver: ResizeObserver | null = null;\n private volumeSliderEl: HTMLDivElement | null = null;\n private volumeContainerEl: HTMLDivElement | null = null;\n private fullscreenBtn: HTMLButtonElement | null = null;\n private isVolumeScrubbing = false;\n private fullscreenChangeHandler: (() => void) | null = null;\n private wheelHandler: ((e: WheelEvent) => void) | null = null;\n\n constructor(movie: Movie, options: ControllerOptions) {\n if (!options || !options.canvas) {\n throw new Error('Controller requires options.canvas (HTMLCanvasElement).');\n }\n this.movie = movie;\n this.options = {\n canvas: options.canvas,\n showExportButton: options.showExportButton ?? true,\n enableKeyboardShortcuts: options.enableKeyboardShortcuts ?? true,\n className: options.className ?? 'movie-controller',\n };\n\n installStyles();\n this.wrapper = this.ensurePositioningContext(this.options.canvas);\n this.root = document.createElement('div');\n this.root.className = this.options.className;\n this.wrapper.appendChild(this.root);\n this.buildBar();\n this.syncRootToCanvas();\n if (typeof ResizeObserver !== 'undefined') {\n this.resizeObserver = new ResizeObserver(() => this.syncRootToCanvas());\n this.resizeObserver.observe(this.options.canvas);\n // Also observe the wrapper: when its size changes (browser resize, sibling\n // panels resizing) the canvas's position can shift without its own size\n // changing, which canvas-only observation would miss.\n this.resizeObserver.observe(this.wrapper);\n }\n this.root.setAttribute('data-state', 'visible');\n this.bindMovieEvents();\n this.bindPlayButton();\n this.bindScrubbing();\n this.bindMuteButton();\n this.bindVolumeSlider();\n this.bindExportPopover();\n this.bindFullscreen();\n this.bindVisibility();\n if (this.options.enableKeyboardShortcuts) this.bindKeyboard();\n }\n\n private buildBar(): void {\n const popoverHtml = this.options.showExportButton ? `\n <div class=\"mc-settings-popover\" role=\"dialog\" aria-label=\"Export settings\" data-open=\"false\">\n <label class=\"mc-settings-row\">\n <span>Format</span>\n <select class=\"mc-settings-format\">\n <option value=\"mp4\">MP4</option>\n <option value=\"webm\">WebM</option>\n <option value=\"mov\">MOV</option>\n </select>\n </label>\n <label class=\"mc-settings-row\">\n <span>Quality</span>\n <select class=\"mc-settings-quality\">\n <option value=\"low\">Low</option>\n <option value=\"medium\">Medium</option>\n <option value=\"high\" selected>High</option>\n <option value=\"very-high\">Very High</option>\n </select>\n </label>\n <button type=\"button\" class=\"mc-export-confirm\">Download</button>\n </div>\n ` : '';\n this.root.innerHTML = `\n <div class=\"mc-progress\" role=\"slider\" tabindex=\"0\" aria-label=\"Seek\" aria-valuemin=\"0\" aria-valuemax=\"${this.movie.totalFrames}\" aria-valuenow=\"0\">\n <div class=\"mc-progress-fill\"></div>\n <div class=\"mc-progress-thumb\"></div>\n </div>\n <div class=\"mc-bar\">\n ${popoverHtml}\n <button class=\"mc-btn mc-play\" aria-label=\"Play\">${ICONS.play}</button>\n <div class=\"mc-volume\">\n <button class=\"mc-btn mc-mute\" aria-label=\"Mute\">${ICONS.volumeOn}</button>\n <div class=\"mc-vol-slider\" role=\"slider\" tabindex=\"0\" aria-label=\"Volume\" aria-valuemin=\"0\" aria-valuemax=\"100\" aria-valuenow=\"100\">\n <div class=\"mc-vol-fill\"></div>\n <div class=\"mc-vol-thumb\"></div>\n </div>\n </div>\n <span class=\"mc-time\">0:00 / 0:00</span>\n <div class=\"mc-spacer\"></div>\n ${this.options.showExportButton ? `<button class=\"mc-btn mc-export\" aria-label=\"Export\" aria-expanded=\"false\">${ICONS.download}</button>` : ''}\n <button class=\"mc-btn mc-fullscreen\" aria-label=\"Enter fullscreen\">${ICONS.fullscreenEnter}</button>\n </div>\n `;\n this.progressEl = this.root.querySelector('.mc-progress') as HTMLDivElement;\n this.progressFillEl = this.root.querySelector('.mc-progress-fill') as HTMLDivElement;\n this.progressThumbEl = this.root.querySelector('.mc-progress-thumb') as HTMLDivElement;\n this.playBtn = this.root.querySelector('.mc-play') as HTMLButtonElement;\n this.muteBtn = this.root.querySelector('.mc-mute') as HTMLButtonElement;\n this.timeEl = this.root.querySelector('.mc-time') as HTMLSpanElement;\n this.exportBtn = this.root.querySelector('.mc-export') as HTMLButtonElement | null;\n this.settingsPopoverEl = this.root.querySelector('.mc-settings-popover') as HTMLDivElement | null;\n this.settingsFormatSelect = this.root.querySelector('.mc-settings-format') as HTMLSelectElement | null;\n this.settingsQualitySelect = this.root.querySelector('.mc-settings-quality') as HTMLSelectElement | null;\n this.exportConfirmBtn = this.root.querySelector('.mc-export-confirm') as HTMLButtonElement | null;\n this.volumeSliderEl = this.root.querySelector('.mc-vol-slider') as HTMLDivElement | null;\n this.volumeContainerEl = this.root.querySelector('.mc-volume') as HTMLDivElement | null;\n this.fullscreenBtn = this.root.querySelector('.mc-fullscreen') as HTMLButtonElement | null;\n if (this.settingsFormatSelect) this.settingsFormatSelect.value = this.exportFormat;\n if (this.settingsQualitySelect) this.settingsQualitySelect.value = this.exportQuality;\n }\n\n private ensurePositioningContext(canvas: HTMLCanvasElement): HTMLDivElement {\n const parent = canvas.parentElement;\n if (!parent) {\n throw new Error('Controller: canvas must be attached to the DOM before constructing.');\n }\n const pos = getComputedStyle(parent).position;\n if (pos === 'relative' || pos === 'absolute' || pos === 'fixed' || pos === 'sticky') {\n // Tag the user's element so the [data-mc-wrap]:fullscreen style hooks apply\n // to it the same way they apply to our auto-wrap. Cleaned up on destroy.\n parent.setAttribute('data-mc-wrap', '');\n return parent as HTMLDivElement;\n }\n const wrap = document.createElement('div');\n wrap.className = 'movie-controller-wrap';\n wrap.setAttribute('data-mc-wrap', '');\n wrap.style.position = 'relative';\n wrap.style.display = 'inline-block';\n wrap.style.lineHeight = '0';\n parent.insertBefore(wrap, canvas);\n wrap.appendChild(canvas);\n this.wrappedHere = true;\n\n return wrap;\n }\n\n private bindMovieEvents(): void {\n this.onReady = () => {\n this.progressEl.setAttribute('aria-valuemax', String(this.movie.totalFrames));\n this.refreshTime(0);\n this.refreshProgress(0);\n this.refreshVolumeUI();\n };\n this.onFrame = ({ frame, totalFrames }) => {\n if (!this.isScrubbing) {\n this.refreshProgress(frame, totalFrames);\n }\n this.refreshTime(frame);\n };\n this.onPause = () => {\n this.refreshPlayIcon();\n // YouTube-style: pause shows the bar momentarily, then auto-hides on idle.\n this.kickIdleTimer();\n };\n this.onProgress = ({ progress, frame, totalFrames }) => {\n if (!this.isExporting || !this.exportFillEl || !this.exportTextEl) return;\n this.exportFillEl.style.width = `${progress}%`;\n this.exportTextEl.textContent = `${progress}% (${frame} / ${totalFrames} frames)`;\n };\n this.movie.on('ready', this.onReady);\n this.movie.on('frame', this.onFrame);\n this.movie.on('pause', this.onPause);\n this.movie.on('progress', this.onProgress);\n }\n\n private bindPlayButton(): void {\n this.playBtn.addEventListener('click', () => {\n if (this.movie.isPlaying) {\n this.movie.pause();\n // movie.pause() emits 'pause' which the onPause handler turns into\n // refreshPlayIcon + kickIdleTimer, so no extra work here.\n } else {\n this.movie.play();\n this.refreshPlayIcon();\n this.kickIdleTimer();\n }\n });\n }\n\n private refreshPlayIcon(): void {\n this.playBtn.innerHTML = this.movie.isPlaying ? ICONS.pause : ICONS.play;\n this.playBtn.setAttribute('aria-label', this.movie.isPlaying ? 'Pause' : 'Play');\n }\n\n private bindMuteButton(): void {\n this.muteBtn.addEventListener('click', () => {\n this.movie.toggleMute();\n this.refreshVolumeUI();\n });\n }\n\n private refreshMuteIcon(): void {\n const silent = this.movie.muted || this.movie.volume <= 0;\n this.muteBtn.innerHTML = silent ? ICONS.volumeOff : ICONS.volumeOn;\n this.muteBtn.setAttribute('aria-label', silent ? 'Unmute' : 'Mute');\n }\n\n private refreshVolumeUI(): void {\n this.refreshMuteIcon();\n if (!this.volumeSliderEl) return;\n const effective = this.movie.muted ? 0 : this.movie.volume;\n this.volumeSliderEl.style.setProperty('--mc-volume', String(effective));\n this.volumeSliderEl.setAttribute('aria-valuenow', String(Math.round(effective * 100)));\n }\n\n private bindVolumeSlider(): void {\n if (!this.volumeSliderEl || !this.volumeContainerEl) return;\n const slider = this.volumeSliderEl;\n const container = this.volumeContainerEl;\n\n const setFromPointer = (clientX: number) => {\n const rect = slider.getBoundingClientRect();\n const v = pxToFraction(clientX, { left: rect.left, width: rect.width }, 4);\n this.movie.volume = v;\n if (this.movie.muted && v > 0) this.movie.muted = false;\n this.refreshVolumeUI();\n };\n\n const onDown = (e: PointerEvent) => {\n this.isVolumeScrubbing = true;\n slider.classList.add('mc-scrubbing');\n try { slider.setPointerCapture(e.pointerId); } catch { /* unsupported */ }\n setFromPointer(e.clientX);\n };\n const onMove = (e: PointerEvent) => {\n if (!this.isVolumeScrubbing) return;\n setFromPointer(e.clientX);\n };\n const onUp = (e: PointerEvent) => {\n if (!this.isVolumeScrubbing) return;\n this.isVolumeScrubbing = false;\n slider.classList.remove('mc-scrubbing');\n try { slider.releasePointerCapture(e.pointerId); } catch { /* unsupported */ }\n };\n slider.addEventListener('pointerdown', onDown);\n slider.addEventListener('pointermove', onMove);\n slider.addEventListener('pointerup', onUp);\n slider.addEventListener('pointercancel', onUp);\n\n this.wheelHandler = (e: WheelEvent) => {\n e.preventDefault();\n this.adjustVolume(e.deltaY < 0 ? 0.05 : -0.05);\n };\n container.addEventListener('wheel', this.wheelHandler, { passive: false });\n }\n\n private bindFullscreen(): void {\n if (!this.fullscreenBtn) return;\n this.fullscreenBtn.addEventListener('click', () => {\n void this.toggleFullscreen();\n });\n this.fullscreenChangeHandler = () => {\n this.refreshFullscreenIcon();\n // Fullscreen reflow can shift the canvas without changing its size, which\n // ResizeObserver would miss; resync the overlay explicitly.\n this.syncRootToCanvas();\n };\n document.addEventListener('fullscreenchange', this.fullscreenChangeHandler);\n }\n\n private async toggleFullscreen(): Promise<void> {\n try {\n if (document.fullscreenElement === this.wrapper) {\n await document.exitFullscreen();\n } else {\n await this.wrapper.requestFullscreen();\n }\n } catch (err) {\n console.warn('pixi-effects: fullscreen denied:', err);\n }\n }\n\n private refreshFullscreenIcon(): void {\n if (!this.fullscreenBtn) return;\n const inFs = document.fullscreenElement === this.wrapper;\n this.fullscreenBtn.innerHTML = inFs ? ICONS.fullscreenExit : ICONS.fullscreenEnter;\n this.fullscreenBtn.setAttribute('aria-label', inFs ? 'Exit fullscreen' : 'Enter fullscreen');\n }\n\n private refreshProgress(frame: number, totalFrames?: number): void {\n const total = totalFrames ?? this.movie.totalFrames;\n const pct = frameToPercent(frame, total);\n this.progressEl.style.setProperty('--mc-fill', String(pct / 100));\n this.progressEl.setAttribute('aria-valuenow', String(frame));\n }\n\n private refreshTime(frame: number): void {\n const fr = this.movie.frameRate || 1;\n const cur = frame / fr;\n const total = this.movie.totalFrames / fr;\n this.timeEl.textContent = `${formatTime(cur)} / ${formatTime(total)}`;\n }\n\n private bindScrubbing(): void {\n const onDown = (e: PointerEvent) => {\n this.isScrubbing = true;\n this.activePointerId = e.pointerId;\n this.wasPlayingBeforeScrub = this.movie.isPlaying;\n if (this.movie.isPlaying) {\n this.movie.pause();\n this.refreshPlayIcon();\n }\n this.progressEl.classList.add('mc-scrubbing');\n try { this.progressEl.setPointerCapture(e.pointerId); } catch { /* unsupported */ }\n this.seekFromPointer(e.clientX);\n };\n const onMove = (e: PointerEvent) => {\n if (!this.isScrubbing) return;\n this.seekFromPointer(e.clientX);\n };\n const onUp = (e: PointerEvent) => {\n if (!this.isScrubbing) return;\n this.seekFromPointer(e.clientX);\n this.isScrubbing = false;\n this.activePointerId = null;\n this.progressEl.classList.remove('mc-scrubbing');\n try { this.progressEl.releasePointerCapture(e.pointerId); } catch { /* unsupported */ }\n if (this.wasPlayingBeforeScrub) {\n this.movie.play();\n this.refreshPlayIcon();\n }\n };\n this.progressEl.addEventListener('pointerdown', onDown);\n this.progressEl.addEventListener('pointermove', onMove);\n this.progressEl.addEventListener('pointerup', onUp);\n this.progressEl.addEventListener('pointercancel', onUp);\n }\n\n private seekFromPointer(clientX: number): void {\n const rect = this.progressEl.getBoundingClientRect();\n const inset = Controller.PROGRESS_INSET_PX;\n const innerLeft = rect.left + inset;\n const innerWidth = Math.max(0, rect.width - 2 * inset);\n const frame = pxToFrame(clientX, { left: innerLeft, width: innerWidth }, this.movie.totalFrames);\n this.refreshProgress(frame);\n void this.movie.gotoFrame(frame);\n }\n\n private bindExportPopover(): void {\n if (!this.exportBtn || !this.settingsPopoverEl) return;\n\n // Download icon on the bar toggles the popover (it does NOT directly trigger export).\n this.exportBtn.addEventListener('click', (e) => {\n e.stopPropagation();\n this.toggleSettings(!this.settingsOpen);\n });\n\n // Confirm button inside the popover triggers the actual export, then closes.\n if (this.exportConfirmBtn) {\n this.exportConfirmBtn.addEventListener('click', () => {\n this.toggleSettings(false);\n void this.handleExport();\n });\n }\n\n if (this.settingsFormatSelect) {\n this.settingsFormatSelect.addEventListener('change', (e) => {\n const v = (e.target as HTMLSelectElement).value;\n if (v === 'mp4' || v === 'webm' || v === 'mov') this.exportFormat = v;\n });\n }\n if (this.settingsQualitySelect) {\n this.settingsQualitySelect.addEventListener('change', (e) => {\n const v = (e.target as HTMLSelectElement).value;\n if (v === 'low' || v === 'medium' || v === 'high' || v === 'very-high') this.exportQuality = v;\n });\n }\n\n this.settingsKeyHandler = (e: KeyboardEvent) => {\n if (e.code === 'Escape' && this.settingsOpen) {\n e.preventDefault();\n this.toggleSettings(false);\n }\n };\n document.addEventListener('keydown', this.settingsKeyHandler);\n\n this.settingsOutsideHandler = (e: PointerEvent) => {\n if (!this.settingsOpen) return;\n const target = e.target as Node | null;\n if (!target) return;\n if (this.settingsPopoverEl?.contains(target)) return;\n if (this.exportBtn?.contains(target)) return;\n this.toggleSettings(false);\n };\n document.addEventListener('pointerdown', this.settingsOutsideHandler);\n }\n\n private toggleSettings(open: boolean): void {\n if (!this.exportBtn || !this.settingsPopoverEl) return;\n this.settingsOpen = open;\n this.settingsPopoverEl.setAttribute('data-open', open ? 'true' : 'false');\n this.exportBtn.setAttribute('aria-expanded', open ? 'true' : 'false');\n if (open) {\n // Keep the bar visible while the popover is open.\n if (this.hideTimer) { clearTimeout(this.hideTimer); this.hideTimer = null; }\n this.setVisible(true);\n } else {\n // Resume normal auto-hide cadence after closing.\n this.kickIdleTimer();\n }\n }\n\n private async handleExport(): Promise<void> {\n if (this.isExporting) return;\n this.isExporting = true;\n const wasPlaying = this.movie.isPlaying;\n if (wasPlaying) {\n this.movie.pause();\n this.refreshPlayIcon();\n }\n this.showExportOverlay();\n try {\n const blob = await this.movie.render({\n format: this.exportFormat,\n video: { bitrate: this.exportQuality },\n audio: { bitrate: this.exportQuality },\n });\n if (this.exportFillEl) this.exportFillEl.style.width = '100%';\n if (this.exportTextEl) this.exportTextEl.textContent = 'Preparing download...';\n this.triggerDownload(blob);\n await new Promise((r) => setTimeout(r, 300));\n } catch (err) {\n console.error('Export failed:', err);\n alert('Export failed.');\n } finally {\n this.hideExportOverlay();\n this.isExporting = false;\n if (wasPlaying) {\n this.movie.play();\n this.refreshPlayIcon();\n }\n }\n }\n\n private triggerDownload(blob: Blob): void {\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = this.makeFilename(blob);\n a.style.display = 'none';\n document.body.appendChild(a);\n a.click();\n a.remove();\n setTimeout(() => URL.revokeObjectURL(url), 100);\n }\n\n private makeFilename(blob: Blob): string {\n const ext = extensionForMimeType(blob.type);\n const d = new Date();\n const pad = (n: number) => n.toString().padStart(2, '0');\n const ts = `${d.getFullYear()}${pad(d.getMonth() + 1)}${pad(d.getDate())}-${pad(d.getHours())}${pad(d.getMinutes())}${pad(d.getSeconds())}`;\n return `movie-${ts}.${ext}`;\n }\n\n private showExportOverlay(): void {\n const overlay = document.createElement('div');\n overlay.className = 'mc-export-overlay';\n overlay.innerHTML = `\n <div class=\"mc-export-panel\">\n <div class=\"mc-export-title\">Exporting video...</div>\n <div class=\"mc-export-track\"><div class=\"mc-export-fill\"></div></div>\n <div class=\"mc-export-text\">0% (0 / 0 frames)</div>\n </div>\n `;\n this.root.appendChild(overlay);\n this.exportOverlay = overlay;\n this.exportFillEl = overlay.querySelector('.mc-export-fill') as HTMLDivElement;\n this.exportTextEl = overlay.querySelector('.mc-export-text') as HTMLDivElement;\n }\n\n private hideExportOverlay(): void {\n if (this.exportOverlay) {\n this.exportOverlay.remove();\n this.exportOverlay = null;\n this.exportFillEl = null;\n this.exportTextEl = null;\n }\n }\n\n private bindVisibility(): void {\n const wrap = this.wrapper;\n this.onWrapPointerMove = () => this.kickIdleTimer();\n this.onWrapMouseLeave = () => {\n if (!this.settingsOpen && !this.isScrubbing && !this.isVolumeScrubbing) this.setVisible(false);\n };\n wrap.addEventListener('pointermove', this.onWrapPointerMove);\n wrap.addEventListener('mouseleave', this.onWrapMouseLeave);\n this.root.addEventListener('pointerenter', () => {\n if (this.hideTimer) { clearTimeout(this.hideTimer); this.hideTimer = null; }\n this.setVisible(true);\n });\n }\n\n private kickIdleTimer(): void {\n this.setVisible(true);\n if (this.hideTimer) { clearTimeout(this.hideTimer); this.hideTimer = null; }\n if (this.settingsOpen) return;\n this.hideTimer = setTimeout(() => {\n if (!this.isScrubbing && !this.isVolumeScrubbing && !this.settingsOpen) this.setVisible(false);\n }, Controller.HIDE_DELAY_MS);\n }\n\n private setVisible(v: boolean): void {\n this.root.setAttribute('data-state', v ? 'visible' : 'hidden');\n }\n\n private syncRootToCanvas(): void {\n const c = this.options.canvas;\n const cr = c.getBoundingClientRect();\n const wr = this.wrapper.getBoundingClientRect();\n this.root.style.left = `${cr.left - wr.left}px`;\n this.root.style.top = `${cr.top - wr.top}px`;\n this.root.style.width = `${cr.width}px`;\n this.root.style.height = `${cr.height}px`;\n }\n\n private bindKeyboard(): void {\n this.keyHandler = (e: KeyboardEvent) => {\n const target = e.target as HTMLElement | null;\n if (target) {\n const tag = target.tagName;\n if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') return;\n if (target.isContentEditable || target.getAttribute?.('contenteditable') === 'true') return;\n }\n if (this.isExporting) return;\n\n switch (e.code) {\n case 'Space':\n e.preventDefault();\n this.playBtn.click();\n break;\n case 'ArrowLeft':\n e.preventDefault();\n this.stepFrame(-1);\n break;\n case 'ArrowRight':\n e.preventDefault();\n this.stepFrame(1);\n break;\n case 'ArrowUp':\n e.preventDefault();\n this.adjustVolume(0.05);\n break;\n case 'ArrowDown':\n e.preventDefault();\n this.adjustVolume(-0.05);\n break;\n case 'KeyM':\n e.preventDefault();\n this.muteBtn.click();\n break;\n case 'KeyE':\n if (e.shiftKey && this.exportBtn) {\n e.preventDefault();\n // Power-user shortcut: skip the popover and export with current settings.\n void this.handleExport();\n }\n break;\n case 'KeyF':\n if (this.fullscreenBtn) {\n e.preventDefault();\n void this.toggleFullscreen();\n }\n break;\n }\n };\n document.addEventListener('keydown', this.keyHandler);\n }\n\n private stepFrame(delta: number): void {\n const next = Math.max(0, Math.min(this.movie.totalFrames, this.movie.currentFrame + delta));\n void this.movie.gotoFrame(next);\n }\n\n private adjustVolume(delta: number): void {\n const next = Math.max(0, Math.min(1, this.movie.volume + delta));\n this.movie.volume = next;\n if (this.movie.muted && next > 0) this.movie.muted = false;\n this.refreshVolumeUI();\n }\n\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n if (this.onReady) { this.movie.off('ready', this.onReady); this.onReady = null; }\n if (this.onFrame) { this.movie.off('frame', this.onFrame); this.onFrame = null; }\n if (this.onPause) { this.movie.off('pause', this.onPause); this.onPause = null; }\n if (this.onProgress) { this.movie.off('progress', this.onProgress); this.onProgress = null; }\n if (this.onWrapPointerMove) {\n this.wrapper.removeEventListener('pointermove', this.onWrapPointerMove);\n this.onWrapPointerMove = null;\n }\n if (this.onWrapMouseLeave) {\n this.wrapper.removeEventListener('mouseleave', this.onWrapMouseLeave);\n this.onWrapMouseLeave = null;\n }\n if (this.resizeObserver) {\n this.resizeObserver.disconnect();\n this.resizeObserver = null;\n }\n this.root.remove();\n if (this.wrappedHere) {\n const parent = this.wrapper.parentElement;\n const canvas = this.options.canvas;\n if (parent) {\n parent.insertBefore(canvas, this.wrapper);\n this.wrapper.remove();\n }\n } else {\n this.wrapper.removeAttribute('data-mc-wrap');\n }\n if (this.keyHandler) {\n document.removeEventListener('keydown', this.keyHandler);\n this.keyHandler = null;\n }\n if (this.settingsKeyHandler) {\n document.removeEventListener('keydown', this.settingsKeyHandler);\n this.settingsKeyHandler = null;\n }\n if (this.settingsOutsideHandler) {\n document.removeEventListener('pointerdown', this.settingsOutsideHandler);\n this.settingsOutsideHandler = null;\n }\n if (this.fullscreenChangeHandler) {\n document.removeEventListener('fullscreenchange', this.fullscreenChangeHandler);\n this.fullscreenChangeHandler = null;\n }\n if (this.wheelHandler && this.volumeContainerEl) {\n this.volumeContainerEl.removeEventListener('wheel', this.wheelHandler);\n this.wheelHandler = null;\n }\n if (document.fullscreenElement === this.wrapper) {\n void document.exitFullscreen().catch(() => {});\n }\n if (this.hideTimer) { clearTimeout(this.hideTimer); this.hideTimer = null; }\n this.hideExportOverlay();\n uninstallStyles();\n }\n}\n"]}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { M as Movie } from './Movie-Bp66rkaC.cjs';
|
|
2
|
+
import 'pixi.js';
|
|
3
|
+
import 'gsap';
|
|
4
|
+
|
|
5
|
+
declare function formatTime(seconds: number): string;
|
|
6
|
+
declare function frameToPercent(frame: number, totalFrames: number): number;
|
|
7
|
+
declare function pxToFrame(clientX: number, rect: {
|
|
8
|
+
left: number;
|
|
9
|
+
width: number;
|
|
10
|
+
}, totalFrames: number): number;
|
|
11
|
+
declare function pxToFraction(clientX: number, rect: {
|
|
12
|
+
left: number;
|
|
13
|
+
width: number;
|
|
14
|
+
}, inset?: number): number;
|
|
15
|
+
declare function extensionForMimeType(mime: string): string;
|
|
16
|
+
interface ControllerOptions {
|
|
17
|
+
canvas: HTMLCanvasElement;
|
|
18
|
+
showExportButton?: boolean;
|
|
19
|
+
enableKeyboardShortcuts?: boolean;
|
|
20
|
+
className?: string;
|
|
21
|
+
}
|
|
22
|
+
interface ResolvedOptions {
|
|
23
|
+
canvas: HTMLCanvasElement;
|
|
24
|
+
showExportButton: boolean;
|
|
25
|
+
enableKeyboardShortcuts: boolean;
|
|
26
|
+
className: string;
|
|
27
|
+
}
|
|
28
|
+
declare class Controller {
|
|
29
|
+
movie: Movie;
|
|
30
|
+
options: ResolvedOptions;
|
|
31
|
+
private root;
|
|
32
|
+
private wrapper;
|
|
33
|
+
private wrappedHere;
|
|
34
|
+
private destroyed;
|
|
35
|
+
private progressEl;
|
|
36
|
+
private progressFillEl;
|
|
37
|
+
private progressThumbEl;
|
|
38
|
+
private playBtn;
|
|
39
|
+
private muteBtn;
|
|
40
|
+
private timeEl;
|
|
41
|
+
private exportBtn;
|
|
42
|
+
private settingsPopoverEl;
|
|
43
|
+
private settingsFormatSelect;
|
|
44
|
+
private settingsQualitySelect;
|
|
45
|
+
private exportConfirmBtn;
|
|
46
|
+
private exportFormat;
|
|
47
|
+
private exportQuality;
|
|
48
|
+
private settingsOpen;
|
|
49
|
+
private hideTimer;
|
|
50
|
+
private static readonly HIDE_DELAY_MS;
|
|
51
|
+
private static readonly PROGRESS_INSET_PX;
|
|
52
|
+
private isScrubbing;
|
|
53
|
+
private wasPlayingBeforeScrub;
|
|
54
|
+
private activePointerId;
|
|
55
|
+
private isExporting;
|
|
56
|
+
private exportOverlay;
|
|
57
|
+
private exportFillEl;
|
|
58
|
+
private exportTextEl;
|
|
59
|
+
private keyHandler;
|
|
60
|
+
private settingsKeyHandler;
|
|
61
|
+
private settingsOutsideHandler;
|
|
62
|
+
private onReady;
|
|
63
|
+
private onFrame;
|
|
64
|
+
private onPause;
|
|
65
|
+
private onProgress;
|
|
66
|
+
private onWrapPointerMove;
|
|
67
|
+
private onWrapMouseLeave;
|
|
68
|
+
private resizeObserver;
|
|
69
|
+
private volumeSliderEl;
|
|
70
|
+
private volumeContainerEl;
|
|
71
|
+
private fullscreenBtn;
|
|
72
|
+
private isVolumeScrubbing;
|
|
73
|
+
private fullscreenChangeHandler;
|
|
74
|
+
private wheelHandler;
|
|
75
|
+
constructor(movie: Movie, options: ControllerOptions);
|
|
76
|
+
private buildBar;
|
|
77
|
+
private ensurePositioningContext;
|
|
78
|
+
private bindMovieEvents;
|
|
79
|
+
private bindPlayButton;
|
|
80
|
+
private refreshPlayIcon;
|
|
81
|
+
private bindMuteButton;
|
|
82
|
+
private refreshMuteIcon;
|
|
83
|
+
private refreshVolumeUI;
|
|
84
|
+
private bindVolumeSlider;
|
|
85
|
+
private bindFullscreen;
|
|
86
|
+
private toggleFullscreen;
|
|
87
|
+
private refreshFullscreenIcon;
|
|
88
|
+
private refreshProgress;
|
|
89
|
+
private refreshTime;
|
|
90
|
+
private bindScrubbing;
|
|
91
|
+
private seekFromPointer;
|
|
92
|
+
private bindExportPopover;
|
|
93
|
+
private toggleSettings;
|
|
94
|
+
private handleExport;
|
|
95
|
+
private triggerDownload;
|
|
96
|
+
private makeFilename;
|
|
97
|
+
private showExportOverlay;
|
|
98
|
+
private hideExportOverlay;
|
|
99
|
+
private bindVisibility;
|
|
100
|
+
private kickIdleTimer;
|
|
101
|
+
private setVisible;
|
|
102
|
+
private syncRootToCanvas;
|
|
103
|
+
private bindKeyboard;
|
|
104
|
+
private stepFrame;
|
|
105
|
+
private adjustVolume;
|
|
106
|
+
destroy(): void;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export { Controller, type ControllerOptions, extensionForMimeType, formatTime, frameToPercent, pxToFraction, pxToFrame };
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { M as Movie } from './Movie-Bp66rkaC.js';
|
|
2
|
+
import 'pixi.js';
|
|
3
|
+
import 'gsap';
|
|
4
|
+
|
|
5
|
+
declare function formatTime(seconds: number): string;
|
|
6
|
+
declare function frameToPercent(frame: number, totalFrames: number): number;
|
|
7
|
+
declare function pxToFrame(clientX: number, rect: {
|
|
8
|
+
left: number;
|
|
9
|
+
width: number;
|
|
10
|
+
}, totalFrames: number): number;
|
|
11
|
+
declare function pxToFraction(clientX: number, rect: {
|
|
12
|
+
left: number;
|
|
13
|
+
width: number;
|
|
14
|
+
}, inset?: number): number;
|
|
15
|
+
declare function extensionForMimeType(mime: string): string;
|
|
16
|
+
interface ControllerOptions {
|
|
17
|
+
canvas: HTMLCanvasElement;
|
|
18
|
+
showExportButton?: boolean;
|
|
19
|
+
enableKeyboardShortcuts?: boolean;
|
|
20
|
+
className?: string;
|
|
21
|
+
}
|
|
22
|
+
interface ResolvedOptions {
|
|
23
|
+
canvas: HTMLCanvasElement;
|
|
24
|
+
showExportButton: boolean;
|
|
25
|
+
enableKeyboardShortcuts: boolean;
|
|
26
|
+
className: string;
|
|
27
|
+
}
|
|
28
|
+
declare class Controller {
|
|
29
|
+
movie: Movie;
|
|
30
|
+
options: ResolvedOptions;
|
|
31
|
+
private root;
|
|
32
|
+
private wrapper;
|
|
33
|
+
private wrappedHere;
|
|
34
|
+
private destroyed;
|
|
35
|
+
private progressEl;
|
|
36
|
+
private progressFillEl;
|
|
37
|
+
private progressThumbEl;
|
|
38
|
+
private playBtn;
|
|
39
|
+
private muteBtn;
|
|
40
|
+
private timeEl;
|
|
41
|
+
private exportBtn;
|
|
42
|
+
private settingsPopoverEl;
|
|
43
|
+
private settingsFormatSelect;
|
|
44
|
+
private settingsQualitySelect;
|
|
45
|
+
private exportConfirmBtn;
|
|
46
|
+
private exportFormat;
|
|
47
|
+
private exportQuality;
|
|
48
|
+
private settingsOpen;
|
|
49
|
+
private hideTimer;
|
|
50
|
+
private static readonly HIDE_DELAY_MS;
|
|
51
|
+
private static readonly PROGRESS_INSET_PX;
|
|
52
|
+
private isScrubbing;
|
|
53
|
+
private wasPlayingBeforeScrub;
|
|
54
|
+
private activePointerId;
|
|
55
|
+
private isExporting;
|
|
56
|
+
private exportOverlay;
|
|
57
|
+
private exportFillEl;
|
|
58
|
+
private exportTextEl;
|
|
59
|
+
private keyHandler;
|
|
60
|
+
private settingsKeyHandler;
|
|
61
|
+
private settingsOutsideHandler;
|
|
62
|
+
private onReady;
|
|
63
|
+
private onFrame;
|
|
64
|
+
private onPause;
|
|
65
|
+
private onProgress;
|
|
66
|
+
private onWrapPointerMove;
|
|
67
|
+
private onWrapMouseLeave;
|
|
68
|
+
private resizeObserver;
|
|
69
|
+
private volumeSliderEl;
|
|
70
|
+
private volumeContainerEl;
|
|
71
|
+
private fullscreenBtn;
|
|
72
|
+
private isVolumeScrubbing;
|
|
73
|
+
private fullscreenChangeHandler;
|
|
74
|
+
private wheelHandler;
|
|
75
|
+
constructor(movie: Movie, options: ControllerOptions);
|
|
76
|
+
private buildBar;
|
|
77
|
+
private ensurePositioningContext;
|
|
78
|
+
private bindMovieEvents;
|
|
79
|
+
private bindPlayButton;
|
|
80
|
+
private refreshPlayIcon;
|
|
81
|
+
private bindMuteButton;
|
|
82
|
+
private refreshMuteIcon;
|
|
83
|
+
private refreshVolumeUI;
|
|
84
|
+
private bindVolumeSlider;
|
|
85
|
+
private bindFullscreen;
|
|
86
|
+
private toggleFullscreen;
|
|
87
|
+
private refreshFullscreenIcon;
|
|
88
|
+
private refreshProgress;
|
|
89
|
+
private refreshTime;
|
|
90
|
+
private bindScrubbing;
|
|
91
|
+
private seekFromPointer;
|
|
92
|
+
private bindExportPopover;
|
|
93
|
+
private toggleSettings;
|
|
94
|
+
private handleExport;
|
|
95
|
+
private triggerDownload;
|
|
96
|
+
private makeFilename;
|
|
97
|
+
private showExportOverlay;
|
|
98
|
+
private hideExportOverlay;
|
|
99
|
+
private bindVisibility;
|
|
100
|
+
private kickIdleTimer;
|
|
101
|
+
private setVisible;
|
|
102
|
+
private syncRootToCanvas;
|
|
103
|
+
private bindKeyboard;
|
|
104
|
+
private stepFrame;
|
|
105
|
+
private adjustVolume;
|
|
106
|
+
destroy(): void;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export { Controller, type ControllerOptions, extensionForMimeType, formatTime, frameToPercent, pxToFraction, pxToFrame };
|