qarl 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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 qarl
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,12 @@
1
+ # QARL (Quantum Animation Remixable Library) 😎
2
+
3
+ QARL is an animation library for my game engine.
4
+
5
+ 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! πŸ™βœ¨
6
+
7
+ ## Installation
8
+
9
+ Install the library via npm:
10
+
11
+ ```bash
12
+ npm install qarl
@@ -0,0 +1,72 @@
1
+
2
+ // created by chatGPT
3
+ const PI2 = Math.PI * 2
4
+
5
+ export const easings = {
6
+ reverse: (t) => 1 - t,
7
+ linear: (t) => t,
8
+ yoyo: (t) => 1 - Math.abs(1 - t * 2),
9
+
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,
13
+
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,
17
+
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,
21
+
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,
25
+
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,
29
+
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
+
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
+ ),
48
+
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
+ }
@@ -0,0 +1,47 @@
1
+ import { easings } from "./easings"
2
+
3
+ /**
4
+ * ΠžΠ±ΡŠΠ΅ΠΊΡ‚, содСрТащий ΠΌΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Ρ‹ Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
5
+ * @namespace
6
+ * @property {function} pingPong - Π Π΅Π°Π»ΠΈΠ·ΡƒΠ΅Ρ‚ ΠΏΠΈΠ½Π³-ΠΏΠΎΠ½Π³ эффСкт для Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
7
+ * @property {function} yoyo - Π Π΅Π°Π»ΠΈΠ·ΡƒΠ΅Ρ‚ эффСкт Π·Π΅Ρ€ΠΊΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎ отраТСния Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
8
+ * @property {function} bounce - Π Π΅Π°Π»ΠΈΠ·ΡƒΠ΅Ρ‚ эффСкт отскока для Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
9
+ * @example
10
+ * const animation = new Core({ time: 1000, mode: modes.pingPong })
11
+ * animation.play()
12
+ * @see {@link Core}
13
+ * @see {@link easings}
14
+ */
15
+ export const modes = {
16
+ /**
17
+ * Π Π΅Π°Π»ΠΈΠ·ΡƒΠ΅Ρ‚ ΠΏΠΈΠ½Π³-ΠΏΠΎΠ½Π³ эффСкт для Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
18
+ * @private
19
+ * @param {number} t - Π’Π΅ΠΊΡƒΡ‰Π΅Π΅ врСмя Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
20
+ * @returns {number} ИзмСнСнноС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ для эффСкта ΠΏΠΈΠ½Π³-ΠΏΠΎΠ½Π³.
21
+ */
22
+ pingPong: function (t) {
23
+ return t <= 0.5
24
+ ? this._easing(t * 2)
25
+ : 1 - this._easing((t - 0.5) * 2)
26
+ },
27
+
28
+ /**
29
+ * Π Π΅Π°Π»ΠΈΠ·ΡƒΠ΅Ρ‚ эффСкт Π·Π΅Ρ€ΠΊΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎ отраТСния Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
30
+ * @private
31
+ * @param {number} t - Π’Π΅ΠΊΡƒΡ‰Π΅Π΅ врСмя Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
32
+ * @returns {number} ИзмСнСнноС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ для эффСкта Π·Π΅Ρ€ΠΊΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎ отраТСния.
33
+ */
34
+ yoyo: function (t) {
35
+ return this._easing(easings.yoyo(t))
36
+ },
37
+
38
+ /**
39
+ * Π Π΅Π°Π»ΠΈΠ·ΡƒΠ΅Ρ‚ эффСкт отскока для Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
40
+ * @private
41
+ * @param {number} t - Π’Π΅ΠΊΡƒΡ‰Π΅Π΅ врСмя Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
42
+ * @returns {number} ИзмСнСнноС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ для эффСкта отскока.
43
+ */
44
+ bounce: function (t) {
45
+ return easings.yoyo(this._easing(t))
46
+ },
47
+ }
@@ -0,0 +1,108 @@
1
+ import { Core } from "../core/Core"
2
+
3
+ export class FromTo extends Core {
4
+
5
+ static DEFAULTS = {
6
+ ...Core.DEFAULTS,
7
+ dynamic: false, // Π² динамичСском состоянии ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ±Π½ΠΎΠ²Π»ΡΡ‚ΡŒ значСния from ΠΈ to Π²ΠΎ врСмя Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ
8
+ target: null,
9
+ from: null,
10
+ to: null
11
+ }
12
+
13
+ _refreshDynamicProps() {
14
+ super._refreshDynamicProps()
15
+ this._processFromTo()
16
+ }
17
+
18
+ _processFromTo() {
19
+ this.target = this.settings.target
20
+
21
+ this._from = this.settings.from || this._createState(this.settings.to || {}, this.target)
22
+ this._to = this.settings.to || this._createState(this.settings.from || {}, this.target)
23
+
24
+ if (!this.target) {
25
+ this._updateFromTo = Core._noop
26
+ } else if (this.settings.dynamic) {
27
+ this._updateFromTo = this._updateDynamic.bind(this)
28
+ } else {
29
+ this._lerps = []
30
+ this._createLerps(this.target, this._from, this._to)
31
+ this._updateFromTo = this._updateBaked.bind(this)
32
+ }
33
+ }
34
+
35
+
36
+ _createState(origPattern = {}, origSource = {}, origTarget = {}) {
37
+ const _copyProperty = (pattern, source, target) => {
38
+ for (const key in pattern) {
39
+ typeof pattern[key] === 'object'
40
+ ? target[key] = {} && _copyProperty(pattern[key], source[key], target[key])
41
+ : target[key] = source[key]
42
+ }
43
+ }
44
+
45
+ _copyProperty(origPattern, origSource, origTarget)
46
+ return origTarget
47
+ }
48
+
49
+ _createLerpStep(target, objFrom, objTo, propName) {
50
+ const staticDelta = objTo[propName] - objFrom[propName]
51
+
52
+ return (easeValue) => {
53
+ target[propName] = objFrom[propName] + staticDelta * easeValue
54
+ }
55
+ }
56
+
57
+ _createLerps(target, from, to) {
58
+ for (const key in to) {
59
+ typeof to[key] === 'object'
60
+ ? this._createLerps(target[key], from[key], to[key])
61
+ : this._lerps.push(this._createLerpStep(target, from, to, key))
62
+ }
63
+ }
64
+
65
+ _update() {
66
+ super._update()
67
+ this._updateFromTo()
68
+ }
69
+
70
+ _updateBaked() {
71
+ this._lerps.forEach(lerpStep => lerpStep(this.easeValue))
72
+ }
73
+
74
+ _updateDynamic(target = this.target, from = this._from, to = this._to) {
75
+ for (const key in to) {
76
+ typeof to[key] === 'object'
77
+ ? this._updateDynamic(target[key], from[key], to[key])
78
+ : target[key] = from[key] + (to[key] - from[key]) * this.easeValue
79
+ }
80
+ }
81
+
82
+ from(newFrom = {}) {
83
+ this.tweak({ from: newFrom })
84
+ this._processFromTo()
85
+ return this
86
+ }
87
+
88
+ to(newTo = {}) {
89
+ this.tweak({ to: newTo })
90
+ this._processFromTo()
91
+ return this
92
+ }
93
+
94
+ swap() {
95
+ const temp = this._from
96
+ this._from = this._to
97
+ this._to = temp
98
+
99
+ if (!this.settings.dynamic) {
100
+ this._lerps = []
101
+ this._createLerps(this.target, this._from, this._to)
102
+ }
103
+
104
+ return this
105
+ }
106
+
107
+ }
108
+
package/core/Core.js ADDED
@@ -0,0 +1,371 @@
1
+ import { Notifier } from "../emitter/Notifier"
2
+ import { DEFAULTS } from "../core/defaults"
3
+ import { EVENTS } from "../core/events"
4
+
5
+
6
+ /**
7
+ * Core - Основной класс для управлСния анимациями.
8
+ *
9
+ * @class Core
10
+ * @param {Object} [overrides={}] - ΠžΠ±ΡŠΠ΅ΠΊΡ‚ для пСрСопрСдСлСния настроСк ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ.
11
+ * @param {Object} [EmitterClass=null] - Класс для управлСния событиями Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
12
+ *
13
+ * @example
14
+ * const animation = new Core({ time: 1000, easing: easings.inOutQuad });
15
+ * animation.play();
16
+ *
17
+ * @property {Object} DEFAULTS - Настройки ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ.
18
+ * @property {number} DEFAULTS.time - ВрСмя Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
19
+ * @property {boolean} DEFAULTS.loop - Π€Π»Π°Π³ бСсконСчного повторСния Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
20
+ * @property {function} DEFAULTS.easing - Ѐункция для управлСния эффСктом Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
21
+ * @property {boolean} DEFAULTS.reversed - Π€Π»Π°Π³ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠ³ΠΎ проигрывания Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
22
+ * @property {number} DEFAULTS.repeat - ΠšΠΎΠ»ΠΈΡ‡Π΅ΡΡ‚Π²ΠΎ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π΅Π½ΠΈΠΉ Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
23
+ * @property {number} DEFAULTS.delay - Π—Π°Π΄Π΅Ρ€ΠΆΠΊΠ° ΠΏΠ΅Ρ€Π΅Π΄ Π½Π°Ρ‡Π°Π»ΠΎΠΌ Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
24
+ *
25
+ * @property {Object} settings - Π’Π΅ΠΊΡƒΡ‰ΠΈΠ΅ настройки Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
26
+ * @property {number} progress - Π’Π΅ΠΊΡƒΡ‰ΠΈΠΉ прогрСсс Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
27
+ * @property {boolean} reversed - Π£ΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, проигрываСтся Π»ΠΈ анимация Π² ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠΌ Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠΈ.
28
+ */
29
+ export class Core {
30
+ static DEFAULTS = DEFAULTS
31
+
32
+ static _noop() { }
33
+
34
+ static mergeConfigs(target, source) {
35
+ for (let key in source) {
36
+ if (typeof source[key] === 'object' && source[key] !== null) {
37
+ if (!target[key] || typeof target[key] !== 'object') {
38
+ target[key] = {}
39
+ }
40
+ Core.mergeConfigs(target[key], source[key])
41
+ } else {
42
+ target[key] = source[key]
43
+ }
44
+ }
45
+ }
46
+
47
+ constructor(overrides = {}, EmitterClass = Notifier) {
48
+ this.settings = {}
49
+ this._emitter = EmitterClass ? new EmitterClass() : null
50
+ this.reset(overrides)
51
+ }
52
+
53
+ /**
54
+ * УстанавливаСт Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΠ΅ состояния Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
55
+ * @private
56
+ */
57
+ _processState() {
58
+ this.step = Core._noop
59
+ this.progress = 0
60
+ this.easeValue = 0
61
+ this.elapsedTime = 0
62
+ this.promise = null
63
+ this._resolve = Core._noop
64
+ this._refreshDynamicProps()
65
+ }
66
+
67
+ /**
68
+ * ΠžΠ±Π½ΠΎΠ²Π»ΡΠ΅Ρ‚ динамичСскиС состояния Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
69
+ * @private
70
+ */
71
+ _refreshDynamicProps() {
72
+ this.time = Math.max(this.settings.time, 0)
73
+ this.repeat = this.settings.repeat > 0 ? this.settings.repeat : this.settings.loop ? Infinity : 0
74
+ this.reversed = this.settings.reversed
75
+ this.remainingDelay = this.settings.delay
76
+
77
+ this._emitEvent = this._emitEvent || Core._noop
78
+ this._emitUpdate = this._emitUpdate || Core._noop
79
+
80
+ this._processEasing()
81
+ }
82
+
83
+ /**
84
+ * УстанавливаСт Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ easing для Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
85
+ * @private
86
+ */
87
+ _processEasing() {
88
+ this._easing = this.reversed ? this._reversedEasing : this.settings.easing
89
+ this._calculateEasing = this.settings.mode ? this.settings.mode.bind(this) : this._easing
90
+ }
91
+
92
+ /**
93
+ * РассчитываСт ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ easing.
94
+ * @param {number} t - ВрСмя прогрСсса.
95
+ * @returns {number} - Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ easing для ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠ³ΠΎ направлСния.
96
+ * @private
97
+ */
98
+ _reversedEasing(t) {
99
+ return this.settings.easing(1 - t)
100
+ }
101
+
102
+ /**
103
+ * ΠžΠ±Π½ΠΎΠ²Π»ΡΠ΅Ρ‚ прогрСсс Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ ΠΈ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ событиС обновлСния.
104
+ * @private
105
+ */
106
+ _update() {
107
+ this.progress = this.elapsedTime / this.time
108
+ this.easeValue = this._calculateEasing(this.progress)
109
+ this._emitUpdate(EVENTS.UPDATE, { progress: this.progress, ease: this.easeValue })
110
+ }
111
+
112
+ /**
113
+ * ΠžΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ Π·Π°Π΄Π΅Ρ€ΠΆΠΊΡƒ ΠΏΠ΅Ρ€Π΅Π΄ Π½Π°Ρ‡Π°Π»ΠΎΠΌ Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
114
+ * @param {number} deltaTime - ВрСмя, ΠΏΡ€ΠΎΡˆΠ΅Π΄ΡˆΠ΅Π΅ с ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅Π³ΠΎ шага.
115
+ * @private
116
+ */
117
+ _stepDelay(deltaTime) {
118
+ this.remainingDelay -= deltaTime
119
+
120
+ if (this.remainingDelay > 0) return
121
+
122
+ this.step = this._stepTime
123
+ this.step(Math.abs(this.remainingDelay))
124
+
125
+ this.remainingDelay = this.settings.delay
126
+ }
127
+
128
+ /**
129
+ * ΠžΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ врСмя Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
130
+ * @param {number} [deltaTime=0] - ВрСмя, ΠΏΡ€ΠΎΡˆΠ΅Π΄ΡˆΠ΅Π΅ с ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅Π³ΠΎ шага.
131
+ * @private
132
+ */
133
+ _stepTime(deltaTime = 0) {
134
+ this.elapsedTime += deltaTime
135
+
136
+ if (this.elapsedTime >= this.time) {
137
+ this.elapsedTime = this.time
138
+ this._update()
139
+ this._complete()
140
+ } else {
141
+ this._update()
142
+ }
143
+ }
144
+
145
+ /**
146
+ * ВызываСтся ΠΏΡ€ΠΈ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
147
+ * @private
148
+ */
149
+ _complete() {
150
+ if (this.repeat-- > 0) {
151
+ this._repeat()
152
+ } else {
153
+ this._resolve()
154
+ this.stop(false)
155
+ this._emitEvent(EVENTS.COMPLETE)
156
+ }
157
+ }
158
+
159
+ /**
160
+ * ΠŸΠΎΠ²Ρ‚ΠΎΡ€ΡΠ΅Ρ‚ Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΡŽ, Ссли установлСны повторСния.
161
+ * @param {boolean} [withEvent=true] - Π€Π»Π°Π³ для Π²Ρ‹Π·ΠΎΠ²Π° события повторСния.
162
+ * @private
163
+ */
164
+ _repeat(withEvent = true) {
165
+ this.remainingDelay = this.settings.repeatDelay
166
+ this.elapsedTime = 0
167
+
168
+ if (this.remainingDelay > 0) {
169
+ this.step = this._stepDelay
170
+ }
171
+
172
+ this._update()
173
+ withEvent && this._emitEvent(EVENTS.REPEAT)
174
+ }
175
+
176
+ /**
177
+ * Π›ΠΎΠ³ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠ΅, Ссли эмиттСр событий Π½Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½.
178
+ * @returns {Core} Π’Π΅ΠΊΡƒΡ‰ΠΈΠΉ экзСмпляр для Ρ†Π΅ΠΏΠΎΡ‡Π΅ΠΊ Π²Ρ‹Π·ΠΎΠ²ΠΎΠ².
179
+ * @private
180
+ */
181
+ _noEmitter() {
182
+ console.warn('Event emitter is not defined')
183
+ return this
184
+ }
185
+
186
+ /**
187
+ * ΠŸΠΎΠ΄ΠΏΠΈΡΡ‹Π²Π°Π΅Ρ‚ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ Π½Π° ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠ΅ событиС.
188
+ * @param {string} event - Имя события.
189
+ * @param {function} handler - ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ события.
190
+ * @param {boolean} [once=false] - Π€Π»Π°Π³ для ΠΎΠ΄Π½ΠΎΡ€Π°Π·ΠΎΠ²ΠΎΠΉ подписки.
191
+ * @returns {Core} Π’Π΅ΠΊΡƒΡ‰ΠΈΠΉ экзСмпляр для Ρ†Π΅ΠΏΠΎΡ‡Π΅ΠΊ Π²Ρ‹Π·ΠΎΠ²ΠΎΠ².
192
+ */
193
+ on(event, handler, once = false) {
194
+ if (!this._emitter) return this._noEmitter()
195
+
196
+ if (event === EVENTS.UPDATE) {
197
+ this._emitUpdate = this._emitter.emit(event, handler)
198
+ } else {
199
+ this._emit = this._emitter.emit(event, handler)
200
+ }
201
+
202
+ once
203
+ ? this._emitter.once(event, handler)
204
+ : this._emitter.on(event, handler)
205
+
206
+ return this
207
+ }
208
+
209
+ /**
210
+ * ΠŸΠΎΠ΄ΠΏΠΈΡΡ‹Π²Π°Π΅Ρ‚ ΠΎΠ΄Π½ΠΎΡ€Π°Π·ΠΎΠ²Ρ‹ΠΉ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ Π½Π° ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠ΅ событиС.
211
+ * @param {string} event - Имя события.
212
+ * @param {function} handler - ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ события.
213
+ * @returns {Core} Π’Π΅ΠΊΡƒΡ‰ΠΈΠΉ экзСмпляр для Ρ†Π΅ΠΏΠΎΡ‡Π΅ΠΊ Π²Ρ‹Π·ΠΎΠ²ΠΎΠ².
214
+ */
215
+ once(event, handler) {
216
+ return this.on(event, handler, true)
217
+ }
218
+
219
+ /**
220
+ * ΠžΡ‚ΠΏΠΈΡΡ‹Π²Π°Π΅Ρ‚ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ΠΎΡ‚ ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠ³ΠΎ события.
221
+ * @param {string} event - Имя события.
222
+ * @param {function} handler - ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ события.
223
+ * @returns {Core} Π’Π΅ΠΊΡƒΡ‰ΠΈΠΉ экзСмпляр для Ρ†Π΅ΠΏΠΎΡ‡Π΅ΠΊ Π²Ρ‹Π·ΠΎΠ²ΠΎΠ².
224
+ */
225
+ off(event, handler) {
226
+ if (!this._emitter) return this._noEmitter()
227
+
228
+ this._emitter.off(event, handler)
229
+ return this
230
+ }
231
+
232
+ /**
233
+ * УдаляСт всС ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ для ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠ³ΠΎ события.
234
+ * @param {string} event - Имя события.
235
+ * @returns {Core} Π’Π΅ΠΊΡƒΡ‰ΠΈΠΉ экзСмпляр для Ρ†Π΅ΠΏΠΎΡ‡Π΅ΠΊ Π²Ρ‹Π·ΠΎΠ²ΠΎΠ².
236
+ */
237
+ removeEvents(event) {
238
+ if (!this._emitter) return this._noEmitter()
239
+
240
+ this._emitEvent = Core._noop
241
+ this._emitUpdate = Core._noop
242
+
243
+ this._emitter.removeAllListeners(event)
244
+ return this
245
+ }
246
+
247
+ /**
248
+ * БбрасываСт настройки ΠΊ значСниям ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ.
249
+ * @param {Object} [newSettings=Core.DEFAULTS] - НовыС настройки.
250
+ * @returns {Core} Π’Π΅ΠΊΡƒΡ‰ΠΈΠΉ экзСмпляр для Ρ†Π΅ΠΏΠΎΡ‡Π΅ΠΊ Π²Ρ‹Π·ΠΎΠ²ΠΎΠ².
251
+ */
252
+ reset(newSettings = this.constructor.DEFAULTS) {
253
+ this.settings = { ...this.constructor.DEFAULTS, ...newSettings }
254
+ this._processState()
255
+ return this
256
+ }
257
+
258
+ /**
259
+ * Π˜Π·ΠΌΠ΅Π½ΡΠ΅Ρ‚ Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠ΅ настройки Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
260
+ * @param {Object} [newSettings={}] - НовыС настройки.
261
+ * @returns {Core} Π’Π΅ΠΊΡƒΡ‰ΠΈΠΉ экзСмпляр для Ρ†Π΅ΠΏΠΎΡ‡Π΅ΠΊ Π²Ρ‹Π·ΠΎΠ²ΠΎΠ².
262
+ */
263
+ tweak(newSettings = {}) {
264
+ Core.mergeConfigs(this.settings, newSettings)
265
+ this._refreshDynamicProps()
266
+ return this
267
+ }
268
+
269
+ /**
270
+ * УстанавливаСт врСмя Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
271
+ * @param {number} [time=0] - ВрСмя для установки.
272
+ * @returns {Core} Π’Π΅ΠΊΡƒΡ‰ΠΈΠΉ экзСмпляр для Ρ†Π΅ΠΏΠΎΡ‡Π΅ΠΊ Π²Ρ‹Π·ΠΎΠ²ΠΎΠ².
273
+ */
274
+ seek(time = 0, callUpdate = true) {
275
+ this.elapsedTime = Math.min(Math.max(time, 0), this.settings.time)
276
+ callUpdate && this._update()
277
+ return this
278
+ }
279
+
280
+ /**
281
+ * УстанавливаСт прогрСсс Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
282
+ * @param {number} [progress=0] - ΠŸΡ€ΠΎΠ³Ρ€Π΅ΡΡ Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ (ΠΎΡ‚ 0 Π΄ΠΎ 1).
283
+ * @returns {Core} Π’Π΅ΠΊΡƒΡ‰ΠΈΠΉ экзСмпляр для Ρ†Π΅ΠΏΠΎΡ‡Π΅ΠΊ Π²Ρ‹Π·ΠΎΠ²ΠΎΠ².
284
+ */
285
+ setProgress(progress = 0, callUpdate = true) {
286
+ this.seek(this.settings.time * progress, callUpdate)
287
+ return this
288
+ }
289
+
290
+ /**
291
+ * ΠœΠ΅Π½ΡΠ΅Ρ‚ Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ (прямоС/ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠ΅).
292
+ * @returns {Core} Π’Π΅ΠΊΡƒΡ‰ΠΈΠΉ экзСмпляр для Ρ†Π΅ΠΏΠΎΡ‡Π΅ΠΊ Π²Ρ‹Π·ΠΎΠ²ΠΎΠ².
293
+ */
294
+ reverse(callUpdate = false) {
295
+ this.reversed = !this.reversed
296
+ this.seek(this.settings.time - this.elapsedTime, callUpdate)
297
+ this._processEasing()
298
+
299
+ return this
300
+ }
301
+
302
+ /**
303
+ * ЗапускаСт Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΡŽ.
304
+ * @param {boolean} [withEvent=true] - Π€Π»Π°Π³ для Π²Ρ‹Π·ΠΎΠ²Π° события ΠΏΡ€ΠΈ запускС.
305
+ * @returns {Core} Π’Π΅ΠΊΡƒΡ‰ΠΈΠΉ экзСмпляр для Ρ†Π΅ΠΏΠΎΡ‡Π΅ΠΊ Π²Ρ‹Π·ΠΎΠ²ΠΎΠ².
306
+ */
307
+ play(withEvent = true) {
308
+ if (this.isPlaying) return this
309
+
310
+ withEvent && this._emitEvent(EVENTS.PLAY)
311
+ if (this.remainingDelay > 0) {
312
+ this.step = this._stepDelay
313
+ } else {
314
+ this.step = this._stepTime
315
+ this._emitEvent(EVENTS.BEGIN)
316
+ }
317
+
318
+ return this
319
+ }
320
+
321
+ /**
322
+ * ЗапускаСт Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΡŽ с Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ΠΌ Promise.
323
+ * @param {Promise} [promise=this.promise] - ΠžΠ±ΡŠΠ΅ΠΊΡ‚ Promise для Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ ΠΏΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡŽ.
324
+ * @returns {Promise} - Promise, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρ€Π°Π·Ρ€Π΅ΡˆΠΈΡ‚ΡΡ ΠΏΡ€ΠΈ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
325
+ */
326
+ playPromise(promise = this.promise) {
327
+ this.play()
328
+ this.promise = promise || new Promise(resolve => this._resolve = resolve)
329
+ return this.promise
330
+ }
331
+
332
+ /**
333
+ * ΠžΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°Π΅Ρ‚ Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΡŽ.
334
+ * @param {boolean} [withEvent=true] - Π€Π»Π°Π³ для Π²Ρ‹Π·ΠΎΠ²Π° события ΠΏΡ€ΠΈ остановкС.
335
+ * @returns {Core} Π’Π΅ΠΊΡƒΡ‰ΠΈΠΉ экзСмпляр для Ρ†Π΅ΠΏΠΎΡ‡Π΅ΠΊ Π²Ρ‹Π·ΠΎΠ²ΠΎΠ².
336
+ */
337
+ stop(withEvent = true) {
338
+ this._processState()
339
+ withEvent && this._emitEvent(EVENTS.STOP)
340
+ return this
341
+ }
342
+
343
+ /**
344
+ * ΠŸΡ€ΠΈΠΎΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°Π΅Ρ‚ Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΡŽ.
345
+ * @returns {Core} Π’Π΅ΠΊΡƒΡ‰ΠΈΠΉ экзСмпляр для Ρ†Π΅ΠΏΠΎΡ‡Π΅ΠΊ Π²Ρ‹Π·ΠΎΠ²ΠΎΠ².
346
+ */
347
+ pause() {
348
+ this.step = Core._noop
349
+ this._emitEvent(EVENTS.PAUSE)
350
+ return this
351
+ }
352
+
353
+ /**
354
+ * ΠŸΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎ запускаСт Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΡŽ с Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ состояния.
355
+ * @param {boolean} [withEvent=true] - Π€Π»Π°Π³ для Π²Ρ‹Π·ΠΎΠ²Π° события ΠΏΡ€ΠΈ пСрСзапускС.
356
+ * @returns {Core} Π’Π΅ΠΊΡƒΡ‰ΠΈΠΉ экзСмпляр для Ρ†Π΅ΠΏΠΎΡ‡Π΅ΠΊ Π²Ρ‹Π·ΠΎΠ²ΠΎΠ².
357
+ */
358
+ replay(withEvent = true) {
359
+ this.stop(withEvent)
360
+ this.play(withEvent)
361
+ return this
362
+ }
363
+
364
+ /**
365
+ * Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚, Π°ΠΊΡ‚ΠΈΠ²Π½Π° Π»ΠΈ анимация.
366
+ * @returns {boolean} - true, Ссли анимация воспроизводится, ΠΈΠ½Π°Ρ‡Π΅ false.
367
+ */
368
+ get isPlaying() {
369
+ return this.step !== Core._noop
370
+ }
371
+ }
@@ -0,0 +1,12 @@
1
+ import { easings } from '../behaviors/easings'
2
+
3
+ export const DEFAULTS = {
4
+ time: 0,
5
+ loop: false,
6
+ mode: null,
7
+ delay: 0,
8
+ repeat: 0,
9
+ easing: easings.linear,
10
+ reversed: false,
11
+ repeatDelay: 0,
12
+ }
package/core/events.js ADDED
@@ -0,0 +1,30 @@
1
+ /**
2
+ * ΠžΠ±ΡŠΠ΅ΠΊΡ‚, содСрТащий события Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
3
+ * @namespace
4
+ * @property {string} PLAY - Π‘ΠΎΠ±Ρ‹Ρ‚ΠΈΠ΅ Π½Π°Ρ‡Π°Π»Π° Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
5
+ * @property {string} STOP - Π‘ΠΎΠ±Ρ‹Ρ‚ΠΈΠ΅ остановки Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
6
+ * @property {string} BEGIN - Π‘ΠΎΠ±Ρ‹Ρ‚ΠΈΠ΅ ΠΏΠ°ΡƒΠ·Ρ‹ Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
7
+ * @property {string} PAUSE - Π‘ΠΎΠ±Ρ‹Ρ‚ΠΈΠ΅ ΠΏΠ°ΡƒΠ·Ρ‹ Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
8
+ * @property {string} UPDATE - Π‘ΠΎΠ±Ρ‹Ρ‚ΠΈΠ΅ обновлСния Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
9
+ * @property {string} REPEAT - Π‘ΠΎΠ±Ρ‹Ρ‚ΠΈΠ΅ повторСния Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
10
+ * @property {string} REVERSE - Π‘ΠΎΠ±Ρ‹Ρ‚ΠΈΠ΅ повторСния Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
11
+ * @property {string} COMPLETE - Π‘ΠΎΠ±Ρ‹Ρ‚ΠΈΠ΅ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
12
+ * @property {string} INTERRUPT - Π‘ΠΎΠ±Ρ‹Ρ‚ΠΈΠ΅ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.
13
+ * @example
14
+ *
15
+ * animation.on(EVENTS.complete, () => console.log('Анимация Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Π°'))
16
+ * animation.once(EVENTS.complete, () => console.log('Анимация Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Π°'))
17
+ *
18
+ * @see {@link Core}
19
+ */
20
+ export const EVENTS = {
21
+ PLAY: 'play',
22
+ STOP: 'stop',
23
+ BEGIN: 'begin',
24
+ PAUSE: 'pause',
25
+ UPDATE: 'update',
26
+ REPEAT: 'repeat',
27
+ REVERSE: 'reverse',
28
+ COMPLETE: 'complete',
29
+ INTERRUPT: 'interrupt',
30
+ }
@@ -0,0 +1,97 @@
1
+ export class Notifier {
2
+ constructor() {
3
+ this.events = {}
4
+ }
5
+
6
+ /**
7
+ * Подписка Π½Π° событиС
8
+ * @param {string} eventName - НазваниС события
9
+ * @param {function} listener - Ѐункция ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ события
10
+ */
11
+ on(eventName, listener) {
12
+ if (!this.events[eventName]) {
13
+ this.events[eventName] = []
14
+ }
15
+ this.events[eventName].push(listener)
16
+ }
17
+
18
+ /**
19
+ * ΠžΡ‚ΠΏΠΈΡΠΊΠ° ΠΎΡ‚ события
20
+ * @param {string} eventName - НазваниС события
21
+ * @param {function} listener - Ѐункция ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ события
22
+ */
23
+ off(eventName, listener) {
24
+ if (!this.events[eventName]) return
25
+ this.events[eventName] = this.events[eventName].filter(l => l !== listener)
26
+ }
27
+
28
+ /**
29
+ * ГСнСрация события
30
+ * @param {string} eventName - НазваниС события
31
+ * @param {...any} args - АргумСнты, ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΡ‹Π΅ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΡƒ события
32
+ */
33
+ emit(eventName, ...args) {
34
+ if (!this.events[eventName]) return
35
+ this.events[eventName].forEach(listener => listener(...args))
36
+ }
37
+
38
+ /**
39
+ * Разовая подписка Π½Π° событиС
40
+ * @param {string} eventName - НазваниС события
41
+ * @param {function} listener - Ѐункция ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ события
42
+ */
43
+ once(eventName, listener) {
44
+ const onceListener = (...args) => {
45
+ this.off(eventName, onceListener)
46
+ listener(...args)
47
+ }
48
+ this.on(eventName, onceListener)
49
+ }
50
+
51
+ /**
52
+ * ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ список ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ² события
53
+ * @param {string} eventName - НазваниС события
54
+ * @returns {function[]} Бписок ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ²
55
+ */
56
+ getListeners(eventName) {
57
+ return this.events[eventName] || []
58
+ }
59
+
60
+ /**
61
+ * ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ количСство ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ² события
62
+ * @param {string} eventName - НазваниС события
63
+ * @returns {number} ΠšΠΎΠ»ΠΈΡ‡Π΅ΡΡ‚Π²ΠΎ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ²
64
+ */
65
+ getListenerCount(eventName) {
66
+ return this.events[eventName] ? this.events[eventName].length : 0
67
+ }
68
+
69
+ /**
70
+ * Π£Π΄Π°Π»Π΅Π½ΠΈΠ΅ всСх подписок ΠΈΠ»ΠΈ подписок ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°
71
+ * @param {string} [eventName] - НазваниС события (ΠΎΠΏΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎ)
72
+ */
73
+ removeAllListeners(eventName) {
74
+ if (eventName) {
75
+ delete this.events[eventName]
76
+ } else {
77
+ this.events = {}
78
+ }
79
+ }
80
+
81
+ /**
82
+ * ΠŸΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ список всСх событий
83
+ * @returns {string[]} Бписок Π½Π°Π·Π²Π°Π½ΠΈΠΉ событий
84
+ */
85
+ getEventNames() {
86
+ return Object.keys(this.events)
87
+ }
88
+
89
+ /**
90
+ * ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ подписчиков Π½Π° событиС
91
+ * @param {string} eventName - НазваниС события
92
+ * @returns {boolean} True, Ссли Π΅ΡΡ‚ΡŒ подписчики, ΠΈΠ½Π°Ρ‡Π΅ False
93
+ */
94
+ hasListeners(eventName) {
95
+ return this.getListenerCount(eventName) > 0
96
+ }
97
+ }
package/index.js ADDED
@@ -0,0 +1,7 @@
1
+ export { Core } from './core/Core'
2
+ export { EVENTS } from './core/events'
3
+ export { DEFAULTS } from './core/defaults'
4
+ export { Notifier } from './emitter/Notifier'
5
+ export { FromTo } from './controllers/FromTo'
6
+ export { easings } from './behaviors/easings'
7
+ export { modes } from './behaviors/modes'
package/package.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "qarl",
3
+ "version": "1.0.0",
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
+ }