mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-15 12:34:30 +00:00
infra: removed web support
Separated the web support into a new project repository. https://github.com/thorvg/thorvg.web This will help maintain the core logic more efficiently. issue: https://github.com/thorvg/thorvg/issues/2297
This commit is contained in:
parent
7b9bebe1de
commit
b19ae5b8c0
11 changed files with 0 additions and 3874 deletions
|
@ -1,31 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
env: {
|
|
||||||
browser: true,
|
|
||||||
es2021: true,
|
|
||||||
},
|
|
||||||
extends: ["standard-with-typescript", "plugin:wc/best-practice"],
|
|
||||||
overrides: [
|
|
||||||
{
|
|
||||||
env: {
|
|
||||||
node: true,
|
|
||||||
},
|
|
||||||
files: [".eslintrc.{js,cjs}"],
|
|
||||||
parserOptions: {
|
|
||||||
sourceType: "script",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
parserOptions: {
|
|
||||||
ecmaVersion: "latest",
|
|
||||||
sourceType: "module",
|
|
||||||
},
|
|
||||||
rules: {
|
|
||||||
semi: [2, "always"],
|
|
||||||
"@typescript-eslint/semi": "off",
|
|
||||||
},
|
|
||||||
settings: {
|
|
||||||
wc: {
|
|
||||||
elementBaseClasses: ["LitElement"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
147
web/.gitignore
vendored
147
web/.gitignore
vendored
|
@ -1,147 +0,0 @@
|
||||||
### Node ###
|
|
||||||
# Logs
|
|
||||||
logs
|
|
||||||
*.log
|
|
||||||
npm-debug.log*
|
|
||||||
yarn-debug.log*
|
|
||||||
yarn-error.log*
|
|
||||||
lerna-debug.log*
|
|
||||||
.pnpm-debug.log*
|
|
||||||
|
|
||||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
|
||||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
|
||||||
|
|
||||||
# Runtime data
|
|
||||||
pids
|
|
||||||
*.pid
|
|
||||||
*.seed
|
|
||||||
*.pid.lock
|
|
||||||
|
|
||||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
|
||||||
lib-cov
|
|
||||||
|
|
||||||
# Coverage directory used by tools like istanbul
|
|
||||||
coverage
|
|
||||||
*.lcov
|
|
||||||
|
|
||||||
# nyc test coverage
|
|
||||||
.nyc_output
|
|
||||||
|
|
||||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
|
||||||
.grunt
|
|
||||||
|
|
||||||
# Bower dependency directory (https://bower.io/)
|
|
||||||
bower_components
|
|
||||||
|
|
||||||
# node-waf configuration
|
|
||||||
.lock-wscript
|
|
||||||
|
|
||||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
|
||||||
build/Release
|
|
||||||
|
|
||||||
# Dependency directories
|
|
||||||
node_modules/
|
|
||||||
jspm_packages/
|
|
||||||
|
|
||||||
# Snowpack dependency directory (https://snowpack.dev/)
|
|
||||||
web_modules/
|
|
||||||
|
|
||||||
# TypeScript cache
|
|
||||||
*.tsbuildinfo
|
|
||||||
|
|
||||||
# Optional npm cache directory
|
|
||||||
.npm
|
|
||||||
|
|
||||||
# Optional eslint cache
|
|
||||||
.eslintcache
|
|
||||||
|
|
||||||
# Optional stylelint cache
|
|
||||||
.stylelintcache
|
|
||||||
|
|
||||||
# Microbundle cache
|
|
||||||
.rpt2_cache/
|
|
||||||
.rts2_cache_cjs/
|
|
||||||
.rts2_cache_es/
|
|
||||||
.rts2_cache_umd/
|
|
||||||
|
|
||||||
# Optional REPL history
|
|
||||||
.node_repl_history
|
|
||||||
|
|
||||||
# Output of 'npm pack'
|
|
||||||
*.tgz
|
|
||||||
|
|
||||||
# Yarn Integrity file
|
|
||||||
.yarn-integrity
|
|
||||||
|
|
||||||
# dotenv environment variable files
|
|
||||||
.env
|
|
||||||
.env.development.local
|
|
||||||
.env.test.local
|
|
||||||
.env.production.local
|
|
||||||
.env.local
|
|
||||||
|
|
||||||
# parcel-bundler cache (https://parceljs.org/)
|
|
||||||
.cache
|
|
||||||
.parcel-cache
|
|
||||||
|
|
||||||
# Next.js build output
|
|
||||||
.next
|
|
||||||
out
|
|
||||||
|
|
||||||
# Nuxt.js build / generate output
|
|
||||||
.nuxt
|
|
||||||
dist
|
|
||||||
|
|
||||||
# Gatsby files
|
|
||||||
.cache/
|
|
||||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
|
||||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
|
||||||
# public
|
|
||||||
|
|
||||||
# vuepress build output
|
|
||||||
.vuepress/dist
|
|
||||||
|
|
||||||
# vuepress v2.x temp and cache directory
|
|
||||||
.temp
|
|
||||||
|
|
||||||
# Docusaurus cache and generated files
|
|
||||||
.docusaurus
|
|
||||||
|
|
||||||
# Serverless directories
|
|
||||||
.serverless/
|
|
||||||
|
|
||||||
# FuseBox cache
|
|
||||||
.fusebox/
|
|
||||||
|
|
||||||
# DynamoDB Local files
|
|
||||||
.dynamodb/
|
|
||||||
|
|
||||||
# TernJS port file
|
|
||||||
.tern-port
|
|
||||||
|
|
||||||
# Stores VSCode versions used for testing VSCode extensions
|
|
||||||
.vscode-test
|
|
||||||
|
|
||||||
# yarn v2
|
|
||||||
.yarn/cache
|
|
||||||
.yarn/unplugged
|
|
||||||
.yarn/build-state.yml
|
|
||||||
.yarn/install-state.gz
|
|
||||||
.pnp.*
|
|
||||||
|
|
||||||
### Node Patch ###
|
|
||||||
# Serverless Webpack directories
|
|
||||||
.webpack/
|
|
||||||
|
|
||||||
# Optional stylelint cache
|
|
||||||
|
|
||||||
# SvelteKit build / generate output
|
|
||||||
.svelte-kit
|
|
||||||
|
|
||||||
# Operating system
|
|
||||||
.DS_Store
|
|
||||||
*.bak
|
|
||||||
*.swp
|
|
||||||
*~
|
|
||||||
|
|
||||||
# End of https://www.toptal.com/developers/gitignore/api/node
|
|
295
web/README.md
295
web/README.md
|
@ -1,295 +0,0 @@
|
||||||
# @thorvg/lottie-player
|
|
||||||
|
|
||||||
A Lottie Player which uses [ThorVG](https://github.com/thorvg/thorvg) as a renderer, provides a web component for easily embedding and playing [Lottie](https://airbnb.io/lottie) animations.
|
|
||||||
|
|
||||||
# Installation
|
|
||||||
|
|
||||||
- Import from CDN
|
|
||||||
```html
|
|
||||||
<script src="https://unpkg.com/@thorvg/lottie-player@latest/dist/lottie-player.js"></script>
|
|
||||||
```
|
|
||||||
|
|
||||||
- Install from [NPM](https://www.npmjs.com/package/@thorvg/lottie-player)
|
|
||||||
```sh
|
|
||||||
npm install @thorvg/lottie-player
|
|
||||||
```
|
|
||||||
|
|
||||||
# Usage
|
|
||||||
### With HTML (Basic Usage)
|
|
||||||
|
|
||||||
Once you import from CDN, you can access `<lottie-player/>`
|
|
||||||
|
|
||||||
```html
|
|
||||||
<lottie-player
|
|
||||||
autoPlay
|
|
||||||
loop
|
|
||||||
mode="normal"
|
|
||||||
src="https://lottie.host/6d7dd6e2-ab92-4e98-826a-2f8430768886/NGnHQ6brWA.json"
|
|
||||||
style="width: 500px; height: 500px;"
|
|
||||||
>
|
|
||||||
</lottie-player>
|
|
||||||
```
|
|
||||||
|
|
||||||
### With NPM (JS/TS)
|
|
||||||
|
|
||||||
Import the library and please follow Basic Usage, you can use library on any NPM-based project such as React, Vue and Svelte.
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import '@thorvg/lottie-player';
|
|
||||||
```
|
|
||||||
|
|
||||||
### With ReactJS + TypeScript
|
|
||||||
|
|
||||||
Add `declarations.d.ts` on the root of project and make sure following declaration.
|
|
||||||
|
|
||||||
```js
|
|
||||||
declare namespace JSX {
|
|
||||||
interface IntrinsicElements {
|
|
||||||
"lottie-player": any;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Then you will be able to use this as same as above
|
|
||||||
```js
|
|
||||||
import '@thorvg/lottie-player';
|
|
||||||
|
|
||||||
<lottie-player
|
|
||||||
autoPlay
|
|
||||||
loop
|
|
||||||
mode="normal"
|
|
||||||
src="https://lottie.host/6d7dd6e2-ab92-4e98-826a-2f8430768886/NGnHQ6brWA.json"
|
|
||||||
style="width: 500px; height: 500px;"
|
|
||||||
>
|
|
||||||
</lottie-player>
|
|
||||||
```
|
|
||||||
|
|
||||||
### With SSR Framework
|
|
||||||
We should be careful when using on SSR frameworks such as NextJS, NuxtJS and Svelte, as it means the library must to be rendered on browser/client side.
|
|
||||||
|
|
||||||
- NextJS
|
|
||||||
```ts
|
|
||||||
import { useEffect } from "react";
|
|
||||||
|
|
||||||
export default function Home() {
|
|
||||||
// ...
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
import("@thorvg/lottie-player");
|
|
||||||
});
|
|
||||||
|
|
||||||
// ...
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
- NuxtJS
|
|
||||||
```html
|
|
||||||
<template>
|
|
||||||
{/* ... */}
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
mounted() {
|
|
||||||
import("@thorvg/lottie-player");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
```
|
|
||||||
|
|
||||||
- Svelte
|
|
||||||
```html
|
|
||||||
<script>
|
|
||||||
import { onMount } from 'svelte';
|
|
||||||
|
|
||||||
onMount(async () => {
|
|
||||||
await import('@thorvg/lottie-player');
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
```
|
|
||||||
|
|
||||||
# API
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
| Property | Description | Type | Default Value | Required |
|
|
||||||
| --- | --- | --- | --- | --- |
|
|
||||||
| src | A graphic resource to play. It could be an internal/external URL or JSON string for Lottie. | string | undefined | Y |
|
|
||||||
| speed | Animation speed (for Lottie) | number | 1 | N |
|
|
||||||
| autoplay | When set to true, automatically plays the animation on loading it (for Lottie) | boolean | false | N |
|
|
||||||
| count | Number of times to loop the animation | number | undefined | N |
|
|
||||||
| loop | When set to true, loops the animation. The count property defines the number of times to loop the animation. Setting the count property to 0 and setting the loop to true, loops the animation indefinitely. | boolean | false | N |
|
|
||||||
| direction | Direction of the animation. Set to 1 to play the animation forward or set to -1 to play it backward. | number (1 or -1) | 1 | N |
|
|
||||||
| mode | Play mode. Setting the mode to PlayMode.Bounce plays the animation in an indefinite cycle, forwards and then backwards. | PlayMode | PlayMode.Normal | N |
|
|
||||||
| intermission | Duration (in milliseconds) to pause before playing each cycle in a looped animation. Set this parameter to 0 (no pause) or any positive number. | number | 1 | N |
|
|
||||||
|
|
||||||
## Events
|
|
||||||
|
|
||||||
You can adapt the event with the following code example
|
|
||||||
|
|
||||||
```jsx
|
|
||||||
const player = document.querySelector('lottie-player');
|
|
||||||
|
|
||||||
player.addEventListener('load', () => {
|
|
||||||
// TODO: implements
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
| Name | Description |
|
|
||||||
| --- | --- |
|
|
||||||
| load | A graphic resource is loaded |
|
|
||||||
| error | An animation data can’t be parsed. |
|
|
||||||
| ready | Animation data is loaded and player is ready |
|
|
||||||
| play | Animation starts playing |
|
|
||||||
| pause | Animation is paused |
|
|
||||||
| stop | Animation is stopped |
|
|
||||||
| freeze | Animation is paused due to player being invisible |
|
|
||||||
| loop | An animation loop is completed |
|
|
||||||
| complete | Animation is complete (all loops completed) |
|
|
||||||
| frame | A new frame is entered |
|
|
||||||
|
|
||||||
|
|
||||||
## Methods
|
|
||||||
|
|
||||||
**Method** : `load(src: string | object)`
|
|
||||||
|
|
||||||
**Purpose** : Load and play Lottie animation
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
| Name | Type | Description
|
|
||||||
| --- | --- | --- |
|
|
||||||
| src | `string` or `object` | URL, or a JSON string or object representing a Lottie animation to play.
|
|
||||||
|
|
||||||
**Return Type** : `Promise<void>`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Method** : `play()`
|
|
||||||
|
|
||||||
**Purpose** : Play loaded animation
|
|
||||||
|
|
||||||
**Return Type** : `void`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Method** : `pause()`
|
|
||||||
|
|
||||||
**Purpose** : Pause playing animation
|
|
||||||
|
|
||||||
**Return Type** : `void`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Method** : `stop()`
|
|
||||||
|
|
||||||
**Purpose** : Stop current animation
|
|
||||||
|
|
||||||
**Return Type** : `void`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Method** : `seek(frame: number)`
|
|
||||||
|
|
||||||
**Purpose** : Move to a given frame
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
| Name | Type | Description
|
|
||||||
| --- | --- | --- |
|
|
||||||
| src | `number` | The frame number to move, shouldn't be less than 0 and greater than `totalFrame`
|
|
||||||
|
|
||||||
**Return Type** : `void`
|
|
||||||
|
|
||||||
> [!TIP]
|
|
||||||
> You can easily check total frame of animation, use `player.totalFrame`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Method** : `destory()`
|
|
||||||
|
|
||||||
**Purpose** : Destroy animation and lottie-player element
|
|
||||||
|
|
||||||
**Return Type** : `void`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Method** : `setLooping(value: boolean)`
|
|
||||||
|
|
||||||
**Purpose** : Enable animation loop
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
| Name | Type | Description
|
|
||||||
| --- | --- | --- |
|
|
||||||
| value | `boolean` | `true` enables looping, while `false` disables looping.
|
|
||||||
|
|
||||||
**Return Type** : `void`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Method** : `setDirection(value: number)`
|
|
||||||
|
|
||||||
**Purpose** : Set animation direction
|
|
||||||
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
| Name | Type | Description
|
|
||||||
| --- | --- | --- |
|
|
||||||
| value | `number` | Direction values. `1` to play the animation forward, `-1` to play it backward.
|
|
||||||
|
|
||||||
**Return Type** : `void`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Method** : `setSpeed(value: number)`
|
|
||||||
|
|
||||||
**Purpose** : Set speed of animation
|
|
||||||
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
| Name | Type | Description
|
|
||||||
| --- | --- | --- |
|
|
||||||
| value | `number` | Playback speed. The value must be any positive integer.
|
|
||||||
|
|
||||||
**Return Type** : `void`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Method** : `setBgColor(value: string)`
|
|
||||||
|
|
||||||
**Purpose** : Set a backgroud color
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
| Name | Type | Description
|
|
||||||
| --- | --- | --- |
|
|
||||||
| value | `string` | Color values. Hex(#fff) or string('red') to set background color
|
|
||||||
|
|
||||||
**Return Type** : `void`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Method** : `save(target: ExportableType)`
|
|
||||||
|
|
||||||
**Purpose** : Export current animation to other file type
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
| Name | Type | Description
|
|
||||||
| --- | --- | --- |
|
|
||||||
| value | `ExportableType` | File type to export
|
|
||||||
|
|
||||||
**Return Type** : `void`
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Method** : `getVersion()`
|
|
||||||
|
|
||||||
**Purpose** : Return current ThorVG version
|
|
||||||
|
|
||||||
**Return Type** : `LibraryVersion`
|
|
||||||
|
|
||||||
# Examples
|
|
||||||
|
|
||||||
Please check these examples in various environments.
|
|
||||||
|
|
||||||
- [VanillaJS Usage](https://codesandbox.io/p/sandbox/thorvg-lottieplayer-vanillajs-t737qm)
|
|
||||||
- [React Usage](https://codesandbox.io/p/devbox/thorvg-lottieplayer-react-hkkrq3)
|
|
||||||
- [VueJS Usage](https://codesandbox.io/p/devbox/thorvg-lottieplayer-vue-758h3l)
|
|
||||||
- [Svelte Usage](https://codesandbox.io/p/devbox/thorvg-lottieplayer-svelte-xd4zp6)
|
|
|
@ -1,277 +0,0 @@
|
||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<title>@thorvg/lottie-player | Benchmark</title>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(4, 1fr);
|
|
||||||
gap: 10px;
|
|
||||||
padding: 10px;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
canvas {
|
|
||||||
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<script
|
|
||||||
src="../dist/lottie-player.js"
|
|
||||||
type="text/javascript"
|
|
||||||
></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>ThorVG Web</h1>
|
|
||||||
|
|
||||||
<lottie-player
|
|
||||||
autoPlay
|
|
||||||
loop
|
|
||||||
src="https://lottie.host/6d7dd6e2-ab92-4e98-826a-2f8430768886/NGnHQ6brWA.json"
|
|
||||||
style="width: 300px; height: 300px"
|
|
||||||
></lottie-player>
|
|
||||||
|
|
||||||
<lottie-player
|
|
||||||
autoPlay
|
|
||||||
loop
|
|
||||||
src="https://lottie.host/6d7dd6e2-ab92-4e98-826a-2f8430768886/NGnHQ6brWA.json"
|
|
||||||
style="width: 300px; height: 300px"
|
|
||||||
></lottie-player>
|
|
||||||
|
|
||||||
<lottie-player
|
|
||||||
autoPlay
|
|
||||||
loop
|
|
||||||
src="https://lottie.host/6d7dd6e2-ab92-4e98-826a-2f8430768886/NGnHQ6brWA.json"
|
|
||||||
style="width: 300px; height: 300px"
|
|
||||||
></lottie-player>
|
|
||||||
|
|
||||||
<lottie-player
|
|
||||||
autoPlay
|
|
||||||
loop
|
|
||||||
src="https://lottie.host/6d7dd6e2-ab92-4e98-826a-2f8430768886/NGnHQ6brWA.json"
|
|
||||||
style="width: 300px; height: 300px"
|
|
||||||
></lottie-player>
|
|
||||||
|
|
||||||
<lottie-player
|
|
||||||
autoPlay
|
|
||||||
loop
|
|
||||||
src="https://lottie.host/6d7dd6e2-ab92-4e98-826a-2f8430768886/NGnHQ6brWA.json"
|
|
||||||
style="width: 300px; height: 300px"
|
|
||||||
></lottie-player>
|
|
||||||
|
|
||||||
<lottie-player
|
|
||||||
autoPlay
|
|
||||||
loop
|
|
||||||
src="https://lottie.host/6d7dd6e2-ab92-4e98-826a-2f8430768886/NGnHQ6brWA.json"
|
|
||||||
style="width: 300px; height: 300px"
|
|
||||||
></lottie-player>
|
|
||||||
|
|
||||||
<lottie-player
|
|
||||||
autoPlay
|
|
||||||
loop
|
|
||||||
src="https://lottie.host/6d7dd6e2-ab92-4e98-826a-2f8430768886/NGnHQ6brWA.json"
|
|
||||||
style="width: 300px; height: 300px"
|
|
||||||
></lottie-player>
|
|
||||||
|
|
||||||
<lottie-player
|
|
||||||
autoPlay
|
|
||||||
loop
|
|
||||||
src="https://lottie.host/6d7dd6e2-ab92-4e98-826a-2f8430768886/NGnHQ6brWA.json"
|
|
||||||
style="width: 300px; height: 300px"
|
|
||||||
></lottie-player>
|
|
||||||
|
|
||||||
<lottie-player
|
|
||||||
autoPlay
|
|
||||||
loop
|
|
||||||
src="https://lottie.host/6d7dd6e2-ab92-4e98-826a-2f8430768886/NGnHQ6brWA.json"
|
|
||||||
style="width: 300px; height: 300px"
|
|
||||||
></lottie-player>
|
|
||||||
|
|
||||||
<lottie-player
|
|
||||||
autoPlay
|
|
||||||
loop
|
|
||||||
src="https://lottie.host/6d7dd6e2-ab92-4e98-826a-2f8430768886/NGnHQ6brWA.json"
|
|
||||||
style="width: 300px; height: 300px"
|
|
||||||
></lottie-player>
|
|
||||||
|
|
||||||
<lottie-player
|
|
||||||
autoPlay
|
|
||||||
loop
|
|
||||||
src="https://lottie.host/6d7dd6e2-ab92-4e98-826a-2f8430768886/NGnHQ6brWA.json"
|
|
||||||
style="width: 300px; height: 300px"
|
|
||||||
></lottie-player>
|
|
||||||
|
|
||||||
<lottie-player
|
|
||||||
autoPlay
|
|
||||||
loop
|
|
||||||
src="https://lottie.host/6d7dd6e2-ab92-4e98-826a-2f8430768886/NGnHQ6brWA.json"
|
|
||||||
style="width: 300px; height: 300px"
|
|
||||||
></lottie-player>
|
|
||||||
|
|
||||||
<lottie-player
|
|
||||||
autoPlay
|
|
||||||
loop
|
|
||||||
src="https://lottie.host/6d7dd6e2-ab92-4e98-826a-2f8430768886/NGnHQ6brWA.json"
|
|
||||||
style="width: 300px; height: 300px"
|
|
||||||
></lottie-player>
|
|
||||||
|
|
||||||
<lottie-player
|
|
||||||
autoPlay
|
|
||||||
loop
|
|
||||||
src="https://lottie.host/6d7dd6e2-ab92-4e98-826a-2f8430768886/NGnHQ6brWA.json"
|
|
||||||
style="width: 300px; height: 300px"
|
|
||||||
></lottie-player>
|
|
||||||
|
|
||||||
<lottie-player
|
|
||||||
autoPlay
|
|
||||||
loop
|
|
||||||
src="https://lottie.host/6d7dd6e2-ab92-4e98-826a-2f8430768886/NGnHQ6brWA.json"
|
|
||||||
style="width: 300px; height: 300px"
|
|
||||||
></lottie-player>
|
|
||||||
|
|
||||||
<lottie-player
|
|
||||||
autoPlay
|
|
||||||
loop
|
|
||||||
src="https://lottie.host/6d7dd6e2-ab92-4e98-826a-2f8430768886/NGnHQ6brWA.json"
|
|
||||||
style="width: 300px; height: 300px"
|
|
||||||
></lottie-player>
|
|
||||||
|
|
||||||
<lottie-player
|
|
||||||
autoPlay
|
|
||||||
loop
|
|
||||||
src="https://lottie.host/6d7dd6e2-ab92-4e98-826a-2f8430768886/NGnHQ6brWA.json"
|
|
||||||
style="width: 300px; height: 300px"
|
|
||||||
></lottie-player>
|
|
||||||
|
|
||||||
<lottie-player
|
|
||||||
autoPlay
|
|
||||||
loop
|
|
||||||
src="https://lottie.host/6d7dd6e2-ab92-4e98-826a-2f8430768886/NGnHQ6brWA.json"
|
|
||||||
style="width: 300px; height: 300px"
|
|
||||||
></lottie-player>
|
|
||||||
|
|
||||||
<lottie-player
|
|
||||||
autoPlay
|
|
||||||
loop
|
|
||||||
src="https://lottie.host/6d7dd6e2-ab92-4e98-826a-2f8430768886/NGnHQ6brWA.json"
|
|
||||||
style="width: 300px; height: 300px"
|
|
||||||
></lottie-player>
|
|
||||||
|
|
||||||
<lottie-player
|
|
||||||
autoPlay
|
|
||||||
loop
|
|
||||||
src="https://lottie.host/6d7dd6e2-ab92-4e98-826a-2f8430768886/NGnHQ6brWA.json"
|
|
||||||
style="width: 300px; height: 300px"
|
|
||||||
></lottie-player>
|
|
||||||
|
|
||||||
<lottie-player
|
|
||||||
autoPlay
|
|
||||||
loop
|
|
||||||
src="https://lottie.host/6d7dd6e2-ab92-4e98-826a-2f8430768886/NGnHQ6brWA.json"
|
|
||||||
style="width: 300px; height: 300px"
|
|
||||||
></lottie-player>
|
|
||||||
|
|
||||||
<lottie-player
|
|
||||||
autoPlay
|
|
||||||
loop
|
|
||||||
src="https://lottie.host/6d7dd6e2-ab92-4e98-826a-2f8430768886/NGnHQ6brWA.json"
|
|
||||||
style="width: 300px; height: 300px"
|
|
||||||
></lottie-player>
|
|
||||||
|
|
||||||
<lottie-player
|
|
||||||
autoPlay
|
|
||||||
loop
|
|
||||||
src="https://lottie.host/6d7dd6e2-ab92-4e98-826a-2f8430768886/NGnHQ6brWA.json"
|
|
||||||
style="width: 300px; height: 300px"
|
|
||||||
></lottie-player>
|
|
||||||
|
|
||||||
<lottie-player
|
|
||||||
autoPlay
|
|
||||||
loop
|
|
||||||
src="https://lottie.host/6d7dd6e2-ab92-4e98-826a-2f8430768886/NGnHQ6brWA.json"
|
|
||||||
style="width: 300px; height: 300px"
|
|
||||||
></lottie-player>
|
|
||||||
|
|
||||||
<lottie-player
|
|
||||||
autoPlay
|
|
||||||
loop
|
|
||||||
src="https://lottie.host/6d7dd6e2-ab92-4e98-826a-2f8430768886/NGnHQ6brWA.json"
|
|
||||||
style="width: 300px; height: 300px"
|
|
||||||
></lottie-player>
|
|
||||||
|
|
||||||
<lottie-player
|
|
||||||
autoPlay
|
|
||||||
loop
|
|
||||||
src="https://lottie.host/6d7dd6e2-ab92-4e98-826a-2f8430768886/NGnHQ6brWA.json"
|
|
||||||
style="width: 300px; height: 300px"
|
|
||||||
></lottie-player>
|
|
||||||
|
|
||||||
<lottie-player
|
|
||||||
autoPlay
|
|
||||||
loop
|
|
||||||
src="https://lottie.host/6d7dd6e2-ab92-4e98-826a-2f8430768886/NGnHQ6brWA.json"
|
|
||||||
style="width: 300px; height: 300px"
|
|
||||||
></lottie-player>
|
|
||||||
|
|
||||||
<lottie-player
|
|
||||||
autoPlay
|
|
||||||
loop
|
|
||||||
src="https://lottie.host/6d7dd6e2-ab92-4e98-826a-2f8430768886/NGnHQ6brWA.json"
|
|
||||||
style="width: 300px; height: 300px"
|
|
||||||
></lottie-player>
|
|
||||||
|
|
||||||
<lottie-player
|
|
||||||
autoPlay
|
|
||||||
loop
|
|
||||||
src="https://lottie.host/6d7dd6e2-ab92-4e98-826a-2f8430768886/NGnHQ6brWA.json"
|
|
||||||
style="width: 300px; height: 300px"
|
|
||||||
></lottie-player>
|
|
||||||
|
|
||||||
<lottie-player
|
|
||||||
autoPlay
|
|
||||||
loop
|
|
||||||
src="https://lottie.host/6d7dd6e2-ab92-4e98-826a-2f8430768886/NGnHQ6brWA.json"
|
|
||||||
style="width: 300px; height: 300px"
|
|
||||||
></lottie-player>
|
|
||||||
|
|
||||||
<script src="https://mrdoob.github.io/stats.js/build/stats.min.js"></script>
|
|
||||||
<script>
|
|
||||||
var statsFPS = new Stats();
|
|
||||||
statsFPS.showPanel(0); // 0: fps
|
|
||||||
statsFPS.dom.style.cssText =
|
|
||||||
"position:fixed;top:0;left:0;cursor:pointer;opacity:0.9;z-index:10000";
|
|
||||||
document.body.appendChild(statsFPS.dom);
|
|
||||||
|
|
||||||
var statsMS = new Stats();
|
|
||||||
statsMS.showPanel(1); // 1: ms
|
|
||||||
statsMS.dom.style.cssText =
|
|
||||||
"position:fixed;top:0;left:80px;cursor:pointer;opacity:0.9;z-index:10000";
|
|
||||||
document.body.appendChild(statsMS.dom);
|
|
||||||
|
|
||||||
var statsMB;
|
|
||||||
if (self.performance && self.performance.memory) {
|
|
||||||
statsMB = new Stats();
|
|
||||||
statsMB.showPanel(2); // 2: mb
|
|
||||||
statsMB.dom.style.cssText =
|
|
||||||
"position:fixed;top:0;left:160px;cursor:pointer;opacity:0.9;z-index:10000";
|
|
||||||
document.body.appendChild(statsMB.dom);
|
|
||||||
}
|
|
||||||
|
|
||||||
function animate() {
|
|
||||||
statsFPS.begin();
|
|
||||||
statsMS.begin();
|
|
||||||
if (statsMB) statsMB.begin();
|
|
||||||
|
|
||||||
statsFPS.end();
|
|
||||||
statsMS.end();
|
|
||||||
if (statsMB) statsMB.end();
|
|
||||||
|
|
||||||
requestAnimationFrame(animate);
|
|
||||||
}
|
|
||||||
|
|
||||||
requestAnimationFrame(animate);
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,166 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<title>ThorVG Lottie Player</title>
|
|
||||||
<meta name="description" content="A web lottie player using ThorVG as a renderer" />
|
|
||||||
<script src="../dist/lottie-player.js"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div>
|
|
||||||
<div>
|
|
||||||
<button onclick="playAnimation()">Play</button>
|
|
||||||
<button onclick="pauseAnimation()">Pause</button>
|
|
||||||
<button onclick="stopAnimation()">Stop</button>
|
|
||||||
<button onclick="createAnimation()">Create</button>
|
|
||||||
<button onclick="destroyAnimation()">Destroy</button>
|
|
||||||
<button onclick="save('gif')">save2gif</button>
|
|
||||||
<button onclick="save('tvg')">save2tvg</button>
|
|
||||||
<button onclick="save('png')">save2png</button>
|
|
||||||
<div>
|
|
||||||
<label for="reverseCheckbox">Reverse</label>
|
|
||||||
<input type="checkbox" id="reverseCheckbox" onchange="toggleReverse(event)">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<label for="loopCheckbox">Loop</label>
|
|
||||||
<input type="checkbox" id="loopCheckbox" onchange="toggleLoop(event)" checked>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<label for="speedRange">Speed</label>
|
|
||||||
<input type="range" id="speedRange" min="0.1" max="2" step="0.1" value="1" onchange="changeSpeed(this.value)">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<label for="frameRange">Frame</label>
|
|
||||||
<input type="range" id="frameRange" min="1" max="100" step="1" value="1" onchange="seekFrame(this.value)">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="lottie"></div>
|
|
||||||
</div>
|
|
||||||
<script>
|
|
||||||
let animation;
|
|
||||||
window.onload = function() {
|
|
||||||
createAnimation();
|
|
||||||
}
|
|
||||||
|
|
||||||
function createAnimation() {
|
|
||||||
if (animation) {
|
|
||||||
alert('Animation already exists');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const lottie = document.querySelector('.lottie');
|
|
||||||
animation = document.createElement('lottie-player');
|
|
||||||
|
|
||||||
animation.autoPlay = true;
|
|
||||||
animation.loop = true;
|
|
||||||
animation.src = "https://lottie.host/6d7dd6e2-ab92-4e98-826a-2f8430768886/NGnHQ6brWA.json";
|
|
||||||
animation.style.width = "500px";
|
|
||||||
animation.style.height = "500px";
|
|
||||||
|
|
||||||
lottie.appendChild(animation);
|
|
||||||
|
|
||||||
animation = document.querySelector('lottie-player');
|
|
||||||
const frameRange = document.querySelector('#frameRange');
|
|
||||||
|
|
||||||
animation.addEventListener('frame', function(e) {
|
|
||||||
frameRange.value = e.detail.frame / animation.totalFrame * 100;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function pauseAnimation() {
|
|
||||||
if (!animation) {
|
|
||||||
alert('Animation is not created yet');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
animation.pause();
|
|
||||||
}
|
|
||||||
|
|
||||||
function stopAnimation() {
|
|
||||||
if (!animation) {
|
|
||||||
alert('Animation is not created yet');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
animation.stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
function seekFrame(framePercentage) {
|
|
||||||
if (!animation) {
|
|
||||||
alert('Animation is not created yet');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
animation.seek(animation.totalFrames * framePercentage / 100);
|
|
||||||
}
|
|
||||||
|
|
||||||
function destroyAnimation() {
|
|
||||||
if (!animation) {
|
|
||||||
alert('No animation to destroy');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
animation.destroy();
|
|
||||||
animation = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
function playAnimation() {
|
|
||||||
if (!animation) {
|
|
||||||
alert('Animation is not created yet');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
animation.play();
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleLoop(e) {
|
|
||||||
if (!animation) {
|
|
||||||
alert('Animation is not created yet');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
animation.setLooping(e.target.checked);
|
|
||||||
if (animation.currentState !== 'playing') {
|
|
||||||
animation.play();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function changeSpeed(speed) {
|
|
||||||
if (!animation) {
|
|
||||||
alert('Animation is not created yet');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
animation.setSpeed(speed);
|
|
||||||
if (animation.currentState !== 'playing') {
|
|
||||||
animation.play();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleReverse(e) {
|
|
||||||
if (!animation) {
|
|
||||||
alert('Animation is not created yet');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
animation.setDirection(e.target.checked ? -1 : 1);
|
|
||||||
if (animation.currentState !== 'playing') {
|
|
||||||
animation.play();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function save(ext) {
|
|
||||||
if (!animation) {
|
|
||||||
alert('Animation is not created yet');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
animation.save(ext);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,68 +0,0 @@
|
||||||
{
|
|
||||||
"name": "@thorvg/lottie-player",
|
|
||||||
"version": "1.0.0-beta.0",
|
|
||||||
"description": "A web lottie player using ThorVG as a renderer",
|
|
||||||
"main": "./dist/lottie-player.cjs.js",
|
|
||||||
"module": "./dist/lottie-player.esm.js",
|
|
||||||
"exports": {
|
|
||||||
".": {
|
|
||||||
"import": "./dist/lottie-player.cjs.js",
|
|
||||||
"require": "./dist/lottie-player.esm.js"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"publishConfig": {
|
|
||||||
"access": "public"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"dist/"
|
|
||||||
],
|
|
||||||
"types": "./dist/lottie-player.d.ts",
|
|
||||||
"scripts": {
|
|
||||||
"build": "npm run clean && npm run copy:wasm && THORVG_VERSION=$(sed -n -e 4p ../meson.build | sed 's/..$//' | sed -r 's/.{19}//') rollup -c --bundleConfigAsCjs && rm -rf ./dist/thorvg-wasm.js",
|
|
||||||
"build:watch": "npm run clean && npm run copy:wasm && rollup -c --bundleConfigAsCjs --watch",
|
|
||||||
"copy:wasm": "cp ../build_wasm/src/bindings/wasm/thorvg-wasm.js ./dist",
|
|
||||||
"clean": "rm -rf dist && mkdir dist && touch dist/index.js",
|
|
||||||
"test": "echo \"Error: no test specified\" && exit 1",
|
|
||||||
"lint": "eslint ./src --ext .ts,.tsx,.js",
|
|
||||||
"lint:fix": "eslint ./src --ext .ts,.tsx,.js --fix"
|
|
||||||
},
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git+https://github.com/thorvg/thorvg.git"
|
|
||||||
},
|
|
||||||
"author": "Jinny You <jinny@lottiefiles.com>",
|
|
||||||
"license": "MIT",
|
|
||||||
"bugs": {
|
|
||||||
"url": "https://github.com/thorvg/thorvg/issues"
|
|
||||||
},
|
|
||||||
"homepage": "https://thorvg.org",
|
|
||||||
"keywords": [
|
|
||||||
"lottie",
|
|
||||||
"animation",
|
|
||||||
"thorvg",
|
|
||||||
"tvg"
|
|
||||||
],
|
|
||||||
"devDependencies": {
|
|
||||||
"@rollup/plugin-commonjs": "^25.0.7",
|
|
||||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
|
||||||
"@swc/core": "^1.3.99",
|
|
||||||
"@typescript-eslint/eslint-plugin": "^6.4.0",
|
|
||||||
"eslint": "^8.0.1",
|
|
||||||
"eslint-config-standard-with-typescript": "^40.0.0",
|
|
||||||
"eslint-plugin-import": "^2.25.2",
|
|
||||||
"eslint-plugin-n": "^15.0.0 || ^16.0.0 ",
|
|
||||||
"eslint-plugin-promise": "^6.0.0",
|
|
||||||
"eslint-plugin-wc": "^2.0.4",
|
|
||||||
"rollup": "^4.6.0",
|
|
||||||
"rollup-plugin-baked-env": "^1.0.1",
|
|
||||||
"rollup-plugin-dts": "^6.1.0",
|
|
||||||
"rollup-plugin-polyfill-node": "^0.13.0",
|
|
||||||
"rollup-plugin-swc3": "^0.10.4",
|
|
||||||
"rollup-plugin-terser": "^7.0.2",
|
|
||||||
"typescript": "*"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"lit": "^3.1.0",
|
|
||||||
"url": "^0.11.3"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,93 +0,0 @@
|
||||||
import { swc } from "rollup-plugin-swc3";
|
|
||||||
import { dts } from "rollup-plugin-dts";
|
|
||||||
import { nodeResolve } from "@rollup/plugin-node-resolve";
|
|
||||||
import commonjs from "@rollup/plugin-commonjs";
|
|
||||||
import { terser } from "rollup-plugin-terser";
|
|
||||||
import nodePolyfills from 'rollup-plugin-polyfill-node';
|
|
||||||
import bakedEnv from 'rollup-plugin-baked-env';
|
|
||||||
import pkg from './package.json';
|
|
||||||
|
|
||||||
const name = 'lottie-player';
|
|
||||||
const globals = {
|
|
||||||
url: "url",
|
|
||||||
lit: "lit",
|
|
||||||
"lit/decorators.js": "lit/decorators.js",
|
|
||||||
};
|
|
||||||
|
|
||||||
export default [
|
|
||||||
{
|
|
||||||
input: "./src/lottie-player.ts",
|
|
||||||
treeshake: false,
|
|
||||||
output: [
|
|
||||||
{
|
|
||||||
file: './dist/lottie-player.js',
|
|
||||||
format: "umd",
|
|
||||||
name,
|
|
||||||
minifyInternalExports: true,
|
|
||||||
inlineDynamicImports: true,
|
|
||||||
sourcemap: true,
|
|
||||||
globals,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
file: pkg.main,
|
|
||||||
name,
|
|
||||||
format: "cjs",
|
|
||||||
minifyInternalExports: true,
|
|
||||||
inlineDynamicImports: true,
|
|
||||||
sourcemap: true,
|
|
||||||
globals,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
file: pkg.module,
|
|
||||||
format: "esm",
|
|
||||||
name,
|
|
||||||
inlineDynamicImports: true,
|
|
||||||
sourcemap: true,
|
|
||||||
globals,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
plugins: [
|
|
||||||
bakedEnv({ THORVG_VERSION: process.env.THORVG_VERSION }),
|
|
||||||
nodePolyfills(),
|
|
||||||
commonjs({
|
|
||||||
include: /node_modules/
|
|
||||||
}),
|
|
||||||
swc({
|
|
||||||
include: /\.[mc]?[jt]sx?$/,
|
|
||||||
exclude: /node_modules/,
|
|
||||||
tsconfig: "tsconfig.json",
|
|
||||||
jsc: {
|
|
||||||
parser: {
|
|
||||||
syntax: "typescript",
|
|
||||||
tsx: false,
|
|
||||||
decorators: true,
|
|
||||||
declaration: true,
|
|
||||||
dynamicImport: true,
|
|
||||||
},
|
|
||||||
target: "es5",
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
nodeResolve(),
|
|
||||||
terser({
|
|
||||||
compress: true,
|
|
||||||
mangle: true,
|
|
||||||
output: {
|
|
||||||
comments: false,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
input: "./src/lottie-player.ts",
|
|
||||||
treeshake: false,
|
|
||||||
output: [
|
|
||||||
{
|
|
||||||
file: './dist/lottie-player.d.ts',
|
|
||||||
format: "esm",
|
|
||||||
}
|
|
||||||
],
|
|
||||||
plugins: [
|
|
||||||
dts(),
|
|
||||||
],
|
|
||||||
}
|
|
||||||
];
|
|
|
@ -1,663 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2023 - 2024 the ThorVG project. All rights reserved.
|
|
||||||
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
* SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { html, PropertyValueMap, LitElement, type TemplateResult } from 'lit';
|
|
||||||
import { customElement, property } from 'lit/decorators.js';
|
|
||||||
|
|
||||||
// @ts-ignore: WASM Glue code doesn't have type & Only available on build progress
|
|
||||||
import Module from '../dist/thorvg-wasm';
|
|
||||||
import { THORVG_VERSION } from './version';
|
|
||||||
|
|
||||||
type LottieJson = Map<PropertyKey, any>;
|
|
||||||
type TvgModule = any;
|
|
||||||
|
|
||||||
let _module: any;
|
|
||||||
(async () => {
|
|
||||||
_module = await Module();
|
|
||||||
})();
|
|
||||||
|
|
||||||
// Define library version
|
|
||||||
export interface LibraryVersion {
|
|
||||||
THORVG_VERSION: string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Define file type which can be exported
|
|
||||||
export enum ExportableType {
|
|
||||||
GIF = 'gif',
|
|
||||||
TVG = 'tvg',
|
|
||||||
PNG = 'png',
|
|
||||||
}
|
|
||||||
|
|
||||||
// Define mime type which player can load
|
|
||||||
export enum MimeType {
|
|
||||||
JSON = 'json',
|
|
||||||
JPG = 'jpg',
|
|
||||||
PNG = 'png',
|
|
||||||
SVG = 'svg',
|
|
||||||
TVG = 'tvg',
|
|
||||||
}
|
|
||||||
|
|
||||||
// Define valid player states
|
|
||||||
export enum PlayerState {
|
|
||||||
Destroyed = 'destroyed', // Player is destroyed by `destroy()` method
|
|
||||||
Error = 'error', // An error occurred
|
|
||||||
Loading = 'loading', // Player is loading
|
|
||||||
Paused = 'paused', // Player is paused
|
|
||||||
Playing = 'playing', // Player is playing
|
|
||||||
Stopped = 'stopped', // Player is stopped
|
|
||||||
Frozen = 'frozen', // Player is paused due to player being invisible
|
|
||||||
}
|
|
||||||
|
|
||||||
// Define play modes
|
|
||||||
export enum PlayMode {
|
|
||||||
Bounce = 'bounce',
|
|
||||||
Normal = 'normal',
|
|
||||||
}
|
|
||||||
|
|
||||||
// Define player events
|
|
||||||
export enum PlayerEvent {
|
|
||||||
Complete = 'complete',
|
|
||||||
Destroyed = 'destroyed',
|
|
||||||
Error = 'error',
|
|
||||||
Frame = 'frame',
|
|
||||||
Freeze = 'freeze',
|
|
||||||
Load = 'load',
|
|
||||||
Loop = 'loop',
|
|
||||||
Pause = 'pause',
|
|
||||||
Play = 'play',
|
|
||||||
Ready = 'ready',
|
|
||||||
Stop = 'stop',
|
|
||||||
}
|
|
||||||
|
|
||||||
const _parseLottieFromURL = async (url: string): Promise<LottieJson> => {
|
|
||||||
if (typeof url !== 'string') {
|
|
||||||
throw new Error(`The url value must be a string`);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const srcUrl: URL = new URL(url);
|
|
||||||
const result = await fetch(srcUrl.toString());
|
|
||||||
const json = await result.json();
|
|
||||||
|
|
||||||
return json;
|
|
||||||
} catch (err) {
|
|
||||||
throw new Error(
|
|
||||||
`An error occurred while trying to load the Lottie file from URL`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const _parseImageFromURL = async (url: string): Promise<ArrayBuffer> => {
|
|
||||||
const response = await fetch(url);
|
|
||||||
return response.arrayBuffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
const _parseJSON = async (data: string): Promise<string> => {
|
|
||||||
try {
|
|
||||||
data = JSON.parse(data);
|
|
||||||
} catch (err) {
|
|
||||||
const json = await _parseLottieFromURL(data as string);
|
|
||||||
data = JSON.stringify(json);
|
|
||||||
}
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
const _parseSrc = async (src: string | object | ArrayBuffer, mimeType: MimeType): Promise<Uint8Array> => {
|
|
||||||
const encoder = new TextEncoder();
|
|
||||||
let data = src;
|
|
||||||
|
|
||||||
switch (typeof data) {
|
|
||||||
case 'object':
|
|
||||||
if (data instanceof ArrayBuffer) {
|
|
||||||
return new Uint8Array(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
data = JSON.stringify(data);
|
|
||||||
return encoder.encode(data);
|
|
||||||
case 'string':
|
|
||||||
if (mimeType === MimeType.JSON) {
|
|
||||||
data = await _parseJSON(data);
|
|
||||||
return encoder.encode(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
const buffer = await _parseImageFromURL(data);
|
|
||||||
return new Uint8Array(buffer);
|
|
||||||
default:
|
|
||||||
throw new Error('Invalid src type');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const _wait = (timeToDelay: number) => {
|
|
||||||
return new Promise((resolve) => setTimeout(resolve, timeToDelay))
|
|
||||||
};
|
|
||||||
|
|
||||||
const _downloadFile = (fileName: string, blob: Blob) => {
|
|
||||||
const link = document.createElement('a');
|
|
||||||
link.setAttribute('href', URL.createObjectURL(blob));
|
|
||||||
link.setAttribute('download', fileName);
|
|
||||||
document.body.appendChild(link);
|
|
||||||
link.click();
|
|
||||||
document.body.removeChild(link);
|
|
||||||
}
|
|
||||||
|
|
||||||
@customElement('lottie-player')
|
|
||||||
export class LottiePlayer extends LitElement {
|
|
||||||
/**
|
|
||||||
* Lottie animation JSON data or URL to JSON.
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
@property({ type: String })
|
|
||||||
public src?: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* File mime type.
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
@property({ type: MimeType })
|
|
||||||
public mimeType: MimeType = MimeType.JSON;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Animation speed.
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
@property({ type: Number })
|
|
||||||
public speed: number = 1.0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Autoplay animation on load.
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
@property({ type: Boolean })
|
|
||||||
public autoPlay: boolean = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Number of times to loop animation.
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
@property({ type: Number })
|
|
||||||
public count?: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether to loop animation.
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
@property({ type: Boolean })
|
|
||||||
public loop: boolean = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Direction of animation.
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
@property({ type: Number })
|
|
||||||
public direction: number = 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Play mode.
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
@property()
|
|
||||||
public mode: PlayMode = PlayMode.Normal;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Intermission
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
@property()
|
|
||||||
public intermission: number = 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* total frame of current animation (readonly)
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
@property({ type: Number })
|
|
||||||
public totalFrame: number = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* current frame of current animation (readonly)
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
@property({ type: Number })
|
|
||||||
public currentFrame: number = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Player state
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
@property({ type: Number })
|
|
||||||
public currentState: PlayerState = PlayerState.Loading;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* original size of the animation (readonly)
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
@property({ type: Float32Array })
|
|
||||||
public get size(): Float32Array {
|
|
||||||
return Float32Array.from(this._TVG?.size() || [0, 0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private _TVG?: TvgModule;
|
|
||||||
private _canvas?: HTMLCanvasElement;
|
|
||||||
private _imageData?: ImageData;
|
|
||||||
private _beginTime: number = Date.now();
|
|
||||||
private _counter: number = 1;
|
|
||||||
private _timer?: ReturnType<typeof setInterval>;
|
|
||||||
private _observer?: IntersectionObserver;
|
|
||||||
private _observable: boolean = false;
|
|
||||||
|
|
||||||
private async _init(): Promise<void> {
|
|
||||||
if (!_module) {
|
|
||||||
//NOTE: ThorVG Module has not loaded
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this._timer) {
|
|
||||||
//NOTE: ThorVG Module has loaded, but called this function again
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
clearInterval(this._timer);
|
|
||||||
this._timer = undefined;
|
|
||||||
|
|
||||||
this._TVG = new _module.TvgLottieAnimation();
|
|
||||||
|
|
||||||
if (this.src) {
|
|
||||||
this.load(this.src, this.mimeType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private _observerCallback(entries: IntersectionObserverEntry[]) {
|
|
||||||
const entry = entries[0];
|
|
||||||
const target = entry.target as LottiePlayer;
|
|
||||||
target._observable = entry.isIntersecting;
|
|
||||||
|
|
||||||
if (entry.isIntersecting) {
|
|
||||||
if (target.currentState === PlayerState.Frozen) {
|
|
||||||
target.play();
|
|
||||||
}
|
|
||||||
} else if (target.currentState === PlayerState.Playing) {
|
|
||||||
target.freeze();
|
|
||||||
target.dispatchEvent(new CustomEvent(PlayerEvent.Freeze));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected firstUpdated(_changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>): void {
|
|
||||||
this._canvas = this.shadowRoot!.querySelector('#thorvg-canvas') as HTMLCanvasElement;
|
|
||||||
this._canvas.width = this._canvas.offsetWidth;
|
|
||||||
this._canvas.height = this._canvas.offsetHeight;
|
|
||||||
|
|
||||||
this._observer = new IntersectionObserver(this._observerCallback);
|
|
||||||
this._observer.observe(this);
|
|
||||||
|
|
||||||
if (!this._TVG) {
|
|
||||||
this._timer = setInterval(this._init.bind(this), 100);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.src) {
|
|
||||||
this.load(this.src, this.mimeType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected createRenderRoot(): HTMLElement | DocumentFragment {
|
|
||||||
this.style.display = 'block';
|
|
||||||
return super.createRenderRoot();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _animLoop(){
|
|
||||||
if (!this._TVG) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (await this._update()) {
|
|
||||||
this._render();
|
|
||||||
window.requestAnimationFrame(this._animLoop.bind(this));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private _loadBytes(data: Uint8Array, rPath: string = ''): void {
|
|
||||||
const isLoaded = this._TVG.load(data, this.mimeType, this._canvas!.width, this._canvas!.height, rPath);
|
|
||||||
if (!isLoaded) {
|
|
||||||
throw new Error('Unable to load an image. Error: ', this._TVG.error());
|
|
||||||
}
|
|
||||||
|
|
||||||
this._render();
|
|
||||||
this.dispatchEvent(new CustomEvent(PlayerEvent.Load));
|
|
||||||
|
|
||||||
if (this.autoPlay) {
|
|
||||||
this.play();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private _flush(): void {
|
|
||||||
const context = this._canvas!.getContext('2d');
|
|
||||||
context!.putImageData(this._imageData!, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private _render(): void {
|
|
||||||
this._TVG.resize(this._canvas!.width, this._canvas!.height);
|
|
||||||
const isUpdated = this._TVG.update();
|
|
||||||
|
|
||||||
if (!isUpdated) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const buffer = this._TVG.render();
|
|
||||||
const clampedBuffer = new Uint8ClampedArray(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
||||||
if (clampedBuffer.length < 1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._imageData = new ImageData(clampedBuffer, this._canvas!.width, this._canvas!.height);
|
|
||||||
this._flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _update(): Promise<boolean> {
|
|
||||||
if (this.currentState !== PlayerState.Playing) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const duration = this._TVG.duration();
|
|
||||||
const currentTime = Date.now() / 1000;
|
|
||||||
this.currentFrame = (currentTime - this._beginTime) / duration * this.totalFrame * this.speed;
|
|
||||||
if (this.direction === -1) {
|
|
||||||
this.currentFrame = this.totalFrame - this.currentFrame;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
(this.direction === 1 && this.currentFrame >= this.totalFrame) ||
|
|
||||||
(this.direction === -1 && this.currentFrame <= 0)
|
|
||||||
) {
|
|
||||||
const totalCount = this.count ? this.mode === PlayMode.Bounce ? this.count * 2 : this.count : 0;
|
|
||||||
if (this.loop || (totalCount && this._counter < totalCount)) {
|
|
||||||
if (this.mode === PlayMode.Bounce) {
|
|
||||||
this.direction = this.direction === 1 ? -1 : 1;
|
|
||||||
this.currentFrame = this.direction === 1 ? 0 : this.totalFrame;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.count) {
|
|
||||||
this._counter += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
await _wait(this.intermission);
|
|
||||||
this.play();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.dispatchEvent(new CustomEvent(PlayerEvent.Complete));
|
|
||||||
this.currentState = PlayerState.Stopped;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.dispatchEvent(new CustomEvent(PlayerEvent.Frame, {
|
|
||||||
detail: {
|
|
||||||
frame: this.currentFrame,
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
return this._TVG.frame(this.currentFrame);
|
|
||||||
}
|
|
||||||
|
|
||||||
private _frame(curFrame: number): void {
|
|
||||||
this.pause();
|
|
||||||
this.currentFrame = curFrame;
|
|
||||||
this._TVG.frame(curFrame);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configure and load
|
|
||||||
* @param src Lottie animation JSON data or URL to JSON.
|
|
||||||
* @param mimeType The MIME type of the data to be loaded, defaults to JSON
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
public async load(src: string | object, mimeType: MimeType = MimeType.JSON): Promise<void> {
|
|
||||||
try {
|
|
||||||
const bytes = await _parseSrc(src, mimeType);
|
|
||||||
this.dispatchEvent(new CustomEvent(PlayerEvent.Ready));
|
|
||||||
|
|
||||||
this.mimeType = mimeType;
|
|
||||||
this._loadBytes(bytes);
|
|
||||||
} catch (err) {
|
|
||||||
this.currentState = PlayerState.Error;
|
|
||||||
this.dispatchEvent(new CustomEvent(PlayerEvent.Error));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start playing animation.
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
public play(): void {
|
|
||||||
if (this.mimeType !== MimeType.JSON) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.totalFrame = this._TVG.totalFrame();
|
|
||||||
if (this.totalFrame < 1) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._beginTime = Date.now() / 1000;
|
|
||||||
if (this.currentState === PlayerState.Playing) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._observable) {
|
|
||||||
this.currentState = PlayerState.Playing;
|
|
||||||
window.requestAnimationFrame(this._animLoop.bind(this));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.currentState = PlayerState.Frozen;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pause animation.
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
public pause(): void {
|
|
||||||
this.currentState = PlayerState.Paused;
|
|
||||||
this.dispatchEvent(new CustomEvent(PlayerEvent.Pause));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stop animation.
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
public stop(): void {
|
|
||||||
this.currentState = PlayerState.Stopped;
|
|
||||||
this.currentFrame = 0;
|
|
||||||
this._counter = 1;
|
|
||||||
this.seek(0);
|
|
||||||
|
|
||||||
this.dispatchEvent(new CustomEvent(PlayerEvent.Stop));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Freeze animation.
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
public freeze(): void {
|
|
||||||
this.currentState = PlayerState.Frozen;
|
|
||||||
this.dispatchEvent(new CustomEvent(PlayerEvent.Freeze));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Seek to a given frame
|
|
||||||
* @param frame Frame number to move
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
public async seek(frame: number): Promise<void> {
|
|
||||||
this._frame(frame);
|
|
||||||
await this._update();
|
|
||||||
this._render();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adjust the canvas size.
|
|
||||||
* @param width The width to resize
|
|
||||||
* @param height The height to resize
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
public resize(width: number, height: number) {
|
|
||||||
this._canvas!.width = width;
|
|
||||||
this._canvas!.height = height;
|
|
||||||
|
|
||||||
if (this.currentState !== PlayerState.Playing) {
|
|
||||||
this._render();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destroy animation and lottie-player element.
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
public destroy(): void {
|
|
||||||
if (!this._TVG) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._TVG.delete();
|
|
||||||
this._TVG = null;
|
|
||||||
this.currentState = PlayerState.Destroyed;
|
|
||||||
|
|
||||||
if (this._observer) {
|
|
||||||
this._observer.disconnect();
|
|
||||||
this._observer = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.dispatchEvent(new CustomEvent(PlayerEvent.Destroyed));
|
|
||||||
this.remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the repeating of the animation.
|
|
||||||
* @param value Whether to enable repeating. Boolean true enables repeating.
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
public setLooping(value: boolean): void {
|
|
||||||
if (!this._TVG) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.loop = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Animation play direction.
|
|
||||||
* @param value Direction values. (1: forward, -1: backward)
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
public setDirection(value: number): void {
|
|
||||||
if (!this._TVG) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.direction = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set animation play speed.
|
|
||||||
* @param value Playback speed. (any positive number)
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
public setSpeed(value: number): void {
|
|
||||||
if (!this._TVG) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.speed = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set a background color. (default: 0x00000000)
|
|
||||||
* @param value Hex(#fff) or string(red) of background color
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
public setBgColor(value: string): void {
|
|
||||||
if (!this._TVG) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._canvas!.style.backgroundColor = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Save current animation to other file type
|
|
||||||
* @param target File type to export
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
public async save(target: ExportableType): Promise<void> {
|
|
||||||
if (!this._TVG) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const fileName = `output.${target}`;
|
|
||||||
|
|
||||||
if (target === ExportableType.PNG) {
|
|
||||||
this._canvas!.toBlob((blob: Blob | null) => {
|
|
||||||
if (!blob) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_downloadFile('output.png', blob);
|
|
||||||
}, 'image/png');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const isExported = this._TVG.save(target);
|
|
||||||
if (!isExported) {
|
|
||||||
throw new Error('Unable to save. Error: ', this._TVG.error());
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = _module.FS.readFile(fileName);
|
|
||||||
|
|
||||||
if (target === ExportableType.GIF && data.length < 6) {
|
|
||||||
throw new Error(
|
|
||||||
`Unable to save the GIF data. The generated file size is invalid.`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target === ExportableType.TVG && data.length < 33) {
|
|
||||||
throw new Error(
|
|
||||||
`Unable to save the TVG data. The generated file size is invalid.`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const blob = new Blob([data], {type: 'application/octet-stream'});
|
|
||||||
_downloadFile(fileName, blob);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return thorvg version
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
public getVersion(): LibraryVersion {
|
|
||||||
return {
|
|
||||||
THORVG_VERSION,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public render(): TemplateResult {
|
|
||||||
return html`
|
|
||||||
<canvas id="thorvg-canvas" style="width: 100%; height: 100%;" />
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
// @ts-ignore: injected process.env from `rollup-plugin-baked-env`
|
|
||||||
import env from 'process.env';
|
|
||||||
export const THORVG_VERSION = env.THORVG_VERSION || '' as string;
|
|
|
@ -1,42 +0,0 @@
|
||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"baseUrl": "./",
|
|
||||||
"paths": {
|
|
||||||
"@dist/*": [
|
|
||||||
"dist/*"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"target": "es2017",
|
|
||||||
"lib": [
|
|
||||||
"esnext.array",
|
|
||||||
"esnext",
|
|
||||||
"es2017",
|
|
||||||
"dom"
|
|
||||||
],
|
|
||||||
"experimentalDecorators": true,
|
|
||||||
"module": "esnext",
|
|
||||||
"moduleResolution": "node",
|
|
||||||
"allowJs": true,
|
|
||||||
"checkJs": false,
|
|
||||||
"declaration": true,
|
|
||||||
"declarationMap": true,
|
|
||||||
"sourceMap": true,
|
|
||||||
"esModuleInterop": true,
|
|
||||||
"forceConsistentCasingInFileNames": true,
|
|
||||||
"strict": true,
|
|
||||||
"noImplicitAny": true,
|
|
||||||
"noImplicitThis": true,
|
|
||||||
"noUnusedLocals": true,
|
|
||||||
"noUnusedParameters": true,
|
|
||||||
"noFallthroughCasesInSwitch": true,
|
|
||||||
"skipLibCheck": true
|
|
||||||
},
|
|
||||||
"include": [
|
|
||||||
"src/**/*.ts"
|
|
||||||
],
|
|
||||||
"exclude": [
|
|
||||||
"node_modules",
|
|
||||||
"example",
|
|
||||||
"dist"
|
|
||||||
],
|
|
||||||
}
|
|
2089
web/yarn.lock
2089
web/yarn.lock
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue