qarl 1.1.1 → 1.2.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/README.md +272 -68
- package/dist/qarl.es.min.js +1 -0
- package/kill-port.js +16 -0
- package/package.json +36 -19
- package/src/behaviors/easings.js +68 -62
- package/src/behaviors/modes.js +7 -10
- package/src/controllers/Curve.js +115 -96
- package/src/controllers/FromTo.js +32 -48
- package/src/core/Core.js +366 -344
- package/src/core/Loop.js +57 -0
- package/src/core/Manager.js +73 -0
- package/src/core/defaults.js +15 -4
- package/src/core/events.js +7 -21
- package/src/core/getCreator.js +30 -0
- package/src/core/play.js +13 -0
- package/src/index.js +10 -0
- package/src/ultra/FromToUltra.js +104 -0
- package/test/index.html +13 -0
- package/test/styles.css +15 -0
- package/test/test-three-scene.js +272 -0
- package/webpack.config.js +100 -0
- package/index.js +0 -8
- package/src/emitter/Notifier.js +0 -97
package/README.md
CHANGED
|
@@ -1,68 +1,272 @@
|
|
|
1
|
-
# QARL (Quantum Animation Remixable Library) 😎
|
|
2
|
-
|
|
3
|
-
*Description generated by GPT while we were busy doing more important things.*
|
|
4
|
-
|
|
5
|
-
QARL is an animation library for
|
|
6
|
-
|
|
7
|
-
⚠️ **Attention!** ⚠️
|
|
8
|
-
|
|
9
|
-
New project! 💡 It surely has some bugs, unfinished features, and odd solutions, but
|
|
10
|
-
|
|
11
|
-
## Why QARL? 🏎️💨
|
|
12
|
-
|
|
13
|
-
Looking for performance? QARL's FromTo animation computes so fast, it feels like it bends space-time! 💫 No more waiting for slow calculations—just smooth, seamless transitions that keep up with the pace of your game.
|
|
14
|
-
|
|
15
|
-
## Installation
|
|
16
|
-
|
|
17
|
-
Install the library via npm:
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
npm install qarl
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
## FromTo example
|
|
24
|
-
|
|
25
|
-
```js
|
|
26
|
-
const cube3 = new THREE.Mesh(
|
|
27
|
-
new THREE.BoxGeometry(),
|
|
28
|
-
new THREE.MeshBasicMaterial({ color: 0x00ffff })
|
|
29
|
-
)
|
|
30
|
-
|
|
31
|
-
new QARL.FromTo({
|
|
32
|
-
target: cube3,
|
|
33
|
-
dynamic: true,
|
|
34
|
-
loop: true,
|
|
35
|
-
time: 3000,
|
|
36
|
-
mode: QARL.modes.pingPong, // bounce, yoyo, pingPong
|
|
37
|
-
easing: QARL.easings.outQuad,
|
|
38
|
-
from: { rotation: { x: 1, y: 2 }, position: { x: 2, z: 2 }, scale: { x: .01, y: 1, z: 1 } },
|
|
39
|
-
to: { rotation: { x: 3, y: -5 }, position: { x: -2, z: -2 }, scale: { x: 3, y: .5, z: .5 } },
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
new
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
1
|
+
# QARL (Quantum Animation Remixable Library) 😎
|
|
2
|
+
|
|
3
|
+
*Description generated by GPT while we were busy doing more important things.*
|
|
4
|
+
|
|
5
|
+
QARL is an animation library for game engine.
|
|
6
|
+
|
|
7
|
+
⚠️ **Attention!** ⚠️
|
|
8
|
+
|
|
9
|
+
New project! 💡 It surely has some bugs, unfinished features, and odd solutions, but a lot of heart and effort went into it. Thanks for stopping by—hope it will be enjoyed! 🙏✨
|
|
10
|
+
|
|
11
|
+
## Why QARL? 🏎️💨
|
|
12
|
+
|
|
13
|
+
Looking for performance? QARL's FromTo animation computes so fast, it feels like it bends space-time! 💫 No more waiting for slow calculations—just smooth, seamless transitions that keep up with the pace of your game.
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
Install the library via npm:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install qarl
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## FromTo example
|
|
24
|
+
|
|
25
|
+
```js
|
|
26
|
+
const cube3 = new THREE.Mesh(
|
|
27
|
+
new THREE.BoxGeometry(),
|
|
28
|
+
new THREE.MeshBasicMaterial({ color: 0x00ffff })
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
const fromToAnim = new QARL.FromTo({
|
|
32
|
+
target: cube3,
|
|
33
|
+
dynamic: true, // default false - to bake from and to
|
|
34
|
+
loop: true,
|
|
35
|
+
time: 3000,
|
|
36
|
+
mode: QARL.modes.pingPong, // bounce, yoyo, pingPong
|
|
37
|
+
easing: QARL.easings.outQuad,
|
|
38
|
+
from: { rotation: { x: 1, y: 2 }, position: { x: 2, z: 2 }, scale: { x: .01, y: 1, z: 1 } },
|
|
39
|
+
to: { rotation: { x: 3, y: -5 }, position: { x: -2, z: -2 }, scale: { x: 3, y: .5, z: .5 } },
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
// fromToAnim.play()
|
|
43
|
+
|
|
44
|
+
// fromToAnim.step(dt)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Curve example
|
|
48
|
+
|
|
49
|
+
```js
|
|
50
|
+
const cube3 = new THREE.Mesh(
|
|
51
|
+
new THREE.BoxGeometry(),
|
|
52
|
+
new THREE.MeshBasicMaterial({ color: 0xff00ff })
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
// default mode
|
|
56
|
+
|
|
57
|
+
const curveAnim = new QARL.Curve({
|
|
58
|
+
target: cube3,
|
|
59
|
+
loop: true,
|
|
60
|
+
time: 10000,
|
|
61
|
+
mode: QARL.modes.yoyo,
|
|
62
|
+
easing: QARL.easings.inOutBack,
|
|
63
|
+
smoothing: 10,
|
|
64
|
+
|
|
65
|
+
// position.x
|
|
66
|
+
points: [
|
|
67
|
+
[-2],
|
|
68
|
+
[ 2],
|
|
69
|
+
[ 2],
|
|
70
|
+
[-2],
|
|
71
|
+
[-2],
|
|
72
|
+
[ 2],
|
|
73
|
+
],
|
|
74
|
+
|
|
75
|
+
// or position.x and position.y
|
|
76
|
+
// points: [
|
|
77
|
+
// [-2, -2],
|
|
78
|
+
// [ 2, -2],
|
|
79
|
+
// [ 2, 0],
|
|
80
|
+
// [-2, 0],
|
|
81
|
+
// [-2, 2],
|
|
82
|
+
// [ 2, 2],
|
|
83
|
+
// ],
|
|
84
|
+
|
|
85
|
+
// or position.x, position.y and position.z
|
|
86
|
+
// points: [
|
|
87
|
+
// [-2, -2, 0,],
|
|
88
|
+
// [ 2, -2, 0,],
|
|
89
|
+
// [ 2, 0, 1,],
|
|
90
|
+
// [-2, 0, 1,],
|
|
91
|
+
// [-2, 2, 0,],
|
|
92
|
+
// [ 2, 2, 0,],
|
|
93
|
+
// ],
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
// or custome mode
|
|
97
|
+
|
|
98
|
+
const curveAnim = new QARL.Curve({
|
|
99
|
+
target: cube3,
|
|
100
|
+
loop: true,
|
|
101
|
+
time: 10000,
|
|
102
|
+
mode: QARL.modes.yoyo,
|
|
103
|
+
easing: QARL.easings.inOutBack,
|
|
104
|
+
smoothing: 10,
|
|
105
|
+
properties: ['position.z', 'scale.y', 'scale.z', 'position.x'], // custom properties order
|
|
106
|
+
points: [
|
|
107
|
+
[0, .5, .5, -2,],
|
|
108
|
+
[0, .2, .2, 2,],
|
|
109
|
+
[1, .5, .5, 2,],
|
|
110
|
+
[1, .2, .2, -2,],
|
|
111
|
+
[0, .5, .5, -2,],
|
|
112
|
+
[0, .2, .2, 2,],
|
|
113
|
+
],
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
// curveAnim.play()
|
|
117
|
+
|
|
118
|
+
// curveAnim.step(dt)
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
## Manager example
|
|
123
|
+
|
|
124
|
+
```js
|
|
125
|
+
const qarlManager = new QARL.Manager()
|
|
126
|
+
|
|
127
|
+
const cube3 = new THREE.Mesh(
|
|
128
|
+
new THREE.BoxGeometry(),
|
|
129
|
+
new THREE.MeshBasicMaterial({ color: 0xff00ff })
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
const qarl1 = qarlManager.create({
|
|
133
|
+
target: cube3,
|
|
134
|
+
loop: true,
|
|
135
|
+
time: 10000,
|
|
136
|
+
mode: QARL.modes.yoyo,
|
|
137
|
+
easing: QARL.easings.inOutBack,
|
|
138
|
+
smoothing: 10,
|
|
139
|
+
// properties: ['position.x', 'position.y', 'position.z'], // default properties
|
|
140
|
+
points: [
|
|
141
|
+
[-2, -2, 0],
|
|
142
|
+
[ 2, -2, 0],
|
|
143
|
+
[ 2, 0, 1],
|
|
144
|
+
[-2, 0, 1],
|
|
145
|
+
[-2, 2, 0],
|
|
146
|
+
[ 2, 2, 0],
|
|
147
|
+
],
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
// or
|
|
151
|
+
|
|
152
|
+
const cube3clone = cube3.clone()
|
|
153
|
+
|
|
154
|
+
const qarl2 = qarlManager.create({
|
|
155
|
+
target: cube3clone,
|
|
156
|
+
loop: true,
|
|
157
|
+
time: 3000,
|
|
158
|
+
mode: QARL.modes.pingPong, // bounce, yoyo, pingPong
|
|
159
|
+
easing: QARL.easings.outQuad,
|
|
160
|
+
from: { rotation: { x: 1, y: 2 }, position: { x: 2, z: 2 }, scale: { x: .01, y: 1, z: 1 } },
|
|
161
|
+
to: { rotation: { x: 3, y: -5 }, position: { x: -2, z: -2 }, scale: { x: 3, y: .5, z: .5 } },
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
// qarlManager.update(dt)
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Play Animation Instantly example
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
```js
|
|
171
|
+
const cube3 = new THREE.Mesh(
|
|
172
|
+
new THREE.BoxGeometry(),
|
|
173
|
+
new THREE.MeshBasicMaterial({ color: 0xff00ff })
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
QARL.play({
|
|
177
|
+
target: cube3,
|
|
178
|
+
loop: true,
|
|
179
|
+
time: 10000,
|
|
180
|
+
mode: QARL.modes.yoyo,
|
|
181
|
+
easing: QARL.easings.inOutBack,
|
|
182
|
+
smoothing: 10,
|
|
183
|
+
// properties: ['position.x', 'position.y', 'position.z'], // default properties
|
|
184
|
+
points: [
|
|
185
|
+
[-2, -2, 0],
|
|
186
|
+
[ 2, -2, 0],
|
|
187
|
+
[ 2, 0, 1],
|
|
188
|
+
[-2, 0, 1],
|
|
189
|
+
[-2, 2, 0],
|
|
190
|
+
[ 2, 2, 0],
|
|
191
|
+
],
|
|
192
|
+
})
|
|
193
|
+
|
|
194
|
+
// or
|
|
195
|
+
|
|
196
|
+
const cube3clone = cube3.clone()
|
|
197
|
+
|
|
198
|
+
QARL.play({
|
|
199
|
+
target: cube3clone,
|
|
200
|
+
loop: true,
|
|
201
|
+
time: 3000,
|
|
202
|
+
mode: QARL.modes.bounce,
|
|
203
|
+
easing: QARL.easings.inOutSine,
|
|
204
|
+
from: { rotation: { x: 1, y: 2 }, position: { x: 2, z: 2 }, scale: { x: .01, y: 1, z: 1 } },
|
|
205
|
+
to: { rotation: { x: 3, y: -5 }, position: { x: -2, z: -2 }, scale: { x: 3, y: .5, z: .5 } },
|
|
206
|
+
})
|
|
207
|
+
|
|
208
|
+
// async
|
|
209
|
+
|
|
210
|
+
await QARL.play({ /*... config ...*/ }, true) // true for async
|
|
211
|
+
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## GlobalManager and Loop example
|
|
215
|
+
|
|
216
|
+
```js
|
|
217
|
+
import { GlobalManager, Loop } from 'qarl';
|
|
218
|
+
|
|
219
|
+
// Создаем объекты для анимации
|
|
220
|
+
const cube = new THREE.Mesh(
|
|
221
|
+
new THREE.BoxGeometry(),
|
|
222
|
+
new THREE.MeshBasicMaterial({ color: 0xff6b6b })
|
|
223
|
+
);
|
|
224
|
+
|
|
225
|
+
const sphere = new THREE.Mesh(
|
|
226
|
+
new THREE.SphereGeometry(0.7),
|
|
227
|
+
new THREE.MeshBasicMaterial({ color: 0x4ecdc4 })
|
|
228
|
+
);
|
|
229
|
+
|
|
230
|
+
// Анимация куба с поворотом
|
|
231
|
+
const cubeAnimation = GlobalManager.create({
|
|
232
|
+
target: cube,
|
|
233
|
+
time: 2000,
|
|
234
|
+
from: { rotation: { x: 0, y: 0, z: 0 } },
|
|
235
|
+
to: { rotation: { x: Math.PI * 2, y: Math.PI * 2, z: Math.PI * 2 } },
|
|
236
|
+
easing: 'outElastic',
|
|
237
|
+
loop: true,
|
|
238
|
+
mode: 'pingPong'
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
// Анимация сферы с движением и масштабированием
|
|
242
|
+
const sphereAnimation = GlobalManager.create({
|
|
243
|
+
target: sphere,
|
|
244
|
+
time: 3000,
|
|
245
|
+
properties: ['position.x', 'position.y', 'position.z', 'scale.x', 'scale.y', 'scale.z'],
|
|
246
|
+
points: [
|
|
247
|
+
[0, 0, 0, 1, 1, 1],
|
|
248
|
+
[1, 2, 0, 2, .5, 2],
|
|
249
|
+
[-1, 2, 0, 1, 2, 1],
|
|
250
|
+
[0, 0, 0, 1, 1, 1]
|
|
251
|
+
],
|
|
252
|
+
smoothing: 20,
|
|
253
|
+
easing: 'outBack',
|
|
254
|
+
loop: true,
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
// Запускаем анимации
|
|
258
|
+
cubeAnimation.play();
|
|
259
|
+
sphereAnimation.play();
|
|
260
|
+
|
|
261
|
+
// Создаем игровой цикл
|
|
262
|
+
const gameLoop = Loop.start((dt) => {
|
|
263
|
+
// Обновляем все анимации через GlobalManager
|
|
264
|
+
GlobalManager.update(dt);
|
|
265
|
+
|
|
266
|
+
// Ваша игровая логика здесь
|
|
267
|
+
// renderer.render(scene, camera);
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
// Остановка цикла (если нужно)
|
|
271
|
+
// Loop.stop(gameLoop);
|
|
272
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var t={228:t=>{var e=Object.prototype.hasOwnProperty,s="~";function i(){}function n(t,e,s){this.fn=t,this.context=e,this.once=s||!1}function r(t,e,i,r,o){if("function"!=typeof i)throw new TypeError("The listener must be a function");var a=new n(i,r||t,o),h=s?s+e:e;return t._events[h]?t._events[h].fn?t._events[h]=[t._events[h],a]:t._events[h].push(a):(t._events[h]=a,t._eventsCount++),t}function o(t,e){0===--t._eventsCount?t._events=new i:delete t._events[e]}function a(){this._events=new i,this._eventsCount=0}Object.create&&(i.prototype=Object.create(null),(new i).__proto__||(s=!1)),a.prototype.eventNames=function(){var t,i,n=[];if(0===this._eventsCount)return n;for(i in t=this._events)e.call(t,i)&&n.push(s?i.slice(1):i);return Object.getOwnPropertySymbols?n.concat(Object.getOwnPropertySymbols(t)):n},a.prototype.listeners=function(t){var e=s?s+t:t,i=this._events[e];if(!i)return[];if(i.fn)return[i.fn];for(var n=0,r=i.length,o=new Array(r);n<r;n++)o[n]=i[n].fn;return o},a.prototype.listenerCount=function(t){var e=s?s+t:t,i=this._events[e];return i?i.fn?1:i.length:0},a.prototype.emit=function(t,e,i,n,r,o){var a=s?s+t:t;if(!this._events[a])return!1;var h,p,c=this._events[a],l=arguments.length;if(c.fn){switch(c.once&&this.removeListener(t,c.fn,void 0,!0),l){case 1:return c.fn.call(c.context),!0;case 2:return c.fn.call(c.context,e),!0;case 3:return c.fn.call(c.context,e,i),!0;case 4:return c.fn.call(c.context,e,i,n),!0;case 5:return c.fn.call(c.context,e,i,n,r),!0;case 6:return c.fn.call(c.context,e,i,n,r,o),!0}for(p=1,h=new Array(l-1);p<l;p++)h[p-1]=arguments[p];c.fn.apply(c.context,h)}else{var u,m=c.length;for(p=0;p<m;p++)switch(c[p].once&&this.removeListener(t,c[p].fn,void 0,!0),l){case 1:c[p].fn.call(c[p].context);break;case 2:c[p].fn.call(c[p].context,e);break;case 3:c[p].fn.call(c[p].context,e,i);break;case 4:c[p].fn.call(c[p].context,e,i,n);break;default:if(!h)for(u=1,h=new Array(l-1);u<l;u++)h[u-1]=arguments[u];c[p].fn.apply(c[p].context,h)}}return!0},a.prototype.on=function(t,e,s){return r(this,t,e,s,!1)},a.prototype.once=function(t,e,s){return r(this,t,e,s,!0)},a.prototype.removeListener=function(t,e,i,n){var r=s?s+t:t;if(!this._events[r])return this;if(!e)return o(this,r),this;var a=this._events[r];if(a.fn)a.fn!==e||n&&!a.once||i&&a.context!==i||o(this,r);else{for(var h=0,p=[],c=a.length;h<c;h++)(a[h].fn!==e||n&&!a[h].once||i&&a[h].context!==i)&&p.push(a[h]);p.length?this._events[r]=1===p.length?p[0]:p:o(this,r)}return this},a.prototype.removeAllListeners=function(t){var e;return t?(e=s?s+t:t,this._events[e]&&o(this,e)):(this._events=new i,this._eventsCount=0),this},a.prototype.off=a.prototype.removeListener,a.prototype.addListener=a.prototype.on,a.prefixed=s,a.EventEmitter=a,t.exports=a}},e={};function s(i){var n=e[i];if(void 0!==n)return n.exports;var r=e[i]={exports:{}};return t[i](r,r.exports,s),r.exports}s.d=(t,e)=>{for(var i in e)s.o(e,i)&&!s.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:e[i]})},s.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);const i=s(228),n={processors:[],time:0,loop:!1,mode:null,delay:0,repeat:0,target:null,easing:t=>t,reversed:!1,repeatDelay:0},r={PLAY:"play",STOP:"stop",BEGIN:"begin",UPDATE:"update",REPEAT:"repeat",COMPLETE:"complete"},o=2*Math.PI,a=Math.pow,h={reverse:t=>1-t,linear:t=>t,yoyo:t=>1-Math.abs(1-2*t),inQuad:t=>a(t,2),outQuad:t=>t*(2-t),inOutQuad:t=>t<.5?2*t*t:(4-2*t)*t-1,inCubic:t=>a(t,3),outCubic:t=>--t*t*t+1,inOutCubic:t=>t<.5?4*a(t,3):(t-1)*(2*t-2)*(2*t-2)+1,inQuart:t=>a(t,4),outQuart:t=>1- --t*a(t,3),inOutQuart:t=>t<.5?8*a(t,4):1-8*--t*t*t*t,inQuint:t=>a(t,5),outQuint:t=>1+--t*a(t,4),inOutQuint:t=>t<.5?16*a(t,5):1+16*--t*t*t*t*t,inSine:t=>1-Math.cos(t*Math.PI/2),outSine:t=>Math.sin(t*Math.PI/2),inOutSine:t=>-(Math.cos(Math.PI*t)-1)/2,inBack:(t,e=1.70158)=>t*t*((e+1)*t-e),outBack:(t,e=1.70158)=>(t-=1)*t*((e+1)*t+e)+1,inOutBack:(t,e=1.70158)=>(t*=2)<1?t*t*((1.525*e+1)*t-1.525*e)*.5:.5*((t-=2)*t*((1.525*e+1)*t+1.525*e)+2),inExpo:t=>0===t?0:Math.pow(2,10*(t-1)),outExpo:t=>1===t?1:1-Math.pow(2,-10*t),inOutExpo:t=>0===t?0:1===t?1:t<.5?.5*Math.pow(2,20*t-10):1-.5*Math.pow(2,-20*t+10),inElastic:(t,e=1,s=.5)=>0===t?0:1===t?1:-e*Math.pow(2,10*(t-1))*Math.sin((t-1-s/o*Math.asin(1/e))*o/s),outElastic:(t,e=1,s=.5)=>0===t?0:1===t?1:e*Math.pow(2,-10*t)*Math.sin((t-s/o*Math.asin(1/e))*o/s)+1,inOutElastic:(t,e=1,s=.5)=>0===t?0:1===t?1:t<.5?-.5*e*Math.pow(2,20*t-10)*Math.sin((20*t-11.125)*o/s):.5*e*Math.pow(2,-20*t+10)*Math.sin((20*t-11.125)*o/s)+1},p={pingPong:function(t){return t<=.5?this._easing(2*t):1-this._easing(2*(t-.5))},yoyo:function(t){return this._easing(h.yoyo(t))},bounce:function(t){return h.yoyo(this._easing(t))}};let c=0;class l extends i{on(...t){return super.on(...t),this}off(...t){return super.off(...t),this}once(...t){return super.once(...t),this}onComplete(...t){return super.on(r.COMPLETE,...t),this}onUpdate(...t){return super.on(r.UPDATE,...t),this}static DEFAULTS=n;static _noop(){}static mergeConfigs(t,e){t!==e&&Object.keys(e).forEach(s=>{"object"==typeof e[s]&&null!==e[s]?(t[s]&&"object"==typeof t[s]||(t[s]={}),l.mergeConfigs(t[s],e[s])):t[s]=e[s]})}static lerp(t,e,s){return t+(e-t)*s}constructor(t={},e){super(),this.index=c++,this.overrides=t,this.settings={},this.reset(t),e&&(this.manager=e),this.lastDeltaTime=0}_processState(){this.step=l._noop,this.progress=0,this.easeValue=0,this.elapsedTime=0,this.promise=null,this._resolve=l._noop,this._refreshDynamicProps()}_refreshDynamicProps(){this.applyProcessors(this.settings);const{target:t,time:e,repeat:s,loop:i,reversed:n,delay:r}=this.settings;this.target=t,this.time=Math.max(e,0),this.repeat=s>0?s:i?1/0:0,this.reversed=n,this.remainingDelay=r,this._processEasing()}_processEasing(){const t="string"==typeof this.settings.easing?h[this.settings.easing]||h.linear:this.settings.easing;this._easing=this.reversed?this._reversedEasing:t;const e="string"==typeof this.settings.mode?p[this.settings.mode]:this.settings.mode;this._calculateEasing=e?e.bind(this):this._easing}_reversedEasing=t=>this.settings.easing(1-t);_update(){this.progress=this.elapsedTime/this.time,this.easeValue=this._calculateEasing(this.progress),this.emit(r.UPDATE,this)}_stepDelay=t=>{this.remainingDelay-=t,this.lastDeltaTime=t,this.remainingDelay>0||(this.step=this._stepTime,this.step(Math.abs(this.remainingDelay)),this.remainingDelay=this.settings.delay)};_stepTime=(t=0)=>{this.elapsedTime+=t,this.lastDeltaTime=t,this.elapsedTime>=this.time?(this.elapsedTime=this.time,this._update(),this._complete()):this._update()};_complete(){this.repeat-- >0?this._repeat():(this._resolve(),this.stop(!1),this.emit(r.COMPLETE))}_repeat(t=!0){this.remainingDelay=this.settings.repeatDelay,this.elapsedTime=0,this.remainingDelay>0&&(this.step=this._stepDelay),this._update(),t&&this.emit(r.REPEAT)}reset(t=this.constructor.DEFAULTS){return this.settings={...this.constructor.DEFAULTS,...t},this._processState(),this}applyProcessors(t=this.settings){t.processors.forEach(e=>{l.mergeConfigs(t,e.call(this,t)||{})})}tweak(t={}){return l.mergeConfigs(this.settings,t),this._refreshDynamicProps(),this}seek(t=0,e=!0){return this.elapsedTime=Math.min(Math.max(t,0),this.time),e&&this._update(),this}setProgress(t=0,e=!0){return this.seek(this.time*t,e)}reverse(t=!1){return this.reversed=!this.reversed,this.seek(this.time-this.elapsedTime,t),this._processEasing(),this}play(t=!0){return this.isPlaying||(t&&this.emit(r.PLAY),this.remainingDelay>0?this.step=this._stepDelay:(this.step=this._stepTime,this.emit(r.BEGIN)),this.manager&&this.manager.addToActive(this)),this}playPromise(t=this.promise){return this.play(),this.promise=t||new Promise(t=>{this._resolve=t}),this.promise}stop(t=!0){return this._processState(),t&&this.emit(r.STOP),this.manager&&this.manager.removeFromActive(this),this}pause(){return this.step=l._noop,this.manager&&this.manager.removeFromActive(this),this}replay(t=!1){return this.stop(t),this.play(t),this}get isPlaying(){return this.step!==l._noop}remove(){this.stop(),this.manager.remove(this)}}class u extends l{static DEFAULTS={...l.DEFAULTS,properties:null,points:[],smoothing:20};_preparePropertySetters(){this.propertySetters=this.properties.map(t=>{const e=t.split("."),s=e.pop();return t=>{let i=this.target;for(let t=0;t<e.length;t++)i=i[e[t]];i[s]=t}})}_generatePath(){const t=this.settings.points,e=Math.max(this.settings.smoothing,1),s=[];function i(t,e,s,i,n){const r=n*n,o=r*n;return t.map((a,h)=>.5*(2*e[h]+(-t[h]+s[h])*n+(2*t[h]-5*e[h]+4*s[h]-i[h])*r+(-t[h]+3*e[h]-3*s[h]+i[h])*o))}this.totalLength=0;for(let n=0;n<t.length-1;n++){const r=t[0===n?n:n-1],o=t[n],a=t[n+1],h=t[n+2<t.length?n+2:n+1];for(let t=0;t<e;t++){const n=i(r,o,a,h,t/e);s.push(n),s.length>1&&(this.totalLength+=this._calculateDistance(s[s.length-2],n))}}return s.push(t[t.length-1]),s}_calculateDistance(t,e){return Math.sqrt(t.reduce((s,i,n)=>s+Math.pow(e[n]-t[n],2),0))}_refreshDynamicProps(){super._refreshDynamicProps(),this.path=this._generatePath(),this.target&&0!==this.path.length?(this._tryToSetupProperties(),this._preparePropertySetters()):this._setTargetProperties=l._noop}_tryToSetupProperties(){if(this.settings.properties)this.properties=this.settings.properties;else if(this.path[0].length<=3){const t=[["position.x"],["position.x","position.y"],["position.x","position.y","position.z"]];this.properties=t[this.path[0].length-1]}else this.properties=[]}_setTargetProperties(t){for(let e=0;e<this.propertySetters.length;e++)this.propertySetters[e](t[e])}_clamp(t,e,s){return Math.max(e,Math.min(t,s))}_getInterpolatedPosition(){const t=this.path.length-1,e=this.easeValue*t,s=this._clamp(e,0,t),i=s>=t?t-1:Math.floor(s),n=Math.min(i+1,t),r=e-i,o=this.path[i],a=this.path[n];return o.map((t,e)=>l.lerp(t,a[e],r))}_update(){super._update(),this._setTargetProperties(this._getInterpolatedPosition())}}class m extends l{static DEFAULTS={...l.DEFAULTS,dynamic:!1,from:null,to:null};_refreshDynamicProps(){super._refreshDynamicProps(),this._processFromTo()}_processFromTo(){this._lerps=[],this.target&&(this._setupStates(),this._createLerps())}_setupStates(){this._from=this.settings.from||this._createState(this.settings.to||{},this.target),this._to=this.settings.to||this._createState(this.settings.from||{},this.target)}_createState(t={},e={},s={}){const i=(t,e,s)=>{for(const n in t)"object"==typeof t[n]?(s[n]={},i(t[n],e[n],s[n])):s[n]=e[n]};return i(t,e,s),s}_createLerpStep(t,e,s,i){if(this.settings.dynamic)return()=>{t[i]=l.lerp(e[i],s[i],this.easeValue)};{const n=e[i],r=s[i]-n;return()=>{t[i]=n+r*this.easeValue}}}_createLerps(t=this.target,e=this._from,s=this._to){for(const i in s)"object"==typeof s[i]?this._createLerps(t[i],e[i],s[i]):this._lerps.push(this._createLerpStep(t,e,s,i))}_update(){super._update();for(const t of this._lerps)t()}from(t={}){return this.tweak({from:t}),this}to(t={}){return this.tweak({to:t}),this}swap(){return this.tweak({from:this.settings.to,to:this.settings.from}),this}}function g(t){return t.target?t.creator?t.creator instanceof l?t.creator:(console.error("Invalid creator provided. Using default creator."),l):t.points?u:t.from||t.to?m:l:l}class f{constructor(){this.activeAnimations=new Map,this.allAnimations=new Map}create({on:t={},once:e={},...s}){const i=new(g(s))(s,this);return Object.keys(t).forEach(e=>{i.on(e,t[e])}),Object.keys(e).forEach(t=>{i.once(t,e[t])}),this.add(i),i}update=t=>{this.activeAnimations.forEach(e=>{e.step(t)})};getActiveAnimations(){return Array.from(this.activeAnimations.values())}getAllAnimations(){return Array.from(this.allAnimations.values())}remove({index:t}={}){t&&(this.activeAnimations.delete(t),this.allAnimations.delete(t))}add(t){this.allAnimations.set(t.index,t)}addToActive(t){this.activeAnimations.set(t.index,t)}removeFromActive(t){this.activeAnimations.delete(t.index)}stopAll(){this.activeAnimations.forEach(t=>{t.stop()})}removeAll(){this.stopAll(),this.activeAnimations.clear(),this.allAnimations.clear()}}const _=new f;class y{constructor(t,e={}){this.callback=t,this.options={maxDeltaTime:100,...e},this.isRunning=!1,this.lastTime=0,this.animationId=null}static start(t,e={}){const s=new y(t,e);return s.start(),s}start(){if(this.isRunning)return;this.isRunning=!0;const t=e=>{if(!this.isRunning)return;const s=Math.min(e-this.lastTime,this.options.maxDeltaTime);this.lastTime=e,this.callback(s),this.isRunning&&(this.animationId=requestAnimationFrame(t))};requestAnimationFrame(e=>{this.lastTime=e,t(e)})}stop(){this.isRunning=!1,this.animationId&&(cancelAnimationFrame(this.animationId),this.animationId=null)}get running(){return this.isRunning}}function v(t,e){const s=new new g(t)(t);return y.start(s.step.bind(s)),e?s.playPromise():s.play()}export{l as Core,u as Curve,n as DEFAULTS,r as EVENTS,m as FromTo,_ as GlobalManager,y as Loop,f as Manager,h as easings,p as modes,v as play};
|
package/kill-port.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const { exec } = require('child_process');
|
|
2
|
+
|
|
3
|
+
exec('netstat -ano | findstr :8081', (error, stdout) => {
|
|
4
|
+
if (stdout) {
|
|
5
|
+
const lines = stdout.trim().split('\n');
|
|
6
|
+
lines.forEach(line => {
|
|
7
|
+
const parts = line.trim().split(/\s+/);
|
|
8
|
+
const pid = parts[parts.length - 1];
|
|
9
|
+
if (pid && pid !== '0') {
|
|
10
|
+
exec(`taskkill /PID ${pid} /F`, (err) => {
|
|
11
|
+
if (!err) console.log(`Killed process ${pid} on port 8081`);
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
});
|
package/package.json
CHANGED
|
@@ -1,19 +1,36 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "qarl",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "simple animation library",
|
|
5
|
-
"main": "
|
|
6
|
-
"
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
"
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
"
|
|
15
|
-
|
|
16
|
-
"url": "https://github.com/ThreePixDroid/qarl
|
|
17
|
-
},
|
|
18
|
-
"
|
|
19
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "qarl",
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"description": "simple animation library",
|
|
5
|
+
"main": "dist/qarl.es.min.js",
|
|
6
|
+
"module": "dist/qarl.es.min.js",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./dist/qarl.es.min.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "webpack --mode=production",
|
|
12
|
+
"dev": "node kill-port.js && webpack serve --mode=development"
|
|
13
|
+
},
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+https://github.com/ThreePixDroid/qarl.git"
|
|
17
|
+
},
|
|
18
|
+
"author": "threepixdroid",
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"bugs": {
|
|
21
|
+
"url": "https://github.com/ThreePixDroid/qarl/issues"
|
|
22
|
+
},
|
|
23
|
+
"homepage": "https://github.com/ThreePixDroid/qarl#readme",
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"eventemitter3": "^5.0.1"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"html-loader": "^5.1.0",
|
|
29
|
+
"html-webpack-plugin": "^5.6.4",
|
|
30
|
+
"terser-webpack-plugin": "^5.3.14",
|
|
31
|
+
"three": "^0.180.0",
|
|
32
|
+
"webpack": "^5.102.1",
|
|
33
|
+
"webpack-cli": "^6.0.1",
|
|
34
|
+
"webpack-dev-server": "^5.2.2"
|
|
35
|
+
}
|
|
36
|
+
}
|
package/src/behaviors/easings.js
CHANGED
|
@@ -1,72 +1,78 @@
|
|
|
1
1
|
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
// created by chatGPT
|
|
3
|
+
const PI2 = Math.PI * 2
|
|
4
|
+
const pow = Math.pow
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
// оптимизировать вычисления - для ускорения
|
|
7
|
+
// сократить код - для компактности
|
|
8
|
+
// разделить на отдельные методы вместо одного большого объекта - для независимости
|
|
9
|
+
// поправить нейминг или перенестив другую область reverse, linear, yoyo - в идеале облегчить доступ через QARL."easeName"
|
|
10
|
+
// или вообще использовать строки вместо функций - "easeName" - для простоты
|
|
11
|
+
export const easings = {
|
|
12
|
+
reverse: (t) => 1 - t,
|
|
13
|
+
linear: (t) => t,
|
|
14
|
+
yoyo: (t) => 1 - Math.abs(1 - t * 2),
|
|
9
15
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
16
|
+
inQuad: (t) => pow(t, 2),
|
|
17
|
+
outQuad: (t) => t * (2 - t),
|
|
18
|
+
inOutQuad: (t) => t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t,
|
|
13
19
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
20
|
+
inCubic: (t) => pow(t, 3),
|
|
21
|
+
outCubic: (t) => (--t) * t * t + 1,
|
|
22
|
+
inOutCubic: (t) => t < 0.5 ? 4 * pow(t, 3) : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1,
|
|
17
23
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
24
|
+
inQuart: (t) => pow(t, 4),
|
|
25
|
+
outQuart: (t) => 1 - (--t) * pow(t, 3),
|
|
26
|
+
inOutQuart: (t) => t < 0.5 ? 8 * pow(t, 4) : 1 - 8 * (--t) * t * t * t,
|
|
21
27
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
28
|
+
inQuint: (t) => pow(t, 5),
|
|
29
|
+
outQuint: (t) => 1 + (--t) * pow(t, 4),
|
|
30
|
+
inOutQuint: (t) => t < 0.5 ? 16 * pow(t, 5) : 1 + 16 * (--t) * t * t * t * t,
|
|
25
31
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
32
|
+
inSine: (t) => 1 - Math.cos((t * Math.PI) / 2),
|
|
33
|
+
outSine: (t) => Math.sin((t * Math.PI) / 2),
|
|
34
|
+
inOutSine: (t) => -(Math.cos(Math.PI * t) - 1) / 2,
|
|
29
35
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
inBack: (t, s = 1.70158) => t * t * ((s + 1) * t - s),
|
|
37
|
+
outBack: (t, s = 1.70158) => ((t -= 1) * t * ((s + 1) * t + s) + 1),
|
|
38
|
+
inOutBack: (t, s = 1.70158) =>
|
|
39
|
+
(t *= 2) < 1
|
|
40
|
+
? 0.5 * (t * t * ((s * 1.525 + 1) * t - s * 1.525))
|
|
41
|
+
: 0.5 * ((t -= 2) * t * ((s * 1.525 + 1) * t + s * 1.525) + 2),
|
|
36
42
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
43
|
+
inExpo: (t) => (t === 0 ? 0 : Math.pow(2, 10 * (t - 1))),
|
|
44
|
+
outExpo: (t) => (t === 1 ? 1 : 1 - Math.pow(2, -10 * t)),
|
|
45
|
+
inOutExpo: (t) => (
|
|
46
|
+
t === 0
|
|
47
|
+
? 0
|
|
48
|
+
: t === 1
|
|
49
|
+
? 1
|
|
50
|
+
: t < 0.5
|
|
51
|
+
? 0.5 * Math.pow(2, 20 * t - 10)
|
|
52
|
+
: 1 - 0.5 * Math.pow(2, -20 * t + 10)
|
|
53
|
+
),
|
|
48
54
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
55
|
+
inElastic: (t, a = 1, p = 0.5) => (
|
|
56
|
+
t === 0
|
|
57
|
+
? 0
|
|
58
|
+
: t === 1
|
|
59
|
+
? 1
|
|
60
|
+
: -a * Math.pow(2, 10 * (t - 1)) * Math.sin(((t - 1 - p / PI2 * Math.asin(1 / a)) * PI2) / p)
|
|
61
|
+
),
|
|
62
|
+
outElastic: (t, a = 1, p = 0.5) => (
|
|
63
|
+
t === 0
|
|
64
|
+
? 0
|
|
65
|
+
: t === 1
|
|
66
|
+
? 1
|
|
67
|
+
: a * Math.pow(2, -10 * t) * Math.sin(((t - p / PI2 * Math.asin(1 / a)) * PI2) / p) + 1
|
|
68
|
+
),
|
|
69
|
+
inOutElastic: (t, a = 1, p = 0.5) => (
|
|
70
|
+
t === 0
|
|
71
|
+
? 0
|
|
72
|
+
: t === 1
|
|
73
|
+
? 1
|
|
74
|
+
: t < 0.5
|
|
75
|
+
? -0.5 * a * Math.pow(2, 20 * t - 10) * Math.sin(((20 * t - 11.125) * PI2) / p)
|
|
76
|
+
: 0.5 * a * Math.pow(2, -20 * t + 10) * Math.sin(((20 * t - 11.125) * PI2) / p) + 1
|
|
77
|
+
)
|
|
78
|
+
}
|
package/src/behaviors/modes.js
CHANGED
|
@@ -15,33 +15,30 @@ import { easings } from "./easings"
|
|
|
15
15
|
export const modes = {
|
|
16
16
|
/**
|
|
17
17
|
* Реализует пинг-понг эффект для анимации.
|
|
18
|
-
* @private
|
|
19
18
|
* @param {number} t - Текущее время анимации.
|
|
20
19
|
* @returns {number} Измененное значение времени для эффекта пинг-понг.
|
|
21
20
|
*/
|
|
22
21
|
pingPong: function (t) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
return t <= 0.5
|
|
23
|
+
? this._easing(t * 2)
|
|
24
|
+
: 1 - this._easing((t - 0.5) * 2)
|
|
26
25
|
},
|
|
27
|
-
|
|
26
|
+
|
|
28
27
|
/**
|
|
29
28
|
* Реализует эффект зеркального отражения анимации.
|
|
30
|
-
* @private
|
|
31
29
|
* @param {number} t - Текущее время анимации.
|
|
32
30
|
* @returns {number} Измененное значение времени для эффекта зеркального отражения.
|
|
33
31
|
*/
|
|
34
32
|
yoyo: function (t) {
|
|
35
|
-
|
|
33
|
+
return this._easing(easings.yoyo(t))
|
|
36
34
|
},
|
|
37
35
|
|
|
38
36
|
/**
|
|
39
37
|
* Реализует эффект отскока для анимации.
|
|
40
|
-
* @private
|
|
41
38
|
* @param {number} t - Текущее время анимации.
|
|
42
39
|
* @returns {number} Измененное значение времени для эффекта отскока.
|
|
43
40
|
*/
|
|
44
41
|
bounce: function (t) {
|
|
45
|
-
|
|
42
|
+
return easings.yoyo(this._easing(t))
|
|
46
43
|
},
|
|
47
|
-
}
|
|
44
|
+
}
|