prismdeckjs 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +45 -0
  3. package/dist/chunks/rapier-D1P_-6v-.js +5727 -0
  4. package/dist/document/archive.d.ts +17 -0
  5. package/dist/document/archive.d.ts.map +1 -0
  6. package/dist/document/archive.js +105 -0
  7. package/dist/document/archive.js.map +1 -0
  8. package/dist/document/html.d.ts +10 -0
  9. package/dist/document/html.d.ts.map +1 -0
  10. package/dist/document/html.js +149 -0
  11. package/dist/document/html.js.map +1 -0
  12. package/dist/document/types.d.ts +188 -0
  13. package/dist/document/types.d.ts.map +1 -0
  14. package/dist/document/types.js +21 -0
  15. package/dist/document/types.js.map +1 -0
  16. package/dist/document/validate.d.ts +9 -0
  17. package/dist/document/validate.d.ts.map +1 -0
  18. package/dist/document/validate.js +77 -0
  19. package/dist/document/validate.js.map +1 -0
  20. package/dist/import/index.d.ts +9 -0
  21. package/dist/import/index.d.ts.map +1 -0
  22. package/dist/import/index.js +41 -0
  23. package/dist/import/index.js.map +1 -0
  24. package/dist/import/odp.d.ts +3 -0
  25. package/dist/import/odp.d.ts.map +1 -0
  26. package/dist/import/odp.js +529 -0
  27. package/dist/import/odp.js.map +1 -0
  28. package/dist/import/pptx.d.ts +3 -0
  29. package/dist/import/pptx.d.ts.map +1 -0
  30. package/dist/import/pptx.js +634 -0
  31. package/dist/import/pptx.js.map +1 -0
  32. package/dist/import/xml.d.ts +19 -0
  33. package/dist/import/xml.d.ts.map +1 -0
  34. package/dist/import/xml.js +100 -0
  35. package/dist/import/xml.js.map +1 -0
  36. package/dist/index.d.ts +12 -0
  37. package/dist/index.d.ts.map +1 -0
  38. package/dist/index.js +12 -0
  39. package/dist/index.js.map +1 -0
  40. package/dist/physics/rapier.d.ts +36 -0
  41. package/dist/physics/rapier.d.ts.map +1 -0
  42. package/dist/physics/rapier.js +137 -0
  43. package/dist/physics/rapier.js.map +1 -0
  44. package/dist/prism-deck.min.js +61229 -0
  45. package/dist/render/renderer.d.ts +78 -0
  46. package/dist/render/renderer.d.ts.map +1 -0
  47. package/dist/render/renderer.js +512 -0
  48. package/dist/render/renderer.js.map +1 -0
  49. package/dist/render/stereo.d.ts +20 -0
  50. package/dist/render/stereo.d.ts.map +1 -0
  51. package/dist/render/stereo.js +26 -0
  52. package/dist/render/stereo.js.map +1 -0
  53. package/dist/runtime/player.d.ts +30 -0
  54. package/dist/runtime/player.d.ts.map +1 -0
  55. package/dist/runtime/player.js +91 -0
  56. package/dist/runtime/player.js.map +1 -0
  57. package/dist/runtime/session.d.ts +50 -0
  58. package/dist/runtime/session.d.ts.map +1 -0
  59. package/dist/runtime/session.js +212 -0
  60. package/dist/runtime/session.js.map +1 -0
  61. package/dist/version.d.ts +2 -0
  62. package/dist/version.d.ts.map +1 -0
  63. package/dist/version.js +3 -0
  64. package/dist/version.js.map +1 -0
  65. package/package.json +61 -0
  66. package/schema/prismdeck.schema.json +124 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stereo.d.ts","sourceRoot":"","sources":["../../src/render/stereo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAE1C,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,UAAU,GAAG,UAAU,CAAC;AAE1D,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,YAAY,CAAC,CAIpE,CAAC;AAEH,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AA6BD,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,iBAAiB,EACvB,KAAK,EAAE,iBAAiB,EACxB,OAAO,EAAE,sBAAsB,GAC9B,IAAI,CAGN"}
