chart-preview 1.0.3 → 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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # chart-preview
2
2
 
3
+ ## 1.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 95d0918: Add support for animated note textures and improve fullscreen handling
8
+
9
+ ## 1.1.0
10
+
11
+ ### Minor Changes
12
+
13
+ - 885a2db: Add note animations (Chrome only)
14
+
3
15
  ## 1.0.3
4
16
 
5
17
  ### Patch Changes
package/README.md CHANGED
@@ -13,6 +13,7 @@ A 3D chart preview player for rhythm games like Clone Hero. Renders chart files
13
13
  - **Web Component** that can be dropped into any project
14
14
  - **Multiple instance support** - run several players simultaneously
15
15
  - **Simple URL-based loading** - just provide a URL to a .sng file
16
+ - **Animated note textures** - supports animated WebP textures
16
17
 
17
18
  ## Installation
18
19
 
@@ -102,6 +103,7 @@ import {
102
103
  ChartPreview,
103
104
  ChartPreviewPlayer,
104
105
  getInstrumentType,
106
+ areAnimationsSupported,
105
107
  } from "chart-preview";
106
108
  import { parseChartFile } from "scan-chart";
107
109
 
@@ -109,7 +111,9 @@ import { parseChartFile } from "scan-chart";
109
111
  const parsedChart = parseChartFile(chartData, "chart", modifiers);
110
112
 
111
113
  // 2. Load textures (cache and reuse for same instrument type)
112
- const textures = await ChartPreview.loadTextures(getInstrumentType("guitar"));
114
+ const textures = await ChartPreview.loadTextures(getInstrumentType("guitar"), {
115
+ animationsEnabled: areAnimationsSupported(),
116
+ });
113
117
 
114
118
  // 3. Load the chart
