@lordicon/web 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.prettierrc +6 -0
- package/LICENSE +30 -0
- package/README.md +148 -0
- package/dist/index.d.ts +388 -0
- package/dist/index.js +6279 -0
- package/examples/01-play.html +16 -0
- package/examples/01-play.ts +13 -0
- package/examples/02-customization.html +26 -0
- package/examples/02-customization.ts +49 -0
- package/examples/03-states.html +21 -0
- package/examples/03-states.ts +31 -0
- package/examples/04-events.html +18 -0
- package/examples/04-events.ts +36 -0
- package/examples/05-playback-control.html +25 -0
- package/examples/05-playback-control.ts +60 -0
- package/examples/icons/coins.json +1 -0
- package/examples/icons/lock.json +1 -0
- package/examples/index.html +59 -0
- package/examples/main.css +45 -0
- package/examples/utils.ts +9 -0
- package/package.json +38 -0
- package/src/index.ts +2 -0
- package/src/interfaces.ts +181 -0
- package/src/lottie.ts +203 -0
- package/src/parsers.ts +230 -0
- package/src/player.ts +807 -0
- package/src/utils.ts +100 -0
- package/tsconfig.json +25 -0
- package/vite-examples.config.ts +14 -0
- package/vite.config.ts +25 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="utf-8" />
|
|
6
|
+
<title>Play</title>
|
|
7
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
8
|
+
<link rel="stylesheet" type="text/css" href="/main.css" />
|
|
9
|
+
<script type="module" src="/01-play.ts"></script>
|
|
10
|
+
</head>
|
|
11
|
+
|
|
12
|
+
<body>
|
|
13
|
+
<div class="icon"></div>
|
|
14
|
+
</body>
|
|
15
|
+
|
|
16
|
+
</html>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Player } from '../src';
|
|
2
|
+
import { loadIcon } from './utils';
|
|
3
|
+
|
|
4
|
+
const data = await loadIcon('coins');
|
|
5
|
+
|
|
6
|
+
const iconElement = document.querySelector('.icon') as HTMLElement;
|
|
7
|
+
|
|
8
|
+
const player = new Player(
|
|
9
|
+
iconElement,
|
|
10
|
+
data,
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
player.play();
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="utf-8" />
|
|
6
|
+
<title>Customization</title>
|
|
7
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
8
|
+
<link rel="stylesheet" type="text/css" href="/main.css" />
|
|
9
|
+
<script type="module" src="/02-customization.ts"></script>
|
|
10
|
+
</head>
|
|
11
|
+
|
|
12
|
+
<body>
|
|
13
|
+
<div class="icon"></div>
|
|
14
|
+
|
|
15
|
+
<div>
|
|
16
|
+
<button data-type="play">Play</button>
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
<div>
|
|
20
|
+
<button data-type="colors">Change colors</button>
|
|
21
|
+
<button data-type="stroke">Change stroke</button>
|
|
22
|
+
<button data-type="state">Change state</button>
|
|
23
|
+
</div>
|
|
24
|
+
</body>
|
|
25
|
+
|
|
26
|
+
</html>
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Player, Stroke } from '../src';
|
|
2
|
+
import { loadIcon, randomHexColor } from './utils';
|
|
3
|
+
|
|
4
|
+
const data = await loadIcon('coins');
|
|
5
|
+
|
|
6
|
+
const iconElement = document.querySelector('.icon') as HTMLElement;
|
|
7
|
+
const buttonsElement = document.querySelectorAll('button') as NodeListOf<HTMLButtonElement>;
|
|
8
|
+
|
|
9
|
+
const player = new Player(
|
|
10
|
+
iconElement,
|
|
11
|
+
data,
|
|
12
|
+
{
|
|
13
|
+
colors: {
|
|
14
|
+
primary: 'red',
|
|
15
|
+
secondary: 'blue',
|
|
16
|
+
},
|
|
17
|
+
stroke: 3,
|
|
18
|
+
state: 'hover-spending',
|
|
19
|
+
}
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
// player.play();
|
|
23
|
+
|
|
24
|
+
buttonsElement.forEach(buttonElement => {
|
|
25
|
+
const type: 'play' | 'colors' | 'stroke' | 'state' = buttonElement.dataset.type as any;
|
|
26
|
+
|
|
27
|
+
buttonElement.addEventListener('click', () => {
|
|
28
|
+
if (type === 'play') {
|
|
29
|
+
if (!player.playing) {
|
|
30
|
+
player.playFromStart();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (type === 'colors') {
|
|
35
|
+
if (Math.random() < 0.5) {
|
|
36
|
+
player.colors.secondary = randomHexColor();
|
|
37
|
+
} else {
|
|
38
|
+
player.colors.primary = randomHexColor();
|
|
39
|
+
}
|
|
40
|
+
} else if (type === 'stroke') {
|
|
41
|
+
player.stroke = (Math.floor(Math.random() * 3) + 1) as Stroke; // Random stroke between 1 and 3
|
|
42
|
+
} else if (type === 'state') {
|
|
43
|
+
const availableStates = player.availableStates;
|
|
44
|
+
const currentStateIndex = availableStates.findIndex(state => state.name === player.state);
|
|
45
|
+
const nextStateIndex = (currentStateIndex + 1) % availableStates.length;
|
|
46
|
+
player.state = availableStates[nextStateIndex].name;
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="utf-8" />
|
|
6
|
+
<title>States</title>
|
|
7
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
8
|
+
<link rel="stylesheet" type="text/css" href="/main.css" />
|
|
9
|
+
<script type="module" src="/03-states.ts"></script>
|
|
10
|
+
</head>
|
|
11
|
+
|
|
12
|
+
<body>
|
|
13
|
+
<div class="icon"></div>
|
|
14
|
+
|
|
15
|
+
<div>
|
|
16
|
+
<label for="state-select">Choose state:</label>
|
|
17
|
+
<select id="state-select"></select>
|
|
18
|
+
</div>
|
|
19
|
+
</body>
|
|
20
|
+
|
|
21
|
+
</html>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Player } from '../src';
|
|
2
|
+
import { loadIcon } from './utils';
|
|
3
|
+
|
|
4
|
+
const data = await loadIcon('coins');
|
|
5
|
+
|
|
6
|
+
const iconElement = document.querySelector('.icon') as HTMLElement;
|
|
7
|
+
const selectElement = document.querySelector('select') as HTMLSelectElement;
|
|
8
|
+
|
|
9
|
+
const player = new Player(
|
|
10
|
+
iconElement,
|
|
11
|
+
data,
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
const availableStates = player.availableStates;
|
|
15
|
+
availableStates.forEach((state) => {
|
|
16
|
+
const option = document.createElement('option');
|
|
17
|
+
option.value = state.name;
|
|
18
|
+
option.textContent = state.name;
|
|
19
|
+
selectElement.appendChild(option);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
selectElement.addEventListener('change', (event) => {
|
|
23
|
+
const selectedState = (event.target as HTMLSelectElement).value;
|
|
24
|
+
player.state = selectedState;
|
|
25
|
+
|
|
26
|
+
player.playFromStart();
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// Set the initial state to the default state
|
|
30
|
+
selectElement.value = availableStates.find(state => state.default)?.name!;
|
|
31
|
+
player.play();
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="utf-8" />
|
|
6
|
+
<title>Events</title>
|
|
7
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
8
|
+
<link rel="stylesheet" type="text/css" href="/main.css" />
|
|
9
|
+
<script type="module" src="/04-events.ts"></script>
|
|
10
|
+
</head>
|
|
11
|
+
|
|
12
|
+
<body>
|
|
13
|
+
<div class="icon"></div>
|
|
14
|
+
|
|
15
|
+
<div id="frame"></div>
|
|
16
|
+
</body>
|
|
17
|
+
|
|
18
|
+
</html>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Player } from '../src';
|
|
2
|
+
import { loadIcon } from './utils';
|
|
3
|
+
|
|
4
|
+
const data = await loadIcon('lock');
|
|
5
|
+
|
|
6
|
+
const iconElement = document.querySelector('.icon') as HTMLElement;
|
|
7
|
+
const frameElement = document.getElementById('frame') as HTMLElement;
|
|
8
|
+
|
|
9
|
+
const player = new Player(
|
|
10
|
+
iconElement,
|
|
11
|
+
data,
|
|
12
|
+
{
|
|
13
|
+
state: 'morph-unlocked',
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
autoInit: false, // Prevent auto-initialization
|
|
17
|
+
},
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
player.addEventListener('ready', () => {
|
|
22
|
+
player.play();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
player.addEventListener('complete', () => {
|
|
26
|
+
setTimeout(() => {
|
|
27
|
+
player.direction *= -1;
|
|
28
|
+
player.play();
|
|
29
|
+
}, 500);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
player.addEventListener('frame', () => {
|
|
33
|
+
frameElement.textContent = `Frame: ${Math.round(player.frame)}`;
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
player.init();
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="utf-8" />
|
|
6
|
+
<title>Playback control</title>
|
|
7
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
8
|
+
<link rel="stylesheet" type="text/css" href="/main.css" />
|
|
9
|
+
<script type="module" src="/05-playback-control.ts"></script>
|
|
10
|
+
</head>
|
|
11
|
+
|
|
12
|
+
<body>
|
|
13
|
+
<div class="icon"></div>
|
|
14
|
+
|
|
15
|
+
<div>
|
|
16
|
+
<input type="range" id="seek" min="0" max="1" step="1" value="0">
|
|
17
|
+
<label>
|
|
18
|
+
<input type="checkbox" id="loop">
|
|
19
|
+
Loop
|
|
20
|
+
</label>
|
|
21
|
+
<button id="play-pause">Play</button>
|
|
22
|
+
</div>
|
|
23
|
+
</body>
|
|
24
|
+
|
|
25
|
+
</html>
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { Player } from '../src';
|
|
2
|
+
import { loadIcon } from './utils';
|
|
3
|
+
|
|
4
|
+
function refreshButton() {
|
|
5
|
+
if (player.playing) {
|
|
6
|
+
buttonElement.textContent = 'Pause';
|
|
7
|
+
} else {
|
|
8
|
+
buttonElement.textContent = 'Play';
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const data = await loadIcon('lock');
|
|
13
|
+
|
|
14
|
+
const iconElement = document.querySelector('.icon') as HTMLElement;
|
|
15
|
+
const seekElement = document.getElementById('seek') as HTMLInputElement;
|
|
16
|
+
const loopElement = document.getElementById('loop') as HTMLInputElement;
|
|
17
|
+
const buttonElement = document.getElementById('play-pause') as HTMLButtonElement;
|
|
18
|
+
|
|
19
|
+
const player = new Player(
|
|
20
|
+
iconElement,
|
|
21
|
+
data,
|
|
22
|
+
{
|
|
23
|
+
state: 'hover-locked',
|
|
24
|
+
},
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
player.addEventListener('frame', () => {
|
|
28
|
+
seekElement.value = player.frame.toString();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
player.addEventListener('complete', () => {
|
|
32
|
+
refreshButton();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
seekElement.setAttribute('max', '' + (player.frameCount - 1));
|
|
36
|
+
|
|
37
|
+
seekElement.addEventListener('input', () => {
|
|
38
|
+
player.seek(+seekElement.value);
|
|
39
|
+
refreshButton();
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
loopElement.addEventListener('change', () => {
|
|
43
|
+
player.loop = loopElement.checked;
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
buttonElement.addEventListener('click', () => {
|
|
47
|
+
if (player.playing) {
|
|
48
|
+
player.pause();
|
|
49
|
+
} else {
|
|
50
|
+
if (player.frame === player.frameCount) {
|
|
51
|
+
player.playFromStart();
|
|
52
|
+
} else {
|
|
53
|
+
player.play();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
refreshButton();
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
player.play();
|