@twick/player-react 0.15.15 → 0.15.17

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/dist/index.cjs CHANGED
@@ -68,10 +68,20 @@ var init_internal = __esm({
68
68
  const attr = this.getAttribute("fps");
69
69
  return attr ? parseFloat(attr) : this.defaultSettings?.fps ?? 60;
70
70
  }
71
+ set fps(value) {
72
+ if (value != null && Number.isFinite(value)) {
73
+ this.setAttribute("fps", String(value));
74
+ }
75
+ }
71
76
  get quality() {
72
77
  const attr = this.getAttribute("quality");
73
78
  return attr ? parseFloat(attr) : this.defaultSettings?.resolutionScale ?? 1;
74
79
  }
80
+ set quality(value) {
81
+ if (value != null && Number.isFinite(value)) {
82
+ this.setAttribute("quality", String(value));
83
+ }
84
+ }
75
85
  get width() {
76
86
  const attr = this.getAttribute("width");
77
87
  return attr ? parseFloat(attr) : this.defaultSettings?.size.width ?? 0;
@@ -99,6 +109,26 @@ var init_internal = __esm({
99
109
  return {};
100
110
  }
101
111
  }
112
+ get volume() {
113
+ return this._volume;
114
+ }
115
+ set volume(value) {
116
+ if (value != null) {
117
+ this.setAttribute("volume", String(value));
118
+ }
119
+ }
120
+ set playing(value) {
121
+ this.setAttribute(
122
+ "playing",
123
+ value === true || value === "true" ? "true" : "false"
124
+ );
125
+ }
126
+ set looping(value) {
127
+ this.setAttribute(
128
+ "looping",
129
+ value === true || value === "true" ? "true" : "false"
130
+ );
131
+ }
102
132
  root;
103
133
  canvas;
104
134
  overlay;
@@ -107,13 +137,13 @@ var init_internal = __esm({
107
137
  player = null;
108
138
  defaultSettings;
109
139
  abortController = null;
110
- playing = false;
140
+ _playing = false;
111
141
  stage = new import_core.Stage();
112
142
  time = 0;
113
143
  duration = 0;
114
144
  // in frames
115
- looping = true;
116
- volume = 1;
145
+ _looping = true;
146
+ _volume = 1;
117
147
  volumeChangeRequested = true;
118
148
  constructor() {
119
149
  super();
@@ -130,19 +160,19 @@ var init_internal = __esm({
130
160
  }
131
161
  setState(state) {
132
162
  this.state = state;
133
- this.setPlaying(this.playing);
163
+ this.setPlaying(this._playing);
134
164
  }
135
165
  setPlaying(value) {
136
166
  if (this.state === "ready" /* Ready */ && value) {
137
167
  this.player?.togglePlayback(true);
138
- this.playing = true;
168
+ this._playing = true;
139
169
  } else {
140
170
  this.player?.togglePlayback(false);
141
- this.playing = false;
171
+ this._playing = false;
142
172
  }
143
173
  }
144
174
  async updateProject(project) {
145
- const playing = this.playing;
175
+ const playing = this._playing;
146
176
  this.setState("initial" /* Initial */);
147
177
  this.abortController?.abort();
148
178
  this.abortController = new AbortController();
@@ -150,7 +180,7 @@ var init_internal = __esm({
150
180
  this.defaultSettings = (0, import_core.getFullPreviewSettings)(this.project);
151
181
  const player = new import_core.Player(this.project);
152
182
  player.setVariables(this.variables);
153
- player.toggleLoop(this.looping);
183
+ player.toggleLoop(this._looping);
154
184
  this.player?.onRender.unsubscribe(this.render);
155
185
  this.player?.onFrameChanged.unsubscribe(this.handleFrameChanged);
156
186
  this.player?.togglePlayback(false);
@@ -174,7 +204,7 @@ var init_internal = __esm({
174
204
  this.player?.playback.reload();
175
205
  break;
176
206
  case "looping":
177
- this.looping = newValue === "true";
207
+ this._looping = newValue === "true";
178
208
  this.player?.toggleLoop(newValue === "true");
179
209
  break;
180
210
  case "fps":
@@ -184,7 +214,7 @@ var init_internal = __esm({
184
214
  this.updateSettings();
185
215
  break;
186
216
  case "volume":
187
- this.volume = newValue;
217
+ this._volume = newValue;
188
218
  this.volumeChangeRequested = true;
189
219
  }
190
220
  }
@@ -214,8 +244,10 @@ var init_internal = __esm({
214
244
  return;
215
245
  }
216
246
  const e = event;
217
- this.time = e.detail;
218
- this.player?.requestSeek(e.detail * this.player.playback.fps);
247
+ const timeSec = e.detail;
248
+ const frame = timeSec * this.player.playback.fps;
249
+ this.time = timeSec;
250
+ this.player?.requestSeek(frame);
219
251
  this.volumeChangeRequested = true;
220
252
  };
221
253
  handleVolumeChange = (event) => {
@@ -223,8 +255,8 @@ var init_internal = __esm({
223
255
  return;
224
256
  }
225
257
  const e = event;
226
- this.volume = e.detail;
227
- this.player?.playback.currentScene.adjustVolume(this.volume);
258
+ this._volume = e.detail;
259
+ this.player?.playback.currentScene.adjustVolume(this._volume);
228
260
  };
229
261
  /**
230
262
  * Triggered by the player.
@@ -235,7 +267,7 @@ var init_internal = __esm({
235
267
  }
236
268
  this.time = frame / this.player.playback.fps;
237
269
  if (this.volumeChangeRequested || frame === 0) {
238
- this.player?.playback.currentScene.adjustVolume(this.volume);
270
+ this.player?.playback.currentScene.adjustVolume(this._volume);
239
271
  this.volumeChangeRequested = false;
240
272
  }
241
273
  };
@@ -557,6 +589,7 @@ function Player2({
557
589
  const playerRef = (0, import_react2.useRef)(null);
558
590
  const wrapperRef = (0, import_react2.useRef)(null);
559
591
  const lastRect = (0, import_react2.useRef)(null);
592
+ const lastLoggedTimeRef = (0, import_react2.useRef)(null);
560
593
  const onClickHandler = controls ? () => setPlaying((prev) => !prev) : void 0;
561
594
  (0, import_react2.useEffect)(() => {
562
595
  setPlaying(playing);
@@ -570,6 +603,12 @@ function Player2({
570
603
  (0, import_react2.useEffect)(() => {
571
604
  setForcedVolume(volume);
572
605
  }, [volume]);
606
+ const variablesJson = JSON.stringify(variables);
607
+ (0, import_react2.useEffect)(() => {
608
+ if (playerRef.current) {
609
+ playerRef.current.setAttribute("variables", variablesJson);
610
+ }
611
+ }, [variablesJson]);
573
612
  const onTimeUpdateRef = (0, import_react2.useRef)(onTimeUpdate);
574
613
  const onDurationChangeRef = (0, import_react2.useRef)(onDurationChange);
575
614
  (0, import_react2.useEffect)(() => {
@@ -580,8 +619,13 @@ function Player2({
580
619
  }, [onDurationChange]);
581
620
  const handleTimeUpdate = (0, import_react2.useCallback)((event) => {
582
621
  const e = event;
583
- setCurrentTime(e.detail);
584
- onTimeUpdateRef.current(e.detail);
622
+ const t = e.detail;
623
+ const last = lastLoggedTimeRef.current;
624
+ if (last === null || Math.abs(t - last) > 0.05) {
625
+ lastLoggedTimeRef.current = t;
626
+ }
627
+ setCurrentTime(t);
628
+ onTimeUpdateRef.current(t);
585
629
  }, []);
586
630
  const handleDurationUpdate = (0, import_react2.useCallback)((event) => {
587
631
  const e = event;
@@ -699,15 +743,14 @@ function Player2({
699
743
  "twick-player",
700
744
  {
701
745
  ref: playerRef,
702
- playing: String(playingState),
703
- onClick: onClickHandler,
704
- variables: JSON.stringify(variables),
705
- looping: looping ? "true" : "false",
706
- width,
707
- height,
708
746
  quality,
709
747
  fps,
710
- volume: volumeState
748
+ width,
749
+ height,
750
+ volume: volumeState,
751
+ playing: playingState,
752
+ looping,
753
+ onClick: onClickHandler
711
754
  }
712
755
  ),
713
756
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/internal.ts","../src/index.tsx","../src/controls.tsx","../src/icons.tsx","../src/utils.ts"],"sourcesContent":["import type {Project} from '@twick/core';\nimport {Player, Stage, getFullPreviewSettings} from '@twick/core';\n\nimport {Vector2} from '@twick/core';\n\nconst stylesNew = `\n.overlay {\n\tposition: absolute;\n\tleft: 0;\n\tright: 0;\n\ttop: 0;\n\tbottom: 0;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\topacity: 0;\n\ttransition: opacity 0.1s;\n\tz-index: 0;\n }\n .canvas {\n\twidth: 100%;\n\theight: 100%;\n\tdisplay: block;\n\topacity: 1;\n\ttransition: opacity 0.1s;\n }\n`;\n\nconst TEMPLATE = `<style>${stylesNew}</style><div class=\"overlay\"></div>`;\nconst ID = 'twick-player';\n\nenum State {\n Initial = 'initial',\n Loading = 'loading',\n Ready = 'ready',\n Error = 'error',\n}\n\nclass TwickPlayer extends HTMLElement {\n public static get observedAttributes() {\n return [\n 'playing',\n 'variables',\n 'looping',\n 'fps',\n 'quality',\n 'width',\n 'height',\n 'volume',\n ];\n }\n\n private get fps() {\n const attr = this.getAttribute('fps');\n return attr ? parseFloat(attr) : (this.defaultSettings?.fps ?? 60);\n }\n\n private get quality() {\n const attr = this.getAttribute('quality');\n return attr\n ? parseFloat(attr)\n : (this.defaultSettings?.resolutionScale ?? 1);\n }\n\n private get width() {\n const attr = this.getAttribute('width');\n return attr ? parseFloat(attr) : (this.defaultSettings?.size.width ?? 0);\n }\n\n private set width(value: number) {\n if (Number.isFinite(value)) {\n this.setAttribute('width', String(value));\n }\n }\n\n private get height() {\n const attr = this.getAttribute('height');\n return attr ? parseFloat(attr) : (this.defaultSettings?.size.height ?? 0);\n }\n\n private set height(value: number) {\n if (Number.isFinite(value)) {\n this.setAttribute('height', String(value));\n }\n }\n\n private get variables() {\n try {\n const attr = this.getAttribute('variables');\n return attr ? JSON.parse(attr) : {};\n } catch {\n this.project?.logger.warn(`Project variables could not be parsed.`);\n return {};\n }\n }\n\n private readonly root: ShadowRoot;\n private readonly canvas: HTMLCanvasElement;\n private readonly overlay: HTMLCanvasElement;\n\n private state = State.Initial;\n private project: Project | null = null;\n private player: Player | null = null;\n private defaultSettings:\n | ReturnType<typeof getFullPreviewSettings>\n | undefined;\n private abortController: AbortController | null = null;\n private playing = false;\n private stage = new Stage();\n\n private time: number = 0;\n private duration: number = 0; // in frames\n private looping = true;\n private volume = 1;\n private volumeChangeRequested = true;\n\n public constructor() {\n super();\n this.root = this.attachShadow({mode: 'open'});\n this.root.innerHTML = TEMPLATE;\n\n this.overlay = this.root.querySelector('.overlay')!;\n this.canvas = this.stage.finalBuffer;\n this.canvas.classList.add('canvas');\n this.root.prepend(this.canvas);\n this.setState(State.Initial);\n }\n\n public setProject(project: Project) {\n this.updateProject(project);\n }\n\n private setState(state: State) {\n this.state = state;\n this.setPlaying(this.playing);\n }\n\n private setPlaying(value: boolean) {\n if (this.state === State.Ready && value) {\n this.player?.togglePlayback(true);\n this.playing = true;\n } else {\n this.player?.togglePlayback(false);\n this.playing = false;\n }\n }\n\n private async updateProject(project: Project) {\n const playing = this.playing;\n this.setState(State.Initial);\n\n this.abortController?.abort();\n this.abortController = new AbortController();\n\n this.project = project;\n this.defaultSettings = getFullPreviewSettings(this.project);\n\n const player = new Player(this.project);\n player.setVariables(this.variables);\n player.toggleLoop(this.looping);\n\n this.player?.onRender.unsubscribe(this.render);\n this.player?.onFrameChanged.unsubscribe(this.handleFrameChanged);\n this.player?.togglePlayback(false);\n this.player?.deactivate();\n\n this.player = player;\n this.updateSettings();\n\n this.setState(State.Ready);\n this.dispatchEvent(new CustomEvent('playerready', {detail: this.player}));\n\n // Restore previous state\n this.setPlaying(playing);\n this.player.onRender.subscribe(this.render);\n this.player.onFrameChanged.subscribe(this.handleFrameChanged);\n }\n\n public attributeChangedCallback(name: string, _: any, newValue: any) {\n switch (name) {\n case 'playing':\n this.setPlaying(newValue === 'true');\n break;\n case 'variables':\n this.player?.setVariables(this.variables);\n this.player?.requestSeek(this.player.playback.frame);\n this.player?.playback.reload();\n break;\n case 'looping':\n this.looping = newValue === 'true';\n this.player?.toggleLoop(newValue === 'true');\n break;\n case 'fps':\n case 'quality':\n case 'width':\n case 'height':\n this.updateSettings();\n break;\n case 'volume':\n this.volume = newValue;\n this.volumeChangeRequested = true;\n }\n }\n\n /**\n * Runs when the element is removed from the DOM.\n */\n public disconnectedCallback() {\n this.player?.deactivate();\n this.player?.onRender.unsubscribe(this.render);\n\n this.removeEventListener('seekto', this.handleSeekTo);\n this.removeEventListener('volumechange', this.handleVolumeChange);\n }\n\n /**\n * Runs when the element is added to the DOM.\n */\n public connectedCallback() {\n this.player?.activate();\n this.player?.onRender.subscribe(this.render);\n\n this.addEventListener('seekto', this.handleSeekTo);\n this.addEventListener('volumechange', this.handleVolumeChange);\n }\n\n /**\n * Triggered by the timeline.\n */\n private handleSeekTo = (event: Event) => {\n if (!this.project) {\n return;\n }\n\n const e = event as CustomEvent;\n this.time = e.detail;\n this.player?.requestSeek(e.detail * this.player.playback.fps);\n this.volumeChangeRequested = true;\n };\n\n private handleVolumeChange = (event: Event) => {\n if (!this.project) {\n return;\n }\n\n const e = event as CustomEvent;\n this.volume = e.detail;\n\n this.player?.playback.currentScene.adjustVolume(this.volume);\n };\n\n /**\n * Triggered by the player.\n */\n private handleFrameChanged = (frame: number) => {\n if (!this.project || !this.player) {\n return;\n }\n this.time = frame / this.player.playback.fps;\n\n if (this.volumeChangeRequested || frame === 0) {\n this.player?.playback.currentScene.adjustVolume(this.volume);\n this.volumeChangeRequested = false;\n }\n };\n\n /**\n * Called on every frame.\n */\n private render = async () => {\n if (this.player && this.project) {\n await this.stage.render(\n this.player.playback.currentScene,\n this.player.playback.previousScene,\n );\n\n this.dispatchEvent(new CustomEvent('timeupdate', {detail: this.time}));\n\n const durationInFrames = this.player.playback.duration;\n if (durationInFrames === this.duration) {\n return;\n }\n\n this.duration = durationInFrames;\n\n const durationInSeconds = durationInFrames / this.player.playback.fps;\n this.dispatchEvent(\n new CustomEvent('duration', {detail: durationInSeconds}),\n );\n }\n };\n\n private updateSettings() {\n if (!this.defaultSettings) {\n return;\n }\n\n // Use the requested quality (resolutionScale) instead of forcing 1,\n // so the preview canvas can render at higher internal resolution.\n const resolutionScale =\n Number.isFinite(this.quality) && this.quality > 0\n ? this.quality\n : this.defaultSettings.resolutionScale ?? 1;\n\n const settings = {\n ...this.defaultSettings,\n size: new Vector2(this.width, this.height),\n resolutionScale,\n fps: this.fps,\n };\n this.stage.configure(settings);\n this.player?.configure(settings);\n }\n}\n\nif (!customElements.get(ID)) {\n customElements.define(ID, TwickPlayer);\n}\n","'use client';\nimport type {Player as CorePlayer, Project} from '@twick/core';\nimport type {ComponentProps} from 'react';\nimport {useCallback, useEffect, useRef, useState} from 'react';\nimport {Controls} from './controls';\nimport './index.css';\nimport {shouldShowControls} from './utils';\n\ninterface TwickPlayerProps {\n playing?: string;\n variables?: string;\n looping?: string;\n width?: number;\n height?: number;\n quality?: number;\n fps?: number;\n volume?: number;\n}\n\ndeclare global {\n namespace JSX {\n interface IntrinsicElements {\n // eslint-disable-next-line\n 'twick-player': TwickPlayerProps & ComponentProps<'div'>;\n }\n }\n}\n\ninterface PlayerProps {\n project: Project;\n controls?: boolean;\n variables?: Record<string, any>;\n playing?: boolean;\n currentTime?: number;\n volume?: number;\n looping?: boolean;\n fps?: number;\n\n width?: number;\n height?: number;\n quality?: number;\n timeDisplayFormat?: 'MM:SS' | 'MM:SS.mm' | 'MM:SS.m';\n\n onDurationChange?: (duration: number) => void;\n onTimeUpdate?: (currentTime: number) => void;\n onPlayerReady?: (player: CorePlayer) => void;\n onPlayerResize?: (rect: DOMRectReadOnly) => void;\n}\n\nexport function Player({\n project,\n controls = true,\n variables = {},\n playing = false,\n currentTime = 0,\n volume = 1,\n looping = true,\n fps = 30,\n\n width = undefined,\n height = undefined,\n quality = undefined,\n timeDisplayFormat = 'MM:SS',\n\n onDurationChange = () => {},\n onTimeUpdate = () => {},\n onPlayerReady = () => {},\n onPlayerResize = () => {},\n}: PlayerProps) {\n const [playingState, setPlaying] = useState(playing);\n const [isMouseOver, setIsMouseOver] = useState(false);\n const [currentTimeState, setCurrentTime] = useState(currentTime);\n const [volumeState, setVolumeState] = useState(volume);\n const [duration, setDuration] = useState(-1);\n\n const focus = useRef(false);\n const playerRef = useRef<HTMLDivElement | null>(null);\n const wrapperRef = useRef<HTMLDivElement | null>(null);\n const lastRect = useRef<DOMRectReadOnly | null>(null);\n\n const onClickHandler = controls ? () => setPlaying(prev => !prev) : undefined;\n\n /**\n * Sync the playing prop with the player's own state when it changes.\n */\n useEffect(() => {\n setPlaying(playing);\n }, [playing]);\n\n /**\n * Sync the current time with the player's own state.\n */\n useEffect(() => {\n const diff = Math.abs(currentTime - currentTimeState);\n if (diff > 0.05) {\n setForcedTime(currentTime);\n }\n }, [currentTime]);\n\n useEffect(() => {\n setForcedVolume(volume);\n }, [volume]);\n\n /**\n * Receives the current time of the video from the player.\n * Use refs to ensure we always call the latest callbacks.\n */\n const onTimeUpdateRef = useRef(onTimeUpdate);\n const onDurationChangeRef = useRef(onDurationChange);\n \n // Update refs when callbacks change\n useEffect(() => {\n onTimeUpdateRef.current = onTimeUpdate;\n }, [onTimeUpdate]);\n \n useEffect(() => {\n onDurationChangeRef.current = onDurationChange;\n }, [onDurationChange]);\n\n const handleTimeUpdate = useCallback((event: Event) => {\n const e = event as CustomEvent;\n setCurrentTime(e.detail);\n onTimeUpdateRef.current(e.detail);\n }, []);\n\n /**\n * Receives the duration of the video from the player.\n */\n const handleDurationUpdate = useCallback((event: Event) => {\n const e = event as CustomEvent;\n setDuration(e.detail);\n onDurationChangeRef.current(e.detail);\n }, []);\n\n /**\n * Play and pause using the space key.\n */\n const handleKeyDown = useCallback((event: KeyboardEvent) => {\n if (event.code === 'Space' && focus.current) {\n event.preventDefault();\n setPlaying(prev => !prev);\n }\n }, []);\n\n const onPlayerReadyRef = useRef(onPlayerReady);\n \n useEffect(() => {\n onPlayerReadyRef.current = onPlayerReady;\n }, [onPlayerReady]);\n\n const handlePlayerReady = useCallback((event: Event) => {\n const player = (event as CustomEvent).detail;\n if (player) {\n onPlayerReadyRef.current(player);\n }\n \n // Ensure event listeners are attached when player becomes ready\n // This is a fallback in case listeners weren't attached earlier\n const playerElement = playerRef.current;\n if (playerElement) {\n // Remove and re-add to ensure they're attached\n playerElement.removeEventListener('timeupdate', handleTimeUpdate);\n playerElement.removeEventListener('duration', handleDurationUpdate);\n playerElement.addEventListener('timeupdate', handleTimeUpdate);\n playerElement.addEventListener('duration', handleDurationUpdate);\n }\n }, [handleTimeUpdate, handleDurationUpdate]);\n\n const handlePlayerResize = useCallback(\n (entries: ResizeObserverEntry[]) => {\n const [firstEntry] = entries;\n if (!firstEntry || !wrapperRef.current) {\n return;\n }\n\n const newRect = wrapperRef.current.getBoundingClientRect();\n if (\n !lastRect.current ||\n newRect.width !== lastRect.current.width ||\n newRect.height !== lastRect.current.height ||\n newRect.x !== lastRect.current.x ||\n newRect.y !== lastRect.current.y\n ) {\n lastRect.current = newRect;\n onPlayerResize(newRect);\n }\n },\n [onPlayerResize],\n );\n\n useEffect(() => {\n if (!wrapperRef.current) return;\n\n const resizeObserver = new ResizeObserver(handlePlayerResize);\n resizeObserver.observe(wrapperRef.current);\n\n return () => {\n resizeObserver.disconnect();\n };\n }, [handlePlayerResize]);\n\n /**\n * Import the player and add all event listeners.\n */\n useEffect(() => {\n let cleanup: (() => void) | null = null;\n\n const setupListeners = () => {\n const player = playerRef.current;\n if (!player) return;\n\n // Remove any existing listeners first to avoid duplicates\n player.removeEventListener('timeupdate', handleTimeUpdate);\n player.removeEventListener('duration', handleDurationUpdate);\n player.removeEventListener('playerready', handlePlayerReady);\n\n // Add event listeners\n player.addEventListener('timeupdate', handleTimeUpdate);\n player.addEventListener('duration', handleDurationUpdate);\n player.addEventListener('playerready', handlePlayerReady);\n document.addEventListener('keydown', handleKeyDown);\n\n cleanup = () => {\n player.removeEventListener('timeupdate', handleTimeUpdate);\n player.removeEventListener('duration', handleDurationUpdate);\n player.removeEventListener('playerready', handlePlayerReady);\n document.removeEventListener('keydown', handleKeyDown);\n };\n };\n\n // Import the custom element definition\n import('./internal').then(() => {\n // Wait for the next tick to ensure the element is in the DOM\n // Use requestAnimationFrame to ensure the custom element is ready\n requestAnimationFrame(() => {\n if (playerRef.current) {\n (playerRef.current as any).setProject(project);\n // Set up listeners after the element is ready\n setupListeners();\n }\n });\n });\n\n // Also set up listeners immediately if element already exists\n // This handles the case where the element was already in the DOM\n if (playerRef.current) {\n setupListeners();\n }\n\n return () => {\n if (cleanup) {\n cleanup();\n }\n };\n }, [project, handleTimeUpdate, handleDurationUpdate, handlePlayerReady, handleKeyDown]);\n\n /**\n * When the forced time changes, seek to that time.\n */\n function setForcedTime(forcedTime: number) {\n if (playerRef.current) {\n playerRef.current.dispatchEvent(\n new CustomEvent('seekto', {detail: forcedTime}),\n );\n }\n }\n\n function setForcedVolume(volume: number) {\n setVolumeState(volume);\n if (playerRef.current) {\n playerRef.current.dispatchEvent(\n new CustomEvent('volumechange', {detail: volume}),\n );\n }\n }\n\n return (\n <div className=\"twick-player-root w-full h-full\" style={{display: 'contents'}}>\n <div\n ref={wrapperRef}\n className=\"relative cursor-default w-full h-full focus:outline-none\"\n onFocus={() => (focus.current = true)}\n onBlur={() => (focus.current = false)}\n tabIndex={0}\n onMouseEnter={() => setIsMouseOver(true)}\n onMouseLeave={() => setIsMouseOver(false)}\n >\n <div className=\"relative w-full h-full\">\n <twick-player\n ref={playerRef}\n playing={String(playingState)}\n onClick={onClickHandler}\n variables={JSON.stringify(variables)}\n looping={looping ? 'true' : 'false'}\n width={width}\n height={height}\n quality={quality}\n fps={fps}\n volume={volumeState}\n />\n <div\n className={`absolute bottom-0 w-full transition-opacity duration-200 ${\n shouldShowControls(playingState, isMouseOver, !controls)\n ? 'opacity-100'\n : 'opacity-0'\n }`}\n >\n <Controls\n duration={duration}\n playing={playingState}\n setPlaying={setPlaying}\n currentTime={currentTimeState}\n setForcedTime={setForcedTime}\n timeDisplayFormat={timeDisplayFormat}\n volume={volumeState}\n setVolume={setForcedVolume}\n />\n </div>\n </div>\n </div>\n </div>\n );\n}\n","import {useState} from 'react';\nimport {MutedSoundIcon, PauseButton, PlayButton, SoundIcon} from './icons';\nimport {getFormattedTime} from './utils';\n\nfunction PlayPause({\n playing,\n setPlaying,\n}: {\n playing: boolean;\n setPlaying: (playing: boolean) => void;\n}) {\n return (\n <button type=\"button\" className=\"p-1\" onClick={() => setPlaying(!playing)}>\n {playing ? <PauseButton /> : <PlayButton />}\n </button>\n );\n}\n\nfunction VolumeSlider({\n volume,\n setVolume,\n}: {\n volume: number;\n setVolume: (volume: number) => void;\n}) {\n const [isHovering, setIsHovering] = useState(false);\n const [isInteracting, setIsInteracting] = useState(false);\n const [previousVolume, setPreviousVolume] = useState(1);\n\n const handleIconClick = () => {\n if (volume > 0) {\n setPreviousVolume(volume);\n setVolume(0);\n } else {\n setVolume(previousVolume);\n }\n };\n\n return (\n <div\n className=\"flex items-center space-x-2 relative\"\n onMouseEnter={() => setIsHovering(true)}\n onMouseLeave={() => {\n if (!isInteracting) {\n setIsHovering(false);\n }\n }}\n >\n <div\n className=\"w-6 h-6 flex items-center justify-center cursor-pointer\"\n onClick={handleIconClick}\n >\n {volume === 0 ? <MutedSoundIcon /> : <SoundIcon />}\n </div>\n {(isHovering || isInteracting) && (\n <div className=\"flex items-center h-1.5 whitespace-nowrap\">\n <div className=\"relative w-20 h-1.5 bg-gray-300 rounded-full\">\n <div\n className=\"absolute top-0 left-0 h-full bg-gray-100 rounded-full\"\n style={{width: `${volume * 100}%`}}\n />\n <input\n type=\"range\"\n min={0}\n max={1}\n step={0.01}\n value={volume}\n onChange={e => {\n const newVolume = Number(e.target.value);\n setVolume(newVolume);\n if (newVolume > 0) {\n setPreviousVolume(newVolume);\n }\n }}\n onMouseDown={() => setIsInteracting(true)}\n onMouseUp={() => setIsInteracting(false)}\n onMouseLeave={() => setIsInteracting(false)}\n className=\"absolute top-0 left-0 w-full h-full opacity-0 cursor-pointer\"\n />\n </div>\n </div>\n )}\n </div>\n );\n}\n\nfunction Timeline({\n currentTime,\n duration,\n setCurrentTime,\n}: {\n currentTime: number;\n duration: number;\n setCurrentTime: (currentTime: number) => void;\n}) {\n const progressPercentage = (currentTime / duration) * 100;\n\n return (\n <div className=\"relative flex-1 w-full h-1.5 bg-gray-300 rounded-full overflow-hidden\">\n <div\n className=\"absolute top-0 left-0 h-full bg-gray-100\"\n style={{width: `${progressPercentage}%`}}\n />\n <input\n type=\"range\"\n value={currentTime}\n min={0}\n max={duration}\n step={0.01}\n className=\"absolute top-0 left-0 w-full h-full opacity-0 cursor-pointer\"\n onChange={event => setCurrentTime(Number(event.target.value))}\n />\n </div>\n );\n}\n\nexport function Controls({\n duration,\n playing,\n setPlaying,\n currentTime,\n setForcedTime,\n timeDisplayFormat,\n volume,\n setVolume,\n}: {\n duration: number;\n playing: boolean;\n setPlaying: (playing: boolean) => void;\n currentTime: number;\n setForcedTime: (currentTime: number) => void;\n timeDisplayFormat: 'MM:SS' | 'MM:SS.m' | 'MM:SS.mm';\n volume: number;\n setVolume: (volume: number) => void;\n}) {\n return (\n <div className=\"text-white p-4 flex-col space-y-2 bg-gradient-to-t from-gray-500 to-transparent\">\n <div className=\"flex items-center space-x-2\">\n <PlayPause playing={playing} setPlaying={setPlaying} />\n <div className=\"flex items-center space-x-2\">\n <VolumeSlider volume={volume} setVolume={setVolume} />\n <div>\n <span>\n {getFormattedTime(currentTime, duration, timeDisplayFormat)}\n </span>\n </div>\n </div>\n <div className=\"flex-grow\" />\n </div>\n <Timeline\n currentTime={currentTime}\n duration={duration}\n setCurrentTime={setForcedTime}\n />\n </div>\n );\n}\n","export function PlayButton() {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n className=\"w-6 h-6\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M4.5 5.653c0-1.427 1.529-2.33 2.779-1.643l11.54 6.347c1.295.712 1.295 2.573 0 3.286L7.28 19.99c-1.25.687-2.779-.217-2.779-1.643V5.653Z\"\n clipRule=\"evenodd\"\n />\n </svg>\n );\n}\n\nexport function PauseButton() {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n className=\"w-6 h-6\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M6.75 5.25a.75.75 0 0 1 .75-.75H9a.75.75 0 0 1 .75.75v13.5a.75.75 0 0 1-.75.75H7.5a.75.75 0 0 1-.75-.75V5.25Zm7.5 0A.75.75 0 0 1 15 4.5h1.5a.75.75 0 0 1 .75.75v13.5a.75.75 0 0 1-.75.75H15a.75.75 0 0 1-.75-.75V5.25Z\"\n clipRule=\"evenodd\"\n />\n </svg>\n );\n}\n\nexport function SoundIcon() {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n className=\"p-w-6 p-h-6\"\n >\n <path d=\"M18.36,19.36a1,1,0,0,1-.7-.29,1,1,0,0,1,0-1.41,8,8,0,0,0,0-11.32,1,1,0,0,1,1.41-1.41,10,10,0,0,1,0,14.14A1,1,0,0,1,18.36,19.36Z\" />\n <path d=\"M15.54,16.54a1,1,0,0,1-.71-.3,1,1,0,0,1,0-1.41,4,4,0,0,0,0-5.66,1,1,0,0,1,1.41-1.41,6,6,0,0,1,0,8.48A1,1,0,0,1,15.54,16.54Z\" />\n <path d=\"M11.38,4.08a1,1,0,0,0-1.09.21L6.59,8H4a2,2,0,0,0-2,2v4a2,2,0,0,0,2,2H6.59l3.7,3.71A1,1,0,0,0,11,20a.84.84,0,0,0,.38-.08A1,1,0,0,0,12,19V5A1,1,0,0,0,11.38,4.08Z\" />\n </svg>\n );\n}\n\nexport function MutedSoundIcon() {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n className=\"p-w-6 p-h-6\"\n >\n <path d=\"M11.38,4.08a1,1,0,0,0-1.09.21L6.59,8H4a2,2,0,0,0-2,2v4a2,2,0,0,0,2,2H6.59l3.7,3.71A1,1,0,0,0,11,20a.84.84,0,0,0,.38-.08A1,1,0,0,0,12,19V5A1,1,0,0,0,11.38,4.08Z\" />\n <path d=\"M16,15.5a1,1,0,0,1-.71-.29,1,1,0,0,1,0-1.42l5-5a1,1,0,0,1,1.42,1.42l-5,5A1,1,0,0,1,16,15.5Z\" />\n <path d=\"M21,15.5a1,1,0,0,1-.71-.29l-5-5a1,1,0,0,1,1.42-1.42l5,5a1,1,0,0,1,0,1.42A1,1,0,0,1,21,15.5Z\" />\n </svg>\n );\n}\n","export function getFormattedTime(\n timeInSeconds: number,\n absoluteTimeInSeconds: number,\n timeDisplayFormat: 'MM:SS' | 'MM:SS.mm' | 'MM:SS.m',\n) {\n function toFormattedTime(timeInSeconds: number) {\n const minutes = Math.floor(timeInSeconds / 60);\n const seconds = Math.floor(timeInSeconds % 60)\n .toString()\n .padStart(2, '0');\n const milliseconds = Math.floor((timeInSeconds % 1) * 1000)\n .toString()\n .padStart(3, '0');\n\n if (timeDisplayFormat === 'MM:SS') {\n return `${minutes}:${seconds}`;\n }\n\n if (timeDisplayFormat === 'MM:SS.m') {\n return `${minutes}:${seconds}.${milliseconds[0]}`;\n }\n\n if (timeDisplayFormat === 'MM:SS.mm') {\n return `${minutes}:${seconds}.${milliseconds.slice(0, 2)}`;\n }\n }\n\n return `${toFormattedTime(timeInSeconds)} / ${toFormattedTime(absoluteTimeInSeconds)}`;\n}\n\nexport function shouldShowControls(\n playing: boolean,\n isMouseOver: boolean,\n areControlsDisabled: boolean,\n) {\n if (areControlsDisabled) {\n return false;\n }\n\n return !playing || isMouseOver;\n}\n"],"mappings":"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","names":["import_core","Player","import_react","timeInSeconds","import_jsx_runtime","import_jsx_runtime","Player","volume"]}
1
+ {"version":3,"sources":["../src/internal.ts","../src/index.tsx","../src/controls.tsx","../src/icons.tsx","../src/utils.ts"],"sourcesContent":["import type {Project} from '@twick/core';\nimport {Player, Stage, getFullPreviewSettings} from '@twick/core';\n\nimport {Vector2} from '@twick/core';\n\nconst stylesNew = `\n.overlay {\n\tposition: absolute;\n\tleft: 0;\n\tright: 0;\n\ttop: 0;\n\tbottom: 0;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\topacity: 0;\n\ttransition: opacity 0.1s;\n\tz-index: 0;\n }\n .canvas {\n\twidth: 100%;\n\theight: 100%;\n\tdisplay: block;\n\topacity: 1;\n\ttransition: opacity 0.1s;\n }\n`;\n\nconst TEMPLATE = `<style>${stylesNew}</style><div class=\"overlay\"></div>`;\nconst ID = 'twick-player';\n\nenum State {\n Initial = 'initial',\n Loading = 'loading',\n Ready = 'ready',\n Error = 'error',\n}\n\nclass TwickPlayer extends HTMLElement {\n public static get observedAttributes() {\n return [\n 'playing',\n 'variables',\n 'looping',\n 'fps',\n 'quality',\n 'width',\n 'height',\n 'volume',\n ];\n }\n\n public get fps() {\n const attr = this.getAttribute('fps');\n return attr ? parseFloat(attr) : (this.defaultSettings?.fps ?? 60);\n }\n\n public set fps(value: number) {\n if (value != null && Number.isFinite(value)) {\n this.setAttribute('fps', String(value));\n }\n }\n\n public get quality() {\n const attr = this.getAttribute('quality');\n return attr\n ? parseFloat(attr)\n : (this.defaultSettings?.resolutionScale ?? 1);\n }\n\n public set quality(value: number) {\n if (value != null && Number.isFinite(value)) {\n this.setAttribute('quality', String(value));\n }\n }\n\n public get width() {\n const attr = this.getAttribute('width');\n return attr ? parseFloat(attr) : (this.defaultSettings?.size.width ?? 0);\n }\n\n public set width(value: number) {\n if (Number.isFinite(value)) {\n this.setAttribute('width', String(value));\n }\n }\n\n public get height() {\n const attr = this.getAttribute('height');\n return attr ? parseFloat(attr) : (this.defaultSettings?.size.height ?? 0);\n }\n\n public set height(value: number) {\n if (Number.isFinite(value)) {\n this.setAttribute('height', String(value));\n }\n }\n\n private get variables() {\n try {\n const attr = this.getAttribute('variables');\n return attr ? JSON.parse(attr) : {};\n } catch {\n this.project?.logger.warn(`Project variables could not be parsed.`);\n return {};\n }\n }\n\n public get volume() {\n return this._volume;\n }\n\n public set volume(value: number) {\n if (value != null) {\n this.setAttribute('volume', String(value));\n }\n }\n\n public set playing(value: boolean | string) {\n this.setAttribute(\n 'playing',\n value === true || value === 'true' ? 'true' : 'false',\n );\n }\n\n public set looping(value: boolean | string) {\n this.setAttribute(\n 'looping',\n value === true || value === 'true' ? 'true' : 'false',\n );\n }\n\n private readonly root: ShadowRoot;\n private readonly canvas: HTMLCanvasElement;\n private readonly overlay: HTMLCanvasElement;\n\n private state = State.Initial;\n private project: Project | null = null;\n private player: Player | null = null;\n private defaultSettings:\n | ReturnType<typeof getFullPreviewSettings>\n | undefined;\n private abortController: AbortController | null = null;\n private _playing = false;\n private stage = new Stage();\n\n private time: number = 0;\n private duration: number = 0; // in frames\n private _looping = true;\n private _volume = 1;\n private volumeChangeRequested = true;\n\n public constructor() {\n super();\n this.root = this.attachShadow({mode: 'open'});\n this.root.innerHTML = TEMPLATE;\n\n this.overlay = this.root.querySelector('.overlay')!;\n this.canvas = this.stage.finalBuffer;\n this.canvas.classList.add('canvas');\n this.root.prepend(this.canvas);\n this.setState(State.Initial);\n }\n\n public setProject(project: Project) {\n this.updateProject(project);\n }\n\n private setState(state: State) {\n this.state = state;\n this.setPlaying(this._playing);\n }\n\n private setPlaying(value: boolean) {\n if (this.state === State.Ready && value) {\n this.player?.togglePlayback(true);\n this._playing = true;\n } else {\n this.player?.togglePlayback(false);\n this._playing = false;\n }\n }\n\n private async updateProject(project: Project) {\n const playing = this._playing;\n this.setState(State.Initial);\n\n this.abortController?.abort();\n this.abortController = new AbortController();\n\n this.project = project;\n this.defaultSettings = getFullPreviewSettings(this.project);\n\n const player = new Player(this.project);\n player.setVariables(this.variables);\n player.toggleLoop(this._looping);\n\n this.player?.onRender.unsubscribe(this.render);\n this.player?.onFrameChanged.unsubscribe(this.handleFrameChanged);\n this.player?.togglePlayback(false);\n this.player?.deactivate();\n\n this.player = player;\n this.updateSettings();\n\n this.setState(State.Ready);\n this.dispatchEvent(new CustomEvent('playerready', {detail: this.player}));\n\n // Restore previous state\n this.setPlaying(playing);\n this.player.onRender.subscribe(this.render);\n this.player.onFrameChanged.subscribe(this.handleFrameChanged);\n }\n\n public attributeChangedCallback(name: string, _: any, newValue: any) {\n switch (name) {\n case 'playing':\n this.setPlaying(newValue === 'true');\n break;\n case 'variables':\n this.player?.setVariables(this.variables);\n this.player?.requestSeek(this.player.playback.frame);\n this.player?.playback.reload();\n break;\n case 'looping':\n this._looping = newValue === 'true';\n this.player?.toggleLoop(newValue === 'true');\n break;\n case 'fps':\n case 'quality':\n case 'width':\n case 'height':\n this.updateSettings();\n break;\n case 'volume':\n this._volume = newValue;\n this.volumeChangeRequested = true;\n }\n }\n\n /**\n * Runs when the element is removed from the DOM.\n */\n public disconnectedCallback() {\n this.player?.deactivate();\n this.player?.onRender.unsubscribe(this.render);\n\n this.removeEventListener('seekto', this.handleSeekTo);\n this.removeEventListener('volumechange', this.handleVolumeChange);\n }\n\n /**\n * Runs when the element is added to the DOM.\n */\n public connectedCallback() {\n this.player?.activate();\n this.player?.onRender.subscribe(this.render);\n\n this.addEventListener('seekto', this.handleSeekTo);\n this.addEventListener('volumechange', this.handleVolumeChange);\n }\n\n /**\n * Triggered by the timeline.\n */\n private handleSeekTo = (event: Event) => {\n if (!this.project) {\n return;\n }\n\n const e = event as CustomEvent;\n const timeSec = e.detail as number;\n const frame = timeSec * this.player!.playback.fps;\n this.time = timeSec;\n this.player?.requestSeek(frame);\n this.volumeChangeRequested = true;\n };\n\n private handleVolumeChange = (event: Event) => {\n if (!this.project) {\n return;\n }\n\n const e = event as CustomEvent;\n this._volume = e.detail;\n\n this.player?.playback.currentScene.adjustVolume(this._volume);\n };\n\n /**\n * Triggered by the player.\n */\n private handleFrameChanged = (frame: number) => {\n if (!this.project || !this.player) {\n return;\n }\n this.time = frame / this.player.playback.fps;\n\n if (this.volumeChangeRequested || frame === 0) {\n this.player?.playback.currentScene.adjustVolume(this._volume);\n this.volumeChangeRequested = false;\n }\n };\n\n /**\n * Called on every frame.\n */\n private render = async () => {\n if (this.player && this.project) {\n await this.stage.render(\n this.player.playback.currentScene,\n this.player.playback.previousScene,\n );\n\n this.dispatchEvent(new CustomEvent('timeupdate', {detail: this.time}));\n\n const durationInFrames = this.player.playback.duration;\n if (durationInFrames === this.duration) {\n return;\n }\n\n this.duration = durationInFrames;\n\n const durationInSeconds = durationInFrames / this.player.playback.fps;\n this.dispatchEvent(\n new CustomEvent('duration', {detail: durationInSeconds}),\n );\n }\n };\n\n private updateSettings() {\n if (!this.defaultSettings) {\n return;\n }\n\n // Use the requested quality (resolutionScale) instead of forcing 1,\n // so the preview canvas can render at higher internal resolution.\n const resolutionScale =\n Number.isFinite(this.quality) && this.quality > 0\n ? this.quality\n : this.defaultSettings.resolutionScale ?? 1;\n\n const settings = {\n ...this.defaultSettings,\n size: new Vector2(this.width, this.height),\n resolutionScale,\n fps: this.fps,\n };\n this.stage.configure(settings);\n this.player?.configure(settings);\n }\n}\n\nif (!customElements.get(ID)) {\n customElements.define(ID, TwickPlayer);\n}\n","'use client';\nimport type {Player as CorePlayer, Project} from '@twick/core';\nimport type {ComponentProps} from 'react';\nimport {useCallback, useEffect, useRef, useState} from 'react';\nimport {Controls} from './controls';\nimport './index.css';\nimport {shouldShowControls} from './utils';\n\ninterface TwickPlayerProps {\n playing?: boolean | string;\n variables?: string;\n looping?: boolean | string;\n width?: number;\n height?: number;\n quality?: number;\n fps?: number;\n volume?: number;\n}\n\ndeclare global {\n namespace JSX {\n interface IntrinsicElements {\n // eslint-disable-next-line\n 'twick-player': TwickPlayerProps & ComponentProps<'div'>;\n }\n }\n}\n\ninterface PlayerProps {\n project: Project;\n controls?: boolean;\n variables?: Record<string, any>;\n playing?: boolean;\n currentTime?: number;\n volume?: number;\n looping?: boolean;\n fps?: number;\n\n width?: number;\n height?: number;\n quality?: number;\n timeDisplayFormat?: 'MM:SS' | 'MM:SS.mm' | 'MM:SS.m';\n\n onDurationChange?: (duration: number) => void;\n onTimeUpdate?: (currentTime: number) => void;\n onPlayerReady?: (player: CorePlayer) => void;\n onPlayerResize?: (rect: DOMRectReadOnly) => void;\n}\n\nexport function Player({\n project,\n controls = true,\n variables = {},\n playing = false,\n currentTime = 0,\n volume = 1,\n looping = true,\n fps = 30,\n\n width = undefined,\n height = undefined,\n quality = undefined,\n timeDisplayFormat = 'MM:SS',\n\n onDurationChange = () => {},\n onTimeUpdate = () => {},\n onPlayerReady = () => {},\n onPlayerResize = () => {},\n}: PlayerProps) {\n const [playingState, setPlaying] = useState(playing);\n const [isMouseOver, setIsMouseOver] = useState(false);\n const [currentTimeState, setCurrentTime] = useState(currentTime);\n const [volumeState, setVolumeState] = useState(volume);\n const [duration, setDuration] = useState(-1);\n\n const focus = useRef(false);\n const playerRef = useRef<HTMLDivElement | null>(null);\n const wrapperRef = useRef<HTMLDivElement | null>(null);\n const lastRect = useRef<DOMRectReadOnly | null>(null);\n const lastLoggedTimeRef = useRef<number | null>(null);\n\n const onClickHandler = controls ? () => setPlaying(prev => !prev) : undefined;\n\n /**\n * Sync the playing prop with the player's own state when it changes.\n */\n useEffect(() => {\n setPlaying(playing);\n }, [playing]);\n\n /**\n * Sync the current time with the player's own state.\n */\n useEffect(() => {\n const diff = Math.abs(currentTime - currentTimeState);\n if (diff > 0.05) {\n setForcedTime(currentTime);\n }\n }, [currentTime]);\n\n useEffect(() => {\n setForcedVolume(volume);\n }, [volume]);\n\n /**\n * Set variables via setAttribute - the twick-player custom element's variables\n * property is read-only (getter only). React would fail if we passed it as a prop.\n */\n const variablesJson = JSON.stringify(variables);\n useEffect(() => {\n if (playerRef.current) {\n playerRef.current.setAttribute('variables', variablesJson);\n }\n }, [variablesJson]);\n\n /**\n * Receives the current time of the video from the player.\n * Use refs to ensure we always call the latest callbacks.\n */\n const onTimeUpdateRef = useRef(onTimeUpdate);\n const onDurationChangeRef = useRef(onDurationChange);\n \n // Update refs when callbacks change\n useEffect(() => {\n onTimeUpdateRef.current = onTimeUpdate;\n }, [onTimeUpdate]);\n \n useEffect(() => {\n onDurationChangeRef.current = onDurationChange;\n }, [onDurationChange]);\n\n const handleTimeUpdate = useCallback((event: Event) => {\n const e = event as CustomEvent;\n const t = e.detail as number;\n const last = lastLoggedTimeRef.current;\n if (last === null || Math.abs(t - last) > 0.05) {\n lastLoggedTimeRef.current = t;\n }\n setCurrentTime(t);\n onTimeUpdateRef.current(t);\n }, []);\n\n /**\n * Receives the duration of the video from the player.\n */\n const handleDurationUpdate = useCallback((event: Event) => {\n const e = event as CustomEvent;\n setDuration(e.detail);\n onDurationChangeRef.current(e.detail);\n }, []);\n\n /**\n * Play and pause using the space key.\n */\n const handleKeyDown = useCallback((event: KeyboardEvent) => {\n if (event.code === 'Space' && focus.current) {\n event.preventDefault();\n setPlaying(prev => !prev);\n }\n }, []);\n\n const onPlayerReadyRef = useRef(onPlayerReady);\n \n useEffect(() => {\n onPlayerReadyRef.current = onPlayerReady;\n }, [onPlayerReady]);\n\n const handlePlayerReady = useCallback((event: Event) => {\n const player = (event as CustomEvent).detail;\n if (player) {\n onPlayerReadyRef.current(player);\n }\n \n // Ensure event listeners are attached when player becomes ready\n // This is a fallback in case listeners weren't attached earlier\n const playerElement = playerRef.current;\n if (playerElement) {\n // Remove and re-add to ensure they're attached\n playerElement.removeEventListener('timeupdate', handleTimeUpdate);\n playerElement.removeEventListener('duration', handleDurationUpdate);\n playerElement.addEventListener('timeupdate', handleTimeUpdate);\n playerElement.addEventListener('duration', handleDurationUpdate);\n }\n }, [handleTimeUpdate, handleDurationUpdate]);\n\n const handlePlayerResize = useCallback(\n (entries: ResizeObserverEntry[]) => {\n const [firstEntry] = entries;\n if (!firstEntry || !wrapperRef.current) {\n return;\n }\n\n const newRect = wrapperRef.current.getBoundingClientRect();\n if (\n !lastRect.current ||\n newRect.width !== lastRect.current.width ||\n newRect.height !== lastRect.current.height ||\n newRect.x !== lastRect.current.x ||\n newRect.y !== lastRect.current.y\n ) {\n lastRect.current = newRect;\n onPlayerResize(newRect);\n }\n },\n [onPlayerResize],\n );\n\n useEffect(() => {\n if (!wrapperRef.current) return;\n\n const resizeObserver = new ResizeObserver(handlePlayerResize);\n resizeObserver.observe(wrapperRef.current);\n\n return () => {\n resizeObserver.disconnect();\n };\n }, [handlePlayerResize]);\n\n /**\n * Import the player and add all event listeners.\n */\n useEffect(() => {\n let cleanup: (() => void) | null = null;\n\n const setupListeners = () => {\n const player = playerRef.current;\n if (!player) return;\n\n // Remove any existing listeners first to avoid duplicates\n player.removeEventListener('timeupdate', handleTimeUpdate);\n player.removeEventListener('duration', handleDurationUpdate);\n player.removeEventListener('playerready', handlePlayerReady);\n\n // Add event listeners\n player.addEventListener('timeupdate', handleTimeUpdate);\n player.addEventListener('duration', handleDurationUpdate);\n player.addEventListener('playerready', handlePlayerReady);\n document.addEventListener('keydown', handleKeyDown);\n\n cleanup = () => {\n player.removeEventListener('timeupdate', handleTimeUpdate);\n player.removeEventListener('duration', handleDurationUpdate);\n player.removeEventListener('playerready', handlePlayerReady);\n document.removeEventListener('keydown', handleKeyDown);\n };\n };\n\n // Import the custom element definition\n import('./internal').then(() => {\n // Wait for the next tick to ensure the element is in the DOM\n // Use requestAnimationFrame to ensure the custom element is ready\n requestAnimationFrame(() => {\n if (playerRef.current) {\n (playerRef.current as any).setProject(project);\n // Set up listeners after the element is ready\n setupListeners();\n }\n });\n });\n\n // Also set up listeners immediately if element already exists\n // This handles the case where the element was already in the DOM\n if (playerRef.current) {\n setupListeners();\n }\n\n return () => {\n if (cleanup) {\n cleanup();\n }\n };\n }, [project, handleTimeUpdate, handleDurationUpdate, handlePlayerReady, handleKeyDown]);\n\n /**\n * When the forced time changes, seek to that time.\n */\n function setForcedTime(forcedTime: number) {\n if (playerRef.current) {\n playerRef.current.dispatchEvent(\n new CustomEvent('seekto', {detail: forcedTime}),\n );\n }\n }\n\n function setForcedVolume(volume: number) {\n setVolumeState(volume);\n if (playerRef.current) {\n playerRef.current.dispatchEvent(\n new CustomEvent('volumechange', {detail: volume}),\n );\n }\n }\n\n return (\n <div className=\"twick-player-root w-full h-full\" style={{display: 'contents'}}>\n <div\n ref={wrapperRef}\n className=\"relative cursor-default w-full h-full focus:outline-none\"\n onFocus={() => (focus.current = true)}\n onBlur={() => (focus.current = false)}\n tabIndex={0}\n onMouseEnter={() => setIsMouseOver(true)}\n onMouseLeave={() => setIsMouseOver(false)}\n >\n <div className=\"relative w-full h-full\">\n <twick-player\n ref={playerRef}\n quality={quality}\n fps={fps}\n width={width}\n height={height}\n volume={volumeState}\n playing={playingState}\n looping={looping}\n onClick={onClickHandler}\n />\n <div\n className={`absolute bottom-0 w-full transition-opacity duration-200 ${\n shouldShowControls(playingState, isMouseOver, !controls)\n ? 'opacity-100'\n : 'opacity-0'\n }`}\n >\n <Controls\n duration={duration}\n playing={playingState}\n setPlaying={setPlaying}\n currentTime={currentTimeState}\n setForcedTime={setForcedTime}\n timeDisplayFormat={timeDisplayFormat}\n volume={volumeState}\n setVolume={setForcedVolume}\n />\n </div>\n </div>\n </div>\n </div>\n );\n}\n","import {useState} from 'react';\nimport {MutedSoundIcon, PauseButton, PlayButton, SoundIcon} from './icons';\nimport {getFormattedTime} from './utils';\n\nfunction PlayPause({\n playing,\n setPlaying,\n}: {\n playing: boolean;\n setPlaying: (playing: boolean) => void;\n}) {\n return (\n <button type=\"button\" className=\"p-1\" onClick={() => setPlaying(!playing)}>\n {playing ? <PauseButton /> : <PlayButton />}\n </button>\n );\n}\n\nfunction VolumeSlider({\n volume,\n setVolume,\n}: {\n volume: number;\n setVolume: (volume: number) => void;\n}) {\n const [isHovering, setIsHovering] = useState(false);\n const [isInteracting, setIsInteracting] = useState(false);\n const [previousVolume, setPreviousVolume] = useState(1);\n\n const handleIconClick = () => {\n if (volume > 0) {\n setPreviousVolume(volume);\n setVolume(0);\n } else {\n setVolume(previousVolume);\n }\n };\n\n return (\n <div\n className=\"flex items-center space-x-2 relative\"\n onMouseEnter={() => setIsHovering(true)}\n onMouseLeave={() => {\n if (!isInteracting) {\n setIsHovering(false);\n }\n }}\n >\n <div\n className=\"w-6 h-6 flex items-center justify-center cursor-pointer\"\n onClick={handleIconClick}\n >\n {volume === 0 ? <MutedSoundIcon /> : <SoundIcon />}\n </div>\n {(isHovering || isInteracting) && (\n <div className=\"flex items-center h-1.5 whitespace-nowrap\">\n <div className=\"relative w-20 h-1.5 bg-gray-300 rounded-full\">\n <div\n className=\"absolute top-0 left-0 h-full bg-gray-100 rounded-full\"\n style={{width: `${volume * 100}%`}}\n />\n <input\n type=\"range\"\n min={0}\n max={1}\n step={0.01}\n value={volume}\n onChange={e => {\n const newVolume = Number(e.target.value);\n setVolume(newVolume);\n if (newVolume > 0) {\n setPreviousVolume(newVolume);\n }\n }}\n onMouseDown={() => setIsInteracting(true)}\n onMouseUp={() => setIsInteracting(false)}\n onMouseLeave={() => setIsInteracting(false)}\n className=\"absolute top-0 left-0 w-full h-full opacity-0 cursor-pointer\"\n />\n </div>\n </div>\n )}\n </div>\n );\n}\n\nfunction Timeline({\n currentTime,\n duration,\n setCurrentTime,\n}: {\n currentTime: number;\n duration: number;\n setCurrentTime: (currentTime: number) => void;\n}) {\n const progressPercentage = (currentTime / duration) * 100;\n\n return (\n <div className=\"relative flex-1 w-full h-1.5 bg-gray-300 rounded-full overflow-hidden\">\n <div\n className=\"absolute top-0 left-0 h-full bg-gray-100\"\n style={{width: `${progressPercentage}%`}}\n />\n <input\n type=\"range\"\n value={currentTime}\n min={0}\n max={duration}\n step={0.01}\n className=\"absolute top-0 left-0 w-full h-full opacity-0 cursor-pointer\"\n onChange={event => setCurrentTime(Number(event.target.value))}\n />\n </div>\n );\n}\n\nexport function Controls({\n duration,\n playing,\n setPlaying,\n currentTime,\n setForcedTime,\n timeDisplayFormat,\n volume,\n setVolume,\n}: {\n duration: number;\n playing: boolean;\n setPlaying: (playing: boolean) => void;\n currentTime: number;\n setForcedTime: (currentTime: number) => void;\n timeDisplayFormat: 'MM:SS' | 'MM:SS.m' | 'MM:SS.mm';\n volume: number;\n setVolume: (volume: number) => void;\n}) {\n return (\n <div className=\"text-white p-4 flex-col space-y-2 bg-gradient-to-t from-gray-500 to-transparent\">\n <div className=\"flex items-center space-x-2\">\n <PlayPause playing={playing} setPlaying={setPlaying} />\n <div className=\"flex items-center space-x-2\">\n <VolumeSlider volume={volume} setVolume={setVolume} />\n <div>\n <span>\n {getFormattedTime(currentTime, duration, timeDisplayFormat)}\n </span>\n </div>\n </div>\n <div className=\"flex-grow\" />\n </div>\n <Timeline\n currentTime={currentTime}\n duration={duration}\n setCurrentTime={setForcedTime}\n />\n </div>\n );\n}\n","export function PlayButton() {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n className=\"w-6 h-6\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M4.5 5.653c0-1.427 1.529-2.33 2.779-1.643l11.54 6.347c1.295.712 1.295 2.573 0 3.286L7.28 19.99c-1.25.687-2.779-.217-2.779-1.643V5.653Z\"\n clipRule=\"evenodd\"\n />\n </svg>\n );\n}\n\nexport function PauseButton() {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n className=\"w-6 h-6\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M6.75 5.25a.75.75 0 0 1 .75-.75H9a.75.75 0 0 1 .75.75v13.5a.75.75 0 0 1-.75.75H7.5a.75.75 0 0 1-.75-.75V5.25Zm7.5 0A.75.75 0 0 1 15 4.5h1.5a.75.75 0 0 1 .75.75v13.5a.75.75 0 0 1-.75.75H15a.75.75 0 0 1-.75-.75V5.25Z\"\n clipRule=\"evenodd\"\n />\n </svg>\n );\n}\n\nexport function SoundIcon() {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n className=\"p-w-6 p-h-6\"\n >\n <path d=\"M18.36,19.36a1,1,0,0,1-.7-.29,1,1,0,0,1,0-1.41,8,8,0,0,0,0-11.32,1,1,0,0,1,1.41-1.41,10,10,0,0,1,0,14.14A1,1,0,0,1,18.36,19.36Z\" />\n <path d=\"M15.54,16.54a1,1,0,0,1-.71-.3,1,1,0,0,1,0-1.41,4,4,0,0,0,0-5.66,1,1,0,0,1,1.41-1.41,6,6,0,0,1,0,8.48A1,1,0,0,1,15.54,16.54Z\" />\n <path d=\"M11.38,4.08a1,1,0,0,0-1.09.21L6.59,8H4a2,2,0,0,0-2,2v4a2,2,0,0,0,2,2H6.59l3.7,3.71A1,1,0,0,0,11,20a.84.84,0,0,0,.38-.08A1,1,0,0,0,12,19V5A1,1,0,0,0,11.38,4.08Z\" />\n </svg>\n );\n}\n\nexport function MutedSoundIcon() {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n className=\"p-w-6 p-h-6\"\n >\n <path d=\"M11.38,4.08a1,1,0,0,0-1.09.21L6.59,8H4a2,2,0,0,0-2,2v4a2,2,0,0,0,2,2H6.59l3.7,3.71A1,1,0,0,0,11,20a.84.84,0,0,0,.38-.08A1,1,0,0,0,12,19V5A1,1,0,0,0,11.38,4.08Z\" />\n <path d=\"M16,15.5a1,1,0,0,1-.71-.29,1,1,0,0,1,0-1.42l5-5a1,1,0,0,1,1.42,1.42l-5,5A1,1,0,0,1,16,15.5Z\" />\n <path d=\"M21,15.5a1,1,0,0,1-.71-.29l-5-5a1,1,0,0,1,1.42-1.42l5,5a1,1,0,0,1,0,1.42A1,1,0,0,1,21,15.5Z\" />\n </svg>\n );\n}\n","export function getFormattedTime(\n timeInSeconds: number,\n absoluteTimeInSeconds: number,\n timeDisplayFormat: 'MM:SS' | 'MM:SS.mm' | 'MM:SS.m',\n) {\n function toFormattedTime(timeInSeconds: number) {\n const minutes = Math.floor(timeInSeconds / 60);\n const seconds = Math.floor(timeInSeconds % 60)\n .toString()\n .padStart(2, '0');\n const milliseconds = Math.floor((timeInSeconds % 1) * 1000)\n .toString()\n .padStart(3, '0');\n\n if (timeDisplayFormat === 'MM:SS') {\n return `${minutes}:${seconds}`;\n }\n\n if (timeDisplayFormat === 'MM:SS.m') {\n return `${minutes}:${seconds}.${milliseconds[0]}`;\n }\n\n if (timeDisplayFormat === 'MM:SS.mm') {\n return `${minutes}:${seconds}.${milliseconds.slice(0, 2)}`;\n }\n }\n\n return `${toFormattedTime(timeInSeconds)} / ${toFormattedTime(absoluteTimeInSeconds)}`;\n}\n\nexport function shouldShowControls(\n playing: boolean,\n isMouseOver: boolean,\n areControlsDisabled: boolean,\n) {\n if (areControlsDisabled) {\n return false;\n }\n\n return !playing || isMouseOver;\n}\n"],"mappings":"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","names":["import_core","Player","import_react","timeInSeconds","import_jsx_runtime","import_jsx_runtime","Player","volume"]}
package/dist/index.css CHANGED
@@ -1,2 +1,2 @@
1
1
  .twick-player-root{*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }
2
- /*! tailwindcss v3.4.12 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e5e5;box-sizing:border-box}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-tap-highlight-color:transparent}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-size:1em;font-variation-settings:normal}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{color:inherit;font-family:inherit;font-feature-settings:inherit;font-size:100%;font-variation-settings:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#acacac;opacity:1}input::placeholder,textarea::placeholder{color:#acacac;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]{display:none}}.twick-player-root .static{position:static}.twick-player-root .absolute{position:absolute}.twick-player-root .relative{position:relative}.twick-player-root .bottom-0{bottom:0}.twick-player-root .left-0{left:0}.twick-player-root .top-0{top:0}.twick-player-root .block{display:block}.twick-player-root .flex{display:flex}.twick-player-root .contents{display:contents}.twick-player-root .h-1\.5{height:.375rem}.twick-player-root .h-6{height:1.5rem}.twick-player-root .h-full{height:100%}.twick-player-root .w-20{width:5rem}.twick-player-root .w-6{width:1.5rem}.twick-player-root .w-full{width:100%}.twick-player-root .flex-1{flex:1 1 0%}.twick-player-root .flex-grow{flex-grow:1}.twick-player-root .cursor-default{cursor:default}.twick-player-root .cursor-pointer{cursor:pointer}.twick-player-root .flex-col{flex-direction:column}.twick-player-root .items-center{align-items:center}.twick-player-root .justify-center{justify-content:center}.twick-player-root :is(.space-x-2>:not([hidden])~:not([hidden])){--tw-space-x-reverse:0;margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.5rem*var(--tw-space-x-reverse))}.twick-player-root :is(.space-y-2>:not([hidden])~:not([hidden])){--tw-space-y-reverse:0;margin-bottom:calc(.5rem*var(--tw-space-y-reverse));margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)))}.twick-player-root .overflow-hidden{overflow:hidden}.twick-player-root .whitespace-nowrap{white-space:nowrap}.twick-player-root .rounded-full{border-radius:9999px}.twick-player-root .bg-gray-100{--tw-bg-opacity:1;background-color:rgb(243 243 243/var(--tw-bg-opacity))}.twick-player-root .bg-gray-300{--tw-bg-opacity:1;background-color:rgb(199 199 199/var(--tw-bg-opacity))}.twick-player-root .bg-gradient-to-t{background-image:linear-gradient(to top,var(--tw-gradient-stops))}.twick-player-root .from-gray-500{--tw-gradient-from:grey var(--tw-gradient-from-position);--tw-gradient-to:hsla(0,0%,50%,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.twick-player-root .to-transparent{--tw-gradient-to:transparent var(--tw-gradient-to-position)}.twick-player-root .p-1{padding:.25rem}.twick-player-root .p-4{padding:1rem}.twick-player-root .text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.twick-player-root .opacity-0{opacity:0}.twick-player-root .opacity-100{opacity:1}.twick-player-root .transition{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1)}.twick-player-root .transition-opacity{transition-duration:.15s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1)}.twick-player-root .duration-200{transition-duration:.2s}.twick-player-root .focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}
2
+ /*! tailwindcss v3.4.19 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e5e5;box-sizing:border-box}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-tap-highlight-color:transparent}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-size:1em;font-variation-settings:normal}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{color:inherit;font-family:inherit;font-feature-settings:inherit;font-size:100%;font-variation-settings:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#acacac;opacity:1}input::placeholder,textarea::placeholder{color:#acacac;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]:where(:not([hidden=until-found])){display:none}}.twick-player-root .static{position:static}.twick-player-root .absolute{position:absolute}.twick-player-root .relative{position:relative}.twick-player-root .bottom-0{bottom:0}.twick-player-root .left-0{left:0}.twick-player-root .top-0{top:0}.twick-player-root .block{display:block}.twick-player-root .flex{display:flex}.twick-player-root .contents{display:contents}.twick-player-root .h-1\.5{height:.375rem}.twick-player-root .h-6{height:1.5rem}.twick-player-root .h-full{height:100%}.twick-player-root .w-20{width:5rem}.twick-player-root .w-6{width:1.5rem}.twick-player-root .w-full{width:100%}.twick-player-root .flex-1{flex:1 1 0%}.twick-player-root .flex-grow{flex-grow:1}.twick-player-root .cursor-default{cursor:default}.twick-player-root .cursor-pointer{cursor:pointer}.twick-player-root .flex-col{flex-direction:column}.twick-player-root .items-center{align-items:center}.twick-player-root .justify-center{justify-content:center}.twick-player-root :is(.space-x-2>:not([hidden])~:not([hidden])){--tw-space-x-reverse:0;margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.5rem*var(--tw-space-x-reverse))}.twick-player-root :is(.space-y-2>:not([hidden])~:not([hidden])){--tw-space-y-reverse:0;margin-bottom:calc(.5rem*var(--tw-space-y-reverse));margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)))}.twick-player-root .overflow-hidden{overflow:hidden}.twick-player-root .whitespace-nowrap{white-space:nowrap}.twick-player-root .rounded-full{border-radius:9999px}.twick-player-root .bg-gray-100{--tw-bg-opacity:1;background-color:rgb(243 243 243/var(--tw-bg-opacity,1))}.twick-player-root .bg-gray-300{--tw-bg-opacity:1;background-color:rgb(199 199 199/var(--tw-bg-opacity,1))}.twick-player-root .bg-gradient-to-t{background-image:linear-gradient(to top,var(--tw-gradient-stops))}.twick-player-root .from-gray-500{--tw-gradient-from:grey var(--tw-gradient-from-position);--tw-gradient-to:hsla(0,0%,50%,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.twick-player-root .to-transparent{--tw-gradient-to:transparent var(--tw-gradient-to-position)}.twick-player-root .p-1{padding:.25rem}.twick-player-root .p-4{padding:1rem}.twick-player-root .text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.twick-player-root .opacity-0{opacity:0}.twick-player-root .opacity-100{opacity:1}.twick-player-root .transition{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1)}.twick-player-root .transition-opacity{transition-duration:.15s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1)}.twick-player-root .duration-200{transition-duration:.2s}.twick-player-root .focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.css"],"sourcesContent":[".twick-player-root{*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }\n /*! tailwindcss v3.4.12 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e5e5;box-sizing:border-box}:after,:before{--tw-content:\"\"}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-tap-highlight-color:transparent}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-size:1em;font-variation-settings:normal}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{color:inherit;font-family:inherit;font-feature-settings:inherit;font-size:100%;font-variation-settings:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#acacac;opacity:1}input::placeholder,textarea::placeholder{color:#acacac;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]{display:none}}.twick-player-root .static{position:static}.twick-player-root .absolute{position:absolute}.twick-player-root .relative{position:relative}.twick-player-root .bottom-0{bottom:0}.twick-player-root .left-0{left:0}.twick-player-root .top-0{top:0}.twick-player-root .block{display:block}.twick-player-root .flex{display:flex}.twick-player-root .contents{display:contents}.twick-player-root .h-1\\.5{height:.375rem}.twick-player-root .h-6{height:1.5rem}.twick-player-root .h-full{height:100%}.twick-player-root .w-20{width:5rem}.twick-player-root .w-6{width:1.5rem}.twick-player-root .w-full{width:100%}.twick-player-root .flex-1{flex:1 1 0%}.twick-player-root .flex-grow{flex-grow:1}.twick-player-root .cursor-default{cursor:default}.twick-player-root .cursor-pointer{cursor:pointer}.twick-player-root .flex-col{flex-direction:column}.twick-player-root .items-center{align-items:center}.twick-player-root .justify-center{justify-content:center}.twick-player-root :is(.space-x-2>:not([hidden])~:not([hidden])){--tw-space-x-reverse:0;margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.5rem*var(--tw-space-x-reverse))}.twick-player-root :is(.space-y-2>:not([hidden])~:not([hidden])){--tw-space-y-reverse:0;margin-bottom:calc(.5rem*var(--tw-space-y-reverse));margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)))}.twick-player-root .overflow-hidden{overflow:hidden}.twick-player-root .whitespace-nowrap{white-space:nowrap}.twick-player-root .rounded-full{border-radius:9999px}.twick-player-root .bg-gray-100{--tw-bg-opacity:1;background-color:rgb(243 243 243/var(--tw-bg-opacity))}.twick-player-root .bg-gray-300{--tw-bg-opacity:1;background-color:rgb(199 199 199/var(--tw-bg-opacity))}.twick-player-root .bg-gradient-to-t{background-image:linear-gradient(to top,var(--tw-gradient-stops))}.twick-player-root .from-gray-500{--tw-gradient-from:grey var(--tw-gradient-from-position);--tw-gradient-to:hsla(0,0%,50%,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.twick-player-root .to-transparent{--tw-gradient-to:transparent var(--tw-gradient-to-position)}.twick-player-root .p-1{padding:.25rem}.twick-player-root .p-4{padding:1rem}.twick-player-root .text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.twick-player-root .opacity-0{opacity:0}.twick-player-root .opacity-100{opacity:1}.twick-player-root .transition{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1)}.twick-player-root .transition-opacity{transition-duration:.15s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1)}.twick-player-root .duration-200{transition-duration:.2s}.twick-player-root .focus\\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.css"],"sourcesContent":[".twick-player-root{*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }\n /*! tailwindcss v3.4.19 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e5e5;box-sizing:border-box}:after,:before{--tw-content:\"\"}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-tap-highlight-color:transparent}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-size:1em;font-variation-settings:normal}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{color:inherit;font-family:inherit;font-feature-settings:inherit;font-size:100%;font-variation-settings:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#acacac;opacity:1}input::placeholder,textarea::placeholder{color:#acacac;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]:where(:not([hidden=until-found])){display:none}}.twick-player-root .static{position:static}.twick-player-root .absolute{position:absolute}.twick-player-root .relative{position:relative}.twick-player-root .bottom-0{bottom:0}.twick-player-root .left-0{left:0}.twick-player-root .top-0{top:0}.twick-player-root .block{display:block}.twick-player-root .flex{display:flex}.twick-player-root .contents{display:contents}.twick-player-root .h-1\\.5{height:.375rem}.twick-player-root .h-6{height:1.5rem}.twick-player-root .h-full{height:100%}.twick-player-root .w-20{width:5rem}.twick-player-root .w-6{width:1.5rem}.twick-player-root .w-full{width:100%}.twick-player-root .flex-1{flex:1 1 0%}.twick-player-root .flex-grow{flex-grow:1}.twick-player-root .cursor-default{cursor:default}.twick-player-root .cursor-pointer{cursor:pointer}.twick-player-root .flex-col{flex-direction:column}.twick-player-root .items-center{align-items:center}.twick-player-root .justify-center{justify-content:center}.twick-player-root :is(.space-x-2>:not([hidden])~:not([hidden])){--tw-space-x-reverse:0;margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.5rem*var(--tw-space-x-reverse))}.twick-player-root :is(.space-y-2>:not([hidden])~:not([hidden])){--tw-space-y-reverse:0;margin-bottom:calc(.5rem*var(--tw-space-y-reverse));margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)))}.twick-player-root .overflow-hidden{overflow:hidden}.twick-player-root .whitespace-nowrap{white-space:nowrap}.twick-player-root .rounded-full{border-radius:9999px}.twick-player-root .bg-gray-100{--tw-bg-opacity:1;background-color:rgb(243 243 243/var(--tw-bg-opacity,1))}.twick-player-root .bg-gray-300{--tw-bg-opacity:1;background-color:rgb(199 199 199/var(--tw-bg-opacity,1))}.twick-player-root .bg-gradient-to-t{background-image:linear-gradient(to top,var(--tw-gradient-stops))}.twick-player-root .from-gray-500{--tw-gradient-from:grey var(--tw-gradient-from-position);--tw-gradient-to:hsla(0,0%,50%,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.twick-player-root .to-transparent{--tw-gradient-to:transparent var(--tw-gradient-to-position)}.twick-player-root .p-1{padding:.25rem}.twick-player-root .p-4{padding:1rem}.twick-player-root .text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.twick-player-root .opacity-0{opacity:0}.twick-player-root .opacity-100{opacity:1}.twick-player-root .transition{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1)}.twick-player-root .transition-opacity{transition-duration:.15s;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1)}.twick-player-root .duration-200{transition-duration:.2s}.twick-player-root .focus\\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}"],"mappings":"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","names":[]}
package/dist/index.d.cts CHANGED
@@ -3,9 +3,9 @@ import { Project, Player as Player$1 } from '@twick/core';
3
3
  import { ComponentProps } from 'react';
4
4
 
5
5
  interface TwickPlayerProps {
6
- playing?: string;
6
+ playing?: boolean | string;
7
7
  variables?: string;
8
- looping?: string;
8
+ looping?: boolean | string;
9
9
  width?: number;
10
10
  height?: number;
11
11
  quality?: number;
package/dist/index.d.ts CHANGED
@@ -3,9 +3,9 @@ import { Project, Player as Player$1 } from '@twick/core';
3
3
  import { ComponentProps } from 'react';
4
4
 
5
5
  interface TwickPlayerProps {
6
- playing?: string;
6
+ playing?: boolean | string;
7
7
  variables?: string;
8
- looping?: string;
8
+ looping?: boolean | string;
9
9
  width?: number;
10
10
  height?: number;
11
11
  quality?: number;
package/dist/index.js CHANGED
@@ -271,6 +271,7 @@ function Player({
271
271
  const playerRef = useRef(null);
272
272
  const wrapperRef = useRef(null);
273
273
  const lastRect = useRef(null);
274
+ const lastLoggedTimeRef = useRef(null);
274
275
  const onClickHandler = controls ? () => setPlaying((prev) => !prev) : void 0;
275
276
  useEffect(() => {
276
277
  setPlaying(playing);
@@ -284,6 +285,12 @@ function Player({
284
285
  useEffect(() => {
285
286
  setForcedVolume(volume);
286
287
  }, [volume]);
288
+ const variablesJson = JSON.stringify(variables);
289
+ useEffect(() => {
290
+ if (playerRef.current) {
291
+ playerRef.current.setAttribute("variables", variablesJson);
292
+ }
293
+ }, [variablesJson]);
287
294
  const onTimeUpdateRef = useRef(onTimeUpdate);
288
295
  const onDurationChangeRef = useRef(onDurationChange);
289
296
  useEffect(() => {
@@ -294,8 +301,13 @@ function Player({
294
301
  }, [onDurationChange]);
295
302
  const handleTimeUpdate = useCallback((event) => {
296
303
  const e = event;
297
- setCurrentTime(e.detail);
298
- onTimeUpdateRef.current(e.detail);
304
+ const t = e.detail;
305
+ const last = lastLoggedTimeRef.current;
306
+ if (last === null || Math.abs(t - last) > 0.05) {
307
+ lastLoggedTimeRef.current = t;
308
+ }
309
+ setCurrentTime(t);
310
+ onTimeUpdateRef.current(t);
299
311
  }, []);
300
312
  const handleDurationUpdate = useCallback((event) => {
301
313
  const e = event;
@@ -366,7 +378,7 @@ function Player({
366
378
  document.removeEventListener("keydown", handleKeyDown);
367
379
  };
368
380
  };
369
- import("./internal-KYB5ZQ5E.js").then(() => {
381
+ import("./internal-LKI2GAXH.js").then(() => {
370
382
  requestAnimationFrame(() => {
371
383
  if (playerRef.current) {
372
384
  playerRef.current.setProject(project);
@@ -413,15 +425,14 @@ function Player({
413
425
  "twick-player",
414
426
  {
415
427
  ref: playerRef,
416
- playing: String(playingState),
417
- onClick: onClickHandler,
418
- variables: JSON.stringify(variables),
419
- looping: looping ? "true" : "false",
420
- width,
421
- height,
422
428
  quality,
423
429
  fps,
424
- volume: volumeState
430
+ width,
431
+ height,
432
+ volume: volumeState,
433
+ playing: playingState,
434
+ looping,
435
+ onClick: onClickHandler
425
436
  }
426
437
  ),
427
438
  /* @__PURE__ */ jsx3(
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.tsx","../src/controls.tsx","../src/icons.tsx","../src/utils.ts"],"sourcesContent":["'use client';\nimport type {Player as CorePlayer, Project} from '@twick/core';\nimport type {ComponentProps} from 'react';\nimport {useCallback, useEffect, useRef, useState} from 'react';\nimport {Controls} from './controls';\nimport './index.css';\nimport {shouldShowControls} from './utils';\n\ninterface TwickPlayerProps {\n playing?: string;\n variables?: string;\n looping?: string;\n width?: number;\n height?: number;\n quality?: number;\n fps?: number;\n volume?: number;\n}\n\ndeclare global {\n namespace JSX {\n interface IntrinsicElements {\n // eslint-disable-next-line\n 'twick-player': TwickPlayerProps & ComponentProps<'div'>;\n }\n }\n}\n\ninterface PlayerProps {\n project: Project;\n controls?: boolean;\n variables?: Record<string, any>;\n playing?: boolean;\n currentTime?: number;\n volume?: number;\n looping?: boolean;\n fps?: number;\n\n width?: number;\n height?: number;\n quality?: number;\n timeDisplayFormat?: 'MM:SS' | 'MM:SS.mm' | 'MM:SS.m';\n\n onDurationChange?: (duration: number) => void;\n onTimeUpdate?: (currentTime: number) => void;\n onPlayerReady?: (player: CorePlayer) => void;\n onPlayerResize?: (rect: DOMRectReadOnly) => void;\n}\n\nexport function Player({\n project,\n controls = true,\n variables = {},\n playing = false,\n currentTime = 0,\n volume = 1,\n looping = true,\n fps = 30,\n\n width = undefined,\n height = undefined,\n quality = undefined,\n timeDisplayFormat = 'MM:SS',\n\n onDurationChange = () => {},\n onTimeUpdate = () => {},\n onPlayerReady = () => {},\n onPlayerResize = () => {},\n}: PlayerProps) {\n const [playingState, setPlaying] = useState(playing);\n const [isMouseOver, setIsMouseOver] = useState(false);\n const [currentTimeState, setCurrentTime] = useState(currentTime);\n const [volumeState, setVolumeState] = useState(volume);\n const [duration, setDuration] = useState(-1);\n\n const focus = useRef(false);\n const playerRef = useRef<HTMLDivElement | null>(null);\n const wrapperRef = useRef<HTMLDivElement | null>(null);\n const lastRect = useRef<DOMRectReadOnly | null>(null);\n\n const onClickHandler = controls ? () => setPlaying(prev => !prev) : undefined;\n\n /**\n * Sync the playing prop with the player's own state when it changes.\n */\n useEffect(() => {\n setPlaying(playing);\n }, [playing]);\n\n /**\n * Sync the current time with the player's own state.\n */\n useEffect(() => {\n const diff = Math.abs(currentTime - currentTimeState);\n if (diff > 0.05) {\n setForcedTime(currentTime);\n }\n }, [currentTime]);\n\n useEffect(() => {\n setForcedVolume(volume);\n }, [volume]);\n\n /**\n * Receives the current time of the video from the player.\n * Use refs to ensure we always call the latest callbacks.\n */\n const onTimeUpdateRef = useRef(onTimeUpdate);\n const onDurationChangeRef = useRef(onDurationChange);\n \n // Update refs when callbacks change\n useEffect(() => {\n onTimeUpdateRef.current = onTimeUpdate;\n }, [onTimeUpdate]);\n \n useEffect(() => {\n onDurationChangeRef.current = onDurationChange;\n }, [onDurationChange]);\n\n const handleTimeUpdate = useCallback((event: Event) => {\n const e = event as CustomEvent;\n setCurrentTime(e.detail);\n onTimeUpdateRef.current(e.detail);\n }, []);\n\n /**\n * Receives the duration of the video from the player.\n */\n const handleDurationUpdate = useCallback((event: Event) => {\n const e = event as CustomEvent;\n setDuration(e.detail);\n onDurationChangeRef.current(e.detail);\n }, []);\n\n /**\n * Play and pause using the space key.\n */\n const handleKeyDown = useCallback((event: KeyboardEvent) => {\n if (event.code === 'Space' && focus.current) {\n event.preventDefault();\n setPlaying(prev => !prev);\n }\n }, []);\n\n const onPlayerReadyRef = useRef(onPlayerReady);\n \n useEffect(() => {\n onPlayerReadyRef.current = onPlayerReady;\n }, [onPlayerReady]);\n\n const handlePlayerReady = useCallback((event: Event) => {\n const player = (event as CustomEvent).detail;\n if (player) {\n onPlayerReadyRef.current(player);\n }\n \n // Ensure event listeners are attached when player becomes ready\n // This is a fallback in case listeners weren't attached earlier\n const playerElement = playerRef.current;\n if (playerElement) {\n // Remove and re-add to ensure they're attached\n playerElement.removeEventListener('timeupdate', handleTimeUpdate);\n playerElement.removeEventListener('duration', handleDurationUpdate);\n playerElement.addEventListener('timeupdate', handleTimeUpdate);\n playerElement.addEventListener('duration', handleDurationUpdate);\n }\n }, [handleTimeUpdate, handleDurationUpdate]);\n\n const handlePlayerResize = useCallback(\n (entries: ResizeObserverEntry[]) => {\n const [firstEntry] = entries;\n if (!firstEntry || !wrapperRef.current) {\n return;\n }\n\n const newRect = wrapperRef.current.getBoundingClientRect();\n if (\n !lastRect.current ||\n newRect.width !== lastRect.current.width ||\n newRect.height !== lastRect.current.height ||\n newRect.x !== lastRect.current.x ||\n newRect.y !== lastRect.current.y\n ) {\n lastRect.current = newRect;\n onPlayerResize(newRect);\n }\n },\n [onPlayerResize],\n );\n\n useEffect(() => {\n if (!wrapperRef.current) return;\n\n const resizeObserver = new ResizeObserver(handlePlayerResize);\n resizeObserver.observe(wrapperRef.current);\n\n return () => {\n resizeObserver.disconnect();\n };\n }, [handlePlayerResize]);\n\n /**\n * Import the player and add all event listeners.\n */\n useEffect(() => {\n let cleanup: (() => void) | null = null;\n\n const setupListeners = () => {\n const player = playerRef.current;\n if (!player) return;\n\n // Remove any existing listeners first to avoid duplicates\n player.removeEventListener('timeupdate', handleTimeUpdate);\n player.removeEventListener('duration', handleDurationUpdate);\n player.removeEventListener('playerready', handlePlayerReady);\n\n // Add event listeners\n player.addEventListener('timeupdate', handleTimeUpdate);\n player.addEventListener('duration', handleDurationUpdate);\n player.addEventListener('playerready', handlePlayerReady);\n document.addEventListener('keydown', handleKeyDown);\n\n cleanup = () => {\n player.removeEventListener('timeupdate', handleTimeUpdate);\n player.removeEventListener('duration', handleDurationUpdate);\n player.removeEventListener('playerready', handlePlayerReady);\n document.removeEventListener('keydown', handleKeyDown);\n };\n };\n\n // Import the custom element definition\n import('./internal').then(() => {\n // Wait for the next tick to ensure the element is in the DOM\n // Use requestAnimationFrame to ensure the custom element is ready\n requestAnimationFrame(() => {\n if (playerRef.current) {\n (playerRef.current as any).setProject(project);\n // Set up listeners after the element is ready\n setupListeners();\n }\n });\n });\n\n // Also set up listeners immediately if element already exists\n // This handles the case where the element was already in the DOM\n if (playerRef.current) {\n setupListeners();\n }\n\n return () => {\n if (cleanup) {\n cleanup();\n }\n };\n }, [project, handleTimeUpdate, handleDurationUpdate, handlePlayerReady, handleKeyDown]);\n\n /**\n * When the forced time changes, seek to that time.\n */\n function setForcedTime(forcedTime: number) {\n if (playerRef.current) {\n playerRef.current.dispatchEvent(\n new CustomEvent('seekto', {detail: forcedTime}),\n );\n }\n }\n\n function setForcedVolume(volume: number) {\n setVolumeState(volume);\n if (playerRef.current) {\n playerRef.current.dispatchEvent(\n new CustomEvent('volumechange', {detail: volume}),\n );\n }\n }\n\n return (\n <div className=\"twick-player-root w-full h-full\" style={{display: 'contents'}}>\n <div\n ref={wrapperRef}\n className=\"relative cursor-default w-full h-full focus:outline-none\"\n onFocus={() => (focus.current = true)}\n onBlur={() => (focus.current = false)}\n tabIndex={0}\n onMouseEnter={() => setIsMouseOver(true)}\n onMouseLeave={() => setIsMouseOver(false)}\n >\n <div className=\"relative w-full h-full\">\n <twick-player\n ref={playerRef}\n playing={String(playingState)}\n onClick={onClickHandler}\n variables={JSON.stringify(variables)}\n looping={looping ? 'true' : 'false'}\n width={width}\n height={height}\n quality={quality}\n fps={fps}\n volume={volumeState}\n />\n <div\n className={`absolute bottom-0 w-full transition-opacity duration-200 ${\n shouldShowControls(playingState, isMouseOver, !controls)\n ? 'opacity-100'\n : 'opacity-0'\n }`}\n >\n <Controls\n duration={duration}\n playing={playingState}\n setPlaying={setPlaying}\n currentTime={currentTimeState}\n setForcedTime={setForcedTime}\n timeDisplayFormat={timeDisplayFormat}\n volume={volumeState}\n setVolume={setForcedVolume}\n />\n </div>\n </div>\n </div>\n </div>\n );\n}\n","import {useState} from 'react';\nimport {MutedSoundIcon, PauseButton, PlayButton, SoundIcon} from './icons';\nimport {getFormattedTime} from './utils';\n\nfunction PlayPause({\n playing,\n setPlaying,\n}: {\n playing: boolean;\n setPlaying: (playing: boolean) => void;\n}) {\n return (\n <button type=\"button\" className=\"p-1\" onClick={() => setPlaying(!playing)}>\n {playing ? <PauseButton /> : <PlayButton />}\n </button>\n );\n}\n\nfunction VolumeSlider({\n volume,\n setVolume,\n}: {\n volume: number;\n setVolume: (volume: number) => void;\n}) {\n const [isHovering, setIsHovering] = useState(false);\n const [isInteracting, setIsInteracting] = useState(false);\n const [previousVolume, setPreviousVolume] = useState(1);\n\n const handleIconClick = () => {\n if (volume > 0) {\n setPreviousVolume(volume);\n setVolume(0);\n } else {\n setVolume(previousVolume);\n }\n };\n\n return (\n <div\n className=\"flex items-center space-x-2 relative\"\n onMouseEnter={() => setIsHovering(true)}\n onMouseLeave={() => {\n if (!isInteracting) {\n setIsHovering(false);\n }\n }}\n >\n <div\n className=\"w-6 h-6 flex items-center justify-center cursor-pointer\"\n onClick={handleIconClick}\n >\n {volume === 0 ? <MutedSoundIcon /> : <SoundIcon />}\n </div>\n {(isHovering || isInteracting) && (\n <div className=\"flex items-center h-1.5 whitespace-nowrap\">\n <div className=\"relative w-20 h-1.5 bg-gray-300 rounded-full\">\n <div\n className=\"absolute top-0 left-0 h-full bg-gray-100 rounded-full\"\n style={{width: `${volume * 100}%`}}\n />\n <input\n type=\"range\"\n min={0}\n max={1}\n step={0.01}\n value={volume}\n onChange={e => {\n const newVolume = Number(e.target.value);\n setVolume(newVolume);\n if (newVolume > 0) {\n setPreviousVolume(newVolume);\n }\n }}\n onMouseDown={() => setIsInteracting(true)}\n onMouseUp={() => setIsInteracting(false)}\n onMouseLeave={() => setIsInteracting(false)}\n className=\"absolute top-0 left-0 w-full h-full opacity-0 cursor-pointer\"\n />\n </div>\n </div>\n )}\n </div>\n );\n}\n\nfunction Timeline({\n currentTime,\n duration,\n setCurrentTime,\n}: {\n currentTime: number;\n duration: number;\n setCurrentTime: (currentTime: number) => void;\n}) {\n const progressPercentage = (currentTime / duration) * 100;\n\n return (\n <div className=\"relative flex-1 w-full h-1.5 bg-gray-300 rounded-full overflow-hidden\">\n <div\n className=\"absolute top-0 left-0 h-full bg-gray-100\"\n style={{width: `${progressPercentage}%`}}\n />\n <input\n type=\"range\"\n value={currentTime}\n min={0}\n max={duration}\n step={0.01}\n className=\"absolute top-0 left-0 w-full h-full opacity-0 cursor-pointer\"\n onChange={event => setCurrentTime(Number(event.target.value))}\n />\n </div>\n );\n}\n\nexport function Controls({\n duration,\n playing,\n setPlaying,\n currentTime,\n setForcedTime,\n timeDisplayFormat,\n volume,\n setVolume,\n}: {\n duration: number;\n playing: boolean;\n setPlaying: (playing: boolean) => void;\n currentTime: number;\n setForcedTime: (currentTime: number) => void;\n timeDisplayFormat: 'MM:SS' | 'MM:SS.m' | 'MM:SS.mm';\n volume: number;\n setVolume: (volume: number) => void;\n}) {\n return (\n <div className=\"text-white p-4 flex-col space-y-2 bg-gradient-to-t from-gray-500 to-transparent\">\n <div className=\"flex items-center space-x-2\">\n <PlayPause playing={playing} setPlaying={setPlaying} />\n <div className=\"flex items-center space-x-2\">\n <VolumeSlider volume={volume} setVolume={setVolume} />\n <div>\n <span>\n {getFormattedTime(currentTime, duration, timeDisplayFormat)}\n </span>\n </div>\n </div>\n <div className=\"flex-grow\" />\n </div>\n <Timeline\n currentTime={currentTime}\n duration={duration}\n setCurrentTime={setForcedTime}\n />\n </div>\n );\n}\n","export function PlayButton() {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n className=\"w-6 h-6\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M4.5 5.653c0-1.427 1.529-2.33 2.779-1.643l11.54 6.347c1.295.712 1.295 2.573 0 3.286L7.28 19.99c-1.25.687-2.779-.217-2.779-1.643V5.653Z\"\n clipRule=\"evenodd\"\n />\n </svg>\n );\n}\n\nexport function PauseButton() {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n className=\"w-6 h-6\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M6.75 5.25a.75.75 0 0 1 .75-.75H9a.75.75 0 0 1 .75.75v13.5a.75.75 0 0 1-.75.75H7.5a.75.75 0 0 1-.75-.75V5.25Zm7.5 0A.75.75 0 0 1 15 4.5h1.5a.75.75 0 0 1 .75.75v13.5a.75.75 0 0 1-.75.75H15a.75.75 0 0 1-.75-.75V5.25Z\"\n clipRule=\"evenodd\"\n />\n </svg>\n );\n}\n\nexport function SoundIcon() {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n className=\"p-w-6 p-h-6\"\n >\n <path d=\"M18.36,19.36a1,1,0,0,1-.7-.29,1,1,0,0,1,0-1.41,8,8,0,0,0,0-11.32,1,1,0,0,1,1.41-1.41,10,10,0,0,1,0,14.14A1,1,0,0,1,18.36,19.36Z\" />\n <path d=\"M15.54,16.54a1,1,0,0,1-.71-.3,1,1,0,0,1,0-1.41,4,4,0,0,0,0-5.66,1,1,0,0,1,1.41-1.41,6,6,0,0,1,0,8.48A1,1,0,0,1,15.54,16.54Z\" />\n <path d=\"M11.38,4.08a1,1,0,0,0-1.09.21L6.59,8H4a2,2,0,0,0-2,2v4a2,2,0,0,0,2,2H6.59l3.7,3.71A1,1,0,0,0,11,20a.84.84,0,0,0,.38-.08A1,1,0,0,0,12,19V5A1,1,0,0,0,11.38,4.08Z\" />\n </svg>\n );\n}\n\nexport function MutedSoundIcon() {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n className=\"p-w-6 p-h-6\"\n >\n <path d=\"M11.38,4.08a1,1,0,0,0-1.09.21L6.59,8H4a2,2,0,0,0-2,2v4a2,2,0,0,0,2,2H6.59l3.7,3.71A1,1,0,0,0,11,20a.84.84,0,0,0,.38-.08A1,1,0,0,0,12,19V5A1,1,0,0,0,11.38,4.08Z\" />\n <path d=\"M16,15.5a1,1,0,0,1-.71-.29,1,1,0,0,1,0-1.42l5-5a1,1,0,0,1,1.42,1.42l-5,5A1,1,0,0,1,16,15.5Z\" />\n <path d=\"M21,15.5a1,1,0,0,1-.71-.29l-5-5a1,1,0,0,1,1.42-1.42l5,5a1,1,0,0,1,0,1.42A1,1,0,0,1,21,15.5Z\" />\n </svg>\n );\n}\n","export function getFormattedTime(\n timeInSeconds: number,\n absoluteTimeInSeconds: number,\n timeDisplayFormat: 'MM:SS' | 'MM:SS.mm' | 'MM:SS.m',\n) {\n function toFormattedTime(timeInSeconds: number) {\n const minutes = Math.floor(timeInSeconds / 60);\n const seconds = Math.floor(timeInSeconds % 60)\n .toString()\n .padStart(2, '0');\n const milliseconds = Math.floor((timeInSeconds % 1) * 1000)\n .toString()\n .padStart(3, '0');\n\n if (timeDisplayFormat === 'MM:SS') {\n return `${minutes}:${seconds}`;\n }\n\n if (timeDisplayFormat === 'MM:SS.m') {\n return `${minutes}:${seconds}.${milliseconds[0]}`;\n }\n\n if (timeDisplayFormat === 'MM:SS.mm') {\n return `${minutes}:${seconds}.${milliseconds.slice(0, 2)}`;\n }\n }\n\n return `${toFormattedTime(timeInSeconds)} / ${toFormattedTime(absoluteTimeInSeconds)}`;\n}\n\nexport function shouldShowControls(\n playing: boolean,\n isMouseOver: boolean,\n areControlsDisabled: boolean,\n) {\n if (areControlsDisabled) {\n return false;\n }\n\n return !playing || isMouseOver;\n}\n"],"mappings":"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","names":["useState","timeInSeconds","jsx","jsxs","jsx","jsxs","useState","volume"]}
1
+ {"version":3,"sources":["../src/index.tsx","../src/controls.tsx","../src/icons.tsx","../src/utils.ts"],"sourcesContent":["'use client';\nimport type {Player as CorePlayer, Project} from '@twick/core';\nimport type {ComponentProps} from 'react';\nimport {useCallback, useEffect, useRef, useState} from 'react';\nimport {Controls} from './controls';\nimport './index.css';\nimport {shouldShowControls} from './utils';\n\ninterface TwickPlayerProps {\n playing?: boolean | string;\n variables?: string;\n looping?: boolean | string;\n width?: number;\n height?: number;\n quality?: number;\n fps?: number;\n volume?: number;\n}\n\ndeclare global {\n namespace JSX {\n interface IntrinsicElements {\n // eslint-disable-next-line\n 'twick-player': TwickPlayerProps & ComponentProps<'div'>;\n }\n }\n}\n\ninterface PlayerProps {\n project: Project;\n controls?: boolean;\n variables?: Record<string, any>;\n playing?: boolean;\n currentTime?: number;\n volume?: number;\n looping?: boolean;\n fps?: number;\n\n width?: number;\n height?: number;\n quality?: number;\n timeDisplayFormat?: 'MM:SS' | 'MM:SS.mm' | 'MM:SS.m';\n\n onDurationChange?: (duration: number) => void;\n onTimeUpdate?: (currentTime: number) => void;\n onPlayerReady?: (player: CorePlayer) => void;\n onPlayerResize?: (rect: DOMRectReadOnly) => void;\n}\n\nexport function Player({\n project,\n controls = true,\n variables = {},\n playing = false,\n currentTime = 0,\n volume = 1,\n looping = true,\n fps = 30,\n\n width = undefined,\n height = undefined,\n quality = undefined,\n timeDisplayFormat = 'MM:SS',\n\n onDurationChange = () => {},\n onTimeUpdate = () => {},\n onPlayerReady = () => {},\n onPlayerResize = () => {},\n}: PlayerProps) {\n const [playingState, setPlaying] = useState(playing);\n const [isMouseOver, setIsMouseOver] = useState(false);\n const [currentTimeState, setCurrentTime] = useState(currentTime);\n const [volumeState, setVolumeState] = useState(volume);\n const [duration, setDuration] = useState(-1);\n\n const focus = useRef(false);\n const playerRef = useRef<HTMLDivElement | null>(null);\n const wrapperRef = useRef<HTMLDivElement | null>(null);\n const lastRect = useRef<DOMRectReadOnly | null>(null);\n const lastLoggedTimeRef = useRef<number | null>(null);\n\n const onClickHandler = controls ? () => setPlaying(prev => !prev) : undefined;\n\n /**\n * Sync the playing prop with the player's own state when it changes.\n */\n useEffect(() => {\n setPlaying(playing);\n }, [playing]);\n\n /**\n * Sync the current time with the player's own state.\n */\n useEffect(() => {\n const diff = Math.abs(currentTime - currentTimeState);\n if (diff > 0.05) {\n setForcedTime(currentTime);\n }\n }, [currentTime]);\n\n useEffect(() => {\n setForcedVolume(volume);\n }, [volume]);\n\n /**\n * Set variables via setAttribute - the twick-player custom element's variables\n * property is read-only (getter only). React would fail if we passed it as a prop.\n */\n const variablesJson = JSON.stringify(variables);\n useEffect(() => {\n if (playerRef.current) {\n playerRef.current.setAttribute('variables', variablesJson);\n }\n }, [variablesJson]);\n\n /**\n * Receives the current time of the video from the player.\n * Use refs to ensure we always call the latest callbacks.\n */\n const onTimeUpdateRef = useRef(onTimeUpdate);\n const onDurationChangeRef = useRef(onDurationChange);\n \n // Update refs when callbacks change\n useEffect(() => {\n onTimeUpdateRef.current = onTimeUpdate;\n }, [onTimeUpdate]);\n \n useEffect(() => {\n onDurationChangeRef.current = onDurationChange;\n }, [onDurationChange]);\n\n const handleTimeUpdate = useCallback((event: Event) => {\n const e = event as CustomEvent;\n const t = e.detail as number;\n const last = lastLoggedTimeRef.current;\n if (last === null || Math.abs(t - last) > 0.05) {\n lastLoggedTimeRef.current = t;\n }\n setCurrentTime(t);\n onTimeUpdateRef.current(t);\n }, []);\n\n /**\n * Receives the duration of the video from the player.\n */\n const handleDurationUpdate = useCallback((event: Event) => {\n const e = event as CustomEvent;\n setDuration(e.detail);\n onDurationChangeRef.current(e.detail);\n }, []);\n\n /**\n * Play and pause using the space key.\n */\n const handleKeyDown = useCallback((event: KeyboardEvent) => {\n if (event.code === 'Space' && focus.current) {\n event.preventDefault();\n setPlaying(prev => !prev);\n }\n }, []);\n\n const onPlayerReadyRef = useRef(onPlayerReady);\n \n useEffect(() => {\n onPlayerReadyRef.current = onPlayerReady;\n }, [onPlayerReady]);\n\n const handlePlayerReady = useCallback((event: Event) => {\n const player = (event as CustomEvent).detail;\n if (player) {\n onPlayerReadyRef.current(player);\n }\n \n // Ensure event listeners are attached when player becomes ready\n // This is a fallback in case listeners weren't attached earlier\n const playerElement = playerRef.current;\n if (playerElement) {\n // Remove and re-add to ensure they're attached\n playerElement.removeEventListener('timeupdate', handleTimeUpdate);\n playerElement.removeEventListener('duration', handleDurationUpdate);\n playerElement.addEventListener('timeupdate', handleTimeUpdate);\n playerElement.addEventListener('duration', handleDurationUpdate);\n }\n }, [handleTimeUpdate, handleDurationUpdate]);\n\n const handlePlayerResize = useCallback(\n (entries: ResizeObserverEntry[]) => {\n const [firstEntry] = entries;\n if (!firstEntry || !wrapperRef.current) {\n return;\n }\n\n const newRect = wrapperRef.current.getBoundingClientRect();\n if (\n !lastRect.current ||\n newRect.width !== lastRect.current.width ||\n newRect.height !== lastRect.current.height ||\n newRect.x !== lastRect.current.x ||\n newRect.y !== lastRect.current.y\n ) {\n lastRect.current = newRect;\n onPlayerResize(newRect);\n }\n },\n [onPlayerResize],\n );\n\n useEffect(() => {\n if (!wrapperRef.current) return;\n\n const resizeObserver = new ResizeObserver(handlePlayerResize);\n resizeObserver.observe(wrapperRef.current);\n\n return () => {\n resizeObserver.disconnect();\n };\n }, [handlePlayerResize]);\n\n /**\n * Import the player and add all event listeners.\n */\n useEffect(() => {\n let cleanup: (() => void) | null = null;\n\n const setupListeners = () => {\n const player = playerRef.current;\n if (!player) return;\n\n // Remove any existing listeners first to avoid duplicates\n player.removeEventListener('timeupdate', handleTimeUpdate);\n player.removeEventListener('duration', handleDurationUpdate);\n player.removeEventListener('playerready', handlePlayerReady);\n\n // Add event listeners\n player.addEventListener('timeupdate', handleTimeUpdate);\n player.addEventListener('duration', handleDurationUpdate);\n player.addEventListener('playerready', handlePlayerReady);\n document.addEventListener('keydown', handleKeyDown);\n\n cleanup = () => {\n player.removeEventListener('timeupdate', handleTimeUpdate);\n player.removeEventListener('duration', handleDurationUpdate);\n player.removeEventListener('playerready', handlePlayerReady);\n document.removeEventListener('keydown', handleKeyDown);\n };\n };\n\n // Import the custom element definition\n import('./internal').then(() => {\n // Wait for the next tick to ensure the element is in the DOM\n // Use requestAnimationFrame to ensure the custom element is ready\n requestAnimationFrame(() => {\n if (playerRef.current) {\n (playerRef.current as any).setProject(project);\n // Set up listeners after the element is ready\n setupListeners();\n }\n });\n });\n\n // Also set up listeners immediately if element already exists\n // This handles the case where the element was already in the DOM\n if (playerRef.current) {\n setupListeners();\n }\n\n return () => {\n if (cleanup) {\n cleanup();\n }\n };\n }, [project, handleTimeUpdate, handleDurationUpdate, handlePlayerReady, handleKeyDown]);\n\n /**\n * When the forced time changes, seek to that time.\n */\n function setForcedTime(forcedTime: number) {\n if (playerRef.current) {\n playerRef.current.dispatchEvent(\n new CustomEvent('seekto', {detail: forcedTime}),\n );\n }\n }\n\n function setForcedVolume(volume: number) {\n setVolumeState(volume);\n if (playerRef.current) {\n playerRef.current.dispatchEvent(\n new CustomEvent('volumechange', {detail: volume}),\n );\n }\n }\n\n return (\n <div className=\"twick-player-root w-full h-full\" style={{display: 'contents'}}>\n <div\n ref={wrapperRef}\n className=\"relative cursor-default w-full h-full focus:outline-none\"\n onFocus={() => (focus.current = true)}\n onBlur={() => (focus.current = false)}\n tabIndex={0}\n onMouseEnter={() => setIsMouseOver(true)}\n onMouseLeave={() => setIsMouseOver(false)}\n >\n <div className=\"relative w-full h-full\">\n <twick-player\n ref={playerRef}\n quality={quality}\n fps={fps}\n width={width}\n height={height}\n volume={volumeState}\n playing={playingState}\n looping={looping}\n onClick={onClickHandler}\n />\n <div\n className={`absolute bottom-0 w-full transition-opacity duration-200 ${\n shouldShowControls(playingState, isMouseOver, !controls)\n ? 'opacity-100'\n : 'opacity-0'\n }`}\n >\n <Controls\n duration={duration}\n playing={playingState}\n setPlaying={setPlaying}\n currentTime={currentTimeState}\n setForcedTime={setForcedTime}\n timeDisplayFormat={timeDisplayFormat}\n volume={volumeState}\n setVolume={setForcedVolume}\n />\n </div>\n </div>\n </div>\n </div>\n );\n}\n","import {useState} from 'react';\nimport {MutedSoundIcon, PauseButton, PlayButton, SoundIcon} from './icons';\nimport {getFormattedTime} from './utils';\n\nfunction PlayPause({\n playing,\n setPlaying,\n}: {\n playing: boolean;\n setPlaying: (playing: boolean) => void;\n}) {\n return (\n <button type=\"button\" className=\"p-1\" onClick={() => setPlaying(!playing)}>\n {playing ? <PauseButton /> : <PlayButton />}\n </button>\n );\n}\n\nfunction VolumeSlider({\n volume,\n setVolume,\n}: {\n volume: number;\n setVolume: (volume: number) => void;\n}) {\n const [isHovering, setIsHovering] = useState(false);\n const [isInteracting, setIsInteracting] = useState(false);\n const [previousVolume, setPreviousVolume] = useState(1);\n\n const handleIconClick = () => {\n if (volume > 0) {\n setPreviousVolume(volume);\n setVolume(0);\n } else {\n setVolume(previousVolume);\n }\n };\n\n return (\n <div\n className=\"flex items-center space-x-2 relative\"\n onMouseEnter={() => setIsHovering(true)}\n onMouseLeave={() => {\n if (!isInteracting) {\n setIsHovering(false);\n }\n }}\n >\n <div\n className=\"w-6 h-6 flex items-center justify-center cursor-pointer\"\n onClick={handleIconClick}\n >\n {volume === 0 ? <MutedSoundIcon /> : <SoundIcon />}\n </div>\n {(isHovering || isInteracting) && (\n <div className=\"flex items-center h-1.5 whitespace-nowrap\">\n <div className=\"relative w-20 h-1.5 bg-gray-300 rounded-full\">\n <div\n className=\"absolute top-0 left-0 h-full bg-gray-100 rounded-full\"\n style={{width: `${volume * 100}%`}}\n />\n <input\n type=\"range\"\n min={0}\n max={1}\n step={0.01}\n value={volume}\n onChange={e => {\n const newVolume = Number(e.target.value);\n setVolume(newVolume);\n if (newVolume > 0) {\n setPreviousVolume(newVolume);\n }\n }}\n onMouseDown={() => setIsInteracting(true)}\n onMouseUp={() => setIsInteracting(false)}\n onMouseLeave={() => setIsInteracting(false)}\n className=\"absolute top-0 left-0 w-full h-full opacity-0 cursor-pointer\"\n />\n </div>\n </div>\n )}\n </div>\n );\n}\n\nfunction Timeline({\n currentTime,\n duration,\n setCurrentTime,\n}: {\n currentTime: number;\n duration: number;\n setCurrentTime: (currentTime: number) => void;\n}) {\n const progressPercentage = (currentTime / duration) * 100;\n\n return (\n <div className=\"relative flex-1 w-full h-1.5 bg-gray-300 rounded-full overflow-hidden\">\n <div\n className=\"absolute top-0 left-0 h-full bg-gray-100\"\n style={{width: `${progressPercentage}%`}}\n />\n <input\n type=\"range\"\n value={currentTime}\n min={0}\n max={duration}\n step={0.01}\n className=\"absolute top-0 left-0 w-full h-full opacity-0 cursor-pointer\"\n onChange={event => setCurrentTime(Number(event.target.value))}\n />\n </div>\n );\n}\n\nexport function Controls({\n duration,\n playing,\n setPlaying,\n currentTime,\n setForcedTime,\n timeDisplayFormat,\n volume,\n setVolume,\n}: {\n duration: number;\n playing: boolean;\n setPlaying: (playing: boolean) => void;\n currentTime: number;\n setForcedTime: (currentTime: number) => void;\n timeDisplayFormat: 'MM:SS' | 'MM:SS.m' | 'MM:SS.mm';\n volume: number;\n setVolume: (volume: number) => void;\n}) {\n return (\n <div className=\"text-white p-4 flex-col space-y-2 bg-gradient-to-t from-gray-500 to-transparent\">\n <div className=\"flex items-center space-x-2\">\n <PlayPause playing={playing} setPlaying={setPlaying} />\n <div className=\"flex items-center space-x-2\">\n <VolumeSlider volume={volume} setVolume={setVolume} />\n <div>\n <span>\n {getFormattedTime(currentTime, duration, timeDisplayFormat)}\n </span>\n </div>\n </div>\n <div className=\"flex-grow\" />\n </div>\n <Timeline\n currentTime={currentTime}\n duration={duration}\n setCurrentTime={setForcedTime}\n />\n </div>\n );\n}\n","export function PlayButton() {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n className=\"w-6 h-6\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M4.5 5.653c0-1.427 1.529-2.33 2.779-1.643l11.54 6.347c1.295.712 1.295 2.573 0 3.286L7.28 19.99c-1.25.687-2.779-.217-2.779-1.643V5.653Z\"\n clipRule=\"evenodd\"\n />\n </svg>\n );\n}\n\nexport function PauseButton() {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n className=\"w-6 h-6\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M6.75 5.25a.75.75 0 0 1 .75-.75H9a.75.75 0 0 1 .75.75v13.5a.75.75 0 0 1-.75.75H7.5a.75.75 0 0 1-.75-.75V5.25Zm7.5 0A.75.75 0 0 1 15 4.5h1.5a.75.75 0 0 1 .75.75v13.5a.75.75 0 0 1-.75.75H15a.75.75 0 0 1-.75-.75V5.25Z\"\n clipRule=\"evenodd\"\n />\n </svg>\n );\n}\n\nexport function SoundIcon() {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n className=\"p-w-6 p-h-6\"\n >\n <path d=\"M18.36,19.36a1,1,0,0,1-.7-.29,1,1,0,0,1,0-1.41,8,8,0,0,0,0-11.32,1,1,0,0,1,1.41-1.41,10,10,0,0,1,0,14.14A1,1,0,0,1,18.36,19.36Z\" />\n <path d=\"M15.54,16.54a1,1,0,0,1-.71-.3,1,1,0,0,1,0-1.41,4,4,0,0,0,0-5.66,1,1,0,0,1,1.41-1.41,6,6,0,0,1,0,8.48A1,1,0,0,1,15.54,16.54Z\" />\n <path d=\"M11.38,4.08a1,1,0,0,0-1.09.21L6.59,8H4a2,2,0,0,0-2,2v4a2,2,0,0,0,2,2H6.59l3.7,3.71A1,1,0,0,0,11,20a.84.84,0,0,0,.38-.08A1,1,0,0,0,12,19V5A1,1,0,0,0,11.38,4.08Z\" />\n </svg>\n );\n}\n\nexport function MutedSoundIcon() {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n className=\"p-w-6 p-h-6\"\n >\n <path d=\"M11.38,4.08a1,1,0,0,0-1.09.21L6.59,8H4a2,2,0,0,0-2,2v4a2,2,0,0,0,2,2H6.59l3.7,3.71A1,1,0,0,0,11,20a.84.84,0,0,0,.38-.08A1,1,0,0,0,12,19V5A1,1,0,0,0,11.38,4.08Z\" />\n <path d=\"M16,15.5a1,1,0,0,1-.71-.29,1,1,0,0,1,0-1.42l5-5a1,1,0,0,1,1.42,1.42l-5,5A1,1,0,0,1,16,15.5Z\" />\n <path d=\"M21,15.5a1,1,0,0,1-.71-.29l-5-5a1,1,0,0,1,1.42-1.42l5,5a1,1,0,0,1,0,1.42A1,1,0,0,1,21,15.5Z\" />\n </svg>\n );\n}\n","export function getFormattedTime(\n timeInSeconds: number,\n absoluteTimeInSeconds: number,\n timeDisplayFormat: 'MM:SS' | 'MM:SS.mm' | 'MM:SS.m',\n) {\n function toFormattedTime(timeInSeconds: number) {\n const minutes = Math.floor(timeInSeconds / 60);\n const seconds = Math.floor(timeInSeconds % 60)\n .toString()\n .padStart(2, '0');\n const milliseconds = Math.floor((timeInSeconds % 1) * 1000)\n .toString()\n .padStart(3, '0');\n\n if (timeDisplayFormat === 'MM:SS') {\n return `${minutes}:${seconds}`;\n }\n\n if (timeDisplayFormat === 'MM:SS.m') {\n return `${minutes}:${seconds}.${milliseconds[0]}`;\n }\n\n if (timeDisplayFormat === 'MM:SS.mm') {\n return `${minutes}:${seconds}.${milliseconds.slice(0, 2)}`;\n }\n }\n\n return `${toFormattedTime(timeInSeconds)} / ${toFormattedTime(absoluteTimeInSeconds)}`;\n}\n\nexport function shouldShowControls(\n playing: boolean,\n isMouseOver: boolean,\n areControlsDisabled: boolean,\n) {\n if (areControlsDisabled) {\n return false;\n }\n\n return !playing || isMouseOver;\n}\n"],"mappings":"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","names":["useState","timeInSeconds","jsx","jsxs","jsx","jsxs","useState","volume"]}
@@ -42,10 +42,20 @@ var TwickPlayer = class extends HTMLElement {
42
42
  const attr = this.getAttribute("fps");
43
43
  return attr ? parseFloat(attr) : this.defaultSettings?.fps ?? 60;
44
44
  }
45
+ set fps(value) {
46
+ if (value != null && Number.isFinite(value)) {
47
+ this.setAttribute("fps", String(value));
48
+ }
49
+ }
45
50
  get quality() {
46
51
  const attr = this.getAttribute("quality");
47
52
  return attr ? parseFloat(attr) : this.defaultSettings?.resolutionScale ?? 1;
48
53
  }
54
+ set quality(value) {
55
+ if (value != null && Number.isFinite(value)) {
56
+ this.setAttribute("quality", String(value));
57
+ }
58
+ }
49
59
  get width() {
50
60
  const attr = this.getAttribute("width");
51
61
  return attr ? parseFloat(attr) : this.defaultSettings?.size.width ?? 0;
@@ -73,6 +83,26 @@ var TwickPlayer = class extends HTMLElement {
73
83
  return {};
74
84
  }
75
85
  }
86
+ get volume() {
87
+ return this._volume;
88
+ }
89
+ set volume(value) {
90
+ if (value != null) {
91
+ this.setAttribute("volume", String(value));
92
+ }
93
+ }
94
+ set playing(value) {
95
+ this.setAttribute(
96
+ "playing",
97
+ value === true || value === "true" ? "true" : "false"
98
+ );
99
+ }
100
+ set looping(value) {
101
+ this.setAttribute(
102
+ "looping",
103
+ value === true || value === "true" ? "true" : "false"
104
+ );
105
+ }
76
106
  root;
77
107
  canvas;
78
108
  overlay;
@@ -81,13 +111,13 @@ var TwickPlayer = class extends HTMLElement {
81
111
  player = null;
82
112
  defaultSettings;
83
113
  abortController = null;
84
- playing = false;
114
+ _playing = false;
85
115
  stage = new Stage();
86
116
  time = 0;
87
117
  duration = 0;
88
118
  // in frames
89
- looping = true;
90
- volume = 1;
119
+ _looping = true;
120
+ _volume = 1;
91
121
  volumeChangeRequested = true;
92
122
  constructor() {
93
123
  super();
@@ -104,19 +134,19 @@ var TwickPlayer = class extends HTMLElement {
104
134
  }
105
135
  setState(state) {
106
136
  this.state = state;
107
- this.setPlaying(this.playing);
137
+ this.setPlaying(this._playing);
108
138
  }
109
139
  setPlaying(value) {
110
140
  if (this.state === "ready" /* Ready */ && value) {
111
141
  this.player?.togglePlayback(true);
112
- this.playing = true;
142
+ this._playing = true;
113
143
  } else {
114
144
  this.player?.togglePlayback(false);
115
- this.playing = false;
145
+ this._playing = false;
116
146
  }
117
147
  }
118
148
  async updateProject(project) {
119
- const playing = this.playing;
149
+ const playing = this._playing;
120
150
  this.setState("initial" /* Initial */);
121
151
  this.abortController?.abort();
122
152
  this.abortController = new AbortController();
@@ -124,7 +154,7 @@ var TwickPlayer = class extends HTMLElement {
124
154
  this.defaultSettings = getFullPreviewSettings(this.project);
125
155
  const player = new Player(this.project);
126
156
  player.setVariables(this.variables);
127
- player.toggleLoop(this.looping);
157
+ player.toggleLoop(this._looping);
128
158
  this.player?.onRender.unsubscribe(this.render);
129
159
  this.player?.onFrameChanged.unsubscribe(this.handleFrameChanged);
130
160
  this.player?.togglePlayback(false);
@@ -148,7 +178,7 @@ var TwickPlayer = class extends HTMLElement {
148
178
  this.player?.playback.reload();
149
179
  break;
150
180
  case "looping":
151
- this.looping = newValue === "true";
181
+ this._looping = newValue === "true";
152
182
  this.player?.toggleLoop(newValue === "true");
153
183
  break;
154
184
  case "fps":
@@ -158,7 +188,7 @@ var TwickPlayer = class extends HTMLElement {
158
188
  this.updateSettings();
159
189
  break;
160
190
  case "volume":
161
- this.volume = newValue;
191
+ this._volume = newValue;
162
192
  this.volumeChangeRequested = true;
163
193
  }
164
194
  }
@@ -188,8 +218,10 @@ var TwickPlayer = class extends HTMLElement {
188
218
  return;
189
219
  }
190
220
  const e = event;
191
- this.time = e.detail;
192
- this.player?.requestSeek(e.detail * this.player.playback.fps);
221
+ const timeSec = e.detail;
222
+ const frame = timeSec * this.player.playback.fps;
223
+ this.time = timeSec;
224
+ this.player?.requestSeek(frame);
193
225
  this.volumeChangeRequested = true;
194
226
  };
195
227
  handleVolumeChange = (event) => {
@@ -197,8 +229,8 @@ var TwickPlayer = class extends HTMLElement {
197
229
  return;
198
230
  }
199
231
  const e = event;
200
- this.volume = e.detail;
201
- this.player?.playback.currentScene.adjustVolume(this.volume);
232
+ this._volume = e.detail;
233
+ this.player?.playback.currentScene.adjustVolume(this._volume);
202
234
  };
203
235
  /**
204
236
  * Triggered by the player.
@@ -209,7 +241,7 @@ var TwickPlayer = class extends HTMLElement {
209
241
  }
210
242
  this.time = frame / this.player.playback.fps;
211
243
  if (this.volumeChangeRequested || frame === 0) {
212
- this.player?.playback.currentScene.adjustVolume(this.volume);
244
+ this.player?.playback.currentScene.adjustVolume(this._volume);
213
245
  this.volumeChangeRequested = false;
214
246
  }
215
247
  };
@@ -252,4 +284,4 @@ var TwickPlayer = class extends HTMLElement {
252
284
  if (!customElements.get(ID)) {
253
285
  customElements.define(ID, TwickPlayer);
254
286
  }
255
- //# sourceMappingURL=internal-KYB5ZQ5E.js.map
287
+ //# sourceMappingURL=internal-LKI2GAXH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/internal.ts"],"sourcesContent":["import type {Project} from '@twick/core';\nimport {Player, Stage, getFullPreviewSettings} from '@twick/core';\n\nimport {Vector2} from '@twick/core';\n\nconst stylesNew = `\n.overlay {\n\tposition: absolute;\n\tleft: 0;\n\tright: 0;\n\ttop: 0;\n\tbottom: 0;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\topacity: 0;\n\ttransition: opacity 0.1s;\n\tz-index: 0;\n }\n .canvas {\n\twidth: 100%;\n\theight: 100%;\n\tdisplay: block;\n\topacity: 1;\n\ttransition: opacity 0.1s;\n }\n`;\n\nconst TEMPLATE = `<style>${stylesNew}</style><div class=\"overlay\"></div>`;\nconst ID = 'twick-player';\n\nenum State {\n Initial = 'initial',\n Loading = 'loading',\n Ready = 'ready',\n Error = 'error',\n}\n\nclass TwickPlayer extends HTMLElement {\n public static get observedAttributes() {\n return [\n 'playing',\n 'variables',\n 'looping',\n 'fps',\n 'quality',\n 'width',\n 'height',\n 'volume',\n ];\n }\n\n public get fps() {\n const attr = this.getAttribute('fps');\n return attr ? parseFloat(attr) : (this.defaultSettings?.fps ?? 60);\n }\n\n public set fps(value: number) {\n if (value != null && Number.isFinite(value)) {\n this.setAttribute('fps', String(value));\n }\n }\n\n public get quality() {\n const attr = this.getAttribute('quality');\n return attr\n ? parseFloat(attr)\n : (this.defaultSettings?.resolutionScale ?? 1);\n }\n\n public set quality(value: number) {\n if (value != null && Number.isFinite(value)) {\n this.setAttribute('quality', String(value));\n }\n }\n\n public get width() {\n const attr = this.getAttribute('width');\n return attr ? parseFloat(attr) : (this.defaultSettings?.size.width ?? 0);\n }\n\n public set width(value: number) {\n if (Number.isFinite(value)) {\n this.setAttribute('width', String(value));\n }\n }\n\n public get height() {\n const attr = this.getAttribute('height');\n return attr ? parseFloat(attr) : (this.defaultSettings?.size.height ?? 0);\n }\n\n public set height(value: number) {\n if (Number.isFinite(value)) {\n this.setAttribute('height', String(value));\n }\n }\n\n private get variables() {\n try {\n const attr = this.getAttribute('variables');\n return attr ? JSON.parse(attr) : {};\n } catch {\n this.project?.logger.warn(`Project variables could not be parsed.`);\n return {};\n }\n }\n\n public get volume() {\n return this._volume;\n }\n\n public set volume(value: number) {\n if (value != null) {\n this.setAttribute('volume', String(value));\n }\n }\n\n public set playing(value: boolean | string) {\n this.setAttribute(\n 'playing',\n value === true || value === 'true' ? 'true' : 'false',\n );\n }\n\n public set looping(value: boolean | string) {\n this.setAttribute(\n 'looping',\n value === true || value === 'true' ? 'true' : 'false',\n );\n }\n\n private readonly root: ShadowRoot;\n private readonly canvas: HTMLCanvasElement;\n private readonly overlay: HTMLCanvasElement;\n\n private state = State.Initial;\n private project: Project | null = null;\n private player: Player | null = null;\n private defaultSettings:\n | ReturnType<typeof getFullPreviewSettings>\n | undefined;\n private abortController: AbortController | null = null;\n private _playing = false;\n private stage = new Stage();\n\n private time: number = 0;\n private duration: number = 0; // in frames\n private _looping = true;\n private _volume = 1;\n private volumeChangeRequested = true;\n\n public constructor() {\n super();\n this.root = this.attachShadow({mode: 'open'});\n this.root.innerHTML = TEMPLATE;\n\n this.overlay = this.root.querySelector('.overlay')!;\n this.canvas = this.stage.finalBuffer;\n this.canvas.classList.add('canvas');\n this.root.prepend(this.canvas);\n this.setState(State.Initial);\n }\n\n public setProject(project: Project) {\n this.updateProject(project);\n }\n\n private setState(state: State) {\n this.state = state;\n this.setPlaying(this._playing);\n }\n\n private setPlaying(value: boolean) {\n if (this.state === State.Ready && value) {\n this.player?.togglePlayback(true);\n this._playing = true;\n } else {\n this.player?.togglePlayback(false);\n this._playing = false;\n }\n }\n\n private async updateProject(project: Project) {\n const playing = this._playing;\n this.setState(State.Initial);\n\n this.abortController?.abort();\n this.abortController = new AbortController();\n\n this.project = project;\n this.defaultSettings = getFullPreviewSettings(this.project);\n\n const player = new Player(this.project);\n player.setVariables(this.variables);\n player.toggleLoop(this._looping);\n\n this.player?.onRender.unsubscribe(this.render);\n this.player?.onFrameChanged.unsubscribe(this.handleFrameChanged);\n this.player?.togglePlayback(false);\n this.player?.deactivate();\n\n this.player = player;\n this.updateSettings();\n\n this.setState(State.Ready);\n this.dispatchEvent(new CustomEvent('playerready', {detail: this.player}));\n\n // Restore previous state\n this.setPlaying(playing);\n this.player.onRender.subscribe(this.render);\n this.player.onFrameChanged.subscribe(this.handleFrameChanged);\n }\n\n public attributeChangedCallback(name: string, _: any, newValue: any) {\n switch (name) {\n case 'playing':\n this.setPlaying(newValue === 'true');\n break;\n case 'variables':\n this.player?.setVariables(this.variables);\n this.player?.requestSeek(this.player.playback.frame);\n this.player?.playback.reload();\n break;\n case 'looping':\n this._looping = newValue === 'true';\n this.player?.toggleLoop(newValue === 'true');\n break;\n case 'fps':\n case 'quality':\n case 'width':\n case 'height':\n this.updateSettings();\n break;\n case 'volume':\n this._volume = newValue;\n this.volumeChangeRequested = true;\n }\n }\n\n /**\n * Runs when the element is removed from the DOM.\n */\n public disconnectedCallback() {\n this.player?.deactivate();\n this.player?.onRender.unsubscribe(this.render);\n\n this.removeEventListener('seekto', this.handleSeekTo);\n this.removeEventListener('volumechange', this.handleVolumeChange);\n }\n\n /**\n * Runs when the element is added to the DOM.\n */\n public connectedCallback() {\n this.player?.activate();\n this.player?.onRender.subscribe(this.render);\n\n this.addEventListener('seekto', this.handleSeekTo);\n this.addEventListener('volumechange', this.handleVolumeChange);\n }\n\n /**\n * Triggered by the timeline.\n */\n private handleSeekTo = (event: Event) => {\n if (!this.project) {\n return;\n }\n\n const e = event as CustomEvent;\n const timeSec = e.detail as number;\n const frame = timeSec * this.player!.playback.fps;\n this.time = timeSec;\n this.player?.requestSeek(frame);\n this.volumeChangeRequested = true;\n };\n\n private handleVolumeChange = (event: Event) => {\n if (!this.project) {\n return;\n }\n\n const e = event as CustomEvent;\n this._volume = e.detail;\n\n this.player?.playback.currentScene.adjustVolume(this._volume);\n };\n\n /**\n * Triggered by the player.\n */\n private handleFrameChanged = (frame: number) => {\n if (!this.project || !this.player) {\n return;\n }\n this.time = frame / this.player.playback.fps;\n\n if (this.volumeChangeRequested || frame === 0) {\n this.player?.playback.currentScene.adjustVolume(this._volume);\n this.volumeChangeRequested = false;\n }\n };\n\n /**\n * Called on every frame.\n */\n private render = async () => {\n if (this.player && this.project) {\n await this.stage.render(\n this.player.playback.currentScene,\n this.player.playback.previousScene,\n );\n\n this.dispatchEvent(new CustomEvent('timeupdate', {detail: this.time}));\n\n const durationInFrames = this.player.playback.duration;\n if (durationInFrames === this.duration) {\n return;\n }\n\n this.duration = durationInFrames;\n\n const durationInSeconds = durationInFrames / this.player.playback.fps;\n this.dispatchEvent(\n new CustomEvent('duration', {detail: durationInSeconds}),\n );\n }\n };\n\n private updateSettings() {\n if (!this.defaultSettings) {\n return;\n }\n\n // Use the requested quality (resolutionScale) instead of forcing 1,\n // so the preview canvas can render at higher internal resolution.\n const resolutionScale =\n Number.isFinite(this.quality) && this.quality > 0\n ? this.quality\n : this.defaultSettings.resolutionScale ?? 1;\n\n const settings = {\n ...this.defaultSettings,\n size: new Vector2(this.width, this.height),\n resolutionScale,\n fps: this.fps,\n };\n this.stage.configure(settings);\n this.player?.configure(settings);\n }\n}\n\nif (!customElements.get(ID)) {\n customElements.define(ID, TwickPlayer);\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@twick/player-react",
3
- "version": "0.15.15",
3
+ "version": "0.15.17",
4
4
  "description": "",
5
5
  "author": "twick",
6
6
  "license": "MIT",
@@ -25,7 +25,7 @@
25
25
  },
26
26
  "keywords": [],
27
27
  "dependencies": {
28
- "@twick/core": "0.15.15",
28
+ "@twick/core": "0.15.17",
29
29
  "react": "^18",
30
30
  "react-dom": "^18",
31
31
  "uuid": "^10.0.0"
@@ -46,5 +46,5 @@
46
46
  "url": "https://github.com/ncounterspecialist/twick-base.git"
47
47
  },
48
48
  "bugs": "https://github.com/ncounterspecialist/twick-base/issues",
49
- "gitHead": "4510cc8d960f02c83dfa1ad9605e14ebfc4facd0"
49
+ "gitHead": "f9e3171cbbc1aba5a75b4defee1e5cb72c85bc19"
50
50
  }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/internal.ts"],"sourcesContent":["import type {Project} from '@twick/core';\nimport {Player, Stage, getFullPreviewSettings} from '@twick/core';\n\nimport {Vector2} from '@twick/core';\n\nconst stylesNew = `\n.overlay {\n\tposition: absolute;\n\tleft: 0;\n\tright: 0;\n\ttop: 0;\n\tbottom: 0;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\topacity: 0;\n\ttransition: opacity 0.1s;\n\tz-index: 0;\n }\n .canvas {\n\twidth: 100%;\n\theight: 100%;\n\tdisplay: block;\n\topacity: 1;\n\ttransition: opacity 0.1s;\n }\n`;\n\nconst TEMPLATE = `<style>${stylesNew}</style><div class=\"overlay\"></div>`;\nconst ID = 'twick-player';\n\nenum State {\n Initial = 'initial',\n Loading = 'loading',\n Ready = 'ready',\n Error = 'error',\n}\n\nclass TwickPlayer extends HTMLElement {\n public static get observedAttributes() {\n return [\n 'playing',\n 'variables',\n 'looping',\n 'fps',\n 'quality',\n 'width',\n 'height',\n 'volume',\n ];\n }\n\n private get fps() {\n const attr = this.getAttribute('fps');\n return attr ? parseFloat(attr) : (this.defaultSettings?.fps ?? 60);\n }\n\n private get quality() {\n const attr = this.getAttribute('quality');\n return attr\n ? parseFloat(attr)\n : (this.defaultSettings?.resolutionScale ?? 1);\n }\n\n private get width() {\n const attr = this.getAttribute('width');\n return attr ? parseFloat(attr) : (this.defaultSettings?.size.width ?? 0);\n }\n\n private set width(value: number) {\n if (Number.isFinite(value)) {\n this.setAttribute('width', String(value));\n }\n }\n\n private get height() {\n const attr = this.getAttribute('height');\n return attr ? parseFloat(attr) : (this.defaultSettings?.size.height ?? 0);\n }\n\n private set height(value: number) {\n if (Number.isFinite(value)) {\n this.setAttribute('height', String(value));\n }\n }\n\n private get variables() {\n try {\n const attr = this.getAttribute('variables');\n return attr ? JSON.parse(attr) : {};\n } catch {\n this.project?.logger.warn(`Project variables could not be parsed.`);\n return {};\n }\n }\n\n private readonly root: ShadowRoot;\n private readonly canvas: HTMLCanvasElement;\n private readonly overlay: HTMLCanvasElement;\n\n private state = State.Initial;\n private project: Project | null = null;\n private player: Player | null = null;\n private defaultSettings:\n | ReturnType<typeof getFullPreviewSettings>\n | undefined;\n private abortController: AbortController | null = null;\n private playing = false;\n private stage = new Stage();\n\n private time: number = 0;\n private duration: number = 0; // in frames\n private looping = true;\n private volume = 1;\n private volumeChangeRequested = true;\n\n public constructor() {\n super();\n this.root = this.attachShadow({mode: 'open'});\n this.root.innerHTML = TEMPLATE;\n\n this.overlay = this.root.querySelector('.overlay')!;\n this.canvas = this.stage.finalBuffer;\n this.canvas.classList.add('canvas');\n this.root.prepend(this.canvas);\n this.setState(State.Initial);\n }\n\n public setProject(project: Project) {\n this.updateProject(project);\n }\n\n private setState(state: State) {\n this.state = state;\n this.setPlaying(this.playing);\n }\n\n private setPlaying(value: boolean) {\n if (this.state === State.Ready && value) {\n this.player?.togglePlayback(true);\n this.playing = true;\n } else {\n this.player?.togglePlayback(false);\n this.playing = false;\n }\n }\n\n private async updateProject(project: Project) {\n const playing = this.playing;\n this.setState(State.Initial);\n\n this.abortController?.abort();\n this.abortController = new AbortController();\n\n this.project = project;\n this.defaultSettings = getFullPreviewSettings(this.project);\n\n const player = new Player(this.project);\n player.setVariables(this.variables);\n player.toggleLoop(this.looping);\n\n this.player?.onRender.unsubscribe(this.render);\n this.player?.onFrameChanged.unsubscribe(this.handleFrameChanged);\n this.player?.togglePlayback(false);\n this.player?.deactivate();\n\n this.player = player;\n this.updateSettings();\n\n this.setState(State.Ready);\n this.dispatchEvent(new CustomEvent('playerready', {detail: this.player}));\n\n // Restore previous state\n this.setPlaying(playing);\n this.player.onRender.subscribe(this.render);\n this.player.onFrameChanged.subscribe(this.handleFrameChanged);\n }\n\n public attributeChangedCallback(name: string, _: any, newValue: any) {\n switch (name) {\n case 'playing':\n this.setPlaying(newValue === 'true');\n break;\n case 'variables':\n this.player?.setVariables(this.variables);\n this.player?.requestSeek(this.player.playback.frame);\n this.player?.playback.reload();\n break;\n case 'looping':\n this.looping = newValue === 'true';\n this.player?.toggleLoop(newValue === 'true');\n break;\n case 'fps':\n case 'quality':\n case 'width':\n case 'height':\n this.updateSettings();\n break;\n case 'volume':\n this.volume = newValue;\n this.volumeChangeRequested = true;\n }\n }\n\n /**\n * Runs when the element is removed from the DOM.\n */\n public disconnectedCallback() {\n this.player?.deactivate();\n this.player?.onRender.unsubscribe(this.render);\n\n this.removeEventListener('seekto', this.handleSeekTo);\n this.removeEventListener('volumechange', this.handleVolumeChange);\n }\n\n /**\n * Runs when the element is added to the DOM.\n */\n public connectedCallback() {\n this.player?.activate();\n this.player?.onRender.subscribe(this.render);\n\n this.addEventListener('seekto', this.handleSeekTo);\n this.addEventListener('volumechange', this.handleVolumeChange);\n }\n\n /**\n * Triggered by the timeline.\n */\n private handleSeekTo = (event: Event) => {\n if (!this.project) {\n return;\n }\n\n const e = event as CustomEvent;\n this.time = e.detail;\n this.player?.requestSeek(e.detail * this.player.playback.fps);\n this.volumeChangeRequested = true;\n };\n\n private handleVolumeChange = (event: Event) => {\n if (!this.project) {\n return;\n }\n\n const e = event as CustomEvent;\n this.volume = e.detail;\n\n this.player?.playback.currentScene.adjustVolume(this.volume);\n };\n\n /**\n * Triggered by the player.\n */\n private handleFrameChanged = (frame: number) => {\n if (!this.project || !this.player) {\n return;\n }\n this.time = frame / this.player.playback.fps;\n\n if (this.volumeChangeRequested || frame === 0) {\n this.player?.playback.currentScene.adjustVolume(this.volume);\n this.volumeChangeRequested = false;\n }\n };\n\n /**\n * Called on every frame.\n */\n private render = async () => {\n if (this.player && this.project) {\n await this.stage.render(\n this.player.playback.currentScene,\n this.player.playback.previousScene,\n );\n\n this.dispatchEvent(new CustomEvent('timeupdate', {detail: this.time}));\n\n const durationInFrames = this.player.playback.duration;\n if (durationInFrames === this.duration) {\n return;\n }\n\n this.duration = durationInFrames;\n\n const durationInSeconds = durationInFrames / this.player.playback.fps;\n this.dispatchEvent(\n new CustomEvent('duration', {detail: durationInSeconds}),\n );\n }\n };\n\n private updateSettings() {\n if (!this.defaultSettings) {\n return;\n }\n\n // Use the requested quality (resolutionScale) instead of forcing 1,\n // so the preview canvas can render at higher internal resolution.\n const resolutionScale =\n Number.isFinite(this.quality) && this.quality > 0\n ? this.quality\n : this.defaultSettings.resolutionScale ?? 1;\n\n const settings = {\n ...this.defaultSettings,\n size: new Vector2(this.width, this.height),\n resolutionScale,\n fps: this.fps,\n };\n this.stage.configure(settings);\n this.player?.configure(settings);\n }\n}\n\nif (!customElements.get(ID)) {\n customElements.define(ID, TwickPlayer);\n}\n"],"mappings":"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","names":[]}