115
119
  await player.loadChart({
@@ -365,6 +369,10 @@ interface LoadFromUrlConfig {
365
369
  difficulty: Difficulty;
366
370
  /** Initial seek position (0-1). Defaults to 0 */
367
371
  initialSeekPercent?: number;
372
+ /** AbortSignal to cancel the fetch operation */
373
+ signal?: AbortSignal;
374
+ /** Whether to enable animated textures. Defaults to true */
375
+ animationsEnabled?: boolean;
368
376
  }
369
377
  ```
370
378
 
@@ -380,6 +388,8 @@ interface LoadFromSngFileConfig {
380
388
  difficulty: Difficulty;
381
389
  /** Initial seek position (0-1). Defaults to 0 */
382
390
  initialSeekPercent?: number;
391
+ /** Whether to enable animated textures. Defaults to true */
392
+ animationsEnabled?: boolean;
383
393
  }
384
394
  ```
385
395
 
@@ -395,6 +405,8 @@ interface LoadFromChartFilesConfig {
395
405
  difficulty: Difficulty;
396
406
  /** Initial seek position (0-1). Defaults to 0 */
397
407
  initialSeekPercent?: number;
408
+ /** Whether to enable animated textures. Defaults to true */
409
+ animationsEnabled?: boolean;
398
410
  }
399
411
  ```
400
412
 
@@ -444,10 +456,17 @@ interface ChartPreviewPlayerConfig {
444
456
  For advanced use cases, you can use the `ChartPreview` class directly:
445
457
 
446
458
  ```typescript
447
- import { ChartPreview, getInstrumentType } from "chart-preview";
459
+ import {
460
+ ChartPreview,
461
+ getInstrumentType,
462
+ areAnimationsSupported,
463
+ } from "chart-preview";
448
464
 
449
465
  // Load textures (cache for reuse)
450
- const textures = await ChartPreview.loadTextures(getInstrumentType("guitar"));
466
+ // Optionally disable animations for better performance
467
+ const textures = await ChartPreview.loadTextures(getInstrumentType("guitar"), {
468
+ animationsEnabled: areAnimationsSupported(), // or set to false to always use static textures
469
+ });
451
470
 
452
471
  // Create preview
453
472
  const preview = await ChartPreview.create({
@@ -485,8 +504,15 @@ import {
485
504
  prepareChartData,
486
505
  findChartFile,
487
506
  findAudioFiles,
507
+ isVideoFile,
508
+ areAnimationsSupported,
488
509
  } from "chart-preview";
489
510
 
511
+ // Check if animated textures are supported (ImageDecoder API)
512
+ if (areAnimationsSupported()) {
513
+ console.log("Animated note textures will be used");
514
+ }
515
+
490
516
  // Fetch and extract a .sng file
491
517
  const sngData = await fetchSngFile("https://example.com/chart.sng");
492
518
  const files = await extractSngFile(sngData);
@@ -495,6 +521,9 @@ const files = await extractSngFile(sngData);
495
521
  const chartFile = findChartFile(files); // Returns .chart or .mid file
496
522
  const audioFiles = findAudioFiles(files); // Returns audio file data
497
523
 
524
+ // Check if a file is a video (to exclude from processing)
525
+ const nonVideoFiles = files.filter((f) => !isVideoFile(f.fileName));
526
+
498
527
  // Prepare all data for playback
499
528
  const preparedData = await prepareChartData(files, "guitar", "expert");
500
529
  ```
@@ -528,13 +557,14 @@ Requires support for:
528
557
  - Web Audio API
529
558
  - WebGL
530
559
 
560
+ **Animated Textures:** Requires the ImageDecoder API (Chromium-based browsers only: Chrome, Edge, Opera). Use `areAnimationsSupported()` to check. Other browsers fall back to static textures.
561
+
531
562
  ## Dependencies
532
563
 
533
564
  - `three` - 3D rendering
534
565
  - `scan-chart` - Chart parsing
535
566
  - `parse-sng` - .sng file extraction
536
567
  - `eventemitter3` - Event handling
537
- - `lodash` - Utility functions
538
568
 
539
569
  ## License
540
570
 
package/dist/index.d.ts CHANGED
@@ -3,6 +3,56 @@ export { Difficulty, Instrument, InstrumentType, getInstrumentType, instrumentTy
3
3
  import * as THREE from 'three';
4
4
 
5
5
  type ParsedChart = ReturnType<typeof parseChartFile>;
6
+ /**
7
+ * Check if animations are supported on this browser.
8
+ * Use this to conditionally enable/disable animation features.
9
+ */
10
+ declare function areAnimationsSupported(): boolean;
11
+ /**
12
+ * Manages an animated WebP texture using the ImageDecoder API.
13
+ * Pre-decodes all frames during initialization for optimal performance.
14
+ * Falls back to a static texture if ImageDecoder is not supported.
15
+ */
16
+ declare class AnimatedTexture {
17
+ private canvas;
18
+ private ctx;
19
+ texture: THREE.CanvasTexture;
20
+ private frameIndex;
21
+ private frameCount;
22
+ private lastFrameTime;
23
+ private frameDurations;
24
+ /** Pre-decoded frames stored as ImageBitmap for fast synchronous access */
25
+ private frameCache;
26
+ private isAnimated;
27
+ private disposed;
28
+ private constructor();
29
+ /**
30
+ * Creates an AnimatedTexture from a URL.
31
+ * Uses ImageDecoder for animation if available, otherwise loads as static texture.
32
+ * Pre-decodes all frames during initialization for optimal render performance.
33
+ */
34
+ static create(url: string): Promise<AnimatedTexture | THREE.Texture>;
35
+ /**
36
+ * Updates the texture to the current animation frame based on elapsed time.
37
+ * This method is SYNCHRONOUS for optimal render performance - all frames
38
+ * are pre-decoded during initialization.
39
+ */
40
+ tick(): void;
41
+ /**
42
+ * Disposes of resources used by this animated texture.
43
+ */
44
+ dispose(): void;
45
+ }
46
+ /** Collection of animated textures that need to be ticked each frame */
47
+ declare class AnimatedTextureManager {
48
+ private animatedTextures;
49
+ register(texture: AnimatedTexture | THREE.Texture): void;
50
+ /**
51
+ * Updates all animated textures. This is now SYNCHRONOUS for optimal performance.
52
+ */
53
+ tick(): void;
54
+ dispose(): void;
55
+ }
6
56
  /**
7
57
  * Custom note types for 6-fret barre notes.
8
58
  * These are the only sprites without a dedicated NoteType from scan-chart.
@@ -51,6 +101,7 @@ declare class ChartPreview {
51
101
  private renderer;
52
102
  private audioManager;
53
103
  private notesManager;
104
+ private animatedTextureManager;
54
105
  private progressIntervalMs;
55
106
  private lastProgressEmitTime;
56
107
  /**
@@ -138,15 +189,26 @@ declare class ChartPreview {
138
189
  private addStrikelineToScene;
139
190
  private animateFrame;
140
191
  }
192
+ interface LoadTexturesOptions {
193
+ /**
194
+ * Whether to enable animated textures.
195
+ * When true (default), uses ImageDecoder API for animated WebP if available.
196
+ * When false, always loads static textures for better performance.
197
+ * Use `areAnimationsSupported()` to check if animations are supported on the current browser.
198
+ */
199
+ animationsEnabled?: boolean;
200
+ }
141
201
  /**
142
202
  * Loads all required textures for the chart preview.
143
203
  * @param instrumentType The type of instrument to load textures for
144
- * @returns An object containing highway, strikeline, and note textures
204
+ * @param options Optional configuration for texture loading
205
+ * @returns An object containing highway, strikeline, note textures, and animated texture manager
145
206
  */
146
- declare function loadTextures(instrumentType: InstrumentType): Promise<{
207
+ declare function loadTextures(instrumentType: InstrumentType, options?: LoadTexturesOptions): Promise<{
147
208
  highwayTexture: THREE.Texture;
148
209
  strikelineTexture: THREE.Texture;
149
210
  noteTextures: Map<ExtendedNoteType, Map<number, THREE.Texture>>;
211
+ animatedTextureManager: AnimatedTextureManager;
150
212
  }>;
151
213
 
152
214
  /**
@@ -163,6 +225,11 @@ interface LoadFromUrlConfig {
163
225
  initialSeekPercent?: number;
164
226
  /** AbortSignal to cancel the fetch operation */
165
227
  signal?: AbortSignal;
228
+ /**
229
+ * Whether to enable animated textures. Defaults to true.
230
+ * Set to false for better performance or when animations aren't supported.
231
+ */
232
+ animationsEnabled?: boolean;
166
233
  }
167
234
  /**
168
235
  * Configuration for loading a chart from raw .sng file data.
@@ -176,6 +243,11 @@ interface LoadFromSngFileConfig {
176
243
  difficulty: Difficulty;
177
244
  /** Initial seek position as a percentage (0-1). Defaults to 0. */
178
245
  initialSeekPercent?: number;
246
+ /**
247
+ * Whether to enable animated textures. Defaults to true.
248
+ * Set to false for better performance or when animations aren't supported.
249
+ */
250
+ animationsEnabled?: boolean;
179
251
  }
180
252
  /**
181
253
  * Configuration for loading a chart from individual chart and audio files.
@@ -192,6 +264,11 @@ interface LoadFromChartFilesConfig {
192
264
  difficulty: Difficulty;
193
265
  /** Initial seek position as a percentage (0-1). Defaults to 0. */
194
266
  initialSeekPercent?: number;
267
+ /**
268
+ * Whether to enable animated textures. Defaults to true.
269
+ * Set to false for better performance or when animations aren't supported.
270
+ */
271
+ animationsEnabled?: boolean;
195
272
  }
196
273
  /**
197
274
  * Result of preparing chart data for playback.
@@ -252,12 +329,13 @@ declare function isVideoFile(fileName: string): boolean;
252
329
  * @param instrument - The instrument to display
253
330
  * @param difficulty - The difficulty level to display
254
331
  * @param initialSeekPercent - Initial seek position (0-1)
332
+ * @param textureOptions - Options for texture loading (e.g., animations enabled)
255
333
  * @returns Prepared chart data ready for the player
256
334
  */
257
335
  declare function prepareChartData(files: {
258
336
  fileName: string;
259
337
  data: Uint8Array;
260
- }[], instrument: Instrument, difficulty: Difficulty, initialSeekPercent?: number): Promise<PreparedChartData>;
338
+ }[], instrument: Instrument, difficulty: Difficulty, initialSeekPercent?: number, textureOptions?: LoadTexturesOptions): Promise<PreparedChartData>;
261
339
  /**
262
340
  * Fetches a .sng file from a URL.
263
341
  *
@@ -493,4 +571,4 @@ declare global {
493
571
  }
494
572
  }
495
573
 
496
- export { ChartPreview, ChartPreviewConfig, ChartPreviewEvents, ChartPreviewPlayer, ChartPreviewPlayerConfig, LoadFromChartFilesConfig, LoadFromSngFileConfig, LoadFromUrlConfig, ParsedChart, PlayerState, PreparedChartData, extractSngFile, fetchSngFile, findAudioFiles, findChartFile, isVideoFile, prepareChartData };
574
+ export { ChartPreview, ChartPreviewConfig, ChartPreviewEvents, ChartPreviewPlayer, ChartPreviewPlayerConfig, LoadFromChartFilesConfig, LoadFromSngFileConfig, LoadFromUrlConfig, LoadTexturesOptions, ParsedChart, PlayerState, PreparedChartData, areAnimationsSupported, extractSngFile, fetchSngFile, findAudioFiles, findChartFile, isVideoFile, prepareChartData };