@@ -0,0 +1,26 @@
1
+ import { PerspectiveCamera } from 'three';
2
+ export const OUTPUT_PRESETS = Object.freeze({
3
+ mono: { width: 1920, height: 1080, eyeWidth: 1920, logicalEyeAspect: 16 / 9 },
4
+ 'full-sbs': { width: 3840, height: 1080, eyeWidth: 1920, logicalEyeAspect: 16 / 9 },
5
+ 'half-sbs': { width: 1920, height: 1080, eyeWidth: 960, logicalEyeAspect: 16 / 9 },
6
+ });
7
+ function configureEye(camera, eyeOffset, options) {
8
+ const aspect = options.aspect ?? 16 / 9;
9
+ const top = options.near * Math.tan((options.fovDegrees * Math.PI) / 360);
10
+ const right = top * aspect;
11
+ const shift = (-eyeOffset * options.near) / Math.max(options.near, options.convergenceDistance);
12
+ camera.fov = options.fovDegrees;
13
+ camera.near = options.near;
14
+ camera.far = options.far;
15
+ camera.aspect = aspect;
16
+ camera.position.set(eyeOffset, 0, options.distance);
17
+ camera.quaternion.identity();
18
+ camera.projectionMatrix.makePerspective(-right + shift, right + shift, top, -top, options.near, options.far);
19
+ camera.projectionMatrixInverse.copy(camera.projectionMatrix).invert();
20
+ camera.updateMatrixWorld(true);
21
+ }
22
+ export function configureStereoCameraRig(left, right, options) {
23
+ configureEye(left, -options.eyeSeparation / 2, options);
24
+ configureEye(right, options.eyeSeparation / 2, options);
25
+ }
26
+ //# sourceMappingURL=stereo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stereo.js","sourceRoot":"","sources":["../../src/render/stereo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAW1C,MAAM,CAAC,MAAM,cAAc,GAA+C,MAAM,CAAC,MAAM,CAAC;IACtF,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAE,GAAG,CAAC,EAAE;IAC7E,UAAU,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAE,GAAG,CAAC,EAAE;IACnF,UAAU,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,gBAAgB,EAAE,EAAE,GAAG,CAAC,EAAE;CACnF,CAAC,CAAC;AAYH,SAAS,YAAY,CACnB,MAAyB,EACzB,SAAiB,EACjB,OAA+B;IAE/B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,EAAE,GAAG,CAAC,CAAC;IACxC,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC;IAC1E,MAAM,KAAK,GAAG,GAAG,GAAG,MAAM,CAAC;IAC3B,MAAM,KAAK,GAAG,CAAC,CAAC,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAChG,MAAM,CAAC,GAAG,GAAG,OAAO,CAAC,UAAU,CAAC;IAChC,MAAM,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAC3B,MAAM,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;IACzB,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IACpD,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC;IAC7B,MAAM,CAAC,gBAAgB,CAAC,eAAe,CACrC,CAAC,KAAK,GAAG,KAAK,EACd,KAAK,GAAG,KAAK,EACb,GAAG,EACH,CAAC,GAAG,EACJ,OAAO,CAAC,IAAI,EACZ,OAAO,CAAC,GAAG,CACZ,CAAC;IACF,MAAM,CAAC,uBAAuB,CAAC,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,MAAM,EAAE,CAAC;IACtE,MAAM,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,wBAAwB,CACtC,IAAuB,EACvB,KAAwB,EACxB,OAA+B;IAE/B,YAAY,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,aAAa,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;IACxD,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,aAAa,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;AAC1D,CAAC"}
@@ -0,0 +1,30 @@
1
+ import type { LoadedDeck } from '../document/types';
2
+ import { DeckPhysics, type DeckPhysicsOptions } from '../physics/rapier';
3
+ import { DeckRenderer, type DeckRendererOptions } from '../render/renderer';
4
+ import { PresentationSession, type PresentationSessionOptions } from './session';
5
+ export interface DeckPlayerOptions {
6
+ renderer?: DeckRendererOptions;
7
+ session?: PresentationSessionOptions;
8
+ physics?: boolean | DeckPhysicsOptions;
9
+ autoStart?: boolean;
10
+ }
11
+ export declare class DeckPlayer {
12
+ readonly session: PresentationSession;
13
+ readonly renderer: DeckRenderer;
14
+ readonly physics?: DeckPhysics;
15
+ private animationFrame?;
16
+ private previousFrameTime?;
17
+ private disposed;
18
+ private readonly sessionChangeListener;
19
+ private constructor();
20
+ static create(canvas: HTMLCanvasElement, deck: LoadedDeck, options?: DeckPlayerOptions): Promise<DeckPlayer>;
21
+ start(): void;
22
+ stop(): void;
23
+ renderFrame(timestamp?: number): void;
24
+ load(deck: LoadedDeck): void;
25
+ dispose(): void;
26
+ private readonly onAnimationFrame;
27
+ private resetPhysics;
28
+ private assertUsable;
29
+ }
30
+ //# sourceMappingURL=player.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"player.d.ts","sourceRoot":"","sources":["../../src/runtime/player.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EAAE,mBAAmB,EAAE,KAAK,0BAA0B,EAA4B,MAAM,WAAW,CAAC;AAE3G,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,mBAAmB,CAAC;IAC/B,OAAO,CAAC,EAAE,0BAA0B,CAAC;IACrC,OAAO,CAAC,EAAE,OAAO,GAAG,kBAAkB,CAAC;IACvC,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,qBAAa,UAAU;IACrB,QAAQ,CAAC,OAAO,EAAE,mBAAmB,CAAC;IACtC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,OAAO,CAAC,EAAE,WAAW,CAAC;IAC/B,OAAO,CAAC,cAAc,CAAC,CAAS;IAChC,OAAO,CAAC,iBAAiB,CAAC,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAGpC;IAEF,OAAO;WASM,MAAM,CAAC,MAAM,EAAE,iBAAiB,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,UAAU,CAAC;IAgBtH,KAAK,IAAI,IAAI;IAOb,IAAI,IAAI,IAAI;IAMZ,WAAW,CAAC,SAAS,SAAoB,GAAG,IAAI;IAShD,IAAI,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI;IAK5B,OAAO,IAAI,IAAI;IASf,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAK/B;IAEF,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,YAAY;CAGrB"}
@@ -0,0 +1,91 @@
1
+ import { DeckPhysics } from '../physics/rapier';
2
+ import { DeckRenderer } from '../render/renderer';
3
+ import { PresentationSession } from './session';
4
+ export class DeckPlayer {
5
+ session;
6
+ renderer;
7
+ physics;
8
+ animationFrame;
9
+ previousFrameTime;
10
+ disposed = false;
11
+ sessionChangeListener = (event) => {
12
+ const detail = event.detail;
13
+ if (detail.reason === 'deck' || detail.reason === 'slide' || detail.reason === 'content')
14
+ this.resetPhysics();
15
+ };
16
+ constructor(session, renderer, physics) {
17
+ this.session = session;
18
+ this.renderer = renderer;
19
+ this.physics = physics;
20
+ this.renderer.attach(this.session);
21
+ this.session.addEventListener('change', this.sessionChangeListener);
22
+ this.resetPhysics();
23
+ }
24
+ static async create(canvas, deck, options = {}) {
25
+ const session = new PresentationSession(deck, options.session);
26
+ const renderer = new DeckRenderer(canvas, options.renderer);
27
+ try {
28
+ const physics = options.physics
29
+ ? await DeckPhysics.create(typeof options.physics === 'object' ? options.physics : undefined)
30
+ : undefined;
31
+ const player = new DeckPlayer(session, renderer, physics);
32
+ if (options.autoStart)
33
+ player.start();
34
+ return player;
35
+ }
36
+ catch (error) {
37
+ renderer.dispose();
38
+ throw error;
39
+ }
40
+ }
41
+ start() {
42
+ this.assertUsable();
43
+ if (this.animationFrame !== undefined)
44
+ return;
45
+ this.previousFrameTime = undefined;
46
+ this.animationFrame = requestAnimationFrame(this.onAnimationFrame);
47
+ }
48
+ stop() {
49
+ if (this.animationFrame !== undefined)
50
+ cancelAnimationFrame(this.animationFrame);
51
+ this.animationFrame = undefined;
52
+ this.previousFrameTime = undefined;
53
+ }
54
+ renderFrame(timestamp = performance.now()) {
55
+ this.assertUsable();
56
+ const deltaSeconds = this.previousFrameTime === undefined ? 0 : Math.max(0, timestamp - this.previousFrameTime) / 1_000;
57
+ this.previousFrameTime = timestamp;
58
+ this.session.tick(timestamp);
59
+ if (this.physics)
60
+ this.renderer.applyPhysicsTransforms(this.physics.step(deltaSeconds));
61
+ this.renderer.render();
62
+ }
63
+ load(deck) {
64
+ this.assertUsable();
65
+ this.session.replaceDeck(deck);
66
+ }
67
+ dispose() {
68
+ if (this.disposed)
69
+ return;
70
+ this.stop();
71
+ this.disposed = true;
72
+ this.session.removeEventListener('change', this.sessionChangeListener);
73
+ this.physics?.dispose();
74
+ this.renderer.dispose();
75
+ }
76
+ onAnimationFrame = (timestamp) => {
77
+ this.animationFrame = undefined;
78
+ if (this.disposed)
79
+ return;
80
+ this.renderFrame(timestamp);
81
+ this.animationFrame = requestAnimationFrame(this.onAnimationFrame);
82
+ };
83
+ resetPhysics() {
84
+ this.physics?.setSlide(this.session.currentSlide, this.session.document.size);
85
+ }
86
+ assertUsable() {
87
+ if (this.disposed)
88
+ throw new Error('DeckPlayer has been disposed');
89
+ }
90
+ }
91
+ //# sourceMappingURL=player.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"player.js","sourceRoot":"","sources":["../../src/runtime/player.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ import type { DeckAsset, DeckDocument, DeckElement, DeckSlide, ElementPhysics, ElementTransform, LoadedDeck, TextElement } from '../document/types';
2
+ export type SessionChangeReason = 'deck' | 'slide' | 'content' | 'playback';
3
+ export interface SessionChangeDetail {
4
+ reason: SessionChangeReason;
5
+ slideIndex: number;
6
+ elementId?: string;
7
+ }
8
+ export interface PresentationSessionOptions {
9
+ loop?: boolean;
10
+ }
11
+ export interface CreateSlideOptions {
12
+ name?: string;
13
+ background?: string;
14
+ durationMs?: number;
15
+ insertAt?: number;
16
+ }
17
+ export declare class PresentationSession extends EventTarget {
18
+ readonly assets: Map<string, DeckAsset>;
19
+ private _document;
20
+ private _currentSlideIndex;
21
+ private _playing;
22
+ private playbackStartedAt;
23
+ private elapsedBeforePlay;
24
+ private loop;
25
+ constructor(deck: LoadedDeck, options?: PresentationSessionOptions);
26
+ get document(): DeckDocument;
27
+ get currentSlideIndex(): number;
28
+ get currentSlide(): DeckSlide | undefined;
29
+ get isPlaying(): boolean;
30
+ setLoop(loop: boolean): void;
31
+ replaceDeck(deck: LoadedDeck): void;
32
+ goTo(index: number): boolean;
33
+ next(): boolean;
34
+ previous(): boolean;
35
+ play(now?: number): void;
36
+ pause(now?: number): void;
37
+ tick(now?: number): boolean;
38
+ createSlide(layoutId: string, options?: CreateSlideOptions): DeckSlide;
39
+ updateElementTransform(elementId: string, patch: Partial<ElementTransform>): boolean;
40
+ updateElementPhysics(elementId: string, physics: ElementPhysics | undefined): boolean;
41
+ updateText(elementId: string, text: string): boolean;
42
+ removeElement(elementId: string): boolean;
43
+ findElement(elementId: string): DeckElement | undefined;
44
+ findTextElement(elementId: string): TextElement | undefined;
45
+ notifyContentChanged(elementId?: string): void;
46
+ private replaceAssets;
47
+ private resetPlaybackClock;
48
+ private emit;
49
+ }
50
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/runtime/session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,YAAY,EACZ,WAAW,EACX,SAAS,EACT,cAAc,EACd,gBAAgB,EAChB,UAAU,EACV,WAAW,EACZ,MAAM,mBAAmB,CAAC;AAG3B,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,UAAU,CAAC;AAE5E,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,mBAAmB,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,0BAA0B;IACzC,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAoBD,qBAAa,mBAAoB,SAAQ,WAAW;IAClD,QAAQ,CAAC,MAAM,yBAAgC;IAC/C,OAAO,CAAC,SAAS,CAAe;IAChC,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,IAAI,CAAU;gBAEV,IAAI,EAAE,UAAU,EAAE,OAAO,GAAE,0BAA+B;IAStE,IAAI,QAAQ,IAAI,YAAY,CAE3B;IAED,IAAI,iBAAiB,IAAI,MAAM,CAE9B;IAED,IAAI,YAAY,IAAI,SAAS,GAAG,SAAS,CAExC;IAED,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;IAI5B,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI;IASnC,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAS5B,IAAI,IAAI,OAAO;IASf,QAAQ,IAAI,OAAO;IAQnB,IAAI,CAAC,GAAG,SAAoB,GAAG,IAAI;IAOnC,KAAK,CAAC,GAAG,SAAoB,GAAG,IAAI;IAOpC,IAAI,CAAC,GAAG,SAAoB,GAAG,OAAO;IAqBtC,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,kBAAuB,GAAG,SAAS;IAuB1E,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,OAAO;IAQpF,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,SAAS,GAAG,OAAO;IAQrF,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO;IAUpD,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAUzC,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAIvD,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAK3D,oBAAoB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI;IAK9C,OAAO,CAAC,aAAa;IAKrB,OAAO,CAAC,kBAAkB;IAK1B,OAAO,CAAC,IAAI;CAOb"}
@@ -0,0 +1,212 @@
1
+ import { validateDeckDocument } from '../document/validate';
2
+ function cloneDocument(document) {
3
+ return JSON.parse(JSON.stringify(document));
4
+ }
5
+ let fallbackId = 0;
6
+ function uniqueId(prefix) {
7
+ if (globalThis.crypto?.randomUUID)
8
+ return `${prefix}-${globalThis.crypto.randomUUID()}`;
9
+ fallbackId += 1;
10
+ return `${prefix}-${Date.now().toString(36)}-${fallbackId.toString(36)}`;
11
+ }
12
+ function cloneLayoutElement(element) {
13
+ const cloned = JSON.parse(JSON.stringify(element));
14
+ cloned.id = uniqueId('element');
15
+ return cloned;
16
+ }
17
+ export class PresentationSession extends EventTarget {
18
+ assets = new Map();
19
+ _document;
20
+ _currentSlideIndex;
21
+ _playing = false;
22
+ playbackStartedAt = 0;
23
+ elapsedBeforePlay = 0;
24
+ loop;
25
+ constructor(deck, options = {}) {
26
+ super();
27
+ validateDeckDocument(deck.document);
28
+ this._document = cloneDocument(deck.document);
29
+ this.replaceAssets(deck.assets);
30
+ this._currentSlideIndex = this._document.slides.length > 0 ? 0 : -1;
31
+ this.loop = options.loop ?? false;
32
+ }
33
+ get document() {
34
+ return this._document;
35
+ }
36
+ get currentSlideIndex() {
37
+ return this._currentSlideIndex;
38
+ }
39
+ get currentSlide() {
40
+ return this._document.slides[this._currentSlideIndex];
41
+ }
42
+ get isPlaying() {
43
+ return this._playing;
44
+ }
45
+ setLoop(loop) {
46
+ this.loop = loop;
47
+ }
48
+ replaceDeck(deck) {
49
+ validateDeckDocument(deck.document);
50
+ this.pause();
51
+ this._document = cloneDocument(deck.document);
52
+ this.replaceAssets(deck.assets);
53
+ this._currentSlideIndex = this._document.slides.length > 0 ? 0 : -1;
54
+ this.emit('deck');
55
+ }
56
+ goTo(index) {
57
+ if (!Number.isInteger(index) || index < 0 || index >= this._document.slides.length)
58
+ return false;
59
+ if (index === this._currentSlideIndex)
60
+ return true;
61
+ this._currentSlideIndex = index;
62
+ this.resetPlaybackClock();
63
+ this.emit('slide');
64
+ return true;
65
+ }
66
+ next() {
67
+ if (this._document.slides.length === 0)
68
+ return false;
69
+ const nextIndex = this._currentSlideIndex + 1;
70
+ if (nextIndex < this._document.slides.length)
71
+ return this.goTo(nextIndex);
72
+ if (this.loop)
73
+ return this.goTo(0);
74
+ this.pause();
75
+ return false;
76
+ }
77
+ previous() {
78
+ if (this._document.slides.length === 0)
79
+ return false;
80
+ const previousIndex = this._currentSlideIndex - 1;
81
+ if (previousIndex >= 0)
82
+ return this.goTo(previousIndex);
83
+ if (this.loop)
84
+ return this.goTo(this._document.slides.length - 1);
85
+ return false;
86
+ }
87
+ play(now = performance.now()) {
88
+ if (this._playing || !this.currentSlide)
89
+ return;
90
+ this._playing = true;
91
+ this.playbackStartedAt = now;
92
+ this.emit('playback');
93
+ }
94
+ pause(now = performance.now()) {
95
+ if (!this._playing)
96
+ return;
97
+ this.elapsedBeforePlay += Math.max(0, now - this.playbackStartedAt);
98
+ this._playing = false;
99
+ this.emit('playback');
100
+ }
101
+ tick(now = performance.now()) {
102
+ if (!this._playing || !this.currentSlide)
103
+ return false;
104
+ let elapsed = this.elapsedBeforePlay + Math.max(0, now - this.playbackStartedAt);
105
+ let advanced = false;
106
+ let remainingAdvances = this._document.slides.length;
107
+ while (this.currentSlide &&
108
+ (this.currentSlide.durationMs === 0 || elapsed >= this.currentSlide.durationMs) &&
109
+ remainingAdvances > 0) {
110
+ if (this.currentSlide.durationMs > 0)
111
+ elapsed -= this.currentSlide.durationMs;
112
+ if (!this.next())
113
+ return advanced;
114
+ advanced = true;
115
+ remainingAdvances -= 1;
116
+ this.playbackStartedAt = now - elapsed;
117
+ this.elapsedBeforePlay = 0;
118
+ }
119
+ if (remainingAdvances === 0 && this.currentSlide?.durationMs === 0)
120
+ this.pause(now);
121
+ return advanced;
122
+ }
123
+ createSlide(layoutId, options = {}) {
124
+ const layout = this._document.layouts.find((candidate) => candidate.id === layoutId);
125
+ if (!layout)
126
+ throw new Error(`Unknown layout: ${layoutId}`);
127
+ const slide = {
128
+ id: uniqueId('slide'),
129
+ name: options.name ?? `Slide ${this._document.slides.length + 1}`,
130
+ layoutId,
131
+ durationMs: options.durationMs ?? 5_000,
132
+ background: options.background ?? '#FFFFFF',
133
+ elements: layout.elements.map(cloneLayoutElement),
134
+ };
135
+ const insertAt = Math.min(this._document.slides.length, Math.max(0, options.insertAt ?? this._document.slides.length));
136
+ this._document.slides.splice(insertAt, 0, slide);
137
+ this._document.kind = 'presentation';
138
+ if (this._currentSlideIndex < 0)
139
+ this._currentSlideIndex = insertAt;
140
+ else if (insertAt <= this._currentSlideIndex)
141
+ this._currentSlideIndex += 1;
142
+ this.emit('content');
143
+ return slide;
144
+ }
145
+ updateElementTransform(elementId, patch) {
146
+ const element = this.findElement(elementId);
147
+ if (!element)
148
+ return false;
149
+ element.transform = { ...element.transform, ...patch };
150
+ this.emit('content', elementId);
151
+ return true;
152
+ }
153
+ updateElementPhysics(elementId, physics) {
154
+ const element = this.findElement(elementId);
155
+ if (!element)
156
+ return false;
157
+ element.physics = physics ? { ...physics } : undefined;
158
+ this.emit('content', elementId);
159
+ return true;
160
+ }
161
+ updateText(elementId, text) {
162
+ const element = this.findElement(elementId);
163
+ if (!element)
164
+ return false;
165
+ if (element.type === 'text')
166
+ element.text = text;
167
+ else if (element.type === 'shape')
168
+ element.text = text;
169
+ else
170
+ return false;
171
+ this.emit('content', elementId);
172
+ return true;
173
+ }
174
+ removeElement(elementId) {
175
+ const elements = this.currentSlide?.elements;
176
+ if (!elements)
177
+ return false;
178
+ const index = elements.findIndex((element) => element.id === elementId);
179
+ if (index < 0)
180
+ return false;
181
+ elements.splice(index, 1);
182
+ this.emit('content', elementId);
183
+ return true;
184
+ }
185
+ findElement(elementId) {
186
+ return this.currentSlide?.elements.find((element) => element.id === elementId);
187
+ }
188
+ findTextElement(elementId) {
189
+ const element = this.findElement(elementId);
190
+ return element?.type === 'text' ? element : undefined;
191
+ }
192
+ notifyContentChanged(elementId) {
193
+ validateDeckDocument(this._document);
194
+ this.emit('content', elementId);
195
+ }
196
+ replaceAssets(assets) {
197
+ this.assets.clear();
198
+ for (const [id, asset] of assets)
199
+ this.assets.set(id, asset);
200
+ }
201
+ resetPlaybackClock() {
202
+ this.elapsedBeforePlay = 0;
203
+ if (this._playing)
204
+ this.playbackStartedAt = performance.now();
205
+ }
206
+ emit(reason, elementId) {
207
+ this.dispatchEvent(new CustomEvent('change', {
208
+ detail: { reason, slideIndex: this._currentSlideIndex, elementId },
209
+ }));
210
+ }
211
+ }
212
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/runtime/session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const PRISMDECK_PACKAGE_VERSION: string;
2
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,yBAAyB,QAA0B,CAAC"}
@@ -0,0 +1,3 @@
1
+ import packageMetadata from '../package.json' with { type: 'json' };
2
+ export const PRISMDECK_PACKAGE_VERSION = packageMetadata.version;
3
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,MAAM,iBAAiB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAEpE,MAAM,CAAC,MAAM,yBAAyB,GAAG,eAAe,CAAC,OAAO,CAAC"}
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "prismdeckjs",
3
+ "version": "0.1.0",
4
+ "description": "Browser-native spatial presentation SDK",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "homepage": "https://lunarmoon26.github.io/PrismDeckJS/",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/lunarmoon26/PrismDeckJS.git",
11
+ "directory": "packages/prismdeck"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/lunarmoon26/PrismDeckJS/issues"
15
+ },
16
+ "keywords": [
17
+ "presentation",
18
+ "pptx",
19
+ "odp",
20
+ "three.js",
21
+ "stereo",
22
+ "browser"
23
+ ],
24
+ "sideEffects": false,
25
+ "main": "./dist/index.js",
26
+ "types": "./dist/index.d.ts",
27
+ "unpkg": "./dist/prism-deck.min.js",
28
+ "jsdelivr": "./dist/prism-deck.min.js",
29
+ "exports": {
30
+ ".": {
31
+ "types": "./dist/index.d.ts",
32
+ "import": "./dist/index.js"
33
+ },
34
+ "./browser": {
35
+ "types": "./dist/index.d.ts",
36
+ "import": "./dist/prism-deck.min.js"
37
+ },
38
+ "./schema": "./schema/prismdeck.schema.json"
39
+ },
40
+ "files": [
41
+ "dist",
42
+ "schema",
43
+ "README.md"
44
+ ],
45
+ "scripts": {
46
+ "build": "vite build --config vite.browser.config.ts && tsc -p tsconfig.json",
47
+ "test": "vitest run",
48
+ "test:watch": "vitest",
49
+ "typecheck": "tsc -p tsconfig.json --noEmit"
50
+ },
51
+ "dependencies": {
52
+ "@aiden0z/pptx-renderer": "1.2.4",
53
+ "@dimforge/rapier3d-compat": "0.20.0",
54
+ "ajv": "^8.17.1",
55
+ "fflate": "^0.8.2",
56
+ "three": "0.185.1"
57
+ },
58
+ "devDependencies": {
59
+ "vite": "^7.1.0"
60
+ }
61
+ }
@@ -0,0 +1,124 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://prismdeckjs.dev/schema/prismdeck-0.1.0.json",
4
+ "title": "PrismDeck document",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["schemaVersion", "id", "kind", "metadata", "size", "layouts", "slides"],
8
+ "properties": {
9
+ "schemaVersion": { "const": "0.1.0" },
10
+ "id": { "$ref": "#/$defs/id" },
11
+ "kind": { "enum": ["presentation", "template"] },
12
+ "metadata": {
13
+ "type": "object",
14
+ "additionalProperties": false,
15
+ "required": ["title"],
16
+ "properties": {
17
+ "title": { "type": "string" },
18
+ "author": { "type": "string" },
19
+ "description": { "type": "string" },
20
+ "createdAt": { "type": "string" },
21
+ "modifiedAt": { "type": "string" },
22
+ "sourceFormat": { "enum": ["pptx", "odp", "prismdeck", "native"] }
23
+ }
24
+ },
25
+ "size": { "$ref": "#/$defs/size" },
26
+ "layouts": {
27
+ "type": "array",
28
+ "items": { "$ref": "#/$defs/layout" }
29
+ },
30
+ "slides": {
31
+ "type": "array",
32
+ "items": { "$ref": "#/$defs/slide" }
33
+ }
34
+ },
35
+ "$defs": {
36
+ "id": { "type": "string", "minLength": 1, "maxLength": 200 },
37
+ "size": {
38
+ "type": "object",
39
+ "additionalProperties": false,
40
+ "required": ["width", "height"],
41
+ "properties": {
42
+ "width": { "type": "number", "exclusiveMinimum": 0 },
43
+ "height": { "type": "number", "exclusiveMinimum": 0 }
44
+ }
45
+ },
46
+ "frame": {
47
+ "type": "object",
48
+ "additionalProperties": false,
49
+ "required": ["x", "y", "width", "height"],
50
+ "properties": {
51
+ "x": { "type": "number" },
52
+ "y": { "type": "number" },
53
+ "width": { "type": "number", "minimum": 0 },
54
+ "height": { "type": "number", "minimum": 0 }
55
+ }
56
+ },
57
+ "transform": {
58
+ "type": "object",
59
+ "additionalProperties": false,
60
+ "required": ["z", "rotationX", "rotationY", "rotationZ", "scaleX", "scaleY"],
61
+ "properties": {
62
+ "z": { "type": "number" },
63
+ "rotationX": { "type": "number" },
64
+ "rotationY": { "type": "number" },
65
+ "rotationZ": { "type": "number" },
66
+ "scaleX": { "type": "number" },
67
+ "scaleY": { "type": "number" }
68
+ }
69
+ },
70
+ "physics": {
71
+ "type": "object",
72
+ "additionalProperties": false,
73
+ "required": ["body", "shape", "density", "restitution", "friction"],
74
+ "properties": {
75
+ "body": { "enum": ["fixed", "dynamic", "kinematic", "sensor"] },
76
+ "shape": { "enum": ["cuboid", "ball"] },
77
+ "density": { "type": "number", "minimum": 0 },
78
+ "restitution": { "type": "number", "minimum": 0, "maximum": 1 },
79
+ "friction": { "type": "number", "minimum": 0, "maximum": 2 }
80
+ }
81
+ },
82
+ "element": {
83
+ "type": "object",
84
+ "additionalProperties": true,
85
+ "required": ["id", "type", "name", "frame", "transform", "opacity", "visible", "renderOrder"],
86
+ "properties": {
87
+ "id": { "$ref": "#/$defs/id" },
88
+ "type": { "enum": ["text", "image", "shape", "table", "chart", "unsupported"] },
89
+ "name": { "type": "string" },
90
+ "frame": { "$ref": "#/$defs/frame" },
91
+ "transform": { "$ref": "#/$defs/transform" },
92
+ "opacity": { "type": "number", "minimum": 0, "maximum": 1 },
93
+ "visible": { "type": "boolean" },
94
+ "renderOrder": { "type": "integer" },
95
+ "thickness": { "type": "number", "minimum": 0 },
96
+ "physics": { "$ref": "#/$defs/physics" }
97
+ }
98
+ },
99
+ "layout": {
100
+ "type": "object",
101
+ "additionalProperties": false,
102
+ "required": ["id", "name", "elements"],
103
+ "properties": {
104
+ "id": { "$ref": "#/$defs/id" },
105
+ "name": { "type": "string" },
106
+ "elements": { "type": "array", "items": { "$ref": "#/$defs/element" } }
107
+ }
108
+ },
109
+ "slide": {
110
+ "type": "object",
111
+ "additionalProperties": false,
112
+ "required": ["id", "name", "durationMs", "background", "elements"],
113
+ "properties": {
114
+ "id": { "$ref": "#/$defs/id" },
115
+ "name": { "type": "string" },
116
+ "layoutId": { "$ref": "#/$defs/id" },
117
+ "durationMs": { "type": "number", "minimum": 0 },
118
+ "background": { "type": "string", "pattern": "^#[0-9a-fA-F]{6}([0-9a-fA-F]{2})?$" },
119
+ "notes": { "type": "string" },
120
+ "elements": { "type": "array", "items": { "$ref": "#/$defs/element" } }
121
+ }
122
+ }
123
+ }
124
+ }