@infinityfx/lively 0.0.1
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/LICENSE +674 -0
- package/README.md +7 -0
- package/animatable.js +300 -0
- package/animate.js +43 -0
- package/animation.js +333 -0
- package/animations/fade.js +12 -0
- package/animations/move.js +23 -0
- package/animations/pop.js +12 -0
- package/animations/scale.js +22 -0
- package/animations/wipe.js +13 -0
- package/morph.js +112 -0
- package/package.json +11 -0
- package/queue.js +67 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import Animation from '../animation';
|
|
2
|
+
|
|
3
|
+
export default function Move(options = {}) {
|
|
4
|
+
return {
|
|
5
|
+
scaleCorrection: options.scaleCorrection,
|
|
6
|
+
use: Move.use.bind(this, options)
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
Move.use = ({ direction = 'up', scaleCorrection = false } = {}) => {
|
|
11
|
+
|
|
12
|
+
let x = '0px', y = '20px';
|
|
13
|
+
switch (direction) {
|
|
14
|
+
case 'down': y = '-20px';
|
|
15
|
+
break;
|
|
16
|
+
case 'left': x = '20px', y = '0px';
|
|
17
|
+
break;
|
|
18
|
+
case 'right': x = '-20px', y = '0px';
|
|
19
|
+
break;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return new Animation({ position: { x: '0px', y: '0px' }, opacity: 1, scaleCorrection, duration: 0.5 }, { position: { x, y }, opacity: 0 });
|
|
23
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import Animation from '../animation';
|
|
2
|
+
|
|
3
|
+
export default function Pop(options = {}) {
|
|
4
|
+
return {
|
|
5
|
+
scaleCorrection: options.scaleCorrection,
|
|
6
|
+
use: Pop.use.bind(this, options)
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
Pop.use = ({ scaleCorrection = false } = {}) => {
|
|
11
|
+
return new Animation({ opacity: 1, scale: 1, scaleCorrection, duration: 0.25 }, { opacity: 0, scale: 0.85 });
|
|
12
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import Animation from '../animation';
|
|
2
|
+
|
|
3
|
+
export default function Scale(options = {}) {
|
|
4
|
+
return {
|
|
5
|
+
scaleCorrection: options.scaleCorrection,
|
|
6
|
+
use: Scale.use.bind(this, options)
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
Scale.use = ({ direction = 'right', scaleCorrection = false } = {}) => {
|
|
11
|
+
let x = 0, y = 1, origin = { x: 0, y: 0.5 };
|
|
12
|
+
switch (direction) {
|
|
13
|
+
case 'left': origin.x = 1;
|
|
14
|
+
break;
|
|
15
|
+
case 'up': x = 1, y = 0, origin = { x: 0, y: 1 };
|
|
16
|
+
break;
|
|
17
|
+
case 'down': x = 1, y = 0, origin = { x: 0, y: 0 };
|
|
18
|
+
break;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return new Animation({ scale: { x: 1 }, scaleCorrection, origin, duration: 0.6 }, { scale: { x, y } });
|
|
22
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import Animation from '../animation';
|
|
2
|
+
|
|
3
|
+
export default function Wipe(options = {}) {
|
|
4
|
+
return {
|
|
5
|
+
scaleCorrection: options.scaleCorrection,
|
|
6
|
+
use: Wipe.use.bind(this, options)
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
Wipe.use = ({ direction = 'right', scaleCorrection = false } = {}) => {
|
|
11
|
+
if (!['left', 'right', 'top', 'bottom'].includes(direction)) direction = 'right';
|
|
12
|
+
return new Animation({ clip: { [direction]: 0 }, scaleCorrection }, { clip: { [direction]: 1 } });
|
|
13
|
+
}
|
package/morph.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import Animatable from './animatable';
|
|
2
|
+
import Animation from './animation';
|
|
3
|
+
import AnimationQueue from './queue';
|
|
4
|
+
|
|
5
|
+
export default class Morph extends Animatable {
|
|
6
|
+
|
|
7
|
+
constructor(props) {
|
|
8
|
+
super(props);
|
|
9
|
+
|
|
10
|
+
this.animations.morphs = [];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
componentDidMount() {
|
|
14
|
+
const element = this.elements[0];
|
|
15
|
+
if (!element) return;
|
|
16
|
+
|
|
17
|
+
Animation.setInitial(element);
|
|
18
|
+
element.setAttribute('uitools-morph-id', this.props.id);
|
|
19
|
+
element.setAttribute('uitools-morph-active', this.props.active);
|
|
20
|
+
this.self = element;
|
|
21
|
+
this.createResetAnimation();
|
|
22
|
+
|
|
23
|
+
AnimationQueue.delay(() => {
|
|
24
|
+
const targets = document.querySelectorAll(`[uitools-morph-id="${this.props.id}"]`);
|
|
25
|
+
|
|
26
|
+
for (let i = 0; i < targets.length; i++) {
|
|
27
|
+
if (targets[i] === element) continue;
|
|
28
|
+
|
|
29
|
+
this.createMorphAnimation(targets[i], i);
|
|
30
|
+
if (targets[i].getAttribute('uitools-morph-active') !== 'true') this.animations.transition.setInitialStyles(targets[i]);
|
|
31
|
+
}
|
|
32
|
+
}, 0.001);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
componentDidUpdate() {
|
|
36
|
+
const active = this.self.getAttribute('uitools-morph-active') === 'true';
|
|
37
|
+
this.self.setAttribute('uitools-morph-active', this.props.active);
|
|
38
|
+
|
|
39
|
+
AnimationQueue.delay(() => {
|
|
40
|
+
if (this.props.active && !active) {
|
|
41
|
+
this.animations.transition.setInitialStyles(this.self);
|
|
42
|
+
this.animations.transition.play(this.self);
|
|
43
|
+
} else
|
|
44
|
+
if (!this.props.active && active) {
|
|
45
|
+
|
|
46
|
+
let index = 0;
|
|
47
|
+
|
|
48
|
+
const targets = document.querySelectorAll(`[uitools-morph-id="${this.props.id}"]`);
|
|
49
|
+
for (let i = 0; i < targets.length; i++) {
|
|
50
|
+
if (targets[i] === this.self) continue;
|
|
51
|
+
|
|
52
|
+
if (targets[i].getAttribute('uitools-morph-active') === 'true') {
|
|
53
|
+
index = i;
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
this.animations.morphs[index].play(this.self);
|
|
59
|
+
}
|
|
60
|
+
}, 0.001);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
createResetAnimation() {
|
|
64
|
+
const a = this.self.UITools?.initialStyles;
|
|
65
|
+
|
|
66
|
+
this.animations.transition = Animation.from({
|
|
67
|
+
opacity: [0, 0, 1],
|
|
68
|
+
scale: { x: 1, y: 1 },
|
|
69
|
+
position: { x: 0, y: 0 },
|
|
70
|
+
borderRadius: a.borderRadius
|
|
71
|
+
}, {}, this.scaleCorrection);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
createMorphAnimation(target, index) {
|
|
75
|
+
const a = this.self.UITools?.initialStyles;
|
|
76
|
+
const b = target.UITools?.initialStyles;
|
|
77
|
+
|
|
78
|
+
this.animations.morphs[index] = Animation.from({
|
|
79
|
+
position: [
|
|
80
|
+
{ x: 0, y: 0 },
|
|
81
|
+
{
|
|
82
|
+
x: b.x - a.x + (b.clientWidth - a.clientWidth) / 2,
|
|
83
|
+
y: b.y - a.y + (b.clientHeight - a.clientHeight) / 2,
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
x: b.x - a.x + (b.clientWidth - a.clientWidth) / 2,
|
|
87
|
+
y: b.y - a.y + (b.clientHeight - a.clientHeight) / 2,
|
|
88
|
+
}
|
|
89
|
+
],
|
|
90
|
+
scale: [
|
|
91
|
+
{ x: 1, y: 1 },
|
|
92
|
+
{
|
|
93
|
+
x: b.clientWidth / a.clientWidth,
|
|
94
|
+
y: b.clientHeight / a.clientHeight,
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
x: b.clientWidth / a.clientWidth,
|
|
98
|
+
y: b.clientHeight / a.clientHeight,
|
|
99
|
+
}
|
|
100
|
+
],
|
|
101
|
+
opacity: [1, 1, 0],
|
|
102
|
+
borderRadius: [a.borderRadius, b.borderRadius, b.borderRadius]
|
|
103
|
+
}, {}, this.scaleCorrection);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
static defaultProps = {
|
|
107
|
+
id: 0,
|
|
108
|
+
active: false,
|
|
109
|
+
scaleCorrection: false
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@infinityfx/lively",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"repository": "infinityfx-llc/lively",
|
|
7
|
+
"author": "InfinityFX <contact@infinity-fx.com> (https://infinity-fx.com)",
|
|
8
|
+
"license": "GPL-3.0",
|
|
9
|
+
"bugs": "https://github.com/infinityfx-llc/lively/issues",
|
|
10
|
+
"homepage": "https://github.com/infinityfx-llc/lively#readme"
|
|
11
|
+
}
|
package/queue.js
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export default class AnimationQueue {
|
|
2
|
+
|
|
3
|
+
constructor() {
|
|
4
|
+
this.queue = [];
|
|
5
|
+
|
|
6
|
+
this.tick();
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
static get() {
|
|
10
|
+
if (!('UITools' in window)) window.UITools = {};
|
|
11
|
+
if (!('AnimationLoop' in window.UITools)) window.UITools.AnimationQueue = new AnimationQueue();
|
|
12
|
+
|
|
13
|
+
return window.UITools.AnimationQueue;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async tick() {
|
|
17
|
+
const tick = Date.now();
|
|
18
|
+
|
|
19
|
+
for (let i = 0; i < this.queue.length + 1; i++) {
|
|
20
|
+
if (this.queue.length === i || this.queue[i].timestamp > tick) {
|
|
21
|
+
this.queue.splice(0, i);
|
|
22
|
+
break;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
this.queue[i].callback();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
requestAnimationFrame(this.tick.bind(this));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
search(item) {
|
|
32
|
+
let l = 0, h = this.queue.length - 1, m, c;
|
|
33
|
+
|
|
34
|
+
while (l <= h) {
|
|
35
|
+
m = (l + h) >>> 1;
|
|
36
|
+
c = this.queue[m].timestamp - item.timestamp;
|
|
37
|
+
|
|
38
|
+
if (c < 0) {
|
|
39
|
+
l = m + 1;
|
|
40
|
+
} else
|
|
41
|
+
if (c > 0) {
|
|
42
|
+
h = m - 1;
|
|
43
|
+
} else {
|
|
44
|
+
return m;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return l;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
insert(item) {
|
|
52
|
+
const idx = this.search(item);
|
|
53
|
+
|
|
54
|
+
this.queue.splice(idx, 0, item);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
delay(callback, seconds) {
|
|
58
|
+
if (!(callback instanceof Function)) return;
|
|
59
|
+
|
|
60
|
+
this.insert({ callback, timestamp: Date.now() + seconds * 1000 });
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
static async delay(callback, seconds) {
|
|
64
|
+
return this.get().delay(callback, seconds);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
}
|