animot-presenter 0.5.6 → 0.5.9
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/AnimotPresenter.svelte +40 -3
- package/dist/EmbedPlayer.svelte +239 -0
- package/dist/EmbedPlayer.svelte.d.ts +17 -0
- package/dist/cdn/animot-presenter.css +1 -1
- package/dist/cdn/animot-presenter.esm.js +5380 -4900
- package/dist/cdn/animot-presenter.min.js +10 -10
- package/dist/types.d.ts +55 -1
- package/dist/utils/animated-image.d.ts +35 -0
- package/dist/utils/animated-image.js +100 -0
- package/dist/utils/camera.d.ts +43 -0
- package/dist/utils/camera.js +66 -0
- package/dist/utils/decorations.d.ts +26 -0
- package/dist/utils/decorations.js +279 -0
- package/dist/utils/embed-players.d.ts +50 -0
- package/dist/utils/embed-players.js +152 -0
- package/dist/utils/video-embed.d.ts +30 -0
- package/dist/utils/video-embed.js +70 -0
- package/package.json +84 -84
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified wrapper around YouTube IFrame Player API and Vimeo Player.js so the
|
|
3
|
+
* rest of the app can drive embedded videos with the same play/pause/seek/
|
|
4
|
+
* volume calls used for `<video>` elements. The provider libraries are lazy-
|
|
5
|
+
* loaded on first use so a project with no embeds doesn't pay the network cost.
|
|
6
|
+
*
|
|
7
|
+
* What this enables:
|
|
8
|
+
* • Auto-pause embeds when the user navigates away from a slide.
|
|
9
|
+
* • Reset embed `currentTime` to startTime on slide enter (otherwise YouTube
|
|
10
|
+
* persists position across iframe rebuilds).
|
|
11
|
+
* • Render OUR own play/pause/scrub controls on top of the iframe (we hide
|
|
12
|
+
* YouTube's chrome via `controls=0` in the embed URL).
|
|
13
|
+
*
|
|
14
|
+
* What this does NOT enable: server-side export capture. YouTube/Vimeo render
|
|
15
|
+
* frames inside their player; Puppeteer can't screenshot cross-origin iframe
|
|
16
|
+
* content, so exports of slides containing embeds still fall back to the
|
|
17
|
+
* provider-supplied thumbnail (handled in /present's render path).
|
|
18
|
+
*/
|
|
19
|
+
export declare function loadYouTubeAPI(): Promise<typeof window['YT']>;
|
|
20
|
+
export declare function loadVimeoAPI(): Promise<any>;
|
|
21
|
+
export interface UnifiedPlayer {
|
|
22
|
+
play(): Promise<void> | void;
|
|
23
|
+
pause(): Promise<void> | void;
|
|
24
|
+
seekTo(seconds: number): Promise<void> | void;
|
|
25
|
+
getCurrentTime(): Promise<number>;
|
|
26
|
+
getDuration(): Promise<number>;
|
|
27
|
+
setVolume(v: number): void;
|
|
28
|
+
setMuted(m: boolean): void;
|
|
29
|
+
setPlaybackRate(r: number): void;
|
|
30
|
+
destroy(): void;
|
|
31
|
+
/** Subscribe to playing-state changes. Call returned fn to unsubscribe. */
|
|
32
|
+
onStateChange(cb: (state: 'playing' | 'paused' | 'ended' | 'buffering' | 'cued' | 'unstarted') => void): () => void;
|
|
33
|
+
}
|
|
34
|
+
interface CreateOptions {
|
|
35
|
+
provider: 'youtube' | 'vimeo';
|
|
36
|
+
/** The actual <iframe> element. We attach the player to it. */
|
|
37
|
+
iframe: HTMLIFrameElement;
|
|
38
|
+
/** Provider video ID (used for the YouTube ctor; Vimeo binds straight to iframe). */
|
|
39
|
+
videoId?: string;
|
|
40
|
+
startTime?: number;
|
|
41
|
+
muted?: boolean;
|
|
42
|
+
}
|
|
43
|
+
export declare function createEmbedPlayer(opts: CreateOptions): Promise<UnifiedPlayer>;
|
|
44
|
+
declare global {
|
|
45
|
+
interface Window {
|
|
46
|
+
YT: any;
|
|
47
|
+
onYouTubeIframeAPIReady?: () => void;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
export {};
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified wrapper around YouTube IFrame Player API and Vimeo Player.js so the
|
|
3
|
+
* rest of the app can drive embedded videos with the same play/pause/seek/
|
|
4
|
+
* volume calls used for `<video>` elements. The provider libraries are lazy-
|
|
5
|
+
* loaded on first use so a project with no embeds doesn't pay the network cost.
|
|
6
|
+
*
|
|
7
|
+
* What this enables:
|
|
8
|
+
* • Auto-pause embeds when the user navigates away from a slide.
|
|
9
|
+
* • Reset embed `currentTime` to startTime on slide enter (otherwise YouTube
|
|
10
|
+
* persists position across iframe rebuilds).
|
|
11
|
+
* • Render OUR own play/pause/scrub controls on top of the iframe (we hide
|
|
12
|
+
* YouTube's chrome via `controls=0` in the embed URL).
|
|
13
|
+
*
|
|
14
|
+
* What this does NOT enable: server-side export capture. YouTube/Vimeo render
|
|
15
|
+
* frames inside their player; Puppeteer can't screenshot cross-origin iframe
|
|
16
|
+
* content, so exports of slides containing embeds still fall back to the
|
|
17
|
+
* provider-supplied thumbnail (handled in /present's render path).
|
|
18
|
+
*/
|
|
19
|
+
let ytApiPromise = null;
|
|
20
|
+
export function loadYouTubeAPI() {
|
|
21
|
+
if (typeof window === 'undefined')
|
|
22
|
+
return Promise.reject(new Error('SSR'));
|
|
23
|
+
if (window.YT && window.YT.Player)
|
|
24
|
+
return Promise.resolve(window.YT);
|
|
25
|
+
if (ytApiPromise)
|
|
26
|
+
return ytApiPromise;
|
|
27
|
+
ytApiPromise = new Promise((resolve, reject) => {
|
|
28
|
+
// The IFrame API expects a global callback. Chain any pre-existing one
|
|
29
|
+
// so we play nicely with other libraries on the page.
|
|
30
|
+
const prev = window.onYouTubeIframeAPIReady;
|
|
31
|
+
window.onYouTubeIframeAPIReady = () => {
|
|
32
|
+
if (typeof prev === 'function') {
|
|
33
|
+
try {
|
|
34
|
+
prev();
|
|
35
|
+
}
|
|
36
|
+
catch { }
|
|
37
|
+
}
|
|
38
|
+
resolve(window.YT);
|
|
39
|
+
};
|
|
40
|
+
const tag = document.createElement('script');
|
|
41
|
+
tag.src = 'https://www.youtube.com/iframe_api';
|
|
42
|
+
tag.async = true;
|
|
43
|
+
tag.onerror = () => reject(new Error('Failed to load YouTube IFrame API'));
|
|
44
|
+
document.head.appendChild(tag);
|
|
45
|
+
});
|
|
46
|
+
return ytApiPromise;
|
|
47
|
+
}
|
|
48
|
+
let vimeoApiPromise = null;
|
|
49
|
+
export function loadVimeoAPI() {
|
|
50
|
+
if (typeof window === 'undefined')
|
|
51
|
+
return Promise.reject(new Error('SSR'));
|
|
52
|
+
const w = window;
|
|
53
|
+
if (w.Vimeo && w.Vimeo.Player)
|
|
54
|
+
return Promise.resolve(w.Vimeo);
|
|
55
|
+
if (vimeoApiPromise)
|
|
56
|
+
return vimeoApiPromise;
|
|
57
|
+
vimeoApiPromise = new Promise((resolve, reject) => {
|
|
58
|
+
const tag = document.createElement('script');
|
|
59
|
+
tag.src = 'https://player.vimeo.com/api/player.js';
|
|
60
|
+
tag.async = true;
|
|
61
|
+
tag.onload = () => resolve(window.Vimeo);
|
|
62
|
+
tag.onerror = () => reject(new Error('Failed to load Vimeo Player API'));
|
|
63
|
+
document.head.appendChild(tag);
|
|
64
|
+
});
|
|
65
|
+
return vimeoApiPromise;
|
|
66
|
+
}
|
|
67
|
+
export async function createEmbedPlayer(opts) {
|
|
68
|
+
if (opts.provider === 'youtube')
|
|
69
|
+
return createYouTubePlayer(opts);
|
|
70
|
+
return createVimeoPlayer(opts);
|
|
71
|
+
}
|
|
72
|
+
async function createYouTubePlayer(opts) {
|
|
73
|
+
const YT = await loadYouTubeAPI();
|
|
74
|
+
let stateCbs = [];
|
|
75
|
+
const player = await new Promise((resolve) => {
|
|
76
|
+
const p = new YT.Player(opts.iframe, {
|
|
77
|
+
events: {
|
|
78
|
+
onReady: () => resolve(p),
|
|
79
|
+
onStateChange: (e) => {
|
|
80
|
+
const map = {
|
|
81
|
+
[-1]: 'unstarted',
|
|
82
|
+
[0]: 'ended',
|
|
83
|
+
[1]: 'playing',
|
|
84
|
+
[2]: 'paused',
|
|
85
|
+
[3]: 'buffering',
|
|
86
|
+
[5]: 'cued'
|
|
87
|
+
};
|
|
88
|
+
const state = map[e.data] ?? 'unstarted';
|
|
89
|
+
for (const cb of stateCbs)
|
|
90
|
+
try {
|
|
91
|
+
cb(state);
|
|
92
|
+
}
|
|
93
|
+
catch { }
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
if (opts.muted)
|
|
99
|
+
player.mute();
|
|
100
|
+
if (opts.startTime)
|
|
101
|
+
try {
|
|
102
|
+
player.seekTo(opts.startTime, true);
|
|
103
|
+
}
|
|
104
|
+
catch { }
|
|
105
|
+
return {
|
|
106
|
+
play: () => player.playVideo(),
|
|
107
|
+
pause: () => player.pauseVideo(),
|
|
108
|
+
seekTo: (s) => player.seekTo(s, true),
|
|
109
|
+
getCurrentTime: async () => Number(player.getCurrentTime()) || 0,
|
|
110
|
+
getDuration: async () => Number(player.getDuration()) || 0,
|
|
111
|
+
setVolume: (v) => player.setVolume(Math.max(0, Math.min(100, v * 100))),
|
|
112
|
+
setMuted: (m) => (m ? player.mute() : player.unMute()),
|
|
113
|
+
setPlaybackRate: (r) => player.setPlaybackRate(r),
|
|
114
|
+
destroy: () => { try {
|
|
115
|
+
player.destroy();
|
|
116
|
+
}
|
|
117
|
+
catch { } },
|
|
118
|
+
onStateChange: (cb) => { stateCbs.push(cb); return () => { stateCbs = stateCbs.filter((f) => f !== cb); }; }
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
async function createVimeoPlayer(opts) {
|
|
122
|
+
const Vimeo = await loadVimeoAPI();
|
|
123
|
+
const player = new Vimeo.Player(opts.iframe);
|
|
124
|
+
let stateCbs = [];
|
|
125
|
+
await player.ready();
|
|
126
|
+
if (opts.muted)
|
|
127
|
+
await player.setMuted(true);
|
|
128
|
+
if (opts.startTime)
|
|
129
|
+
try {
|
|
130
|
+
await player.setCurrentTime(opts.startTime);
|
|
131
|
+
}
|
|
132
|
+
catch { }
|
|
133
|
+
player.on('play', () => stateCbs.forEach((cb) => cb('playing')));
|
|
134
|
+
player.on('pause', () => stateCbs.forEach((cb) => cb('paused')));
|
|
135
|
+
player.on('ended', () => stateCbs.forEach((cb) => cb('ended')));
|
|
136
|
+
player.on('bufferstart', () => stateCbs.forEach((cb) => cb('buffering')));
|
|
137
|
+
return {
|
|
138
|
+
play: () => player.play(),
|
|
139
|
+
pause: () => player.pause(),
|
|
140
|
+
seekTo: (s) => player.setCurrentTime(s),
|
|
141
|
+
getCurrentTime: () => player.getCurrentTime(),
|
|
142
|
+
getDuration: () => player.getDuration(),
|
|
143
|
+
setVolume: (v) => player.setVolume(Math.max(0, Math.min(1, v))),
|
|
144
|
+
setMuted: (m) => player.setMuted(m),
|
|
145
|
+
setPlaybackRate: (r) => player.setPlaybackRate(r),
|
|
146
|
+
destroy: () => { try {
|
|
147
|
+
player.destroy();
|
|
148
|
+
}
|
|
149
|
+
catch { } },
|
|
150
|
+
onStateChange: (cb) => { stateCbs.push(cb); return () => { stateCbs = stateCbs.filter((f) => f !== cb); }; }
|
|
151
|
+
};
|
|
152
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse a video URL into an embed descriptor. Supports YouTube and Vimeo.
|
|
3
|
+
* Returns null for URLs we don't recognize (the caller should treat those as
|
|
4
|
+
* raw `<video src>` files). Used by VideoElement renderers to switch between
|
|
5
|
+
* `<video>` and `<iframe>` rendering.
|
|
6
|
+
*
|
|
7
|
+
* Important: embed URLs cannot be captured by the server-side export pipeline
|
|
8
|
+
* (cross-origin iframe content isn't accessible to Puppeteer's `__tick` virtual
|
|
9
|
+
* clock and YouTube's player ignores any external time signal). We surface
|
|
10
|
+
* this as a warning in the properties panel.
|
|
11
|
+
*/
|
|
12
|
+
export interface VideoEmbed {
|
|
13
|
+
provider: 'youtube' | 'vimeo';
|
|
14
|
+
/** ID of the video on the provider (`dQw4w9WgXcQ` for YouTube, `123456` for Vimeo). */
|
|
15
|
+
id: string;
|
|
16
|
+
/** Fully-formed src for an `<iframe>`. */
|
|
17
|
+
embedSrc: string;
|
|
18
|
+
/** A poster image we can probe for from the provider. */
|
|
19
|
+
thumbnail?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface ParseEmbedOptions {
|
|
22
|
+
autoplay?: boolean;
|
|
23
|
+
loop?: boolean;
|
|
24
|
+
muted?: boolean;
|
|
25
|
+
startTime?: number;
|
|
26
|
+
endTime?: number;
|
|
27
|
+
showControls?: boolean;
|
|
28
|
+
}
|
|
29
|
+
export declare function parseEmbedUrl(url: string, opts?: ParseEmbedOptions): VideoEmbed | null;
|
|
30
|
+
export declare function isEmbedUrl(url: string): boolean;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse a video URL into an embed descriptor. Supports YouTube and Vimeo.
|
|
3
|
+
* Returns null for URLs we don't recognize (the caller should treat those as
|
|
4
|
+
* raw `<video src>` files). Used by VideoElement renderers to switch between
|
|
5
|
+
* `<video>` and `<iframe>` rendering.
|
|
6
|
+
*
|
|
7
|
+
* Important: embed URLs cannot be captured by the server-side export pipeline
|
|
8
|
+
* (cross-origin iframe content isn't accessible to Puppeteer's `__tick` virtual
|
|
9
|
+
* clock and YouTube's player ignores any external time signal). We surface
|
|
10
|
+
* this as a warning in the properties panel.
|
|
11
|
+
*/
|
|
12
|
+
const YOUTUBE_RE = /(?:youtube\.com\/(?:watch\?v=|embed\/|shorts\/|live\/)|youtu\.be\/)([A-Za-z0-9_-]{6,16})/;
|
|
13
|
+
const VIMEO_RE = /vimeo\.com\/(?:video\/)?(\d{6,12})/;
|
|
14
|
+
export function parseEmbedUrl(url, opts = {}) {
|
|
15
|
+
if (!url)
|
|
16
|
+
return null;
|
|
17
|
+
if (url.startsWith('data:'))
|
|
18
|
+
return null;
|
|
19
|
+
const ytMatch = url.match(YOUTUBE_RE);
|
|
20
|
+
if (ytMatch) {
|
|
21
|
+
const id = ytMatch[1];
|
|
22
|
+
// YouTube's embed parameters: muted+autoplay = playsinline-on-mobile-friendly,
|
|
23
|
+
// loop requires both `loop=1` AND `playlist=<same id>` (quirk of YouTube's API).
|
|
24
|
+
const params = [];
|
|
25
|
+
if (opts.autoplay)
|
|
26
|
+
params.push('autoplay=1');
|
|
27
|
+
if (opts.muted || opts.autoplay)
|
|
28
|
+
params.push('mute=1'); // browsers block unmuted autoplay
|
|
29
|
+
if (opts.loop) {
|
|
30
|
+
params.push('loop=1');
|
|
31
|
+
params.push(`playlist=${id}`);
|
|
32
|
+
}
|
|
33
|
+
if (opts.startTime)
|
|
34
|
+
params.push(`start=${Math.round(opts.startTime)}`);
|
|
35
|
+
if (opts.endTime)
|
|
36
|
+
params.push(`end=${Math.round(opts.endTime)}`);
|
|
37
|
+
if (!opts.showControls)
|
|
38
|
+
params.push('controls=0');
|
|
39
|
+
params.push('rel=0', 'modestbranding=1', 'playsinline=1');
|
|
40
|
+
return {
|
|
41
|
+
provider: 'youtube',
|
|
42
|
+
id,
|
|
43
|
+
embedSrc: `https://www.youtube.com/embed/${id}?${params.join('&')}`,
|
|
44
|
+
thumbnail: `https://i.ytimg.com/vi/${id}/maxresdefault.jpg`
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
const vimMatch = url.match(VIMEO_RE);
|
|
48
|
+
if (vimMatch) {
|
|
49
|
+
const id = vimMatch[1];
|
|
50
|
+
const params = [];
|
|
51
|
+
if (opts.autoplay)
|
|
52
|
+
params.push('autoplay=1');
|
|
53
|
+
if (opts.muted || opts.autoplay)
|
|
54
|
+
params.push('muted=1');
|
|
55
|
+
if (opts.loop)
|
|
56
|
+
params.push('loop=1');
|
|
57
|
+
if (!opts.showControls)
|
|
58
|
+
params.push('controls=0');
|
|
59
|
+
params.push('byline=0', 'portrait=0', 'title=0');
|
|
60
|
+
return {
|
|
61
|
+
provider: 'vimeo',
|
|
62
|
+
id,
|
|
63
|
+
embedSrc: `https://player.vimeo.com/video/${id}?${params.join('&')}`
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
export function isEmbedUrl(url) {
|
|
69
|
+
return parseEmbedUrl(url) !== null;
|
|
70
|
+
}
|
package/package.json
CHANGED
|
@@ -1,84 +1,84 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "animot-presenter",
|
|
3
|
-
"version": "0.5.
|
|
4
|
-
"description": "Embed animated presentations anywhere. Works with vanilla JS, React, Vue, Angular, Svelte, and any frontend framework. Morphing animations, code highlighting, charts, particles, and more.",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"svelte": "./dist/index.js",
|
|
7
|
-
"types": "./dist/index.d.ts",
|
|
8
|
-
"exports": {
|
|
9
|
-
".": {
|
|
10
|
-
"svelte": "./dist/index.js",
|
|
11
|
-
"types": "./dist/index.d.ts",
|
|
12
|
-
"default": "./dist/index.js"
|
|
13
|
-
},
|
|
14
|
-
"./element": {
|
|
15
|
-
"import": "./dist/cdn/animot-presenter.esm.js",
|
|
16
|
-
"require": "./dist/cdn/animot-presenter.min.js"
|
|
17
|
-
},
|
|
18
|
-
"./cdn": {
|
|
19
|
-
"import": "./dist/cdn/animot-presenter.esm.js",
|
|
20
|
-
"require": "./dist/cdn/animot-presenter.min.js"
|
|
21
|
-
},
|
|
22
|
-
"./styles": "./dist/styles/presenter.css"
|
|
23
|
-
},
|
|
24
|
-
"files": [
|
|
25
|
-
"dist",
|
|
26
|
-
"!dist/**/*.test.*",
|
|
27
|
-
"!dist/**/*.spec.*"
|
|
28
|
-
],
|
|
29
|
-
"scripts": {
|
|
30
|
-
"dev": "vite dev",
|
|
31
|
-
"build": "npm run build:svelte && npm run build:element",
|
|
32
|
-
"build:svelte": "svelte-kit sync && svelte-package -o dist",
|
|
33
|
-
"build:element": "vite build --config vite.element.config.ts",
|
|
34
|
-
"package": "npm run build",
|
|
35
|
-
"preview": "vite preview",
|
|
36
|
-
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
|
37
|
-
"prepublishOnly": "npm run build"
|
|
38
|
-
},
|
|
39
|
-
"peerDependencies": {
|
|
40
|
-
"svelte": "^5.0.0"
|
|
41
|
-
},
|
|
42
|
-
"peerDependenciesMeta": {
|
|
43
|
-
"svelte": {
|
|
44
|
-
"optional": true
|
|
45
|
-
}
|
|
46
|
-
},
|
|
47
|
-
"devDependencies": {
|
|
48
|
-
"@sveltejs/adapter-auto": "^3.0.0",
|
|
49
|
-
"@sveltejs/kit": "^2.0.0",
|
|
50
|
-
"@sveltejs/package": "^2.0.0",
|
|
51
|
-
"@sveltejs/vite-plugin-svelte": "^4.0.0",
|
|
52
|
-
"@types/canvas-confetti": "^1.9.0",
|
|
53
|
-
"svelte": "^5.0.0",
|
|
54
|
-
"svelte-check": "^4.0.0",
|
|
55
|
-
"typescript": "^5.0.0",
|
|
56
|
-
"vite": "^5.0.0"
|
|
57
|
-
},
|
|
58
|
-
"dependencies": {
|
|
59
|
-
"@animotion/motion": "^2.0.1",
|
|
60
|
-
"canvas-confetti": "^1.9.4",
|
|
61
|
-
"shiki": "^1.0.0"
|
|
62
|
-
},
|
|
63
|
-
"keywords": [
|
|
64
|
-
"svelte",
|
|
65
|
-
"react",
|
|
66
|
-
"vue",
|
|
67
|
-
"angular",
|
|
68
|
-
"web-component",
|
|
69
|
-
"animation",
|
|
70
|
-
"presentation",
|
|
71
|
-
"slides",
|
|
72
|
-
"morphing",
|
|
73
|
-
"animot",
|
|
74
|
-
"code-animation",
|
|
75
|
-
"typewriter",
|
|
76
|
-
"charts",
|
|
77
|
-
"particles"
|
|
78
|
-
],
|
|
79
|
-
"license": "BUSL-1.1",
|
|
80
|
-
"repository": {
|
|
81
|
-
"type": "git",
|
|
82
|
-
"url": "https://github.com/beeblock/animot-presenter"
|
|
83
|
-
}
|
|
84
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "animot-presenter",
|
|
3
|
+
"version": "0.5.9",
|
|
4
|
+
"description": "Embed animated presentations anywhere. Works with vanilla JS, React, Vue, Angular, Svelte, and any frontend framework. Morphing animations, code highlighting, charts, particles, and more.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"svelte": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"svelte": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./element": {
|
|
15
|
+
"import": "./dist/cdn/animot-presenter.esm.js",
|
|
16
|
+
"require": "./dist/cdn/animot-presenter.min.js"
|
|
17
|
+
},
|
|
18
|
+
"./cdn": {
|
|
19
|
+
"import": "./dist/cdn/animot-presenter.esm.js",
|
|
20
|
+
"require": "./dist/cdn/animot-presenter.min.js"
|
|
21
|
+
},
|
|
22
|
+
"./styles": "./dist/styles/presenter.css"
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"dist",
|
|
26
|
+
"!dist/**/*.test.*",
|
|
27
|
+
"!dist/**/*.spec.*"
|
|
28
|
+
],
|
|
29
|
+
"scripts": {
|
|
30
|
+
"dev": "vite dev",
|
|
31
|
+
"build": "npm run build:svelte && npm run build:element",
|
|
32
|
+
"build:svelte": "svelte-kit sync && svelte-package -o dist",
|
|
33
|
+
"build:element": "vite build --config vite.element.config.ts",
|
|
34
|
+
"package": "npm run build",
|
|
35
|
+
"preview": "vite preview",
|
|
36
|
+
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
|
37
|
+
"prepublishOnly": "npm run build"
|
|
38
|
+
},
|
|
39
|
+
"peerDependencies": {
|
|
40
|
+
"svelte": "^5.0.0"
|
|
41
|
+
},
|
|
42
|
+
"peerDependenciesMeta": {
|
|
43
|
+
"svelte": {
|
|
44
|
+
"optional": true
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@sveltejs/adapter-auto": "^3.0.0",
|
|
49
|
+
"@sveltejs/kit": "^2.0.0",
|
|
50
|
+
"@sveltejs/package": "^2.0.0",
|
|
51
|
+
"@sveltejs/vite-plugin-svelte": "^4.0.0",
|
|
52
|
+
"@types/canvas-confetti": "^1.9.0",
|
|
53
|
+
"svelte": "^5.0.0",
|
|
54
|
+
"svelte-check": "^4.0.0",
|
|
55
|
+
"typescript": "^5.0.0",
|
|
56
|
+
"vite": "^5.0.0"
|
|
57
|
+
},
|
|
58
|
+
"dependencies": {
|
|
59
|
+
"@animotion/motion": "^2.0.1",
|
|
60
|
+
"canvas-confetti": "^1.9.4",
|
|
61
|
+
"shiki": "^1.0.0"
|
|
62
|
+
},
|
|
63
|
+
"keywords": [
|
|
64
|
+
"svelte",
|
|
65
|
+
"react",
|
|
66
|
+
"vue",
|
|
67
|
+
"angular",
|
|
68
|
+
"web-component",
|
|
69
|
+
"animation",
|
|
70
|
+
"presentation",
|
|
71
|
+
"slides",
|
|
72
|
+
"morphing",
|
|
73
|
+
"animot",
|
|
74
|
+
"code-animation",
|
|
75
|
+
"typewriter",
|
|
76
|
+
"charts",
|
|
77
|
+
"particles"
|
|
78
|
+
],
|
|
79
|
+
"license": "BUSL-1.1",
|
|
80
|
+
"repository": {
|
|
81
|
+
"type": "git",
|
|
82
|
+
"url": "https://github.com/beeblock/animot-presenter"
|
|
83
|
+
}
|
|
84
|
+
}
|