@litecanvas/utils 0.13.0 → 0.15.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
@@ -49,4 +49,5 @@ const pos = vec(0, 0)
49
49
  - **Actor**: class to represent game entities. [Usage & Docs](https://github.com/litecanvas/utils/tree/main/src/actor)
50
50
  - **Grid**: class to handle retangular grid areas. [Usage & Docs](https://github.com/litecanvas/utils/tree/main/src/grid)
51
51
  - **Collision** utilities. [Usage & Docs](https://github.com/litecanvas/utils/tree/main/src/collision)
52
- - And [some math utilities](https://github.com/litecanvas/utils/tree/main/src/math)
52
+ - **Tween** to create animations. [Usage & Docs](https://github.com/litecanvas/utils/tree/main/src/tween)
53
+ - And some [math utilities](https://github.com/litecanvas/utils/tree/main/src/math)...
package/dist/actor.js CHANGED
@@ -56,12 +56,15 @@
56
56
  return new Vector(x, y);
57
57
  };
58
58
 
59
+ // node_modules/litecanvas/src/zzfx.js
60
+ globalThis.zzfxV = 1;
61
+
59
62
  // src/actor/index.js
60
- var ANCHOR_CENTER = vec(0.5, 0.5);
61
- var ANCHOR_TOP_LEFT = vec(0, 0);
62
- var ANCHOR_TOP_RIGHT = vec(1, 0);
63
- var ANCHOR_BOT_LEFT = vec(0, 1);
64
- var ANCHOR_BOT_RIGHT = vec(1, 1);
63
+ var ANCHOR_CENTER = /* @__PURE__ */ vec(0.5, 0.5);
64
+ var ANCHOR_TOP_LEFT = /* @__PURE__ */ vec(0, 0);
65
+ var ANCHOR_TOP_RIGHT = /* @__PURE__ */ vec(1, 0);
66
+ var ANCHOR_BOT_LEFT = /* @__PURE__ */ vec(0, 1);
67
+ var ANCHOR_BOT_RIGHT = /* @__PURE__ */ vec(1, 1);
65
68
  var Actor = class {
66
69
  /** @type {Image|HTMLCanvasElement|OffscreenCanvas} */
67
70
  sprite;
@@ -143,6 +146,26 @@
143
146
  get scale() {
144
147
  return this._s;
145
148
  }
149
+ /**
150
+ * Sets the actor scale
151
+ *
152
+ * @param {number} x
153
+ * @param {number} [y]
154
+ */
155
+ scaleTo(x, y = x) {
156
+ this._s.x = x;
157
+ this._s.y = y;
158
+ }
159
+ /**
160
+ * Multiplies the actor scale
161
+ *
162
+ * @param {number} x
163
+ * @param {number} [y]
164
+ */
165
+ scaleBy(x, y = x) {
166
+ this._s.x *= x;
167
+ this._s.y *= y;
168
+ }
146
169
  /**
147
170
  * @returns {number[]}
148
171
  */
@@ -154,16 +177,16 @@
154
177
  return [x, y, w, h];
155
178
  }
156
179
  /**
157
- * Update the transformation matrix, sets the opacity and draw the actor sprite image.
180
+ * Draw the actor
158
181
  *
159
182
  * @param {LitecanvasInstance} [litecanvas]
160
183
  */
161
- draw(litecanvas = globalThis) {
184
+ draw(litecanvas = globalThis, saveContext = true) {
162
185
  if (this.hidden || this.opacity <= 0) return;
163
- litecanvas.push();
186
+ if (saveContext) litecanvas.push();
164
187
  this.transform(litecanvas);
165
188
  this.drawImage(litecanvas);
166
- litecanvas.pop();
189
+ if (saveContext) litecanvas.pop();
167
190
  }
168
191
  /**
169
192
  * @param {LitecanvasInstance} litecanvas
@@ -176,10 +199,10 @@
176
199
  /**
177
200
  * @param {LitecanvasInstance} litecanvas
178
201
  */
179
- drawImage(litecanvas) {
202
+ drawImage(litecanvas, alpha = true) {
180
203
  const anchorX = this.sprite.width * this.anchor.x;
181
204
  const anchorY = this.sprite.height * this.anchor.y;
182
- litecanvas.alpha(this.opacity);
205
+ if (alpha) litecanvas.alpha(this.opacity);
183
206
  litecanvas.image(-anchorX, -anchorY, this.sprite);
184
207
  }
185
208
  };
package/dist/actor.min.js CHANGED
@@ -1 +1 @@
1
- (()=>{var p=Object.defineProperty;var u=(e,t)=>{for(var o in t)p(e,o,{get:t[o],enumerable:!0})};globalThis.utils=globalThis.utils||{};globalThis.utils.global=()=>{for(let e in globalThis.utils)e!=="global"&&(globalThis[e]=globalThis.utils[e])};var a={};u(a,{ANCHOR_BOT_LEFT:()=>y,ANCHOR_BOT_RIGHT:()=>g,ANCHOR_CENTER:()=>x,ANCHOR_TOP_LEFT:()=>c,ANCHOR_TOP_RIGHT:()=>d,Actor:()=>i});var m=2*Math.PI,n=class{x;y;constructor(t=0,o=t){this.x=t,this.y=o}toString(){return`Vector (${this.x}, ${this.y})`}},h=e=>e instanceof n,r=(e=0,t=e)=>(h(e)&&(t=e.y,e=e.x),new n(e,t));var x=r(.5,.5),c=r(0,0),d=r(1,0),y=r(0,1),g=r(1,1),i=class{sprite;pos;_o;_s;angle=0;opacity=1;hidden=!1;constructor(t,o,s=c){this.sprite=t,this.pos=o||r(0),this._o=r(s),this._s=r(1,1)}set x(t){this.pos.x=t}get x(){return this.pos.x}set y(t){this.pos.y=t}get y(){return this.pos.y}set anchor(t){this._o.x=t.x,this._o.y=t.y}get anchor(){return this._o}get width(){return this.sprite.width*this._s.x}get height(){return this.sprite.height*this._s.y}get scale(){return this._s}getBounds(t=!0){let o=this.sprite.width*(t?this._s.x:1),s=this.sprite.height*(t?this._s.y:1),l=this.pos.x-o*this.anchor.x,f=this.pos.y-s*this.anchor.y;return[l,f,o,s]}draw(t=globalThis){this.hidden||this.opacity<=0||(t.push(),this.transform(t),this.drawImage(t),t.pop())}transform(t){t.translate(this.pos.x,this.pos.y),t.rotate(this.angle),t.scale(this._s.x,this._s.y)}drawImage(t){let o=this.sprite.width*this.anchor.x,s=this.sprite.height*this.anchor.y;t.alpha(this.opacity),t.image(-o,-s,this.sprite)}};globalThis.utils=Object.assign(globalThis.utils||{},a);})();
1
+ (()=>{var p=Object.defineProperty;var u=(o,t)=>{for(var e in t)p(o,e,{get:t[e],enumerable:!0})};globalThis.utils=globalThis.utils||{};globalThis.utils.global=()=>{for(let o in globalThis.utils)o!=="global"&&(globalThis[o]=globalThis.utils[o])};var c={};u(c,{ANCHOR_BOT_LEFT:()=>x,ANCHOR_BOT_RIGHT:()=>g,ANCHOR_CENTER:()=>d,ANCHOR_TOP_LEFT:()=>l,ANCHOR_TOP_RIGHT:()=>y,Actor:()=>a});var T=2*Math.PI,n=class{x;y;constructor(t=0,e=t){this.x=t,this.y=e}toString(){return`Vector (${this.x}, ${this.y})`}},h=o=>o instanceof n,s=(o=0,t=o)=>(h(o)&&(t=o.y,o=o.x),new n(o,t));globalThis.zzfxV=1;var d=s(.5,.5),l=s(0,0),y=s(1,0),x=s(0,1),g=s(1,1),a=class{sprite;pos;_o;_s;angle=0;opacity=1;hidden=!1;constructor(t,e,r=l){this.sprite=t,this.pos=e||s(0),this._o=s(r),this._s=s(1,1)}set x(t){this.pos.x=t}get x(){return this.pos.x}set y(t){this.pos.y=t}get y(){return this.pos.y}set anchor(t){this._o.x=t.x,this._o.y=t.y}get anchor(){return this._o}get width(){return this.sprite.width*this._s.x}get height(){return this.sprite.height*this._s.y}get scale(){return this._s}scaleTo(t,e=t){this._s.x=t,this._s.y=e}scaleBy(t,e=t){this._s.x*=t,this._s.y*=e}getBounds(t=!0){let e=this.sprite.width*(t?this._s.x:1),r=this.sprite.height*(t?this._s.y:1),i=this.pos.x-e*this.anchor.x,f=this.pos.y-r*this.anchor.y;return[i,f,e,r]}draw(t=globalThis,e=!0){this.hidden||this.opacity<=0||(e&&t.push(),this.transform(t),this.drawImage(t),e&&t.pop())}transform(t){t.translate(this.pos.x,this.pos.y),t.rotate(this.angle),t.scale(this._s.x,this._s.y)}drawImage(t,e=!0){let r=this.sprite.width*this.anchor.x,i=this.sprite.height*this.anchor.y;e&&t.alpha(this.opacity),t.image(-r,-i,this.sprite)}};globalThis.utils=Object.assign(globalThis.utils||{},c);})();
package/dist/all.js CHANGED
@@ -23,25 +23,41 @@
23
23
  ANCHOR_TOP_LEFT: () => ANCHOR_TOP_LEFT,
24
24
  ANCHOR_TOP_RIGHT: () => ANCHOR_TOP_RIGHT,
25
25
  Actor: () => Actor,
26
+ BACK_IN: () => BACK_IN,
27
+ BACK_IN_OUT: () => BACK_IN_OUT,
28
+ BACK_OUT: () => BACK_OUT,
29
+ BOUNCE_IN: () => BOUNCE_IN,
30
+ BOUNCE_IN_OUT: () => BOUNCE_IN_OUT,
31
+ BOUNCE_OUT: () => BOUNCE_OUT,
26
32
  Camera: () => Camera,
27
33
  DOWN: () => DOWN,
34
+ EASE_IN: () => EASE_IN,
35
+ EASE_IN_OUT: () => EASE_IN_OUT,
36
+ EASE_OUT: () => EASE_OUT,
37
+ ELASTIC_IN: () => ELASTIC_IN,
38
+ ELASTIC_IN_OUT: () => ELASTIC_IN_OUT,
39
+ ELASTIC_OUT: () => ELASTIC_OUT,
28
40
  Grid: () => Grid,
29
41
  LEFT: () => LEFT,
42
+ LINEAR: () => LINEAR,
30
43
  ONE: () => ONE,
31
44
  RIGHT: () => RIGHT,
32
45
  TypedGrid: () => TypedGrid,
33
46
  UP: () => UP,
34
47
  Vector: () => Vector,
35
48
  ZERO: () => ZERO,
49
+ advance: () => advance_default,
36
50
  diff: () => diff_default,
37
51
  fract: () => fract_default,
38
52
  intersection: () => intersection_default,
39
53
  range: () => range_default,
40
54
  resolve: () => resolve_default,
55
+ tween: () => tween,
41
56
  vec: () => vec,
42
57
  vecAbs: () => vecAbs,
43
58
  vecAdd: () => vecAdd,
44
59
  vecAngle: () => vecAngle,
60
+ vecAngleBetween: () => vecAngleBetween,
45
61
  vecCeil: () => vecCeil,
46
62
  vecClamp: () => vecClamp,
47
63
  vecCross: () => vecCross,
@@ -590,8 +606,8 @@
590
606
  if (isVector(x)) {
591
607
  return vecDiv(v, x.x, x.y);
592
608
  }
593
- v.x /= x;
594
- v.y /= y;
609
+ v.x /= x || 1;
610
+ v.y /= y || 1;
595
611
  return v;
596
612
  };
597
613
  var vecRotate = (v, radians) => {
@@ -637,6 +653,7 @@
637
653
  return dx * dx + dy * dy;
638
654
  };
639
655
  var vecAngle = (v) => Math.atan2(v.y, v.x);
656
+ var vecAngleBetween = (v1, v2) => Math.atan2(v2.y - v1.y, v2.x - v1.x);
640
657
  var vecDot = (a, b) => a.x * b.x + a.y * b.y;
641
658
  var vecCross = (a, b) => a.x * b.y - a.y * b.x;
642
659
  var vecLerp = (a, b, t) => {
@@ -685,12 +702,15 @@
685
702
  var DOWN = /* @__PURE__ */ vec(0, 1);
686
703
  var LEFT = /* @__PURE__ */ vec(-1, 0);
687
704
 
705
+ // node_modules/litecanvas/src/zzfx.js
706
+ globalThis.zzfxV = 1;
707
+
688
708
  // src/actor/index.js
689
- var ANCHOR_CENTER = vec(0.5, 0.5);
690
- var ANCHOR_TOP_LEFT = vec(0, 0);
691
- var ANCHOR_TOP_RIGHT = vec(1, 0);
692
- var ANCHOR_BOT_LEFT = vec(0, 1);
693
- var ANCHOR_BOT_RIGHT = vec(1, 1);
709
+ var ANCHOR_CENTER = /* @__PURE__ */ vec(0.5, 0.5);
710
+ var ANCHOR_TOP_LEFT = /* @__PURE__ */ vec(0, 0);
711
+ var ANCHOR_TOP_RIGHT = /* @__PURE__ */ vec(1, 0);
712
+ var ANCHOR_BOT_LEFT = /* @__PURE__ */ vec(0, 1);
713
+ var ANCHOR_BOT_RIGHT = /* @__PURE__ */ vec(1, 1);
694
714
  var Actor = class {
695
715
  /** @type {Image|HTMLCanvasElement|OffscreenCanvas} */
696
716
  sprite;
@@ -772,6 +792,26 @@
772
792
  get scale() {
773
793
  return this._s;
774
794
  }
795
+ /**
796
+ * Sets the actor scale
797
+ *
798
+ * @param {number} x
799
+ * @param {number} [y]
800
+ */
801
+ scaleTo(x, y = x) {
802
+ this._s.x = x;
803
+ this._s.y = y;
804
+ }
805
+ /**
806
+ * Multiplies the actor scale
807
+ *
808
+ * @param {number} x
809
+ * @param {number} [y]
810
+ */
811
+ scaleBy(x, y = x) {
812
+ this._s.x *= x;
813
+ this._s.y *= y;
814
+ }
775
815
  /**
776
816
  * @returns {number[]}
777
817
  */
@@ -783,16 +823,16 @@
783
823
  return [x, y, w, h];
784
824
  }
785
825
  /**
786
- * Update the transformation matrix, sets the opacity and draw the actor sprite image.
826
+ * Draw the actor
787
827
  *
788
828
  * @param {LitecanvasInstance} [litecanvas]
789
829
  */
790
- draw(litecanvas = globalThis) {
830
+ draw(litecanvas = globalThis, saveContext = true) {
791
831
  if (this.hidden || this.opacity <= 0) return;
792
- litecanvas.push();
832
+ if (saveContext) litecanvas.push();
793
833
  this.transform(litecanvas);
794
834
  this.drawImage(litecanvas);
795
- litecanvas.pop();
835
+ if (saveContext) litecanvas.pop();
796
836
  }
797
837
  /**
798
838
  * @param {LitecanvasInstance} litecanvas
@@ -805,10 +845,10 @@
805
845
  /**
806
846
  * @param {LitecanvasInstance} litecanvas
807
847
  */
808
- drawImage(litecanvas) {
848
+ drawImage(litecanvas, alpha = true) {
809
849
  const anchorX = this.sprite.width * this.anchor.x;
810
850
  const anchorY = this.sprite.height * this.anchor.y;
811
- litecanvas.alpha(this.opacity);
851
+ if (alpha) litecanvas.alpha(this.opacity);
812
852
  litecanvas.image(-anchorX, -anchorY, this.sprite);
813
853
  }
814
854
  };
@@ -825,6 +865,166 @@
825
865
  // src/math/range.js
826
866
  var range_default = (size) => Array.from(Array(size).keys());
827
867
 
868
+ // src/math/advance.js
869
+ var advance_default = advance = (position, velocity, acceleration, deltaTime = 1) => {
870
+ if (acceleration) {
871
+ velocity.x += acceleration.x * deltaTime;
872
+ velocity.y += acceleration.y * deltaTime;
873
+ }
874
+ position.x += velocity.x * deltaTime;
875
+ position.y += velocity.y * deltaTime;
876
+ };
877
+
878
+ // src/tween/index.js
879
+ var HALF_PI = Math.PI / 2;
880
+ var tween = (object, prop, toValue, duration = 1, easing = LINEAR) => {
881
+ return new TweenController(object, prop, toValue, duration, easing);
882
+ };
883
+ var LINEAR = (n) => n;
884
+ var EASE_IN = (n) => n * n;
885
+ var EASE_OUT = (n) => -n * (n - 2);
886
+ var EASE_IN_OUT = (n) => {
887
+ if (n < 0.5) {
888
+ return 2 * n * n;
889
+ }
890
+ return -2 * n * n + 4 * n - 1;
891
+ };
892
+ var BACK_IN = (n) => n * n * n - n * Math.sin(n * Math.PI);
893
+ var BACK_OUT = (n) => {
894
+ let a = 1 - n;
895
+ return 1 - (a * a * a - a * Math.sin(a * Math.PI));
896
+ };
897
+ var BACK_IN_OUT = (n) => {
898
+ if (n < 0.5) {
899
+ let a2 = 2 * n;
900
+ return 0.5 * (a2 * a2 * a2 - a2 * Math.sin(a2 * Math.PI));
901
+ }
902
+ let a = 1 - (2 * n - 1);
903
+ return 0.5 * (1 - (a * a * a - a * Math.sin(n * Math.PI))) + 0.5;
904
+ };
905
+ var ELASTIC_IN = (n) => {
906
+ return Math.sin(13 * HALF_PI * n) * Math.pow(2, 10 * (n - 1));
907
+ };
908
+ var ELASTIC_OUT = (n) => {
909
+ return Math.sin(-13 * HALF_PI * (n + 1)) * Math.pow(2, -10 * n) + 1;
910
+ };
911
+ var ELASTIC_IN_OUT = (n) => {
912
+ if (n < 0.5) {
913
+ let a2 = Math.sin(13 * HALF_PI * (2 * n));
914
+ let b2 = Math.pow(2, 10 * (2 * n - 1));
915
+ return 0.5 * a2 * b2;
916
+ }
917
+ let a = Math.sin(-13 * HALF_PI * (2 * n - 1 + 1));
918
+ let b = Math.pow(2, -10 * (2 * n - 1));
919
+ return 0.5 * (a * b + 2);
920
+ };
921
+ var BOUNCE_IN = (n) => 1 - BOUNCE_OUT(1 - n);
922
+ var BOUNCE_OUT = (n) => {
923
+ if (n < 4 / 11) {
924
+ return 121 * n * n / 16;
925
+ } else if (n < 8 / 11) {
926
+ return 363 / 40 * n * n - 99 / 10 * n + 17 / 5;
927
+ } else if (n < 9 / 10) {
928
+ return 4356 / 361 * n * n - 35442 / 1805 * n + 16061 / 1805;
929
+ }
930
+ return 54 / 5 * n * n - 513 / 25 * n + 268 / 25;
931
+ };
932
+ var BOUNCE_IN_OUT = (n) => {
933
+ if (n < 0.5) {
934
+ return 0.5 * BOUNCE_IN(n * 2);
935
+ }
936
+ return 0.5 * BOUNCE_OUT(n * 2 - 1) + 0.5;
937
+ };
938
+ var TweenController = class {
939
+ /** @type {boolean} */
940
+ running = false;
941
+ /** @type {*} */
942
+ _o;
943
+ /** @type {string} */
944
+ _p;
945
+ /** @type {number} */
946
+ _x;
947
+ /** @type {number} */
948
+ _d;
949
+ /** @type {(x: number) => number} */
950
+ _e;
951
+ /** @type {Function[]} */
952
+ _cb = [];
953
+ /** @type {number} */
954
+ _t = 0;
955
+ /** @type {Function} */
956
+ _u = 0;
957
+ /** @type {LitecanvasInstance} */
958
+ _lc;
959
+ /**
960
+ * @param {*} object
961
+ * @param {string} prop
962
+ * @param {number} toValue
963
+ * @param {number} duration
964
+ * @param {(x: number) => number} easing
965
+ */
966
+ constructor(object, prop, toValue, duration, easing) {
967
+ this._o = object;
968
+ this._p = prop;
969
+ this._x = toValue;
970
+ this._d = duration;
971
+ this._e = easing;
972
+ }
973
+ /**
974
+ *
975
+ * @param {LitecanvasInstance} engine
976
+ */
977
+ start(engine = globalThis) {
978
+ if (!this.running) {
979
+ this.stop();
980
+ }
981
+ const fromValue = this._o[this._p] || 0;
982
+ this._lc = engine;
983
+ this._u = engine.listen("update", (dt) => {
984
+ this._o[this._p] = engine.lerp(
985
+ fromValue,
986
+ this._x,
987
+ this._e(this._t / this._d)
988
+ );
989
+ this._t += dt;
990
+ if (this._t >= this._d) {
991
+ this._o[this._p] = this._x;
992
+ this.stop();
993
+ }
994
+ });
995
+ this.running = true;
996
+ return this;
997
+ }
998
+ /**
999
+ * @param {Function} callback
1000
+ */
1001
+ onEnd(callback) {
1002
+ this._cb.push(callback);
1003
+ }
1004
+ /**
1005
+ * @param {boolean} completed if `false` don't call the `onEnd()` registered callbacks.
1006
+ * @returns
1007
+ */
1008
+ stop(completed = true) {
1009
+ if (!this.running || !this._u) return;
1010
+ this.running = false;
1011
+ this._u();
1012
+ if (completed) {
1013
+ for (const callback of this._cb) {
1014
+ callback(this._o);
1015
+ }
1016
+ }
1017
+ }
1018
+ reset() {
1019
+ this._cb.length = 0;
1020
+ this.stop();
1021
+ }
1022
+ get progress() {
1023
+ return this.running ? this._t / this._d : 0;
1024
+ }
1025
+ };
1026
+
828
1027
  // src/_web.js
829
1028
  globalThis.utils = Object.assign(globalThis.utils || {}, src_exports);
830
1029
  })();
1030
+ /*! @litecanvas/utils by Luiz Bills | MIT Licensed */
package/dist/all.min.js CHANGED
@@ -1,2 +1,3 @@
1
- (()=>{var $=Object.defineProperty;var V=(e,t)=>{for(var s in t)$(e,s,{get:t[s],enumerable:!0})};globalThis.utils=globalThis.utils||{};globalThis.utils.global=()=>{for(let e in globalThis.utils)e!=="global"&&(globalThis[e]=globalThis.utils[e])};var P={};V(P,{ANCHOR_BOT_LEFT:()=>yt,ANCHOR_BOT_RIGHT:()=>mt,ANCHOR_CENTER:()=>gt,ANCHOR_TOP_LEFT:()=>B,ANCHOR_TOP_RIGHT:()=>_t,Actor:()=>D,Camera:()=>u,DOWN:()=>xt,Grid:()=>_,LEFT:()=>dt,ONE:()=>ft,RIGHT:()=>pt,TypedGrid:()=>H,UP:()=>ut,Vector:()=>p,ZERO:()=>L,diff:()=>F,fract:()=>j,intersection:()=>g,range:()=>N,resolve:()=>O,vec:()=>n,vecAbs:()=>ot,vecAdd:()=>b,vecAngle:()=>tt,vecCeil:()=>rt,vecClamp:()=>ht,vecCross:()=>et,vecDist:()=>Q,vecDist2:()=>v,vecDiv:()=>y,vecDot:()=>W,vecEq:()=>M,vecFloor:()=>nt,vecIsZero:()=>lt,vecLerp:()=>st,vecLimit:()=>K,vecMag:()=>z,vecMag2:()=>Y,vecMove:()=>ct,vecMult:()=>x,vecNorm:()=>A,vecRand:()=>it,vecReflect:()=>Z,vecRotate:()=>U,vecRound:()=>at,vecSet:()=>X,vecSetMag:()=>J,vecSub:()=>I,wave:()=>G});var g=(e,t,s,i,o,r,a,h)=>{let c=Math.max(e,o),C=Math.min(e+s,o+a)-c,d=Math.max(t,r),m=Math.min(t+i,r+h)-d;return[c,d,C,m]};var O=(e,t,s,i,o,r,a,h)=>{let[c,C,d,m]=g(e,t,s,i,o,r,a,h),f="",T=e,w=t;return d<m?e<o?(f="right",T=o-s):(f="left",T=o+a):t<r?(f="bottom",w=r-i):(f="top",w=r+h),{direction:f,x:T,y:w}};var u=class{_engine=null;x=0;y=0;ox=0;oy=0;width=0;height=0;rotation=0;scale=1;_shake={x:0,y:0,removeListener:null};constructor(t=null,s=0,i=0,o=null,r=null){this._engine=t||globalThis,this.ox=s,this.oy=i,this.resize(o||this._engine.WIDTH-s,r||this._engine.HEIGHT-i),this.x=this.width/2,this.y=this.height/2}resize(t,s){this.width=t,this.height=s,this._engine.emit("camera-resized",this)}start(t=!1){this._engine.push(),t&&this._engine.cliprect(this.ox,this.oy,this.width,this.height);let s=this.ox+this.width/2,i=this.oy+this.height/2;this._engine.translate(s,i),this._engine.scale(this.scale),this._engine.rotate(this.rotation),this._engine.translate(-this.x+this._shake.x,-this.y+this._shake.y)}end(){this._engine.pop()}lookAt(t,s){this.x=t,this.y=s}move(t,s){this.x+=t,this.y+=s}zoom(t){this.scale*=t}zoomTo(t){this.scale=t}rotate(t){this.rotation+=t}rotateTo(t){this.rotation=t}getWorldPoint(t,s,i={}){let o=Math.cos(-this.rotation),r=Math.sin(-this.rotation);return t=(t-this.width/2-this.ox)/this.scale,s=(s-this.height/2-this.oy)/this.scale,i.x=o*t-r*s+this.x,i.y=r*t+o*s+this.y,i}getCameraPoint(t,s,i={}){let o=Math.cos(-this.rotation),r=Math.sin(-this.rotation);return t=t-this.x,s=s-this.y,t=o*t-r*s,s=r*t+o*s,i.x=t*this.scale+this.width/2+this.ox,i.y=s*this.scale+this.height/2+this.oy,i}getBounds(){return[this.ox,this.oy,this.width,this.height]}viewing(t,s,i,o){let r=this.width/2-this.x,a=this.height/2-this.y,h=this.width/this.scale,c=this.height/this.scale;return this._engine.colrect(t,s,i,o,r,a,h,c)}shake(t=1,s=.3){this.shaking||(this._shake.removeListener=this._engine.listen("update",i=>{this._shake.x=this._engine.randi(-t,t),this._shake.y=this._engine.randi(-t,t),s-=i,s<=0&&this.unshake()}))}unshake(){this.shaking&&(this._shake.removeListener(),this._shake.removeListener=null,this._shake.x=this._shake.y=0)}get shaking(){return this._shake.removeListener!==null}};var _=class e{_w;_h;_c;constructor(t,s,i=[]){this._w=Math.max(1,~~t),this._h=Math.max(1,~~s),this._c=i}clear(){this.forEach((t,s)=>this.set(t,s,void 0))}get width(){return this._w}get height(){return this._h}set(t,s,i){this._c[this.pointToIndex(t,s)]=i}get(t,s){return this._c[this.pointToIndex(t,s)]}has(t,s){return this.get(t,s)!=null}get length(){return this._w*this._h}pointToIndex(t,s){return this.clampX(~~t)+this.clampY(~~s)*this._w}indexToPointX(t){return t%this._w}indexToPointY(t){return Math.floor(t/this._w)}forEach(t,s=!1){let i=s?this.length-1:0,o=s?-1:this.length,r=s?-1:1;for(;i!==o;){let a=this.indexToPointX(i),h=this.indexToPointY(i),c=this._c[i];if(t(a,h,c,this)===!1)break;i+=r}}fill(t){this.forEach((s,i)=>{this.set(s,i,t)})}clone(){return e.fromArray(this._w,this._h,this._c)}clampX(t){return k(t,0,this._w-1)}clampY(t){return k(t,0,this._h-1)}toArray(){return this._c.slice()}toString(t=" ",s=!0){if(!s)return this._c.join(t);let i=[];return this.forEach((o,r,a)=>{i[r]=i[r]||"",i[r]+=a+t}),i.join(`
2
- `)}},H=class e extends _{constructor(t,s,i=Uint8Array){super(t,s,null),this._c=new i(this._w*this._h)}has(t,s){return this.get(t,s)!==0}clone(){let t=new e(this._w,this._h,this._c.constructor);return this.forEach((s,i,o)=>{t.set(s,i,o)}),t}};function k(e,t,s){return e<t?t:e>s?s:e}var E=Math.sqrt,R=Math.cos,S=Math.sin,q=2*Math.PI,p=class{x;y;constructor(t=0,s=t){this.x=t,this.y=s}toString(){return`Vector (${this.x}, ${this.y})`}},l=e=>e instanceof p,n=(e=0,t=e)=>(l(e)&&(t=e.y,e=e.x),new p(e,t)),M=(e,t,s=t)=>l(t)?M(e,t.x,t.y):e.x===t&&e.y===s,X=(e,t,s=t)=>(l(t)?X(e,t.x,t.y):(e.x=t,e.y=s),e),b=(e,t,s=t)=>l(t)?b(e,t.x,t.y):(e.x+=t,e.y+=s,e),I=(e,t,s=t)=>l(t)?I(e,t.x,t.y):(e.x-=t,e.y-=s,e),x=(e,t,s=t)=>l(t)?x(e,t.x,t.y):(e.x*=t,e.y*=s,e),y=(e,t,s=t)=>l(t)?y(e,t.x,t.y):(e.x/=t,e.y/=s,e),U=(e,t)=>{let s=R(t),i=S(t);return e.x=s*e.x-i*e.y,e.y=i*e.x+s*e.y,e},Z=(e,t)=>{let s=A(n(t));return I(e,x(s,2*W(e,s)))},J=(e,t)=>(A(e),x(e,t),e),z=e=>E(e.x*e.x+e.y*e.y),Y=e=>e.x*e.x+e.y*e.y,A=e=>{let t=z(e);return t>0&&y(e,t),e},K=(e,t=1)=>{let s=Y(e);return s>t*t&&(y(e,E(s)),x(e,t)),e},Q=(e,t)=>{let s=e.x-t.x,i=e.y-t.y;return E(s*s+i*i)},v=(e,t)=>{let s=e.x-t.x,i=e.y-t.y;return s*s+i*i},tt=e=>Math.atan2(e.y,e.x),W=(e,t)=>e.x*t.x+e.y*t.y,et=(e,t)=>e.x*t.y-e.y*t.x,st=(e,t,s)=>(e.x+=(t.x-e.x)*s||0,e.y+=(t.y-e.y)*s||0,e),it=(e=1,t=e,s=globalThis.rand||Math.random)=>{let i=s()*q,o=s()*(t-e)+e;return n(R(i)*o,S(i)*o)},ot=e=>(e.x=Math.abs(e.x),e.y=Math.abs(e.y),e),rt=e=>(e.x=Math.ceil(e.x),e.y=Math.ceil(e.y),e),nt=e=>(e.x=Math.floor(e.x),e.y=Math.floor(e.y),e),at=e=>(e.x=Math.round(e.x),e.y=Math.round(e.y),e),ht=(e,t,s)=>(e.x<t.x&&(e.x=t.x),e.x>s.x&&(e.x=s.x),e.y<t.y&&(e.y=t.y),e.y>s.y&&(e.y=s.y),e),ct=(e,t,s=1)=>b(e,t.x*s,t.y*s),lt=e=>M(e,L),L=n(0,0),ft=n(1,1),ut=n(0,-1),pt=n(1,0),xt=n(0,1),dt=n(-1,0);var gt=n(.5,.5),B=n(0,0),_t=n(1,0),yt=n(0,1),mt=n(1,1),D=class{sprite;pos;_o;_s;angle=0;opacity=1;hidden=!1;constructor(t,s,i=B){this.sprite=t,this.pos=s||n(0),this._o=n(i),this._s=n(1,1)}set x(t){this.pos.x=t}get x(){return this.pos.x}set y(t){this.pos.y=t}get y(){return this.pos.y}set anchor(t){this._o.x=t.x,this._o.y=t.y}get anchor(){return this._o}get width(){return this.sprite.width*this._s.x}get height(){return this.sprite.height*this._s.y}get scale(){return this._s}getBounds(t=!0){let s=this.sprite.width*(t?this._s.x:1),i=this.sprite.height*(t?this._s.y:1),o=this.pos.x-s*this.anchor.x,r=this.pos.y-i*this.anchor.y;return[o,r,s,i]}draw(t=globalThis){this.hidden||this.opacity<=0||(t.push(),this.transform(t),this.drawImage(t),t.pop())}transform(t){t.translate(this.pos.x,this.pos.y),t.rotate(this.angle),t.scale(this._s.x,this._s.y)}drawImage(t){let s=this.sprite.width*this.anchor.x,i=this.sprite.height*this.anchor.y;t.alpha(this.opacity),t.image(-s,-i,this.sprite)}};var F=(e,t)=>Math.abs(t-e)||0;var G=(e,t,s,i=Math.sin)=>e+(i(s)+1)/2*(t-e);var j=e=>e%1||0;var N=e=>Array.from(Array(e).keys());globalThis.utils=Object.assign(globalThis.utils||{},P);})();
1
+ (()=>{var J=Object.defineProperty;var Q=(t,e)=>{for(var s in e)J(t,s,{get:e[s],enumerable:!0})};globalThis.utils=globalThis.utils||{};globalThis.utils.global=()=>{for(let t in globalThis.utils)t!=="global"&&(globalThis[t]=globalThis.utils[t])};var k={};Q(k,{ANCHOR_BOT_LEFT:()=>bt,ANCHOR_BOT_RIGHT:()=>At,ANCHOR_CENTER:()=>Mt,ANCHOR_TOP_LEFT:()=>G,ANCHOR_TOP_RIGHT:()=>It,Actor:()=>C,BACK_IN:()=>St,BACK_IN_OUT:()=>Pt,BACK_OUT:()=>kt,BOUNCE_IN:()=>Z,BOUNCE_IN_OUT:()=>Bt,BOUNCE_OUT:()=>S,Camera:()=>u,DOWN:()=>wt,EASE_IN:()=>Ot,EASE_IN_OUT:()=>Dt,EASE_OUT:()=>Ct,ELASTIC_IN:()=>Lt,ELASTIC_IN_OUT:()=>Xt,ELASTIC_OUT:()=>Rt,Grid:()=>g,LEFT:()=>Et,LINEAR:()=>K,ONE:()=>yt,RIGHT:()=>Tt,TypedGrid:()=>M,UP:()=>mt,Vector:()=>p,ZERO:()=>F,advance:()=>q,diff:()=>V,fract:()=>z,intersection:()=>d,range:()=>$,resolve:()=>L,tween:()=>Ht,vec:()=>n,vecAbs:()=>ft,vecAdd:()=>A,vecAngle:()=>nt,vecAngleBetween:()=>ht,vecCeil:()=>ut,vecClamp:()=>xt,vecCross:()=>at,vecDist:()=>rt,vecDist2:()=>ot,vecDiv:()=>y,vecDot:()=>N,vecEq:()=>b,vecFloor:()=>pt,vecIsZero:()=>gt,vecLerp:()=>ct,vecLimit:()=>it,vecMag:()=>U,vecMag2:()=>W,vecMove:()=>dt,vecMult:()=>_,vecNorm:()=>O,vecRand:()=>lt,vecReflect:()=>et,vecRotate:()=>tt,vecRound:()=>_t,vecSet:()=>Y,vecSetMag:()=>st,vecSub:()=>H,wave:()=>j});var d=(t,e,s,i,r,o,h,a)=>{let c=Math.max(t,r),P=Math.min(t+s,r+h)-c,x=Math.max(e,o),T=Math.min(e+i,o+a)-x;return[c,x,P,T]};var L=(t,e,s,i,r,o,h,a)=>{let[c,P,x,T]=d(t,e,s,i,r,o,h,a),f="",w=t,E=e;return x<T?t<r?(f="right",w=r-s):(f="left",w=r+h):e<o?(f="bottom",E=o-i):(f="top",E=o+a),{direction:f,x:w,y:E}};var u=class{_engine=null;x=0;y=0;ox=0;oy=0;width=0;height=0;rotation=0;scale=1;_shake={x:0,y:0,removeListener:null};constructor(e=null,s=0,i=0,r=null,o=null){this._engine=e||globalThis,this.ox=s,this.oy=i,this.resize(r||this._engine.WIDTH-s,o||this._engine.HEIGHT-i),this.x=this.width/2,this.y=this.height/2}resize(e,s){this.width=e,this.height=s,this._engine.emit("camera-resized",this)}start(e=!1){this._engine.push(),e&&this._engine.cliprect(this.ox,this.oy,this.width,this.height);let s=this.ox+this.width/2,i=this.oy+this.height/2;this._engine.translate(s,i),this._engine.scale(this.scale),this._engine.rotate(this.rotation),this._engine.translate(-this.x+this._shake.x,-this.y+this._shake.y)}end(){this._engine.pop()}lookAt(e,s){this.x=e,this.y=s}move(e,s){this.x+=e,this.y+=s}zoom(e){this.scale*=e}zoomTo(e){this.scale=e}rotate(e){this.rotation+=e}rotateTo(e){this.rotation=e}getWorldPoint(e,s,i={}){let r=Math.cos(-this.rotation),o=Math.sin(-this.rotation);return e=(e-this.width/2-this.ox)/this.scale,s=(s-this.height/2-this.oy)/this.scale,i.x=r*e-o*s+this.x,i.y=o*e+r*s+this.y,i}getCameraPoint(e,s,i={}){let r=Math.cos(-this.rotation),o=Math.sin(-this.rotation);return e=e-this.x,s=s-this.y,e=r*e-o*s,s=o*e+r*s,i.x=e*this.scale+this.width/2+this.ox,i.y=s*this.scale+this.height/2+this.oy,i}getBounds(){return[this.ox,this.oy,this.width,this.height]}viewing(e,s,i,r){let o=this.width/2-this.x,h=this.height/2-this.y,a=this.width/this.scale,c=this.height/this.scale;return this._engine.colrect(e,s,i,r,o,h,a,c)}shake(e=1,s=.3){this.shaking||(this._shake.removeListener=this._engine.listen("update",i=>{this._shake.x=this._engine.randi(-e,e),this._shake.y=this._engine.randi(-e,e),s-=i,s<=0&&this.unshake()}))}unshake(){this.shaking&&(this._shake.removeListener(),this._shake.removeListener=null,this._shake.x=this._shake.y=0)}get shaking(){return this._shake.removeListener!==null}};var g=class t{_w;_h;_c;constructor(e,s,i=[]){this._w=Math.max(1,~~e),this._h=Math.max(1,~~s),this._c=i}clear(){this.forEach((e,s)=>this.set(e,s,void 0))}get width(){return this._w}get height(){return this._h}set(e,s,i){this._c[this.pointToIndex(e,s)]=i}get(e,s){return this._c[this.pointToIndex(e,s)]}has(e,s){return this.get(e,s)!=null}get length(){return this._w*this._h}pointToIndex(e,s){return this.clampX(~~e)+this.clampY(~~s)*this._w}indexToPointX(e){return e%this._w}indexToPointY(e){return Math.floor(e/this._w)}forEach(e,s=!1){let i=s?this.length-1:0,r=s?-1:this.length,o=s?-1:1;for(;i!==r;){let h=this.indexToPointX(i),a=this.indexToPointY(i),c=this._c[i];if(e(h,a,c,this)===!1)break;i+=o}}fill(e){this.forEach((s,i)=>{this.set(s,i,e)})}clone(){return t.fromArray(this._w,this._h,this._c)}clampX(e){return R(e,0,this._w-1)}clampY(e){return R(e,0,this._h-1)}toArray(){return this._c.slice()}toString(e=" ",s=!0){if(!s)return this._c.join(e);let i=[];return this.forEach((r,o,h)=>{i[o]=i[o]||"",i[o]+=h+e}),i.join(`
2
+ `)}},M=class t extends g{constructor(e,s,i=Uint8Array){super(e,s,null),this._c=new i(this._w*this._h)}has(e,s){return this.get(e,s)!==0}clone(){let e=new t(this._w,this._h,this._c.constructor);return this.forEach((s,i,r)=>{e.set(s,i,r)}),e}};function R(t,e,s){return t<e?e:t>s?s:t}var I=Math.sqrt,X=Math.cos,B=Math.sin,v=2*Math.PI,p=class{x;y;constructor(e=0,s=e){this.x=e,this.y=s}toString(){return`Vector (${this.x}, ${this.y})`}},l=t=>t instanceof p,n=(t=0,e=t)=>(l(t)&&(e=t.y,t=t.x),new p(t,e)),b=(t,e,s=e)=>l(e)?b(t,e.x,e.y):t.x===e&&t.y===s,Y=(t,e,s=e)=>(l(e)?Y(t,e.x,e.y):(t.x=e,t.y=s),t),A=(t,e,s=e)=>l(e)?A(t,e.x,e.y):(t.x+=e,t.y+=s,t),H=(t,e,s=e)=>l(e)?H(t,e.x,e.y):(t.x-=e,t.y-=s,t),_=(t,e,s=e)=>l(e)?_(t,e.x,e.y):(t.x*=e,t.y*=s,t),y=(t,e,s=e)=>l(e)?y(t,e.x,e.y):(t.x/=e||1,t.y/=s||1,t),tt=(t,e)=>{let s=X(e),i=B(e);return t.x=s*t.x-i*t.y,t.y=i*t.x+s*t.y,t},et=(t,e)=>{let s=O(n(e));return H(t,_(s,2*N(t,s)))},st=(t,e)=>(O(t),_(t,e),t),U=t=>I(t.x*t.x+t.y*t.y),W=t=>t.x*t.x+t.y*t.y,O=t=>{let e=U(t);return e>0&&y(t,e),t},it=(t,e=1)=>{let s=W(t);return s>e*e&&(y(t,I(s)),_(t,e)),t},rt=(t,e)=>{let s=t.x-e.x,i=t.y-e.y;return I(s*s+i*i)},ot=(t,e)=>{let s=t.x-e.x,i=t.y-e.y;return s*s+i*i},nt=t=>Math.atan2(t.y,t.x),ht=(t,e)=>Math.atan2(e.y-t.y,e.x-t.x),N=(t,e)=>t.x*e.x+t.y*e.y,at=(t,e)=>t.x*e.y-t.y*e.x,ct=(t,e,s)=>(t.x+=(e.x-t.x)*s||0,t.y+=(e.y-t.y)*s||0,t),lt=(t=1,e=t,s=globalThis.rand||Math.random)=>{let i=s()*v,r=s()*(e-t)+t;return n(X(i)*r,B(i)*r)},ft=t=>(t.x=Math.abs(t.x),t.y=Math.abs(t.y),t),ut=t=>(t.x=Math.ceil(t.x),t.y=Math.ceil(t.y),t),pt=t=>(t.x=Math.floor(t.x),t.y=Math.floor(t.y),t),_t=t=>(t.x=Math.round(t.x),t.y=Math.round(t.y),t),xt=(t,e,s)=>(t.x<e.x&&(t.x=e.x),t.x>s.x&&(t.x=s.x),t.y<e.y&&(t.y=e.y),t.y>s.y&&(t.y=s.y),t),dt=(t,e,s=1)=>A(t,e.x*s,e.y*s),gt=t=>b(t,F),F=n(0,0),yt=n(1,1),mt=n(0,-1),Tt=n(1,0),wt=n(0,1),Et=n(-1,0);globalThis.zzfxV=1;var Mt=n(.5,.5),G=n(0,0),It=n(1,0),bt=n(0,1),At=n(1,1),C=class{sprite;pos;_o;_s;angle=0;opacity=1;hidden=!1;constructor(e,s,i=G){this.sprite=e,this.pos=s||n(0),this._o=n(i),this._s=n(1,1)}set x(e){this.pos.x=e}get x(){return this.pos.x}set y(e){this.pos.y=e}get y(){return this.pos.y}set anchor(e){this._o.x=e.x,this._o.y=e.y}get anchor(){return this._o}get width(){return this.sprite.width*this._s.x}get height(){return this.sprite.height*this._s.y}get scale(){return this._s}scaleTo(e,s=e){this._s.x=e,this._s.y=s}scaleBy(e,s=e){this._s.x*=e,this._s.y*=s}getBounds(e=!0){let s=this.sprite.width*(e?this._s.x:1),i=this.sprite.height*(e?this._s.y:1),r=this.pos.x-s*this.anchor.x,o=this.pos.y-i*this.anchor.y;return[r,o,s,i]}draw(e=globalThis,s=!0){this.hidden||this.opacity<=0||(s&&e.push(),this.transform(e),this.drawImage(e),s&&e.pop())}transform(e){e.translate(this.pos.x,this.pos.y),e.rotate(this.angle),e.scale(this._s.x,this._s.y)}drawImage(e,s=!0){let i=this.sprite.width*this.anchor.x,r=this.sprite.height*this.anchor.y;s&&e.alpha(this.opacity),e.image(-i,-r,this.sprite)}};var V=(t,e)=>Math.abs(e-t)||0;var j=(t,e,s,i=Math.sin)=>t+(i(s)+1)/2*(e-t);var z=t=>t%1||0;var $=t=>Array.from(Array(t).keys());var q=advance=(t,e,s,i=1)=>{s&&(e.x+=s.x*i,e.y+=s.y*i),t.x+=e.x*i,t.y+=e.y*i};var m=Math.PI/2,Ht=(t,e,s,i=1,r=K)=>new D(t,e,s,i,r),K=t=>t,Ot=t=>t*t,Ct=t=>-t*(t-2),Dt=t=>t<.5?2*t*t:-2*t*t+4*t-1,St=t=>t*t*t-t*Math.sin(t*Math.PI),kt=t=>{let e=1-t;return 1-(e*e*e-e*Math.sin(e*Math.PI))},Pt=t=>{if(t<.5){let s=2*t;return .5*(s*s*s-s*Math.sin(s*Math.PI))}let e=1-(2*t-1);return .5*(1-(e*e*e-e*Math.sin(t*Math.PI)))+.5},Lt=t=>Math.sin(13*m*t)*Math.pow(2,10*(t-1)),Rt=t=>Math.sin(-13*m*(t+1))*Math.pow(2,-10*t)+1,Xt=t=>{if(t<.5){let i=Math.sin(13*m*(2*t)),r=Math.pow(2,10*(2*t-1));return .5*i*r}let e=Math.sin(-13*m*(2*t-1+1)),s=Math.pow(2,-10*(2*t-1));return .5*(e*s+2)},Z=t=>1-S(1-t),S=t=>t<4/11?121*t*t/16:t<8/11?363/40*t*t-99/10*t+17/5:t<9/10?4356/361*t*t-35442/1805*t+16061/1805:54/5*t*t-513/25*t+268/25,Bt=t=>t<.5?.5*Z(t*2):.5*S(t*2-1)+.5,D=class{running=!1;_o;_p;_x;_d;_e;_cb=[];_t=0;_u=0;_lc;constructor(e,s,i,r,o){this._o=e,this._p=s,this._x=i,this._d=r,this._e=o}start(e=globalThis){this.running||this.stop();let s=this._o[this._p]||0;return this._lc=e,this._u=e.listen("update",i=>{this._o[this._p]=e.lerp(s,this._x,this._e(this._t/this._d)),this._t+=i,this._t>=this._d&&(this._o[this._p]=this._x,this.stop())}),this.running=!0,this}onEnd(e){this._cb.push(e)}stop(e=!0){if(!(!this.running||!this._u)&&(this.running=!1,this._u(),e))for(let s of this._cb)s(this._o)}reset(){this._cb.length=0,this.stop()}get progress(){return this.running?this._t/this._d:0}};globalThis.utils=Object.assign(globalThis.utils||{},k);})();
3
+ /*! @litecanvas/utils by Luiz Bills | MIT Licensed */
package/dist/math.js CHANGED
@@ -17,6 +17,7 @@
17
17
  // src/math/index.js
18
18
  var math_exports = {};
19
19
  __export(math_exports, {
20
+ advance: () => advance_default,
20
21
  diff: () => diff_default,
21
22
  fract: () => fract_default,
22
23
  range: () => range_default,
@@ -35,6 +36,19 @@
35
36
  // src/math/range.js
36
37
  var range_default = (size) => Array.from(Array(size).keys());
37
38
 
39
+ // src/vector/index.js
40
+ var PI2 = 2 * Math.PI;
41
+
42
+ // src/math/advance.js
43
+ var advance_default = advance = (position, velocity, acceleration, deltaTime = 1) => {
44
+ if (acceleration) {
45
+ velocity.x += acceleration.x * deltaTime;
46
+ velocity.y += acceleration.y * deltaTime;
47
+ }
48
+ position.x += velocity.x * deltaTime;
49
+ position.y += velocity.y * deltaTime;
50
+ };
51
+
38
52
  // src/math/_web.js
39
53
  globalThis.utils = Object.assign(globalThis.utils || {}, math_exports);
40
54
  })();
package/dist/math.min.js CHANGED
@@ -1 +1 @@
1
- (()=>{var u=Object.defineProperty;var b=(l,a)=>{for(var t in a)u(l,t,{get:a[t],enumerable:!0})};globalThis.utils=globalThis.utils||{};globalThis.utils.global=()=>{for(let l in globalThis.utils)l!=="global"&&(globalThis[l]=globalThis.utils[l])};var o={};b(o,{diff:()=>s,fract:()=>r,range:()=>e,wave:()=>i});var s=(l,a)=>Math.abs(a-l)||0;var i=(l,a,t,f=Math.sin)=>l+(f(t)+1)/2*(a-l);var r=l=>l%1||0;var e=l=>Array.from(Array(l).keys());globalThis.utils=Object.assign(globalThis.utils||{},o);})();
1
+ (()=>{var a=Object.defineProperty;var p=(t,o)=>{for(var r in o)a(t,r,{get:o[r],enumerable:!0})};globalThis.utils=globalThis.utils||{};globalThis.utils.global=()=>{for(let t in globalThis.utils)t!=="global"&&(globalThis[t]=globalThis.utils[t])};var s={};p(s,{advance:()=>u,diff:()=>n,fract:()=>x,range:()=>y,wave:()=>c});var n=(t,o)=>Math.abs(o-t)||0;var c=(t,o,r,e=Math.sin)=>t+(e(r)+1)/2*(o-t);var x=t=>t%1||0;var y=t=>Array.from(Array(t).keys());var d=2*Math.PI;var u=advance=(t,o,r,e=1)=>{r&&(o.x+=r.x*e,o.y+=r.y*e),t.x+=o.x*e,t.y+=o.y*e};globalThis.utils=Object.assign(globalThis.utils||{},s);})();
package/dist/tween.js ADDED
@@ -0,0 +1,190 @@
1
+ (() => {
2
+ var __defProp = Object.defineProperty;
3
+ var __export = (target, all) => {
4
+ for (var name in all)
5
+ __defProp(target, name, { get: all[name], enumerable: true });
6
+ };
7
+
8
+ // src/_global.js
9
+ globalThis.utils = globalThis.utils || {};
10
+ globalThis.utils.global = () => {
11
+ for (const key in globalThis.utils) {
12
+ if ("global" === key) continue;
13
+ globalThis[key] = globalThis.utils[key];
14
+ }
15
+ };
16
+
17
+ // src/tween/index.js
18
+ var tween_exports = {};
19
+ __export(tween_exports, {
20
+ BACK_IN: () => BACK_IN,
21
+ BACK_IN_OUT: () => BACK_IN_OUT,
22
+ BACK_OUT: () => BACK_OUT,
23
+ BOUNCE_IN: () => BOUNCE_IN,
24
+ BOUNCE_IN_OUT: () => BOUNCE_IN_OUT,
25
+ BOUNCE_OUT: () => BOUNCE_OUT,
26
+ EASE_IN: () => EASE_IN,
27
+ EASE_IN_OUT: () => EASE_IN_OUT,
28
+ EASE_OUT: () => EASE_OUT,
29
+ ELASTIC_IN: () => ELASTIC_IN,
30
+ ELASTIC_IN_OUT: () => ELASTIC_IN_OUT,
31
+ ELASTIC_OUT: () => ELASTIC_OUT,
32
+ LINEAR: () => LINEAR,
33
+ tween: () => tween
34
+ });
35
+
36
+ // node_modules/litecanvas/src/zzfx.js
37
+ globalThis.zzfxV = 1;
38
+
39
+ // src/tween/index.js
40
+ var HALF_PI = Math.PI / 2;
41
+ var tween = (object, prop, toValue, duration = 1, easing = LINEAR) => {
42
+ return new TweenController(object, prop, toValue, duration, easing);
43
+ };
44
+ var LINEAR = (n) => n;
45
+ var EASE_IN = (n) => n * n;
46
+ var EASE_OUT = (n) => -n * (n - 2);
47
+ var EASE_IN_OUT = (n) => {
48
+ if (n < 0.5) {
49
+ return 2 * n * n;
50
+ }
51
+ return -2 * n * n + 4 * n - 1;
52
+ };
53
+ var BACK_IN = (n) => n * n * n - n * Math.sin(n * Math.PI);
54
+ var BACK_OUT = (n) => {
55
+ let a = 1 - n;
56
+ return 1 - (a * a * a - a * Math.sin(a * Math.PI));
57
+ };
58
+ var BACK_IN_OUT = (n) => {
59
+ if (n < 0.5) {
60
+ let a2 = 2 * n;
61
+ return 0.5 * (a2 * a2 * a2 - a2 * Math.sin(a2 * Math.PI));
62
+ }
63
+ let a = 1 - (2 * n - 1);
64
+ return 0.5 * (1 - (a * a * a - a * Math.sin(n * Math.PI))) + 0.5;
65
+ };
66
+ var ELASTIC_IN = (n) => {
67
+ return Math.sin(13 * HALF_PI * n) * Math.pow(2, 10 * (n - 1));
68
+ };
69
+ var ELASTIC_OUT = (n) => {
70
+ return Math.sin(-13 * HALF_PI * (n + 1)) * Math.pow(2, -10 * n) + 1;
71
+ };
72
+ var ELASTIC_IN_OUT = (n) => {
73
+ if (n < 0.5) {
74
+ let a2 = Math.sin(13 * HALF_PI * (2 * n));
75
+ let b2 = Math.pow(2, 10 * (2 * n - 1));
76
+ return 0.5 * a2 * b2;
77
+ }
78
+ let a = Math.sin(-13 * HALF_PI * (2 * n - 1 + 1));
79
+ let b = Math.pow(2, -10 * (2 * n - 1));
80
+ return 0.5 * (a * b + 2);
81
+ };
82
+ var BOUNCE_IN = (n) => 1 - BOUNCE_OUT(1 - n);
83
+ var BOUNCE_OUT = (n) => {
84
+ if (n < 4 / 11) {
85
+ return 121 * n * n / 16;
86
+ } else if (n < 8 / 11) {
87
+ return 363 / 40 * n * n - 99 / 10 * n + 17 / 5;
88
+ } else if (n < 9 / 10) {
89
+ return 4356 / 361 * n * n - 35442 / 1805 * n + 16061 / 1805;
90
+ }
91
+ return 54 / 5 * n * n - 513 / 25 * n + 268 / 25;
92
+ };
93
+ var BOUNCE_IN_OUT = (n) => {
94
+ if (n < 0.5) {
95
+ return 0.5 * BOUNCE_IN(n * 2);
96
+ }
97
+ return 0.5 * BOUNCE_OUT(n * 2 - 1) + 0.5;
98
+ };
99
+ var TweenController = class {
100
+ /** @type {boolean} */
101
+ running = false;
102
+ /** @type {*} */
103
+ _o;
104
+ /** @type {string} */
105
+ _p;
106
+ /** @type {number} */
107
+ _x;
108
+ /** @type {number} */
109
+ _d;
110
+ /** @type {(x: number) => number} */
111
+ _e;
112
+ /** @type {Function[]} */
113
+ _cb = [];
114
+ /** @type {number} */
115
+ _t = 0;
116
+ /** @type {Function} */
117
+ _u = 0;
118
+ /** @type {LitecanvasInstance} */
119
+ _lc;
120
+ /**
121
+ * @param {*} object
122
+ * @param {string} prop
123
+ * @param {number} toValue
124
+ * @param {number} duration
125
+ * @param {(x: number) => number} easing
126
+ */
127
+ constructor(object, prop, toValue, duration, easing) {
128
+ this._o = object;
129
+ this._p = prop;
130
+ this._x = toValue;
131
+ this._d = duration;
132
+ this._e = easing;
133
+ }
134
+ /**
135
+ *
136
+ * @param {LitecanvasInstance} engine
137
+ */
138
+ start(engine = globalThis) {
139
+ if (!this.running) {
140
+ this.stop();
141
+ }
142
+ const fromValue = this._o[this._p] || 0;
143
+ this._lc = engine;
144
+ this._u = engine.listen("update", (dt) => {
145
+ this._o[this._p] = engine.lerp(
146
+ fromValue,
147
+ this._x,
148
+ this._e(this._t / this._d)
149
+ );
150
+ this._t += dt;
151
+ if (this._t >= this._d) {
152
+ this._o[this._p] = this._x;
153
+ this.stop();
154
+ }
155
+ });
156
+ this.running = true;
157
+ return this;
158
+ }
159
+ /**
160
+ * @param {Function} callback
161
+ */
162
+ onEnd(callback) {
163
+ this._cb.push(callback);
164
+ }
165
+ /**
166
+ * @param {boolean} completed if `false` don't call the `onEnd()` registered callbacks.
167
+ * @returns
168
+ */
169
+ stop(completed = true) {
170
+ if (!this.running || !this._u) return;
171
+ this.running = false;
172
+ this._u();
173
+ if (completed) {
174
+ for (const callback of this._cb) {
175
+ callback(this._o);
176
+ }
177
+ }
178
+ }
179
+ reset() {
180
+ this._cb.length = 0;
181
+ this.stop();
182
+ }
183
+ get progress() {
184
+ return this.running ? this._t / this._d : 0;
185
+ }
186
+ };
187
+
188
+ // src/tween/_web.js
189
+ globalThis.utils = Object.assign(globalThis.utils || {}, tween_exports);
190
+ })();
@@ -0,0 +1 @@
1
+ (()=>{var p=Object.defineProperty;var h=(t,e)=>{for(var o in e)p(t,o,{get:e[o],enumerable:!0})};globalThis.utils=globalThis.utils||{};globalThis.utils.global=()=>{for(let t in globalThis.utils)t!=="global"&&(globalThis[t]=globalThis.utils[t])};var l={};h(l,{BACK_IN:()=>x,BACK_IN_OUT:()=>m,BACK_OUT:()=>E,BOUNCE_IN:()=>f,BOUNCE_IN_OUT:()=>w,BOUNCE_OUT:()=>n,EASE_IN:()=>_,EASE_IN_OUT:()=>T,EASE_OUT:()=>g,ELASTIC_IN:()=>I,ELASTIC_IN_OUT:()=>y,ELASTIC_OUT:()=>b,LINEAR:()=>c,tween:()=>d});globalThis.zzfxV=1;var r=Math.PI/2,d=(t,e,o,s=1,i=c)=>new a(t,e,o,s,i),c=t=>t,_=t=>t*t,g=t=>-t*(t-2),T=t=>t<.5?2*t*t:-2*t*t+4*t-1,x=t=>t*t*t-t*Math.sin(t*Math.PI),E=t=>{let e=1-t;return 1-(e*e*e-e*Math.sin(e*Math.PI))},m=t=>{if(t<.5){let o=2*t;return .5*(o*o*o-o*Math.sin(o*Math.PI))}let e=1-(2*t-1);return .5*(1-(e*e*e-e*Math.sin(t*Math.PI)))+.5},I=t=>Math.sin(13*r*t)*Math.pow(2,10*(t-1)),b=t=>Math.sin(-13*r*(t+1))*Math.pow(2,-10*t)+1,y=t=>{if(t<.5){let s=Math.sin(13*r*(2*t)),i=Math.pow(2,10*(2*t-1));return .5*s*i}let e=Math.sin(-13*r*(2*t-1+1)),o=Math.pow(2,-10*(2*t-1));return .5*(e*o+2)},f=t=>1-n(1-t),n=t=>t<4/11?121*t*t/16:t<8/11?363/40*t*t-99/10*t+17/5:t<9/10?4356/361*t*t-35442/1805*t+16061/1805:54/5*t*t-513/25*t+268/25,w=t=>t<.5?.5*f(t*2):.5*n(t*2-1)+.5,a=class{running=!1;_o;_p;_x;_d;_e;_cb=[];_t=0;_u=0;_lc;constructor(e,o,s,i,u){this._o=e,this._p=o,this._x=s,this._d=i,this._e=u}start(e=globalThis){this.running||this.stop();let o=this._o[this._p]||0;return this._lc=e,this._u=e.listen("update",s=>{this._o[this._p]=e.lerp(o,this._x,this._e(this._t/this._d)),this._t+=s,this._t>=this._d&&(this._o[this._p]=this._x,this.stop())}),this.running=!0,this}onEnd(e){this._cb.push(e)}stop(e=!0){if(!(!this.running||!this._u)&&(this.running=!1,this._u(),e))for(let o of this._cb)o(this._o)}reset(){this._cb.length=0,this.stop()}get progress(){return this.running?this._t/this._d:0}};globalThis.utils=Object.assign(globalThis.utils||{},l);})();
package/dist/vector.js CHANGED
@@ -19,6 +19,7 @@
19
19
  vecAbs: () => vecAbs,
20
20
  vecAdd: () => vecAdd,
21
21
  vecAngle: () => vecAngle,
22
+ vecAngleBetween: () => vecAngleBetween,
22
23
  vecCeil: () => vecCeil,
23
24
  vecClamp: () => vecClamp,
24
25
  vecCross: () => vecCross,
@@ -119,8 +120,8 @@
119
120
  if (isVector(x)) {
120
121
  return vecDiv(v, x.x, x.y);
121
122
  }
122
- v.x /= x;
123
- v.y /= y;
123
+ v.x /= x || 1;
124
+ v.y /= y || 1;
124
125
  return v;
125
126
  };
126
127
  var vecRotate = (v, radians) => {
@@ -166,6 +167,7 @@
166
167
  return dx * dx + dy * dy;
167
168
  };
168
169
  var vecAngle = (v) => Math.atan2(v.y, v.x);
170
+ var vecAngleBetween = (v1, v2) => Math.atan2(v2.y - v1.y, v2.x - v1.x);
169
171
  var vecDot = (a, b) => a.x * b.x + a.y * b.y;
170
172
  var vecCross = (a, b) => a.x * b.y - a.y * b.x;
171
173
  var vecLerp = (a, b, t) => {
@@ -1 +1 @@
1
- (()=>{var C=Object.defineProperty;var E=(t,o)=>{for(var r in o)C(t,r,{get:o[r],enumerable:!0})};var a={};E(a,{DOWN:()=>J,LEFT:()=>K,ONE:()=>k,RIGHT:()=>B,UP:()=>z,Vector:()=>s,ZERO:()=>q,vec:()=>c,vecAbs:()=>j,vecAdd:()=>i,vecAngle:()=>P,vecCeil:()=>w,vecClamp:()=>H,vecCross:()=>U,vecDist:()=>L,vecDist2:()=>N,vecDiv:()=>y,vecDot:()=>T,vecEq:()=>u,vecFloor:()=>F,vecIsZero:()=>W,vecLerp:()=>Z,vecLimit:()=>A,vecMag:()=>R,vecMag2:()=>D,vecMove:()=>V,vecMult:()=>x,vecNorm:()=>h,vecRand:()=>$,vecReflect:()=>S,vecRotate:()=>O,vecRound:()=>G,vecSet:()=>g,vecSetMag:()=>b,vecSub:()=>l});var p=Math.sqrt,f=Math.cos,d=Math.sin,I=2*Math.PI,s=class{x;y;constructor(o=0,r=o){this.x=o,this.y=r}toString(){return`Vector (${this.x}, ${this.y})`}},n=t=>t instanceof s,c=(t=0,o=t)=>(n(t)&&(o=t.y,t=t.x),new s(t,o)),u=(t,o,r=o)=>n(o)?u(t,o.x,o.y):t.x===o&&t.y===r,g=(t,o,r=o)=>(n(o)?g(t,o.x,o.y):(t.x=o,t.y=r),t),i=(t,o,r=o)=>n(o)?i(t,o.x,o.y):(t.x+=o,t.y+=r,t),l=(t,o,r=o)=>n(o)?l(t,o.x,o.y):(t.x-=o,t.y-=r,t),x=(t,o,r=o)=>n(o)?x(t,o.x,o.y):(t.x*=o,t.y*=r,t),y=(t,o,r=o)=>n(o)?y(t,o.x,o.y):(t.x/=o,t.y/=r,t),O=(t,o)=>{let r=f(o),e=d(o);return t.x=r*t.x-e*t.y,t.y=e*t.x+r*t.y,t},S=(t,o)=>{let r=h(c(o));return l(t,x(r,2*T(t,r)))},b=(t,o)=>(h(t),x(t,o),t),R=t=>p(t.x*t.x+t.y*t.y),D=t=>t.x*t.x+t.y*t.y,h=t=>{let o=R(t);return o>0&&y(t,o),t},A=(t,o=1)=>{let r=D(t);return r>o*o&&(y(t,p(r)),x(t,o)),t},L=(t,o)=>{let r=t.x-o.x,e=t.y-o.y;return p(r*r+e*e)},N=(t,o)=>{let r=t.x-o.x,e=t.y-o.y;return r*r+e*e},P=t=>Math.atan2(t.y,t.x),T=(t,o)=>t.x*o.x+t.y*o.y,U=(t,o)=>t.x*o.y-t.y*o.x,Z=(t,o,r)=>(t.x+=(o.x-t.x)*r||0,t.y+=(o.y-t.y)*r||0,t),$=(t=1,o=t,r=globalThis.rand||Math.random)=>{let e=r()*I,M=r()*(o-t)+t;return c(f(e)*M,d(e)*M)},j=t=>(t.x=Math.abs(t.x),t.y=Math.abs(t.y),t),w=t=>(t.x=Math.ceil(t.x),t.y=Math.ceil(t.y),t),F=t=>(t.x=Math.floor(t.x),t.y=Math.floor(t.y),t),G=t=>(t.x=Math.round(t.x),t.y=Math.round(t.y),t),H=(t,o,r)=>(t.x<o.x&&(t.x=o.x),t.x>r.x&&(t.x=r.x),t.y<o.y&&(t.y=o.y),t.y>r.y&&(t.y=r.y),t),V=(t,o,r=1)=>i(t,o.x*r,o.y*r),W=t=>u(t,q),q=c(0,0),k=c(1,1),z=c(0,-1),B=c(1,0),J=c(0,1),K=c(-1,0);globalThis.utils=Object.assign(globalThis.utils||{},a);})();
1
+ (()=>{var A=Object.defineProperty;var C=(t,e)=>{for(var o in e)A(t,o,{get:e[o],enumerable:!0})};var h={};C(h,{DOWN:()=>K,LEFT:()=>Q,ONE:()=>k,RIGHT:()=>J,UP:()=>z,Vector:()=>s,ZERO:()=>q,vec:()=>c,vecAbs:()=>j,vecAdd:()=>i,vecAngle:()=>P,vecAngleBetween:()=>w,vecCeil:()=>B,vecClamp:()=>H,vecCross:()=>U,vecDist:()=>L,vecDist2:()=>N,vecDiv:()=>y,vecDot:()=>T,vecEq:()=>u,vecFloor:()=>F,vecIsZero:()=>W,vecLerp:()=>Z,vecLimit:()=>b,vecMag:()=>R,vecMag2:()=>D,vecMove:()=>V,vecMult:()=>x,vecNorm:()=>l,vecRand:()=>$,vecReflect:()=>O,vecRotate:()=>I,vecRound:()=>G,vecSet:()=>g,vecSetMag:()=>S,vecSub:()=>a});var p=Math.sqrt,f=Math.cos,d=Math.sin,E=2*Math.PI,s=class{x;y;constructor(e=0,o=e){this.x=e,this.y=o}toString(){return`Vector (${this.x}, ${this.y})`}},n=t=>t instanceof s,c=(t=0,e=t)=>(n(t)&&(e=t.y,t=t.x),new s(t,e)),u=(t,e,o=e)=>n(e)?u(t,e.x,e.y):t.x===e&&t.y===o,g=(t,e,o=e)=>(n(e)?g(t,e.x,e.y):(t.x=e,t.y=o),t),i=(t,e,o=e)=>n(e)?i(t,e.x,e.y):(t.x+=e,t.y+=o,t),a=(t,e,o=e)=>n(e)?a(t,e.x,e.y):(t.x-=e,t.y-=o,t),x=(t,e,o=e)=>n(e)?x(t,e.x,e.y):(t.x*=e,t.y*=o,t),y=(t,e,o=e)=>n(e)?y(t,e.x,e.y):(t.x/=e||1,t.y/=o||1,t),I=(t,e)=>{let o=f(e),r=d(e);return t.x=o*t.x-r*t.y,t.y=r*t.x+o*t.y,t},O=(t,e)=>{let o=l(c(e));return a(t,x(o,2*T(t,o)))},S=(t,e)=>(l(t),x(t,e),t),R=t=>p(t.x*t.x+t.y*t.y),D=t=>t.x*t.x+t.y*t.y,l=t=>{let e=R(t);return e>0&&y(t,e),t},b=(t,e=1)=>{let o=D(t);return o>e*e&&(y(t,p(o)),x(t,e)),t},L=(t,e)=>{let o=t.x-e.x,r=t.y-e.y;return p(o*o+r*r)},N=(t,e)=>{let o=t.x-e.x,r=t.y-e.y;return o*o+r*r},P=t=>Math.atan2(t.y,t.x),w=(t,e)=>Math.atan2(e.y-t.y,e.x-t.x),T=(t,e)=>t.x*e.x+t.y*e.y,U=(t,e)=>t.x*e.y-t.y*e.x,Z=(t,e,o)=>(t.x+=(e.x-t.x)*o||0,t.y+=(e.y-t.y)*o||0,t),$=(t=1,e=t,o=globalThis.rand||Math.random)=>{let r=o()*E,M=o()*(e-t)+t;return c(f(r)*M,d(r)*M)},j=t=>(t.x=Math.abs(t.x),t.y=Math.abs(t.y),t),B=t=>(t.x=Math.ceil(t.x),t.y=Math.ceil(t.y),t),F=t=>(t.x=Math.floor(t.x),t.y=Math.floor(t.y),t),G=t=>(t.x=Math.round(t.x),t.y=Math.round(t.y),t),H=(t,e,o)=>(t.x<e.x&&(t.x=e.x),t.x>o.x&&(t.x=o.x),t.y<e.y&&(t.y=e.y),t.y>o.y&&(t.y=o.y),t),V=(t,e,o=1)=>i(t,e.x*o,e.y*o),W=t=>u(t,q),q=c(0,0),k=c(1,1),z=c(0,-1),J=c(1,0),K=c(0,1),Q=c(-1,0);globalThis.utils=Object.assign(globalThis.utils||{},h);})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@litecanvas/utils",
3
- "version": "0.13.0",
3
+ "version": "0.15.0",
4
4
  "description": "Utilities to help build litecanvas games",
5
5
  "author": "Luiz Bills <luizbills@pm.me>",
6
6
  "license": "MIT",
package/src/_web.js CHANGED
@@ -1,3 +1,4 @@
1
+ /*! @litecanvas/utils by Luiz Bills | MIT Licensed */
1
2
  import "./_global.js"
2
3
  import * as utils from "./index.js"
3
4
 
@@ -1,11 +1,11 @@
1
1
  import { Vector, vec } from "../vector/index.js"
2
2
  import "litecanvas"
3
3
 
4
- export const ANCHOR_CENTER = vec(0.5, 0.5)
5
- export const ANCHOR_TOP_LEFT = vec(0, 0)
6
- export const ANCHOR_TOP_RIGHT = vec(1, 0)
7
- export const ANCHOR_BOT_LEFT = vec(0, 1)
8
- export const ANCHOR_BOT_RIGHT = vec(1, 1)
4
+ export const ANCHOR_CENTER = /** @__PURE__ */ vec(0.5, 0.5)
5
+ export const ANCHOR_TOP_LEFT = /** @__PURE__ */ vec(0, 0)
6
+ export const ANCHOR_TOP_RIGHT = /** @__PURE__ */ vec(1, 0)
7
+ export const ANCHOR_BOT_LEFT = /** @__PURE__ */ vec(0, 1)
8
+ export const ANCHOR_BOT_RIGHT = /** @__PURE__ */ vec(1, 1)
9
9
 
10
10
  export class Actor {
11
11
  /** @type {Image|HTMLCanvasElement|OffscreenCanvas} */
@@ -105,6 +105,28 @@ export class Actor {
105
105
  return this._s
106
106
  }
107
107
 
108
+ /**
109
+ * Sets the actor scale
110
+ *
111
+ * @param {number} x
112
+ * @param {number} [y]
113
+ */
114
+ scaleTo(x, y = x) {
115
+ this._s.x = x
116
+ this._s.y = y
117
+ }
118
+
119
+ /**
120
+ * Multiplies the actor scale
121
+ *
122
+ * @param {number} x
123
+ * @param {number} [y]
124
+ */
125
+ scaleBy(x, y = x) {
126
+ this._s.x *= x
127
+ this._s.y *= y
128
+ }
129
+
108
130
  /**
109
131
  * @returns {number[]}
110
132
  */
@@ -117,19 +139,19 @@ export class Actor {
117
139
  }
118
140
 
119
141
  /**
120
- * Update the transformation matrix, sets the opacity and draw the actor sprite image.
142
+ * Draw the actor
121
143
  *
122
144
  * @param {LitecanvasInstance} [litecanvas]
123
145
  */
124
- draw(litecanvas = globalThis) {
146
+ draw(litecanvas = globalThis, saveContext = true) {
125
147
  if (this.hidden || this.opacity <= 0) return
126
148
 
127
- litecanvas.push()
149
+ if (saveContext) litecanvas.push()
128
150
 
129
151
  this.transform(litecanvas)
130
152
  this.drawImage(litecanvas)
131
153
 
132
- litecanvas.pop()
154
+ if (saveContext) litecanvas.pop()
133
155
  }
134
156
 
135
157
  /**
@@ -144,10 +166,12 @@ export class Actor {
144
166
  /**
145
167
  * @param {LitecanvasInstance} litecanvas
146
168
  */
147
- drawImage(litecanvas) {
169
+ drawImage(litecanvas, alpha = true) {
148
170
  const anchorX = this.sprite.width * this.anchor.x
149
171
  const anchorY = this.sprite.height * this.anchor.y
150
- litecanvas.alpha(this.opacity)
172
+
173
+ if (alpha) litecanvas.alpha(this.opacity)
174
+
151
175
  litecanvas.image(-anchorX, -anchorY, this.sprite)
152
176
  }
153
177
  }
package/src/index.js CHANGED
@@ -5,3 +5,4 @@ export * from "./grid/index.js"
5
5
  export * from "./vector/index.js"
6
6
  export * from "./actor/index.js"
7
7
  export * from "./math/index.js"
8
+ export * from "./tween/index.js"
@@ -0,0 +1,20 @@
1
+ import { Vector, vecMult, vecAdd } from "../vector"
2
+
3
+ /**
4
+ * Move a vector (position) using another vectors: velocity and acceleration (optional).
5
+ * Note: This function changes the position and velocity vectors.
6
+ *
7
+ * @param {Vector} position
8
+ * @param {Vector} velocity
9
+ * @param {Vector?} acceleration
10
+ * @param {number?} deltaTime
11
+ */
12
+ export default advance = (position, velocity, acceleration, deltaTime = 1) => {
13
+ if (acceleration) {
14
+ velocity.x += acceleration.x * deltaTime
15
+ velocity.y += acceleration.y * deltaTime
16
+ }
17
+
18
+ position.x += velocity.x * deltaTime
19
+ position.y += velocity.y * deltaTime
20
+ }
package/src/math/index.js CHANGED
@@ -2,3 +2,4 @@ export { default as diff } from "./diff.js"
2
2
  export { default as wave } from "./wave.js"
3
3
  export { default as fract } from "./fract.js"
4
4
  export { default as range } from "./range.js"
5
+ export { default as advance } from "./advance.js"
@@ -0,0 +1,175 @@
1
+ # Tween
2
+
3
+ You can animate object property using the `tween().`
4
+
5
+ **CDN**: https://unpkg.com/@litecanvas/utils/dist/tween.js
6
+
7
+ ## tween
8
+
9
+ Animate a object property over time.
10
+
11
+ Syntax:
12
+
13
+ ```ts
14
+ tween(
15
+ object: any,
16
+ prop: string,
17
+ toValue: number,
18
+ duration?: number, // default: 1
19
+ easing?: (n: number) => number // default: LINEAR (see below)
20
+ ): TweenController
21
+ ```
22
+
23
+ ```js
24
+ // basic example
25
+ // move the rect position x from 100 to 250 over 2 seconds
26
+ import litecanvas from "litecanvas"
27
+ import { tween } from "@litecanvas/utils"
28
+
29
+ let object
30
+
31
+ litecanvas()
32
+
33
+ function init() {
34
+ pos = {
35
+ x: 100,
36
+ y: CENTERY,
37
+ }
38
+
39
+ // create the animation
40
+ const animation = tween(pos, "x", 250, 2)
41
+
42
+ // start the animation
43
+ animation.start()
44
+
45
+ // or just
46
+ // tween(...).start()
47
+ }
48
+
49
+ function draw() {
50
+ cls(0)
51
+ // draw the animated rect
52
+ rectfill(pos.x, pos.y, 50, 50, 3)
53
+ }
54
+ ```
55
+
56
+ ## TweenController
57
+
58
+ ### TweenController#start()
59
+
60
+ Starts the animation
61
+
62
+ Syntax: `.start(engine?: LitecanvasInstance): TweenController`
63
+
64
+ ```js
65
+ // if your litecanvas has config.global = false
66
+ // you need to pass the engine instance to all animations
67
+ const engine = litecanvas({
68
+ global: false
69
+ })
70
+
71
+ function init () {
72
+ engine.tween(...).start(engine)
73
+ }
74
+ ```
75
+
76
+ ```js
77
+ // otherwhise, just call `start()` without arguments
78
+ const engine = litecanvas({
79
+ // global: true // default value
80
+ })
81
+
82
+ function init () {
83
+ // just call start
84
+ engine.tween(...).start()
85
+ }
86
+ ```
87
+
88
+ ### TweenController#onEnd()
89
+
90
+ Enqueues a callback to be executed when the animation finishes.
91
+
92
+ Syntax: `.onEnd(callback?: (object:any) => void): void`
93
+
94
+ ```js
95
+ // lets imagine a animation
96
+ let anim = tween(...)
97
+
98
+ // print in console when that tween finishes
99
+ anim.onEnd(() => {
100
+ console.log('FINISHED')
101
+ })
102
+ ```
103
+
104
+ ### TweenController#stop()
105
+
106
+ Stops the animation.
107
+
108
+ Syntax: `.stop(complete?: boolean): void`
109
+
110
+ ```js
111
+ // lets imagine a animation with 5 seconds of duration
112
+ let anim = tween(...)
113
+
114
+ // call `stop()` to interrumpt that animation
115
+ // and call all "onEnd" callbacks
116
+ anim.stop()
117
+
118
+ // or
119
+ // call `stop()` to interrumpt that animation
120
+ // and NOT call the "onEnd" callbacks
121
+ anim.stop(false)
122
+ ```
123
+
124
+ ### TweenController#reset()
125
+
126
+ Stops the animation and remove all `.onEnd()` registered callbacks.
127
+
128
+ ### TweenController#progress
129
+
130
+ Returns the percentage of the animation's progress, a number between `0.0` and `1.0`. Where `0` represents 0% and `1` represents 100%.
131
+
132
+ ### Easing Functions
133
+
134
+ We provide few easing functions:
135
+
136
+ - `LINEAR` (the default)
137
+ - `BOUNCE_IN`
138
+ - `BOUNCE_OUT`
139
+ - `BOUNCE_IN_OUT`
140
+ - `EASE_IN`
141
+ - `EASE_OUT`
142
+ - `EASE_IN_OUT`
143
+ - `ELASTIC_IN`
144
+ - `ELASTIC_OUT`
145
+ - `ELASTIC_IN_OUT`
146
+ - `BACK_IN`
147
+ - `BACK_OUT`
148
+ - `BACK_IN_OUT`
149
+
150
+ You should use the `tween()`'s fifth argument to choose a easing function.
151
+
152
+ ```js
153
+ import litecanvas from "litecanvas"
154
+ import { tween, BOUNCE_OUT } from "@litecanvas/utils"
155
+
156
+ let object
157
+
158
+ litecanvas()
159
+
160
+ function init() {
161
+ pos = {
162
+ x: 100,
163
+ y: CENTERY,
164
+ }
165
+
166
+ tween(pos, "x", 250, 2, BOUNCE_OUT).start()
167
+ }
168
+
169
+ function draw() {
170
+ cls(0)
171
+ rectfill(pos.x, pos.y, 50, 50, 3)
172
+ }
173
+ ```
174
+
175
+ [See all Easing Functions in action](https://litecanvas.js.org?c=eJylVN9v2jAQfs9fceuTs2YpbN0LEpMYYwOtAmml2sM0TSY5wJvroNhpQVP%2F951jOxCg28Mkgu63v7vv7MoIqdOVLBZcsjiKskJpA8i1UCsNffgdAdxMpqPBl4Sk0eB29GMybcTZ3fzA3Kg3g9v5ZBgCvXbiDJb3s7vpMJT1yrGrMQyGn0OkFdtmpz61mpjye6Q%2BZoufmJn0F%2B40893FrbiPlcqMKNQ%2B9oHLCg%2BiJYbYYVWWqAyFdpqJkSKFwYyrB66ZHdujyM26B286HQuRV6bQGZfYgyWXGgknjXsZThVKGBbX4y7q4%2F3sKVGJe25jeqAqKZPauO1Bx0k7Lz1F9KcNL23mA2as2%2BnEZEKVe8PXyYf5GF4BORIYjyafxnOnxTY1r0ru%2B%2B%2FC1RVka65WCGYtNE10D7Ta5Nwgy40DK5bAHOC0ARpDiaYqVdQ0k26pbA0u3e6NTQI5zSOiYnVHzuu6u9heOIHaSLdODEi9o8XetxZB3ykiTutzGcbRmZPTQo1Uzmjy%2FXd%2B3mfA2bnbER%2BW2DUd7cj4HPzdAfzdf8I%2FZCEv%2BSPbM%2FDibxRkUrN6FaRQWC8lu647IZZtHeIY%2FeZwWharEVybKMqMedaS0GxCC53A2zj4HTG%2BweA7Ku5gYe5n41OXQsqwO1QhzDWB1ydFOGzKYlWi1rDgJX3aFlNgS5WUVZeiLPq5LX95ynSokMD1OYzKvhPFEjJ%2Ftx0TECZuOcatsYd06du%2FLUeUtWkyfLPB3BPVCry89NQdvSj9%2FtFKpBLVyqxjv52nD5C9%2Bs%2Fdw%2FMbTStVbFj8r22Pnv4AeWDaqw%3D%3D)
@@ -0,0 +1,4 @@
1
+ import "../_global.js"
2
+ import * as tweenUtils from "./index.js"
3
+
4
+ globalThis.utils = Object.assign(globalThis.utils || {}, tweenUtils)
@@ -0,0 +1,170 @@
1
+ import "litecanvas"
2
+
3
+ const HALF_PI = Math.PI / 2
4
+
5
+ export const tween = (object, prop, toValue, duration = 1, easing = LINEAR) => {
6
+ return new TweenController(object, prop, toValue, duration, easing)
7
+ }
8
+
9
+ export const LINEAR = (n) => n
10
+
11
+ export const EASE_IN = (n) => n * n
12
+ export const EASE_OUT = (n) => -n * (n - 2.0)
13
+ export const EASE_IN_OUT = (n) => {
14
+ if (n < 0.5) {
15
+ return 2.0 * n * n
16
+ }
17
+ return -2.0 * n * n + 4.0 * n - 1.0
18
+ }
19
+
20
+ export const BACK_IN = (n) => n * n * n - n * Math.sin(n * Math.PI)
21
+ export const BACK_OUT = (n) => {
22
+ let a = 1.0 - n
23
+ return 1.0 - (a * a * a - a * Math.sin(a * Math.PI))
24
+ }
25
+ export const BACK_IN_OUT = (n) => {
26
+ if (n < 0.5) {
27
+ let a = 2.0 * n
28
+ return 0.5 * (a * a * a - a * Math.sin(a * Math.PI))
29
+ }
30
+ let a = 1.0 - (2.0 * n - 1.0)
31
+ return 0.5 * (1.0 - (a * a * a - a * Math.sin(n * Math.PI))) + 0.5
32
+ }
33
+
34
+ export const ELASTIC_IN = (n) => {
35
+ return Math.sin(13 * HALF_PI * n) * Math.pow(2, 10 * (n - 1))
36
+ }
37
+ export const ELASTIC_OUT = (n) => {
38
+ return Math.sin(-13 * HALF_PI * (n + 1)) * Math.pow(2, -10 * n) + 1
39
+ }
40
+ export const ELASTIC_IN_OUT = (n) => {
41
+ if (n < 0.5) {
42
+ let a = Math.sin(13 * HALF_PI * (2 * n))
43
+ let b = Math.pow(2, 10 * (2 * n - 1))
44
+ return 0.5 * a * b
45
+ }
46
+ let a = Math.sin(-13 * HALF_PI * (2 * n - 1 + 1))
47
+ let b = Math.pow(2, -10 * (2 * n - 1))
48
+ return 0.5 * (a * b + 2)
49
+ }
50
+
51
+ export const BOUNCE_IN = (n) => 1 - BOUNCE_OUT(1 - n)
52
+ export const BOUNCE_OUT = (n) => {
53
+ if (n < 4.0 / 11.0) {
54
+ return (121.0 * n * n) / 16.0
55
+ } else if (n < 8.0 / 11.0) {
56
+ return (363.0 / 40.0) * n * n - (99.0 / 10.0) * n + 17.0 / 5.0
57
+ } else if (n < 9.0 / 10.0) {
58
+ return (4356.0 / 361.0) * n * n - (35442.0 / 1805.0) * n + 16061.0 / 1805.0
59
+ }
60
+ return (54.0 / 5.0) * n * n - (513.0 / 25.0) * n + 268.0 / 25.0
61
+ }
62
+ export const BOUNCE_IN_OUT = (n) => {
63
+ if (n < 0.5) {
64
+ return 0.5 * BOUNCE_IN(n * 2)
65
+ }
66
+ return 0.5 * BOUNCE_OUT(n * 2 - 1) + 0.5
67
+ }
68
+
69
+ class TweenController {
70
+ /** @type {boolean} */
71
+ running = false
72
+
73
+ /** @type {*} */
74
+ _o
75
+ /** @type {string} */
76
+ _p
77
+ /** @type {number} */
78
+ _x
79
+ /** @type {number} */
80
+ _d
81
+ /** @type {(x: number) => number} */
82
+ _e
83
+ /** @type {Function[]} */
84
+ _cb = []
85
+ /** @type {number} */
86
+ _t = 0
87
+ /** @type {Function} */
88
+ _u = 0
89
+ /** @type {LitecanvasInstance} */
90
+ _lc
91
+
92
+ /**
93
+ * @param {*} object
94
+ * @param {string} prop
95
+ * @param {number} toValue
96
+ * @param {number} duration
97
+ * @param {(x: number) => number} easing
98
+ */
99
+ constructor(object, prop, toValue, duration, easing) {
100
+ this._o = object
101
+ this._p = prop
102
+ this._x = toValue
103
+ this._d = duration
104
+ this._e = easing
105
+ }
106
+
107
+ /**
108
+ *
109
+ * @param {LitecanvasInstance} engine
110
+ */
111
+ start(engine = globalThis) {
112
+ if (!this.running) {
113
+ this.stop()
114
+ }
115
+
116
+ const fromValue = this._o[this._p] || 0
117
+
118
+ this._lc = engine
119
+ this._u = engine.listen("update", (dt) => {
120
+ this._o[this._p] = engine.lerp(
121
+ fromValue,
122
+ this._x,
123
+ this._e(this._t / this._d)
124
+ )
125
+ this._t += dt
126
+ if (this._t >= this._d) {
127
+ this._o[this._p] = this._x
128
+ this.stop()
129
+ }
130
+ })
131
+
132
+ this.running = true
133
+
134
+ return this
135
+ }
136
+
137
+ /**
138
+ * @param {Function} callback
139
+ */
140
+ onEnd(callback) {
141
+ this._cb.push(callback)
142
+ }
143
+
144
+ /**
145
+ * @param {boolean} completed if `false` don't call the `onEnd()` registered callbacks.
146
+ * @returns
147
+ */
148
+ stop(completed = true) {
149
+ if (!this.running || !this._u) return
150
+
151
+ this.running = false
152
+
153
+ this._u()
154
+
155
+ if (completed) {
156
+ for (const callback of this._cb) {
157
+ callback(this._o)
158
+ }
159
+ }
160
+ }
161
+
162
+ reset() {
163
+ this._cb.length = 0
164
+ this.stop()
165
+ }
166
+
167
+ get progress() {
168
+ return this.running ? this._t / this._d : 0
169
+ }
170
+ }
@@ -150,8 +150,9 @@ export const vecDiv = (v, x, y = x) => {
150
150
  return vecDiv(v, x.x, x.y)
151
151
  }
152
152
 
153
- v.x /= x
154
- v.y /= y
153
+ // prevent division by zero
154
+ v.x /= x || 1
155
+ v.y /= y || 1
155
156
 
156
157
  return v
157
158
  }
@@ -278,6 +279,15 @@ export const vecDist2 = (a, b) => {
278
279
  */
279
280
  export const vecAngle = (v) => Math.atan2(v.y, v.x)
280
281
 
282
+ /**
283
+ * Calculates the angle between two vectors.
284
+ *
285
+ * @param {Vector} v1
286
+ * @param {Vector} v2
287
+ * @returns {number}
288
+ */
289
+ export const vecAngleBetween = (v1, v2) => Math.atan2(v2.y - v1.y, v2.x - v1.x)
290
+
281
291
  /**
282
292
  * Calculates the dot product of two vectors.
283
293
  *