@litecanvas/utils 0.14.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
@@ -60,11 +60,11 @@
60
60
  globalThis.zzfxV = 1;
61
61
 
62
62
  // src/actor/index.js
63
- var ANCHOR_CENTER = vec(0.5, 0.5);
64
- var ANCHOR_TOP_LEFT = vec(0, 0);
65
- var ANCHOR_TOP_RIGHT = vec(1, 0);
66
- var ANCHOR_BOT_LEFT = vec(0, 1);
67
- 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);
68
68
  var Actor = class {
69
69
  /** @type {Image|HTMLCanvasElement|OffscreenCanvas} */
70
70
  sprite;
@@ -146,6 +146,26 @@
146
146
  get scale() {
147
147
  return this._s;
148
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
+ }
149
169
  /**
150
170
  * @returns {number[]}
151
171
  */
@@ -157,16 +177,16 @@
157
177
  return [x, y, w, h];
158
178
  }
159
179
  /**
160
- * Update the transformation matrix, sets the opacity and draw the actor sprite image.
180
+ * Draw the actor
161
181
  *
162
182
  * @param {LitecanvasInstance} [litecanvas]
163
183
  */
164
- draw(litecanvas = globalThis) {
184
+ draw(litecanvas = globalThis, saveContext = true) {
165
185
  if (this.hidden || this.opacity <= 0) return;
166
- litecanvas.push();
186
+ if (saveContext) litecanvas.push();
167
187
  this.transform(litecanvas);
168
188
  this.drawImage(litecanvas);
169
- litecanvas.pop();
189
+ if (saveContext) litecanvas.pop();
170
190
  }
171
191
  /**
172
192
  * @param {LitecanvasInstance} litecanvas
@@ -179,10 +199,10 @@
179
199
  /**
180
200
  * @param {LitecanvasInstance} litecanvas
181
201
  */
182
- drawImage(litecanvas) {
202
+ drawImage(litecanvas, alpha = true) {
183
203
  const anchorX = this.sprite.width * this.anchor.x;
184
204
  const anchorY = this.sprite.height * this.anchor.y;
185
- litecanvas.alpha(this.opacity);
205
+ if (alpha) litecanvas.alpha(this.opacity);
186
206
  litecanvas.image(-anchorX, -anchorY, this.sprite);
187
207
  }
188
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:()=>x,ANCHOR_BOT_RIGHT:()=>g,ANCHOR_CENTER:()=>d,ANCHOR_TOP_LEFT:()=>c,ANCHOR_TOP_RIGHT:()=>y,Actor:()=>i});var _=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));globalThis.zzfxV=1;var d=r(.5,.5),c=r(0,0),y=r(1,0),x=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,21 +23,36 @@
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,
@@ -591,8 +606,8 @@
591
606
  if (isVector(x)) {
592
607
  return vecDiv(v, x.x, x.y);
593
608
  }
594
- v.x /= x;
595
- v.y /= y;
609
+ v.x /= x || 1;
610
+ v.y /= y || 1;
596
611
  return v;
597
612
  };
598
613
  var vecRotate = (v, radians) => {
@@ -691,11 +706,11 @@
691
706
  globalThis.zzfxV = 1;
692
707
 
693
708
  // src/actor/index.js
694
- var ANCHOR_CENTER = vec(0.5, 0.5);
695
- var ANCHOR_TOP_LEFT = vec(0, 0);
696
- var ANCHOR_TOP_RIGHT = vec(1, 0);
697
- var ANCHOR_BOT_LEFT = vec(0, 1);
698
- 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);
699
714
  var Actor = class {
700
715
  /** @type {Image|HTMLCanvasElement|OffscreenCanvas} */
701
716
  sprite;
@@ -777,6 +792,26 @@
777
792
  get scale() {
778
793
  return this._s;
779
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
+ }
780
815
  /**
781
816
  * @returns {number[]}
782
817
  */
@@ -788,16 +823,16 @@
788
823
  return [x, y, w, h];
789
824
  }
790
825
  /**
791
- * Update the transformation matrix, sets the opacity and draw the actor sprite image.
826
+ * Draw the actor
792
827
  *
793
828
  * @param {LitecanvasInstance} [litecanvas]
794
829
  */
795
- draw(litecanvas = globalThis) {
830
+ draw(litecanvas = globalThis, saveContext = true) {
796
831
  if (this.hidden || this.opacity <= 0) return;
797
- litecanvas.push();
832
+ if (saveContext) litecanvas.push();
798
833
  this.transform(litecanvas);
799
834
  this.drawImage(litecanvas);
800
- litecanvas.pop();
835
+ if (saveContext) litecanvas.pop();
801
836
  }
802
837
  /**
803
838
  * @param {LitecanvasInstance} litecanvas
@@ -810,10 +845,10 @@
810
845
  /**
811
846
  * @param {LitecanvasInstance} litecanvas
812
847
  */
813
- drawImage(litecanvas) {
848
+ drawImage(litecanvas, alpha = true) {
814
849
  const anchorX = this.sprite.width * this.anchor.x;
815
850
  const anchorY = this.sprite.height * this.anchor.y;
816
- litecanvas.alpha(this.opacity);
851
+ if (alpha) litecanvas.alpha(this.opacity);
817
852
  litecanvas.image(-anchorX, -anchorY, this.sprite);
818
853
  }
819
854
  };
@@ -830,6 +865,165 @@
830
865
  // src/math/range.js
831
866
  var range_default = (size) => Array.from(Array(size).keys());
832
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
+
833
1027
  // src/_web.js
834
1028
  globalThis.utils = Object.assign(globalThis.utils || {}, src_exports);
835
1029
  })();
