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 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 my game engine.
6
-
7
- ⚠️ **Attention!** ⚠️
8
-
9
- New project! 💡 It surely has some bugs, unfinished features, and odd solutions, but I've put a lot of heart and effort into it. Thanks for stopping by—I hope you'll enjoy it! 🙏✨
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
- ## Curve example
44
-
45
- ```js
46
- const cube3 = new THREE.Mesh(
47
- new THREE.BoxGeometry(),
48
- new THREE.MeshBasicMaterial({ color: 0xff00ff })
49
- )
50
-
51
- new QARL.Curve({
52
- target: cube3,
53
- loop: true,
54
- time: 10000,
55
- mode: QARL.modes.yoyo,
56
- easing: QARL.easings.inOutBack,
57
- smoothing: 10,
58
- properties: ['position.x', 'position.y', 'position.z', 'scale.x', 'scale.y', 'scale.z'],
59
- points: [
60
- [-2, -2, 0, .1, .5, .5],
61
- [ 2, -2, 0, .5, .2, .2],
62
- [ 2, 0, 1, .1, .5, .5],
63
- [-2, 0, 1, .5, .2, .2],
64
- [-2, 2, 0, .1, .5, .5],
65
- [ 2, 2, 0, .5, .2, .2],
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.1.1",
4
- "description": "simple animation library",
5
- "main": "index.js",
6
- "scripts": {
7
- "test": "echo \"Error: no test specified\" && exit 1"
8
- },
9
- "repository": {
10
- "type": "git",
11
- "url": "git+https://github.com/ThreePixDroid/qarl.git"
12
- },
13
- "author": "threepixdroid",
14
- "license": "MIT",
15
- "bugs": {
16
- "url": "https://github.com/ThreePixDroid/qarl/issues"
17
- },
18
- "homepage": "https://github.com/ThreePixDroid/qarl#readme"
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
+ }
@@ -1,72 +1,78 @@
1
1
 
2
- // created by chatGPT
3
- const PI2 = Math.PI * 2
2
+ // created by chatGPT
3
+ const PI2 = Math.PI * 2
4
+ const pow = Math.pow
4
5
 
5
- export const easings = {
6
- reverse: (t) => 1 - t,
7
- linear: (t) => t,
8
- yoyo: (t) => 1 - Math.abs(1 - t * 2),
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
- inQuad: (t) => t * t,
11
- outQuad: (t) => t * (2 - t),
12
- inOutQuad: (t) => t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t,
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
- inCubic: (t) => t * t * t,
15
- outCubic: (t) => (--t) * t * t + 1,
16
- inOutCubic: (t) => t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1,
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
- inQuart: (t) => t * t * t * t,
19
- outQuart: (t) => 1 - (--t) * t * t * t,
20
- inOutQuart: (t) => t < 0.5 ? 8 * t * t * t * t : 1 - 8 * (--t) * t * t * t,
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
- inQuint: (t) => t * t * t * t * t,
23
- outQuint: (t) => 1 + (--t) * t * t * t * t,
24
- inOutQuint: (t) => t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * (--t) * t * t * t * t,
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
- inSine: (t) => 1 - Math.cos((t * Math.PI) / 2),
27
- outSine: (t) => Math.sin((t * Math.PI) / 2),
28
- inOutSine: (t) => -(Math.cos(Math.PI * t) - 1) / 2,
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
- inBack: (t, s = 1.70158) => t * t * ((s + 1) * t - s),
31
- outBack: (t, s = 1.70158) => ((t -= 1) * t * ((s + 1) * t + s) + 1),
32
- inOutBack: (t, s = 1.70158) =>
33
- (t *= 2) < 1
34
- ? 0.5 * (t * t * ((s * 1.525 + 1) * t - s * 1.525))
35
- : 0.5 * ((t -= 2) * t * ((s * 1.525 + 1) * t + s * 1.525) + 2),
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
- inExpo: (t) => (t === 0 ? 0 : Math.pow(2, 10 * (t - 1))),
38
- outExpo: (t) => (t === 1 ? 1 : 1 - Math.pow(2, -10 * t)),
39
- inOutExpo: (t) => (
40
- t === 0
41
- ? 0
42
- : t === 1
43
- ? 1
44
- : t < 0.5
45
- ? 0.5 * Math.pow(2, 20 * t - 10)
46
- : 1 - 0.5 * Math.pow(2, -20 * t + 10)
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
- inElastic: (t, a = 1, p = 0.5) => (
50
- t === 0
51
- ? 0
52
- : t === 1
53
- ? 1
54
- : -a * Math.pow(2, 10 * (t - 1)) * Math.sin(((t - 1 - p / PI2 * Math.asin(1 / a)) * PI2) / p)
55
- ),
56
- outElastic: (t, a = 1, p = 0.5) => (
57
- t === 0
58
- ? 0
59
- : t === 1
60
- ? 1
61
- : a * Math.pow(2, -10 * t) * Math.sin(((t - p / PI2 * Math.asin(1 / a)) * PI2) / p) + 1
62
- ),
63
- inOutElastic: (t, a = 1, p = 0.5) => (
64
- t === 0
65
- ? 0
66
- : t === 1
67
- ? 1
68
- : t < 0.5
69
- ? -0.5 * a * Math.pow(2, 20 * t - 10) * Math.sin(((20 * t - 11.125) * PI2) / p)
70
- : 0.5 * a * Math.pow(2, -20 * t + 10) * Math.sin(((20 * t - 11.125) * PI2) / p) + 1
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
+ }
@@ -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
- return t <= 0.5
24
- ? this._easing(t * 2)
25
- : 1 - this._easing((t - 0.5) * 2)
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
- return this._easing(easings.yoyo(t))
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
- return easings.yoyo(this._easing(t))
42
+ return easings.yoyo(this._easing(t))
46
43
  },
47
- }
44
+ }