lotio 1.0.0-test
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/README.md +447 -0
- package/browser/index.js +451 -0
- package/browser/lotio.js +2 -0
- package/browser/lotio.wasm +0 -0
- package/browser/wasm.js +410 -0
- package/package.json +24 -0
package/browser/wasm.js
ADDED
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
// Load WASM module
|
|
2
|
+
let Module = null;
|
|
3
|
+
|
|
4
|
+
export async function initLotio(wasmPath = './lotio.wasm') {
|
|
5
|
+
// Load Emscripten module
|
|
6
|
+
let jsPath = wasmPath.replace('.wasm', '.js');
|
|
7
|
+
|
|
8
|
+
// Keep relative paths as-is - script tags resolve relative to the page's base URL
|
|
9
|
+
// Script tags work best with relative paths like './browser/lotio.js'
|
|
10
|
+
// Only convert to absolute if it's already an absolute URL (http/https)
|
|
11
|
+
if (!jsPath.startsWith('http://') && !jsPath.startsWith('https://') && !jsPath.startsWith('//')) {
|
|
12
|
+
// Path is relative - keep it relative for script tags
|
|
13
|
+
// Script tags will resolve it relative to the current page automatically
|
|
14
|
+
// No need to convert to absolute path
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Check if already loaded
|
|
18
|
+
if (typeof createLotioModule !== 'undefined') {
|
|
19
|
+
Module = await createLotioModule();
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Load the module using a script tag approach for CommonJS compatibility
|
|
24
|
+
return new Promise((resolve, reject) => {
|
|
25
|
+
// Load the script
|
|
26
|
+
const script = document.createElement('script');
|
|
27
|
+
script.src = jsPath;
|
|
28
|
+
script.async = true;
|
|
29
|
+
script.onload = () => {
|
|
30
|
+
// Wait for the script to execute and define createLotioModule
|
|
31
|
+
const tryLoad = () => {
|
|
32
|
+
// The script should define createLotioModule globally
|
|
33
|
+
const factory = window.createLotioModule || globalThis.createLotioModule || (typeof createLotioModule !== 'undefined' ? createLotioModule : null);
|
|
34
|
+
if (typeof factory === 'function') {
|
|
35
|
+
factory().then(mod => {
|
|
36
|
+
Module = mod;
|
|
37
|
+
// Verify Module has required functions and properties
|
|
38
|
+
if (!Module._malloc || !Module._free || !Module._lotio_init) {
|
|
39
|
+
console.error('Module object:', Module);
|
|
40
|
+
console.error('Available functions:', Object.keys(Module).filter(k => typeof Module[k] === 'function').slice(0, 20));
|
|
41
|
+
reject(new Error('Module is missing required functions (_malloc, _free, or _lotio_init)'));
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
// HEAP arrays should be exported directly, but if not, try to create them
|
|
45
|
+
// First check if they're already available
|
|
46
|
+
if (Module.HEAP8 && Module.HEAP32 && Module.HEAPF32 && Module.HEAPU8) {
|
|
47
|
+
console.log('HEAP arrays already available');
|
|
48
|
+
} else {
|
|
49
|
+
// Try to find the memory buffer
|
|
50
|
+
let memoryBuffer = null;
|
|
51
|
+
|
|
52
|
+
// Check if HEAP arrays exist but weren't detected
|
|
53
|
+
if (Module.HEAP8 && Module.HEAP8.buffer) {
|
|
54
|
+
memoryBuffer = Module.HEAP8.buffer;
|
|
55
|
+
} else if (Module.HEAPU8 && Module.HEAPU8.buffer) {
|
|
56
|
+
memoryBuffer = Module.HEAPU8.buffer;
|
|
57
|
+
} else if (Module.memory && Module.memory.buffer) {
|
|
58
|
+
memoryBuffer = Module.memory.buffer;
|
|
59
|
+
} else if (Module.buffer) {
|
|
60
|
+
memoryBuffer = Module.buffer;
|
|
61
|
+
} else {
|
|
62
|
+
// Last resort: try to get memory from WASM instance
|
|
63
|
+
// The Module might have the memory internally
|
|
64
|
+
console.warn('HEAP arrays not found, but continuing - they may be created on first use');
|
|
65
|
+
// Don't reject, let's see if they get created when needed
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (memoryBuffer) {
|
|
69
|
+
// Create HEAP arrays from the buffer
|
|
70
|
+
Module.HEAP8 = new Int8Array(memoryBuffer);
|
|
71
|
+
Module.HEAPU8 = new Uint8Array(memoryBuffer);
|
|
72
|
+
Module.HEAP16 = new Int16Array(memoryBuffer);
|
|
73
|
+
Module.HEAPU16 = new Uint16Array(memoryBuffer);
|
|
74
|
+
Module.HEAP32 = new Int32Array(memoryBuffer);
|
|
75
|
+
Module.HEAPU32 = new Uint32Array(memoryBuffer);
|
|
76
|
+
Module.HEAPF32 = new Float32Array(memoryBuffer);
|
|
77
|
+
Module.HEAPF64 = new Float64Array(memoryBuffer);
|
|
78
|
+
console.log('Created HEAP arrays from memory buffer');
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
console.log('Module initialized successfully');
|
|
82
|
+
resolve(true);
|
|
83
|
+
}).catch(reject);
|
|
84
|
+
} else {
|
|
85
|
+
// Retry after a short delay
|
|
86
|
+
if (typeof window.createLotioModule === 'undefined' && typeof createLotioModule === 'undefined') {
|
|
87
|
+
setTimeout(tryLoad, 50);
|
|
88
|
+
} else {
|
|
89
|
+
console.error('Available globals:', Object.keys(window).filter(k => k.includes('Lotio') || k.includes('lotio') || k.includes('create')));
|
|
90
|
+
reject(new Error('createLotioModule not found after loading script. Check console for available globals.'));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
tryLoad();
|
|
95
|
+
};
|
|
96
|
+
script.onerror = (error) => {
|
|
97
|
+
reject(new Error(`Failed to load script: ${jsPath} - ${error}`));
|
|
98
|
+
};
|
|
99
|
+
document.head.appendChild(script);
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export function createAnimation(jsonData, layerOverrides = null, textPadding = 0.97, textMeasurementMode = 'accurate') {
|
|
104
|
+
if (!Module) {
|
|
105
|
+
throw new Error('WASM module not initialized. Call initLotio() first.');
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Check if Module has the required functions
|
|
109
|
+
if (!Module._malloc || !Module._free || !Module._lotio_init) {
|
|
110
|
+
console.error('Module object:', Module);
|
|
111
|
+
console.error('Available functions:', Object.keys(Module).filter(k => typeof Module[k] === 'function'));
|
|
112
|
+
throw new Error('Module is not properly initialized. Missing _malloc, _free, or _lotio_init functions.');
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Ensure HEAP arrays are available - create them from memory if needed
|
|
116
|
+
if (!Module.HEAP32 || !Module.HEAPF32 || !Module.HEAPU8) {
|
|
117
|
+
// Try to find the memory buffer
|
|
118
|
+
let memoryBuffer = null;
|
|
119
|
+
|
|
120
|
+
// Check various ways the memory might be exposed
|
|
121
|
+
if (Module.HEAP8 && Module.HEAP8.buffer) {
|
|
122
|
+
memoryBuffer = Module.HEAP8.buffer;
|
|
123
|
+
} else if (Module.HEAPU8 && Module.HEAPU8.buffer) {
|
|
124
|
+
memoryBuffer = Module.HEAPU8.buffer;
|
|
125
|
+
} else if (Module.memory && Module.memory.buffer) {
|
|
126
|
+
memoryBuffer = Module.memory.buffer;
|
|
127
|
+
} else if (Module.buffer) {
|
|
128
|
+
memoryBuffer = Module.buffer;
|
|
129
|
+
} else {
|
|
130
|
+
// Try to get memory from WASM instance
|
|
131
|
+
// After first malloc, memory should be initialized
|
|
132
|
+
// Allocate a small buffer to trigger memory initialization
|
|
133
|
+
const testPtr = Module._malloc(1);
|
|
134
|
+
if (testPtr !== null && testPtr !== 0) {
|
|
135
|
+
// Now try to access memory
|
|
136
|
+
// The memory should be available via Module.HEAP* after first allocation
|
|
137
|
+
if (Module.HEAP8) {
|
|
138
|
+
memoryBuffer = Module.HEAP8.buffer;
|
|
139
|
+
} else {
|
|
140
|
+
Module._free(testPtr);
|
|
141
|
+
throw new Error('Cannot access WASM memory buffer even after allocation');
|
|
142
|
+
}
|
|
143
|
+
Module._free(testPtr);
|
|
144
|
+
} else {
|
|
145
|
+
throw new Error('Failed to allocate test memory - WASM memory not initialized');
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (memoryBuffer) {
|
|
150
|
+
Module.HEAP8 = new Int8Array(memoryBuffer);
|
|
151
|
+
Module.HEAPU8 = new Uint8Array(memoryBuffer);
|
|
152
|
+
Module.HEAP16 = new Int16Array(memoryBuffer);
|
|
153
|
+
Module.HEAPU16 = new Uint16Array(memoryBuffer);
|
|
154
|
+
Module.HEAP32 = new Int32Array(memoryBuffer);
|
|
155
|
+
Module.HEAPU32 = new Uint32Array(memoryBuffer);
|
|
156
|
+
Module.HEAPF32 = new Float32Array(memoryBuffer);
|
|
157
|
+
Module.HEAPF64 = new Float64Array(memoryBuffer);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const jsonStr = typeof jsonData === 'string' ? jsonData : JSON.stringify(jsonData);
|
|
162
|
+
const layerOverridesStr = layerOverrides ? (typeof layerOverrides === 'string' ? layerOverrides : JSON.stringify(layerOverrides)) : null;
|
|
163
|
+
|
|
164
|
+
// Convert textMeasurementMode string to integer (0=FAST, 1=ACCURATE, 2=PIXEL_PERFECT)
|
|
165
|
+
const modeStr = String(textMeasurementMode).toLowerCase();
|
|
166
|
+
let modeInt = 1; // Default to ACCURATE
|
|
167
|
+
if (modeStr === 'fast') {
|
|
168
|
+
modeInt = 0;
|
|
169
|
+
} else if (modeStr === 'accurate') {
|
|
170
|
+
modeInt = 1;
|
|
171
|
+
} else if (modeStr === 'pixel-perfect' || modeStr === 'pixelperfect') {
|
|
172
|
+
modeInt = 2;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Allocate memory using exported _malloc
|
|
176
|
+
const jsonPtr = Module._malloc(jsonStr.length + 1);
|
|
177
|
+
if (!jsonPtr) {
|
|
178
|
+
throw new Error('Failed to allocate memory for JSON data');
|
|
179
|
+
}
|
|
180
|
+
Module.stringToUTF8(jsonStr, jsonPtr, jsonStr.length + 1);
|
|
181
|
+
|
|
182
|
+
let layerOverridesPtr = 0;
|
|
183
|
+
let layerOverridesLen = 0;
|
|
184
|
+
if (layerOverridesStr) {
|
|
185
|
+
layerOverridesPtr = Module._malloc(layerOverridesStr.length + 1);
|
|
186
|
+
if (!layerOverridesPtr) {
|
|
187
|
+
Module._free(jsonPtr);
|
|
188
|
+
throw new Error('Failed to allocate memory for layer overrides');
|
|
189
|
+
}
|
|
190
|
+
layerOverridesLen = layerOverridesStr.length;
|
|
191
|
+
Module.stringToUTF8(layerOverridesStr, layerOverridesPtr, layerOverridesStr.length + 1);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const result = Module._lotio_init(jsonPtr, jsonStr.length, layerOverridesPtr, layerOverridesLen, textPadding, modeInt);
|
|
195
|
+
|
|
196
|
+
Module._free(jsonPtr);
|
|
197
|
+
if (layerOverridesPtr) {
|
|
198
|
+
Module._free(layerOverridesPtr);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (result !== 0) {
|
|
202
|
+
throw new Error('Failed to initialize animation');
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Get animation info
|
|
206
|
+
const widthPtr = Module._malloc(4);
|
|
207
|
+
const heightPtr = Module._malloc(4);
|
|
208
|
+
const durationPtr = Module._malloc(4);
|
|
209
|
+
const fpsPtr = Module._malloc(4);
|
|
210
|
+
|
|
211
|
+
Module._lotio_get_info(widthPtr, heightPtr, durationPtr, fpsPtr);
|
|
212
|
+
|
|
213
|
+
const info = {
|
|
214
|
+
width: Module.HEAP32[widthPtr / 4],
|
|
215
|
+
height: Module.HEAP32[heightPtr / 4],
|
|
216
|
+
duration: Module.HEAPF32[durationPtr / 4],
|
|
217
|
+
fps: Module.HEAPF32[fpsPtr / 4]
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
Module._free(widthPtr);
|
|
221
|
+
Module._free(heightPtr);
|
|
222
|
+
Module._free(durationPtr);
|
|
223
|
+
Module._free(fpsPtr);
|
|
224
|
+
|
|
225
|
+
return info;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export function renderFrameRGBA(time) {
|
|
229
|
+
if (!Module) {
|
|
230
|
+
throw new Error('WASM module not initialized.');
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Ensure HEAP arrays are available - use same logic as createAnimation
|
|
234
|
+
if (!Module.HEAP32 || !Module.HEAPU8) {
|
|
235
|
+
let memoryBuffer = null;
|
|
236
|
+
if (Module.HEAP8 && Module.HEAP8.buffer) {
|
|
237
|
+
memoryBuffer = Module.HEAP8.buffer;
|
|
238
|
+
} else if (Module.HEAPU8 && Module.HEAPU8.buffer) {
|
|
239
|
+
memoryBuffer = Module.HEAPU8.buffer;
|
|
240
|
+
} else if (Module.memory && Module.memory.buffer) {
|
|
241
|
+
memoryBuffer = Module.memory.buffer;
|
|
242
|
+
} else {
|
|
243
|
+
// Trigger memory initialization with a test allocation
|
|
244
|
+
const testPtr = Module._malloc(1);
|
|
245
|
+
if (testPtr !== null && testPtr !== 0) {
|
|
246
|
+
if (Module.HEAP8) {
|
|
247
|
+
memoryBuffer = Module.HEAP8.buffer;
|
|
248
|
+
}
|
|
249
|
+
Module._free(testPtr);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
if (memoryBuffer) {
|
|
253
|
+
Module.HEAPU8 = new Uint8Array(memoryBuffer);
|
|
254
|
+
Module.HEAP32 = new Int32Array(memoryBuffer);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Get animation info to determine buffer size
|
|
259
|
+
const widthPtr = Module._malloc(4);
|
|
260
|
+
const heightPtr = Module._malloc(4);
|
|
261
|
+
Module._lotio_get_info(widthPtr, heightPtr, null, null);
|
|
262
|
+
const width = Module.HEAP32[widthPtr / 4];
|
|
263
|
+
const height = Module.HEAP32[heightPtr / 4];
|
|
264
|
+
Module._free(widthPtr);
|
|
265
|
+
Module._free(heightPtr);
|
|
266
|
+
|
|
267
|
+
const bufferSize = width * height * 4; // RGBA
|
|
268
|
+
const bufferPtr = Module._malloc(bufferSize);
|
|
269
|
+
|
|
270
|
+
const result = Module._lotio_render_frame(time, bufferPtr, bufferSize);
|
|
271
|
+
|
|
272
|
+
if (result !== 0) {
|
|
273
|
+
Module._free(bufferPtr);
|
|
274
|
+
const errorMsg = result === 1 ? 'Animation not initialized' :
|
|
275
|
+
result === 2 ? 'Buffer too small' :
|
|
276
|
+
result === 3 ? 'Failed to create surface' :
|
|
277
|
+
result === 4 ? 'Failed to create image snapshot' :
|
|
278
|
+
result === 5 ? 'Failed to read pixels' :
|
|
279
|
+
result === 6 ? 'Failed to create conversion surface' :
|
|
280
|
+
result === 7 ? 'Failed to create converted image' :
|
|
281
|
+
`Unknown error: ${result}`;
|
|
282
|
+
throw new Error(`Failed to render frame: ${errorMsg} (code ${result})`);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// Copy data to Uint8Array
|
|
286
|
+
// Create a view into the WASM memory
|
|
287
|
+
const bufferView = new Uint8Array(Module.HEAPU8.buffer, bufferPtr, bufferSize);
|
|
288
|
+
// Create a copy to avoid issues with memory being freed
|
|
289
|
+
const rgba = new Uint8Array(bufferView);
|
|
290
|
+
|
|
291
|
+
Module._free(bufferPtr);
|
|
292
|
+
|
|
293
|
+
return { rgba, width, height };
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
export function getVersion() {
|
|
297
|
+
if (!Module) {
|
|
298
|
+
throw new Error('WASM module not initialized. Call initLotio() first.');
|
|
299
|
+
}
|
|
300
|
+
return Module.UTF8ToString(Module._lotio_get_version());
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
export function registerFont(fontName, fontData) {
|
|
304
|
+
if (!Module) {
|
|
305
|
+
throw new Error('WASM module not initialized. Call initLotio() first.');
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
if (!Module._lotio_register_font) {
|
|
309
|
+
throw new Error('Font registration not available. Rebuild with _lotio_register_font exported.');
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// Ensure HEAP arrays are available
|
|
313
|
+
if (!Module.HEAPU8) {
|
|
314
|
+
if (Module.memory && Module.memory.buffer) {
|
|
315
|
+
Module.HEAPU8 = new Uint8Array(Module.memory.buffer);
|
|
316
|
+
} else {
|
|
317
|
+
throw new Error('Cannot access WASM memory for font registration.');
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// Allocate memory for font data
|
|
322
|
+
const fontDataPtr = Module._malloc(fontData.length);
|
|
323
|
+
if (!fontDataPtr) {
|
|
324
|
+
throw new Error('Failed to allocate memory for font data');
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// Copy font data to WASM memory
|
|
328
|
+
Module.HEAPU8.set(fontData, fontDataPtr);
|
|
329
|
+
|
|
330
|
+
// Allocate memory for font name
|
|
331
|
+
const fontNamePtr = Module._malloc(fontName.length + 1);
|
|
332
|
+
if (!fontNamePtr) {
|
|
333
|
+
Module._free(fontDataPtr);
|
|
334
|
+
throw new Error('Failed to allocate memory for font name');
|
|
335
|
+
}
|
|
336
|
+
Module.stringToUTF8(fontName, fontNamePtr, fontName.length + 1);
|
|
337
|
+
|
|
338
|
+
// Register font
|
|
339
|
+
const result = Module._lotio_register_font(fontNamePtr, fontDataPtr, fontData.length);
|
|
340
|
+
|
|
341
|
+
// Free memory
|
|
342
|
+
Module._free(fontDataPtr);
|
|
343
|
+
Module._free(fontNamePtr);
|
|
344
|
+
|
|
345
|
+
if (result !== 0) {
|
|
346
|
+
throw new Error(`Failed to register font: ${fontName} (error code: ${result})`);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
console.log(`Font registered: ${fontName}`);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
export function cleanup() {
|
|
353
|
+
if (Module) {
|
|
354
|
+
Module._lotio_cleanup();
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// Helper to render frame to canvas
|
|
359
|
+
export function renderFrameToCanvas(canvas, time, bgColor = '#2a2a2a') {
|
|
360
|
+
const { rgba, width, height } = renderFrameRGBA(time);
|
|
361
|
+
|
|
362
|
+
// Set canvas size
|
|
363
|
+
canvas.width = width;
|
|
364
|
+
canvas.height = height;
|
|
365
|
+
|
|
366
|
+
const ctx = canvas.getContext('2d');
|
|
367
|
+
|
|
368
|
+
// Fill with background color first
|
|
369
|
+
ctx.fillStyle = bgColor;
|
|
370
|
+
ctx.fillRect(0, 0, width, height);
|
|
371
|
+
|
|
372
|
+
const imageData = ctx.createImageData(width, height);
|
|
373
|
+
|
|
374
|
+
// Copy RGBA data - ensure we have the right length
|
|
375
|
+
if (rgba.length !== width * height * 4) {
|
|
376
|
+
console.error(`RGBA buffer size mismatch: expected ${width * height * 4}, got ${rgba.length}`);
|
|
377
|
+
throw new Error(`Invalid RGBA buffer size: expected ${width * height * 4}, got ${rgba.length}`);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// Create a temporary canvas to composite the image over the background
|
|
381
|
+
// This ensures the background color shows through transparent areas
|
|
382
|
+
const tempCanvas = document.createElement('canvas');
|
|
383
|
+
tempCanvas.width = width;
|
|
384
|
+
tempCanvas.height = height;
|
|
385
|
+
const tempCtx = tempCanvas.getContext('2d');
|
|
386
|
+
|
|
387
|
+
// Fill temp canvas with background color
|
|
388
|
+
tempCtx.fillStyle = bgColor;
|
|
389
|
+
tempCtx.fillRect(0, 0, width, height);
|
|
390
|
+
|
|
391
|
+
// Draw the RGBA image data on top
|
|
392
|
+
imageData.data.set(rgba);
|
|
393
|
+
tempCtx.putImageData(imageData, 0, 0);
|
|
394
|
+
|
|
395
|
+
// Draw the composited result to the main canvas
|
|
396
|
+
ctx.drawImage(tempCanvas, 0, 0);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// Helper to render frame as ImageData
|
|
400
|
+
export function renderFrameAsImageData(time) {
|
|
401
|
+
const { rgba, width, height } = renderFrameRGBA(time);
|
|
402
|
+
const canvas = document.createElement('canvas');
|
|
403
|
+
canvas.width = width;
|
|
404
|
+
canvas.height = height;
|
|
405
|
+
const ctx = canvas.getContext('2d');
|
|
406
|
+
const imageData = ctx.createImageData(width, height);
|
|
407
|
+
imageData.data.set(rgba);
|
|
408
|
+
return imageData;
|
|
409
|
+
}
|
|
410
|
+
|
package/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "lotio",
|
|
3
|
+
"version": "1.0.0-test",
|
|
4
|
+
"description": "High-performance Lottie animation frame renderer for the browser",
|
|
5
|
+
"main": "browser/lotio.js",
|
|
6
|
+
"module": "browser/lotio.js",
|
|
7
|
+
"files": [
|
|
8
|
+
"browser"
|
|
9
|
+
],
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "https://github.com/matrunchyk/lotio.git"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"lottie",
|
|
16
|
+
"animation",
|
|
17
|
+
"renderer",
|
|
18
|
+
"skia",
|
|
19
|
+
"webassembly",
|
|
20
|
+
"wasm"
|
|
21
|
+
],
|
|
22
|
+
"author": "matrunchyk",
|
|
23
|
+
"license": "MIT"
|
|
24
|
+
}
|