package/dist/all.min.js CHANGED
@@ -1,3 +1,3 @@
1
- (()=>{var U=Object.defineProperty;var $=(e,t)=>{for(var s in t)U(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 k={};$(k,{ANCHOR_BOT_LEFT:()=>mt,ANCHOR_BOT_RIGHT:()=>Tt,ANCHOR_CENTER:()=>yt,ANCHOR_TOP_LEFT:()=>F,ANCHOR_TOP_RIGHT:()=>_t,Actor:()=>D,Camera:()=>u,DOWN:()=>xt,Grid:()=>y,LEFT:()=>gt,ONE:()=>ut,RIGHT:()=>dt,TypedGrid:()=>E,UP:()=>pt,Vector:()=>p,ZERO:()=>B,diff:()=>G,fract:()=>j,intersection:()=>g,range:()=>z,resolve:()=>S,vec:()=>n,vecAbs:()=>rt,vecAdd:()=>b,vecAngle:()=>tt,vecAngleBetween:()=>et,vecCeil:()=>nt,vecClamp:()=>ct,vecCross:()=>st,vecDist:()=>Q,vecDist2:()=>v,vecDiv:()=>_,vecDot:()=>W,vecEq:()=>H,vecFloor:()=>at,vecIsZero:()=>ft,vecLerp:()=>it,vecLimit:()=>K,vecMag:()=>R,vecMag2:()=>Y,vecMove:()=>lt,vecMult:()=>d,vecNorm:()=>A,vecRand:()=>ot,vecReflect:()=>Z,vecRotate:()=>q,vecRound:()=>ht,vecSet:()=>P,vecSetMag:()=>J,vecSub:()=>I,wave:()=>V});var g=(e,t,s,i,o,r,a,h)=>{let c=Math.max(e,o),C=Math.min(e+s,o+a)-c,x=Math.max(t,r),m=Math.min(t+i,r+h)-x;return[c,x,C,m]};var S=(e,t,s,i,o,r,a,h)=>{let[c,C,x,m]=g(e,t,s,i,o,r,a,h),f="",T=e,w=t;return x<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 y=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 O(t,0,this._w-1)}clampY(t){return O(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
- `)}},E=class e extends y{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 O(e,t,s){return e<t?t:e>s?s:e}var M=Math.sqrt,X=Math.cos,L=Math.sin,N=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)),H=(e,t,s=t)=>l(t)?H(e,t.x,t.y):e.x===t&&e.y===s,P=(e,t,s=t)=>(l(t)?P(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),d=(e,t,s=t)=>l(t)?d(e,t.x,t.y):(e.x*=t,e.y*=s,e),_=(e,t,s=t)=>l(t)?_(e,t.x,t.y):(e.x/=t,e.y/=s,e),q=(e,t)=>{let s=X(t),i=L(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,d(s,2*W(e,s)))},J=(e,t)=>(A(e),d(e,t),e),R=e=>M(e.x*e.x+e.y*e.y),Y=e=>e.x*e.x+e.y*e.y,A=e=>{let t=R(e);return t>0&&_(e,t),e},K=(e,t=1)=>{let s=Y(e);return s>t*t&&(_(e,M(s)),d(e,t)),e},Q=(e,t)=>{let s=e.x-t.x,i=e.y-t.y;return M(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),et=(e,t)=>Math.atan2(t.y-e.y,t.x-e.x),W=(e,t)=>e.x*t.x+e.y*t.y,st=(e,t)=>e.x*t.y-e.y*t.x,it=(e,t,s)=>(e.x+=(t.x-e.x)*s||0,e.y+=(t.y-e.y)*s||0,e),ot=(e=1,t=e,s=globalThis.rand||Math.random)=>{let i=s()*N,o=s()*(t-e)+e;return n(X(i)*o,L(i)*o)},rt=e=>(e.x=Math.abs(e.x),e.y=Math.abs(e.y),e),nt=e=>(e.x=Math.ceil(e.x),e.y=Math.ceil(e.y),e),at=e=>(e.x=Math.floor(e.x),e.y=Math.floor(e.y),e),ht=e=>(e.x=Math.round(e.x),e.y=Math.round(e.y),e),ct=(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),lt=(e,t,s=1)=>b(e,t.x*s,t.y*s),ft=e=>H(e,B),B=n(0,0),ut=n(1,1),pt=n(0,-1),dt=n(1,0),xt=n(0,1),gt=n(-1,0);globalThis.zzfxV=1;var yt=n(.5,.5),F=n(0,0),_t=n(1,0),mt=n(0,1),Tt=n(1,1),D=class{sprite;pos;_o;_s;angle=0;opacity=1;hidden=!1;constructor(t,s,i=F){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 G=(e,t)=>Math.abs(t-e)||0;var V=(e,t,s,i=Math.sin)=>e+(i(s)+1)/2*(t-e);var j=e=>e%1||0;var z=e=>Array.from(Array(e).keys());globalThis.utils=Object.assign(globalThis.utils||{},k);})();
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
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
@@ -120,8 +120,8 @@
120
120
  if (isVector(x)) {
121
121
  return vecDiv(v, x.x, x.y);
122
122
  }
123
- v.x /= x;
124
- v.y /= y;
123
+ v.x /= x || 1;
124
+ v.y /= y || 1;
125
125
  return v;
126
126
  };
127
127
  var vecRotate = (v, radians) => {
@@ -1 +1 @@
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,t.y/=o,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);})();
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.14.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",
@@ -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
  }