chart-preview 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -357,6 +357,11 @@ export class ChartPreviewPlayer extends HTMLElement {
357
357
  connectedCallback() {
358
358
  this.setAttribute("tabindex", "0");
359
359
  document.addEventListener("fullscreenchange", this.handleFullscreenChange);
360
+ // Safari uses webkit prefix
361
+ document.addEventListener(
362
+ "webkitfullscreenchange",
363
+ this.handleFullscreenChange
364
+ );
360
365
  }
361
366
 
362
367
  disconnectedCallback() {
@@ -365,6 +370,10 @@ export class ChartPreviewPlayer extends HTMLElement {
365
370
  "fullscreenchange",
366
371
  this.handleFullscreenChange
367
372
  );
373
+ document.removeEventListener(
374
+ "webkitfullscreenchange",
375
+ this.handleFullscreenChange
376
+ );
368
377
  this.removeEventListener("keydown", this.handleKeydown);
369
378
  }
370
379
 
@@ -467,8 +476,9 @@ export class ChartPreviewPlayer extends HTMLElement {
467
476
  }
468
477
  });
469
478
 
470
- // Fullscreen button
471
- this.fullscreenBtn.addEventListener("click", () => {
479
+ // Fullscreen button - stop propagation to prevent any parent handlers
480
+ this.fullscreenBtn.addEventListener("click", (e) => {
481
+ e.stopPropagation();
472
482
  this.toggleFullscreen();
473
483
  });
474
484
 
@@ -525,14 +535,20 @@ export class ChartPreviewPlayer extends HTMLElement {
525
535
  };
526
536
 
527
537
  private handleFullscreenChange = () => {
528
- this._isFullscreen = document.fullscreenElement === this.container;
538
+ // Check if we're in fullscreen mode (support both standard and webkit prefix)
539
+ const fullscreenElement =
540
+ document.fullscreenElement ||
541
+ (document as unknown as { webkitFullscreenElement?: Element })
542
+ .webkitFullscreenElement;
543
+ this._isFullscreen =
544
+ fullscreenElement !== null && fullscreenElement !== undefined;
529
545
  this.container.classList.toggle("fullscreen", this._isFullscreen);
530
546
  this.fullscreenBtn.innerHTML = this._isFullscreen
531
547
  ? ICONS.fullscreenExit
532
548
  : ICONS.fullscreen;
533
549
  this.fullscreenBtn.title = this._isFullscreen
534
550
  ? "Exit fullscreen"
535
- : "Toggle fullscreen";
551
+ : "Enter fullscreen";
536
552
  };
537
553
 
538
554
  private onSeekStart() {
@@ -900,7 +916,8 @@ export class ChartPreviewPlayer extends HTMLElement {
900
916
  files,
901
917
  config.instrument,
902
918
  config.difficulty,
903
- config.initialSeekPercent
919
+ config.initialSeekPercent,
920
+ { animationsEnabled: config.animationsEnabled }
904
921
  );
905
922
 
906
923
  // Load the chart
@@ -948,7 +965,8 @@ export class ChartPreviewPlayer extends HTMLElement {
948
965
  files,
949
966
  config.instrument,
950
967
  config.difficulty,
951
- config.initialSeekPercent
968
+ config.initialSeekPercent,
969
+ { animationsEnabled: config.animationsEnabled }
952
970
  );
953
971
 
954
972
  // Load the chart
@@ -992,7 +1010,8 @@ export class ChartPreviewPlayer extends HTMLElement {
992
1010
  config.files,
993
1011
  config.instrument,
994
1012
  config.difficulty,
995
- config.initialSeekPercent
1013
+ config.initialSeekPercent,
1014
+ { animationsEnabled: config.animationsEnabled }
996
1015
  );
997
1016
 
998
1017
  // Load the chart
@@ -1105,12 +1124,46 @@ export class ChartPreviewPlayer extends HTMLElement {
1105
1124
  * Toggle fullscreen mode
1106
1125
  */
1107
1126
  async toggleFullscreen(): Promise<void> {
1108
- if (!document.fullscreenEnabled) return;
1127
+ // Check for fullscreen support (standard and webkit)
1128
+ const doc = document as unknown as {
1129
+ fullscreenEnabled?: boolean;
1130
+ webkitFullscreenEnabled?: boolean;
1131
+ fullscreenElement?: Element;
1132
+ webkitFullscreenElement?: Element;
1133
+ exitFullscreen?: () => Promise<void>;
1134
+ webkitExitFullscreen?: () => void;
1135
+ };
1136
+ const container = this.container as unknown as {
1137
+ requestFullscreen?: () => Promise<void>;
1138
+ webkitRequestFullscreen?: () => void;
1139
+ };
1140
+
1141
+ const isFullscreenEnabled =
1142
+ doc.fullscreenEnabled || doc.webkitFullscreenEnabled;
1143
+ if (!isFullscreenEnabled) return;
1144
+
1145
+ const fullscreenElement =
1146
+ doc.fullscreenElement || doc.webkitFullscreenElement;
1109
1147
 
1110
- if (this._isFullscreen) {
1111
- await document.exitFullscreen();
1112
- } else {
1113
- await this.container.requestFullscreen();
1148
+ try {
1149
+ if (fullscreenElement) {
1150
+ // Exit fullscreen
1151
+ if (doc.exitFullscreen) {
1152
+ await doc.exitFullscreen();
1153
+ } else if (doc.webkitExitFullscreen) {
1154
+ doc.webkitExitFullscreen();
1155
+ }
1156
+ } else {
1157
+ // Enter fullscreen
1158
+ if (container.requestFullscreen) {
1159
+ await container.requestFullscreen();
1160
+ } else if (container.webkitRequestFullscreen) {
1161
+ container.webkitRequestFullscreen();
1162
+ }
1163
+ }
1164
+ } catch (error) {
1165
+ // Fullscreen request can fail due to user gesture requirements or other reasons
1166
+ console.warn("Fullscreen toggle failed:", error);
1114
1167
  }
1115
1168
  }
1116
1169
 
package/src/SngLoader.ts CHANGED
@@ -7,7 +7,11 @@ import {
7
7
  type Instrument,
8
8
  type ScannedChart,
9
9
  } from "scan-chart";
10
- import { ChartPreview, type ParsedChart } from "./ChartPreview";
10
+ import {
11
+ ChartPreview,
12
+ type LoadTexturesOptions,
13
+ type ParsedChart,
14
+ } from "./ChartPreview";
11
15
 
12
16
  /**
13
17
  * Audio file extensions supported by the chart preview.
@@ -33,6 +37,11 @@ export interface LoadFromUrlConfig {
33
37
  initialSeekPercent?: number;
34
38
  /** AbortSignal to cancel the fetch operation */
35
39
  signal?: AbortSignal;
40
+ /**
41
+ * Whether to enable animated textures. Defaults to true.
42
+ * Set to false for better performance or when animations aren't supported.
43
+ */
44
+ animationsEnabled?: boolean;
36
45
  }
37
46
 
38
47
  /**
@@ -47,6 +56,11 @@ export interface LoadFromSngFileConfig {
47
56
  difficulty: Difficulty;
48
57
  /** Initial seek position as a percentage (0-1). Defaults to 0. */
49
58
  initialSeekPercent?: number;
59
+ /**
60
+ * Whether to enable animated textures. Defaults to true.
61
+ * Set to false for better performance or when animations aren't supported.
62
+ */
63
+ animationsEnabled?: boolean;
50
64
  }
51
65
 
52
66
  /**
@@ -61,6 +75,11 @@ export interface LoadFromChartFilesConfig {
61
75
  difficulty: Difficulty;
62
76
  /** Initial seek position as a percentage (0-1). Defaults to 0. */
63
77
  initialSeekPercent?: number;
78
+ /**
79
+ * Whether to enable animated textures. Defaults to true.
80
+ * Set to false for better performance or when animations aren't supported.
81
+ */
82
+ animationsEnabled?: boolean;
64
83
  }
65
84
 
66
85
  /**
@@ -218,13 +237,15 @@ export function isVideoFile(fileName: string): boolean {
218
237
  * @param instrument - The instrument to display
219
238
  * @param difficulty - The difficulty level to display
220
239
  * @param initialSeekPercent - Initial seek position (0-1)
240
+ * @param textureOptions - Options for texture loading (e.g., animations enabled)
221
241
  * @returns Prepared chart data ready for the player
222
242
  */
223
243
  export async function prepareChartData(
224
244
  files: { fileName: string; data: Uint8Array }[],
225
245
  instrument: Instrument,
226
246
  difficulty: Difficulty,
227
- initialSeekPercent = 0
247
+ initialSeekPercent = 0,
248
+ textureOptions: LoadTexturesOptions = {}
228
249
  ): Promise<PreparedChartData> {
229
250
  // Filter out video files
230
251
  const filteredFiles = files.filter((f) => !isVideoFile(f.fileName));
@@ -276,7 +297,10 @@ export async function prepareChartData(
276
297
 
277
298
  // Load textures for the instrument type
278
299
  const instrumentType = getInstrumentType(instrument);
279
- const textures = await ChartPreview.loadTextures(instrumentType);
300
+ const textures = await ChartPreview.loadTextures(
301
+ instrumentType,
302
+ textureOptions
303
+ );
280
304
 
281
305
  // Calculate audio length from the last note or from metadata
282
306
  const lastNote = parsedChart.trackData
package/src/index.ts CHANGED
@@ -1,8 +1,10 @@
1
1
  // Core classes
2
2
  export {
3
3
  ChartPreview,
4
+ areAnimationsSupported,
4
5
  type ChartPreviewConfig,
5
6
  type ChartPreviewEvents,
7
+ type LoadTexturesOptions,
6
8
  type ParsedChart,
7
9
  } from "./ChartPreview";
8
10