@litecanvas/utils 0.22.0 → 0.24.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/dist/all.js +151 -13
- package/dist/all.min.js +2 -2
- package/dist/noise.js +153 -0
- package/dist/noise.min.js +1 -0
- package/dist/tween.js +20 -13
- package/dist/tween.min.js +1 -1
- package/package.json +6 -3
- package/src/collision/resolve.js +1 -1
- package/src/index.js +1 -0
- package/src/noise/README.md +74 -0
- package/src/noise/_web.js +4 -0
- package/src/noise/index.js +169 -0
- package/src/tween/README.md +15 -8
- package/src/tween/index.js +23 -16
package/dist/all.js
CHANGED
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
Grid: () => Grid,
|
|
41
41
|
LEFT: () => LEFT,
|
|
42
42
|
LINEAR: () => LINEAR,
|
|
43
|
+
Noise: () => Noise,
|
|
43
44
|
ONE: () => ONE,
|
|
44
45
|
RIGHT: () => RIGHT,
|
|
45
46
|
TypedGrid: () => TypedGrid,
|
|
@@ -1015,14 +1016,15 @@
|
|
|
1015
1016
|
}
|
|
1016
1017
|
/**
|
|
1017
1018
|
* @param {LitecanvasInstance} [engine]
|
|
1018
|
-
* @returns {
|
|
1019
|
+
* @returns {this}
|
|
1019
1020
|
*/
|
|
1020
1021
|
start(engine) {
|
|
1021
|
-
if (
|
|
1022
|
-
this
|
|
1022
|
+
if (this.running) {
|
|
1023
|
+
return this;
|
|
1023
1024
|
}
|
|
1024
1025
|
this._cu.stop(false);
|
|
1025
1026
|
this._ch = this._cu = this;
|
|
1027
|
+
this.running = true;
|
|
1026
1028
|
const fromValue = this._o[this._p] || 0;
|
|
1027
1029
|
const toValue = this._rel ? fromValue + this._x : this._x;
|
|
1028
1030
|
this._lc = this._lc || engine || globalThis;
|
|
@@ -1039,15 +1041,6 @@
|
|
|
1039
1041
|
this.stop();
|
|
1040
1042
|
}
|
|
1041
1043
|
});
|
|
1042
|
-
this.running = true;
|
|
1043
|
-
return this;
|
|
1044
|
-
}
|
|
1045
|
-
/**
|
|
1046
|
-
* @param {Function} callback
|
|
1047
|
-
* @returns {this}
|
|
1048
|
-
*/
|
|
1049
|
-
onEnd(callback) {
|
|
1050
|
-
this._cb.push(callback);
|
|
1051
1044
|
return this;
|
|
1052
1045
|
}
|
|
1053
1046
|
/**
|
|
@@ -1055,7 +1048,7 @@
|
|
|
1055
1048
|
* @returns {this}
|
|
1056
1049
|
*/
|
|
1057
1050
|
stop(completed = true) {
|
|
1058
|
-
if (!this.
|
|
1051
|
+
if (!this._u) return this;
|
|
1059
1052
|
this.running = false;
|
|
1060
1053
|
this._u();
|
|
1061
1054
|
this._t = 0;
|
|
@@ -1066,6 +1059,21 @@
|
|
|
1066
1059
|
}
|
|
1067
1060
|
return this;
|
|
1068
1061
|
}
|
|
1062
|
+
/**
|
|
1063
|
+
* @param {LitecanvasInstance} [engine]
|
|
1064
|
+
* @returns {this}
|
|
1065
|
+
*/
|
|
1066
|
+
restart(engine = null, completed = false) {
|
|
1067
|
+
return this.stop(completed).restart(engine);
|
|
1068
|
+
}
|
|
1069
|
+
/**
|
|
1070
|
+
* @param {Function} callback
|
|
1071
|
+
* @returns {this}
|
|
1072
|
+
*/
|
|
1073
|
+
onEnd(callback) {
|
|
1074
|
+
this._cb.push(callback);
|
|
1075
|
+
return this;
|
|
1076
|
+
}
|
|
1069
1077
|
/**
|
|
1070
1078
|
* @param {TweenController} another
|
|
1071
1079
|
* @returns {this}
|
|
@@ -1120,6 +1128,136 @@
|
|
|
1120
1128
|
}
|
|
1121
1129
|
};
|
|
1122
1130
|
|
|
1131
|
+
// src/noise/index.js
|
|
1132
|
+
var PERLIN_YWRAPB = 4;
|
|
1133
|
+
var PERLIN_YWRAP = 1 << PERLIN_YWRAPB;
|
|
1134
|
+
var PERLIN_ZWRAPB = 8;
|
|
1135
|
+
var PERLIN_ZWRAP = 1 << PERLIN_ZWRAPB;
|
|
1136
|
+
var PERLIN_SIZE = 4095;
|
|
1137
|
+
var scaled_cosine = (i) => 0.5 * (1 - Math.cos(i * Math.PI));
|
|
1138
|
+
var Noise = class {
|
|
1139
|
+
/**
|
|
1140
|
+
* Array to store Perlin noise values.
|
|
1141
|
+
* @type {number[]}
|
|
1142
|
+
* @private
|
|
1143
|
+
*/
|
|
1144
|
+
_p = [];
|
|
1145
|
+
/**
|
|
1146
|
+
* Number of octaves for the Perlin noise. Higher values create more detail.
|
|
1147
|
+
* @type {number}
|
|
1148
|
+
* @private
|
|
1149
|
+
*/
|
|
1150
|
+
_po = 4;
|
|
1151
|
+
/**
|
|
1152
|
+
* Amplitude falloff factor for Perlin noise. Determines the reduction of amplitude per octave.
|
|
1153
|
+
* @type {number}
|
|
1154
|
+
* @private
|
|
1155
|
+
*/
|
|
1156
|
+
_pf = 0.5;
|
|
1157
|
+
/**
|
|
1158
|
+
* @type {LitecanvasInstance}
|
|
1159
|
+
* @private
|
|
1160
|
+
*/
|
|
1161
|
+
_e = null;
|
|
1162
|
+
/**
|
|
1163
|
+
* @param {LitecanvasInstance} engine
|
|
1164
|
+
*/
|
|
1165
|
+
constructor(engine) {
|
|
1166
|
+
this._e = engine || globalThis;
|
|
1167
|
+
this.noiseSeed();
|
|
1168
|
+
}
|
|
1169
|
+
/**
|
|
1170
|
+
* Generates Perlin noise for the given coordinates.
|
|
1171
|
+
* @param {number} x - X-coordinate.
|
|
1172
|
+
* @param {number} [y=0] - Y-coordinate (default is 0).
|
|
1173
|
+
* @param {number} [z=0] - Z-coordinate (default is 0).
|
|
1174
|
+
* @returns {number} A noise value in the range [0, 1).
|
|
1175
|
+
*/
|
|
1176
|
+
noise(x, y = 0, z = 0) {
|
|
1177
|
+
if (x < 0) {
|
|
1178
|
+
x = -x;
|
|
1179
|
+
}
|
|
1180
|
+
if (y < 0) {
|
|
1181
|
+
y = -y;
|
|
1182
|
+
}
|
|
1183
|
+
if (z < 0) {
|
|
1184
|
+
z = -z;
|
|
1185
|
+
}
|
|
1186
|
+
let xi = Math.floor(x), yi = Math.floor(y), zi = Math.floor(z);
|
|
1187
|
+
let xf = x - xi;
|
|
1188
|
+
let yf = y - yi;
|
|
1189
|
+
let zf = z - zi;
|
|
1190
|
+
let rxf, ryf;
|
|
1191
|
+
let r = 0;
|
|
1192
|
+
let ampl = 0.5;
|
|
1193
|
+
let n1, n2, n3;
|
|
1194
|
+
for (let o = 0; o < this._po; o++) {
|
|
1195
|
+
let of = xi + (yi << PERLIN_YWRAPB) + (zi << PERLIN_ZWRAPB);
|
|
1196
|
+
rxf = scaled_cosine(xf);
|
|
1197
|
+
ryf = scaled_cosine(yf);
|
|
1198
|
+
n1 = this._p[of & PERLIN_SIZE];
|
|
1199
|
+
n1 += rxf * (this._p[of + 1 & PERLIN_SIZE] - n1);
|
|
1200
|
+
n2 = this._p[of + PERLIN_YWRAP & PERLIN_SIZE];
|
|
1201
|
+
n2 += rxf * (this._p[of + PERLIN_YWRAP + 1 & PERLIN_SIZE] - n2);
|
|
1202
|
+
n1 += ryf * (n2 - n1);
|
|
1203
|
+
of += PERLIN_ZWRAP;
|
|
1204
|
+
n2 = this._p[of & PERLIN_SIZE];
|
|
1205
|
+
n2 += rxf * (this._p[of + 1 & PERLIN_SIZE] - n2);
|
|
1206
|
+
n3 = this._p[of + PERLIN_YWRAP & PERLIN_SIZE];
|
|
1207
|
+
n3 += rxf * (this._p[of + PERLIN_YWRAP + 1 & PERLIN_SIZE] - n3);
|
|
1208
|
+
n2 += ryf * (n3 - n2);
|
|
1209
|
+
n1 += scaled_cosine(zf) * (n2 - n1);
|
|
1210
|
+
r += n1 * ampl;
|
|
1211
|
+
ampl *= this._pf;
|
|
1212
|
+
xi <<= 1;
|
|
1213
|
+
xf *= 2;
|
|
1214
|
+
yi <<= 1;
|
|
1215
|
+
yf *= 2;
|
|
1216
|
+
zi <<= 1;
|
|
1217
|
+
zf *= 2;
|
|
1218
|
+
if (xf >= 1) {
|
|
1219
|
+
xi++;
|
|
1220
|
+
xf--;
|
|
1221
|
+
}
|
|
1222
|
+
if (yf >= 1) {
|
|
1223
|
+
yi++;
|
|
1224
|
+
yf--;
|
|
1225
|
+
}
|
|
1226
|
+
if (zf >= 1) {
|
|
1227
|
+
zi++;
|
|
1228
|
+
zf--;
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
return r;
|
|
1232
|
+
}
|
|
1233
|
+
/**
|
|
1234
|
+
* Adjusts the detail level of the noise by setting the number of octaves and amplitude falloff.
|
|
1235
|
+
* @param {number} lod - Level of detail (number of octaves).
|
|
1236
|
+
* @param {number} falloff - Amplitude falloff per octave.
|
|
1237
|
+
*/
|
|
1238
|
+
noiseDetail(lod, falloff) {
|
|
1239
|
+
if (lod > 0) {
|
|
1240
|
+
this._po = lod;
|
|
1241
|
+
}
|
|
1242
|
+
if (falloff > 0) {
|
|
1243
|
+
this._pf = falloff;
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
/**
|
|
1247
|
+
* Sets a seed for the Perlin noise generator, ensuring deterministic results.
|
|
1248
|
+
* @param {number} value - Seed value.
|
|
1249
|
+
*/
|
|
1250
|
+
noiseSeed(value = null) {
|
|
1251
|
+
if (value != null) {
|
|
1252
|
+
this._e.seed(value);
|
|
1253
|
+
}
|
|
1254
|
+
const random = this._e.rand || Math.random;
|
|
1255
|
+
for (let i = 0; i < PERLIN_SIZE + 1; i++) {
|
|
1256
|
+
this._p[i] = random();
|
|
1257
|
+
}
|
|
1258
|
+
}
|
|
1259
|
+
};
|
|
1260
|
+
|
|
1123
1261
|
// src/_web.js
|
|
1124
1262
|
globalThis.utils = Object.assign(globalThis.utils || {}, src_exports);
|
|
1125
1263
|
})();
|
package/dist/all.min.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
(()=>{var
|
|
2
|
-
`)}},
|
|
1
|
+
(()=>{var at=Object.defineProperty;var ct=(e,t)=>{for(var s in t)at(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 B={};ct(B,{ANCHOR_BOT_LEFT:()=>Xt,ANCHOR_BOT_RIGHT:()=>Yt,ANCHOR_CENTER:()=>Lt,ANCHOR_TOP_LEFT:()=>J,ANCHOR_TOP_RIGHT:()=>Rt,Actor:()=>R,BACK_IN:()=>Ft,BACK_IN_OUT:()=>Vt,BACK_OUT:()=>Gt,BOUNCE_IN:()=>ot,BOUNCE_IN_OUT:()=>zt,BOUNCE_OUT:()=>Y,Camera:()=>T,DOWN:()=>Ct,EASE_IN:()=>Wt,EASE_IN_OUT:()=>Ut,EASE_OUT:()=>Bt,ELASTIC_IN:()=>jt,ELASTIC_IN_OUT:()=>Zt,ELASTIC_OUT:()=>$t,Grid:()=>b,LEFT:()=>kt,LINEAR:()=>rt,Noise:()=>W,ONE:()=>St,RIGHT:()=>Pt,TypedGrid:()=>S,UP:()=>Dt,Vector:()=>w,ZERO:()=>K,advance:()=>st,diff:()=>Q,fract:()=>tt,intersection:()=>I,mod:()=>it,range:()=>et,resolve:()=>F,tween:()=>Nt,vec:()=>n,vecAbs:()=>Et,vecAdd:()=>C,vecAngle:()=>gt,vecAngleBetween:()=>yt,vecCeil:()=>Mt,vecClamp:()=>Ht,vecCross:()=>mt,vecDist:()=>dt,vecDist2:()=>xt,vecDiv:()=>H,vecDot:()=>q,vecEq:()=>P,vecFloor:()=>It,vecIsZero:()=>Ot,vecLerp:()=>Tt,vecLimit:()=>_t,vecMag:()=>Z,vecMag2:()=>z,vecMove:()=>At,vecMult:()=>E,vecNorm:()=>L,vecRand:()=>wt,vecReflect:()=>ft,vecRotate:()=>ut,vecRound:()=>bt,vecSet:()=>$,vecSetMag:()=>pt,vecSub:()=>k,wave:()=>v});var I=(e,t,s,i,r,o,h,a)=>{let c=Math.max(e,r),x=Math.min(e+s,r+h)-c,u=Math.max(t,o),g=Math.min(t+i,o+a)-u;return[c,u,x,g]};var F=(e,t,s,i,r,o,h,a)=>{let[c,x,u,g]=I(e,t,s,i,r,o,h,a),d="",m=e,l=t;return u<g?e<r?(d="right",m=r-s):(d="left",m=r+h):t<o?(d="bottom",l=o-i):(d="top",l=o+a),{direction:d,x:m,y:l}};var T=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,r=null,o=null){this._engine=t||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(t,s){this.width=t,this.height=s,this._engine.emit("camera-resized",this)}start(t=!1){if(this._engine.push(),t){let r=path();r.rect(this.ox,this.oy,this.width,this.height),this._engine.clip(r)}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 r=Math.cos(-this.rotation),o=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=r*t-o*s+this.x,i.y=o*t+r*s+this.y,i}getCameraPoint(t,s,i={}){let r=Math.cos(-this.rotation),o=Math.sin(-this.rotation);return t=t-this.x,s=s-this.y,t=r*t-o*s,s=o*t+r*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,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(t,s,i,r,o,h,a,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 b=class e{_w;_h;_c;constructor(t,s,i=[]){this._w=Math.max(1,~~t),this._h=Math.max(1,~~s),this._c=i}[Symbol.iterator](){let t=0;return{next:()=>({value:[this.indexToPointX(t),this.indexToPointY(t),this._c[t++]],done:t>this._c.length})}}clone(){return new e(this._w,this._h,this._c)}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}check(t,s){return t>=0&&t<this._w&&s>=0&&s<this._h}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,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(t(h,a,c,this)===!1)break;i+=o}}fill(t){this.forEach((s,i)=>{this.set(s,i,t)})}clampX(t){return G(t,0,this._w-1)}clampY(t){return G(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((r,o,h)=>{i[o]=i[o]||"",i[o]+=h+t}),i.join(`
|
|
2
|
+
`)}},S=class e extends b{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,r)=>{t.set(s,i,r)}),t}};function G(e,t,s){return e<t?t:e>s?s:e}var D=Math.sqrt,V=Math.cos,j=Math.sin,lt=2*Math.PI,w=class{x;y;constructor(t=0,s=t){this.x=t,this.y=s}toString(){return`Vector (${this.x}, ${this.y})`}},y=e=>e instanceof w,n=(e=0,t=e)=>(y(e)&&(t=e.y,e=e.x),new w(e,t)),P=(e,t,s=t)=>y(t)?P(e,t.x,t.y):e.x===t&&e.y===s,$=(e,t,s=t)=>(y(t)?$(e,t.x,t.y):(e.x=t,e.y=s),e),C=(e,t,s=t)=>y(t)?C(e,t.x,t.y):(e.x+=t,e.y+=s,e),k=(e,t,s=t)=>y(t)?k(e,t.x,t.y):(e.x-=t,e.y-=s,e),E=(e,t,s=t)=>y(t)?E(e,t.x,t.y):(e.x*=t,e.y*=s,e),H=(e,t,s=t)=>y(t)?H(e,t.x,t.y):(e.x/=t||1,e.y/=s||1,e),ut=(e,t)=>{let s=V(t),i=j(t);return e.x=s*e.x-i*e.y,e.y=i*e.x+s*e.y,e},ft=(e,t)=>{let s=L(n(t));return k(e,E(s,2*q(e,s)))},pt=(e,t)=>(L(e),E(e,t),e),Z=e=>D(e.x*e.x+e.y*e.y),z=e=>e.x*e.x+e.y*e.y,L=e=>{let t=Z(e);return t>0&&H(e,t),e},_t=(e,t=1)=>{let s=z(e);return s>t*t&&(H(e,D(s)),E(e,t)),e},dt=(e,t)=>{let s=e.x-t.x,i=e.y-t.y;return D(s*s+i*i)},xt=(e,t)=>{let s=e.x-t.x,i=e.y-t.y;return s*s+i*i},gt=e=>Math.atan2(e.y,e.x),yt=(e,t)=>Math.atan2(t.y-e.y,t.x-e.x),q=(e,t)=>e.x*t.x+e.y*t.y,mt=(e,t)=>e.x*t.y-e.y*t.x,Tt=(e,t,s)=>(e.x+=(t.x-e.x)*s||0,e.y+=(t.y-e.y)*s||0,e),wt=(e=1,t=e,s=globalThis.rand||Math.random)=>{let i=s()*lt,r=s()*(t-e)+e;return n(V(i)*r,j(i)*r)},Et=e=>(e.x=Math.abs(e.x),e.y=Math.abs(e.y),e),Mt=e=>(e.x=Math.ceil(e.x),e.y=Math.ceil(e.y),e),It=e=>(e.x=Math.floor(e.x),e.y=Math.floor(e.y),e),bt=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),At=(e,t,s=1)=>C(e,t.x*s,t.y*s),Ot=e=>P(e,K),K=n(0,0),St=n(1,1),Dt=n(0,-1),Pt=n(1,0),Ct=n(0,1),kt=n(-1,0);var Lt=n(.5,.5),J=n(0,0),Rt=n(1,0),Xt=n(0,1),Yt=n(1,1),R=class{sprite;pos;_o;_s;flipX=!1;flipY=!1;angle=0;opacity=1;hidden=!1;constructor(t,s,i=J){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}scaleTo(t,s=t){this._s.x=t,this._s.y=s}scaleBy(t,s=t){this._s.x*=t,this._s.y*=s}getBounds(t=!0){let s=this.sprite.width*(t?this._s.x:1),i=this.sprite.height*(t?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(t=globalThis,s=!0){this.hidden||this.opacity<=0||(s&&t.push(),this.transform(t),this.drawImage(t),s&&t.pop())}transform(t){t.translate(this.pos.x,this.pos.y),t.rotate(t.deg2rad(this.angle)),t.scale((this.flipX?-1:1)*this._s.x,(this.flipY?-1:1)*this._s.y)}drawImage(t,s=!0){let i=this.anchor,r=-this.sprite.width*(this.flipX?1-i.x:i.x),o=-this.sprite.height*(this.flipY?1-i.y:i.y);s&&t.alpha(this.opacity),t.image(r,o,this.sprite)}};var Q=(e,t)=>Math.abs(t-e)||0;var v=(e,t,s,i=Math.sin)=>e+(i(s)+1)/2*(t-e);var tt=e=>e%1||0;var et=e=>Array.from(Array(e).keys());var st=advance=(e,t,s,i=1)=>{s&&(t.x+=s.x*i,t.y+=s.y*i),e.x+=t.x*i,e.y+=t.y*i};var it=(e,t)=>(t+e%t)%t;var A=Math.PI/2,Nt=(e,t,s,i=1,r=rt)=>new X(e,t,s,i,r),rt=e=>e,Wt=e=>e*e,Bt=e=>-e*(e-2),Ut=e=>e<.5?2*e*e:-2*e*e+4*e-1,Ft=e=>e*e*e-e*Math.sin(e*Math.PI),Gt=e=>{let t=1-e;return 1-(t*t*t-t*Math.sin(t*Math.PI))},Vt=e=>{if(e<.5){let s=2*e;return .5*(s*s*s-s*Math.sin(s*Math.PI))}let t=1-(2*e-1);return .5*(1-(t*t*t-t*Math.sin(e*Math.PI)))+.5},jt=e=>Math.sin(13*A*e)*Math.pow(2,10*(e-1)),$t=e=>Math.sin(-13*A*(e+1))*Math.pow(2,-10*e)+1,Zt=e=>{if(e<.5){let i=Math.sin(13*A*(2*e)),r=Math.pow(2,10*(2*e-1));return .5*i*r}let t=Math.sin(-13*A*(2*e-1+1)),s=Math.pow(2,-10*(2*e-1));return .5*(t*s+2)},ot=e=>1-Y(1-e),Y=e=>e<4/11?121*e*e/16:e<8/11?363/40*e*e-99/10*e+17/5:e<9/10?4356/361*e*e-35442/1805*e+16061/1805:54/5*e*e-513/25*e+268/25,zt=e=>e<.5?.5*ot(e*2):.5*Y(e*2-1)+.5,X=class{running=!1;_o;_p;_x;_d;_w;_e;_rel;_cb=[];_t=0;_u=0;_ch=this;_cu=this;_lc;constructor(t,s,i,r,o){this._o=t,this._p=s,this._x=i,this._d=r,this._e=o,this._w=0}start(t){if(this.running)return this;this._cu.stop(!1),this._ch=this._cu=this,this.running=!0;let s=this._o[this._p]||0,i=this._rel?s+this._x:this._x;return this._lc=this._lc||t||globalThis,this._u=this._lc.listen("update",r=>{if(this._t<=this._w){this._t+=r;return}let o=this._t-this._w;this._o[this._p]=this._lc.lerp(s,i,this._e(o/this._d)),this._t+=r,o>=this._d&&(this._o[this._p]=i,this.stop())}),this}stop(t=!0){if(!this._u)return this;if(this.running=!1,this._u(),this._t=0,t)for(let s of this._cb)s(this._o);return this}restart(t=null,s=!1){return this.stop(s).restart(t)}onEnd(t){return this._cb.push(t),this}chain(t){return this._ch.onEnd(()=>{this._cu=t.start(this._lc)}),this._ch=t,this}reset(){return this._cb.length=0,this.stop()}relative(t=!0){return this._rel=t,this}delay(t){return this._w=t,this}get current(){return this._cu}get progress(){return this.running&&this._t>this._w?(this._t-this._w)/this._d:0}};var nt=4,O=1<<nt,ht=8,qt=1<<ht,_=4095,N=e=>.5*(1-Math.cos(e*Math.PI)),W=class{_p=[];_po=4;_pf=.5;_e=null;constructor(t){this._e=t||globalThis,this.noiseSeed()}noise(t,s=0,i=0){t<0&&(t=-t),s<0&&(s=-s),i<0&&(i=-i);let r=Math.floor(t),o=Math.floor(s),h=Math.floor(i),a=t-r,c=s-o,x=i-h,u,g,d=0,m=.5,l,f,M;for(let U=0;U<this._po;U++){let p=r+(o<<nt)+(h<<ht);u=N(a),g=N(c),l=this._p[p&_],l+=u*(this._p[p+1&_]-l),f=this._p[p+O&_],f+=u*(this._p[p+O+1&_]-f),l+=g*(f-l),p+=qt,f=this._p[p&_],f+=u*(this._p[p+1&_]-f),M=this._p[p+O&_],M+=u*(this._p[p+O+1&_]-M),f+=g*(M-f),l+=N(x)*(f-l),d+=l*m,m*=this._pf,r<<=1,a*=2,o<<=1,c*=2,h<<=1,x*=2,a>=1&&(r++,a--),c>=1&&(o++,c--),x>=1&&(h++,x--)}return d}noiseDetail(t,s){t>0&&(this._po=t),s>0&&(this._pf=s)}noiseSeed(t=null){t!=null&&this._e.seed(t);let s=this._e.rand||Math.random;for(let i=0;i<_+1;i++)this._p[i]=s()}};globalThis.utils=Object.assign(globalThis.utils||{},B);})();
|
|
3
3
|
/*! @litecanvas/utils by Luiz Bills | MIT Licensed */
|
package/dist/noise.js
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
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/noise/index.js
|
|
18
|
+
var noise_exports = {};
|
|
19
|
+
__export(noise_exports, {
|
|
20
|
+
Noise: () => Noise
|
|
21
|
+
});
|
|
22
|
+
var PERLIN_YWRAPB = 4;
|
|
23
|
+
var PERLIN_YWRAP = 1 << PERLIN_YWRAPB;
|
|
24
|
+
var PERLIN_ZWRAPB = 8;
|
|
25
|
+
var PERLIN_ZWRAP = 1 << PERLIN_ZWRAPB;
|
|
26
|
+
var PERLIN_SIZE = 4095;
|
|
27
|
+
var scaled_cosine = (i) => 0.5 * (1 - Math.cos(i * Math.PI));
|
|
28
|
+
var Noise = class {
|
|
29
|
+
/**
|
|
30
|
+
* Array to store Perlin noise values.
|
|
31
|
+
* @type {number[]}
|
|
32
|
+
* @private
|
|
33
|
+
*/
|
|
34
|
+
_p = [];
|
|
35
|
+
/**
|
|
36
|
+
* Number of octaves for the Perlin noise. Higher values create more detail.
|
|
37
|
+
* @type {number}
|
|
38
|
+
* @private
|
|
39
|
+
*/
|
|
40
|
+
_po = 4;
|
|
41
|
+
/**
|
|
42
|
+
* Amplitude falloff factor for Perlin noise. Determines the reduction of amplitude per octave.
|
|
43
|
+
* @type {number}
|
|
44
|
+
* @private
|
|
45
|
+
*/
|
|
46
|
+
_pf = 0.5;
|
|
47
|
+
/**
|
|
48
|
+
* @type {LitecanvasInstance}
|
|
49
|
+
* @private
|
|
50
|
+
*/
|
|
51
|
+
_e = null;
|
|
52
|
+
/**
|
|
53
|
+
* @param {LitecanvasInstance} engine
|
|
54
|
+
*/
|
|
55
|
+
constructor(engine) {
|
|
56
|
+
this._e = engine || globalThis;
|
|
57
|
+
this.noiseSeed();
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Generates Perlin noise for the given coordinates.
|
|
61
|
+
* @param {number} x - X-coordinate.
|
|
62
|
+
* @param {number} [y=0] - Y-coordinate (default is 0).
|
|
63
|
+
* @param {number} [z=0] - Z-coordinate (default is 0).
|
|
64
|
+
* @returns {number} A noise value in the range [0, 1).
|
|
65
|
+
*/
|
|
66
|
+
noise(x, y = 0, z = 0) {
|
|
67
|
+
if (x < 0) {
|
|
68
|
+
x = -x;
|
|
69
|
+
}
|
|
70
|
+
if (y < 0) {
|
|
71
|
+
y = -y;
|
|
72
|
+
}
|
|
73
|
+
if (z < 0) {
|
|
74
|
+
z = -z;
|
|
75
|
+
}
|
|
76
|
+
let xi = Math.floor(x), yi = Math.floor(y), zi = Math.floor(z);
|
|
77
|
+
let xf = x - xi;
|
|
78
|
+
let yf = y - yi;
|
|
79
|
+
let zf = z - zi;
|
|
80
|
+
let rxf, ryf;
|
|
81
|
+
let r = 0;
|
|
82
|
+
let ampl = 0.5;
|
|
83
|
+
let n1, n2, n3;
|
|
84
|
+
for (let o = 0; o < this._po; o++) {
|
|
85
|
+
let of = xi + (yi << PERLIN_YWRAPB) + (zi << PERLIN_ZWRAPB);
|
|
86
|
+
rxf = scaled_cosine(xf);
|
|
87
|
+
ryf = scaled_cosine(yf);
|
|
88
|
+
n1 = this._p[of & PERLIN_SIZE];
|
|
89
|
+
n1 += rxf * (this._p[of + 1 & PERLIN_SIZE] - n1);
|
|
90
|
+
n2 = this._p[of + PERLIN_YWRAP & PERLIN_SIZE];
|
|
91
|
+
n2 += rxf * (this._p[of + PERLIN_YWRAP + 1 & PERLIN_SIZE] - n2);
|
|
92
|
+
n1 += ryf * (n2 - n1);
|
|
93
|
+
of += PERLIN_ZWRAP;
|
|
94
|
+
n2 = this._p[of & PERLIN_SIZE];
|
|
95
|
+
n2 += rxf * (this._p[of + 1 & PERLIN_SIZE] - n2);
|
|
96
|
+
n3 = this._p[of + PERLIN_YWRAP & PERLIN_SIZE];
|
|
97
|
+
n3 += rxf * (this._p[of + PERLIN_YWRAP + 1 & PERLIN_SIZE] - n3);
|
|
98
|
+
n2 += ryf * (n3 - n2);
|
|
99
|
+
n1 += scaled_cosine(zf) * (n2 - n1);
|
|
100
|
+
r += n1 * ampl;
|
|
101
|
+
ampl *= this._pf;
|
|
102
|
+
xi <<= 1;
|
|
103
|
+
xf *= 2;
|
|
104
|
+
yi <<= 1;
|
|
105
|
+
yf *= 2;
|
|
106
|
+
zi <<= 1;
|
|
107
|
+
zf *= 2;
|
|
108
|
+
if (xf >= 1) {
|
|
109
|
+
xi++;
|
|
110
|
+
xf--;
|
|
111
|
+
}
|
|
112
|
+
if (yf >= 1) {
|
|
113
|
+
yi++;
|
|
114
|
+
yf--;
|
|
115
|
+
}
|
|
116
|
+
if (zf >= 1) {
|
|
117
|
+
zi++;
|
|
118
|
+
zf--;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return r;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Adjusts the detail level of the noise by setting the number of octaves and amplitude falloff.
|
|
125
|
+
* @param {number} lod - Level of detail (number of octaves).
|
|
126
|
+
* @param {number} falloff - Amplitude falloff per octave.
|
|
127
|
+
*/
|
|
128
|
+
noiseDetail(lod, falloff) {
|
|
129
|
+
if (lod > 0) {
|
|
130
|
+
this._po = lod;
|
|
131
|
+
}
|
|
132
|
+
if (falloff > 0) {
|
|
133
|
+
this._pf = falloff;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Sets a seed for the Perlin noise generator, ensuring deterministic results.
|
|
138
|
+
* @param {number} value - Seed value.
|
|
139
|
+
*/
|
|
140
|
+
noiseSeed(value = null) {
|
|
141
|
+
if (value != null) {
|
|
142
|
+
this._e.seed(value);
|
|
143
|
+
}
|
|
144
|
+
const random = this._e.rand || Math.random;
|
|
145
|
+
for (let i = 0; i < PERLIN_SIZE + 1; i++) {
|
|
146
|
+
this._p[i] = random();
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
// src/noise/_web.js
|
|
152
|
+
globalThis.utils = Object.assign(globalThis.utils || {}, noise_exports);
|
|
153
|
+
})();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(()=>{var w=Object.defineProperty;var S=(s,t)=>{for(var e in t)w(s,e,{get:t[e],enumerable:!0})};globalThis.utils=globalThis.utils||{};globalThis.utils.global=()=>{for(let s in globalThis.utils)s!=="global"&&(globalThis[s]=globalThis.utils[s])};var b={};S(b,{Noise:()=>E});var H=4,_=1<<H,D=8,v=1<<D,a=4095,T=s=>.5*(1-Math.cos(s*Math.PI)),E=class{_p=[];_po=4;_pf=.5;_e=null;constructor(t){this._e=t||globalThis,this.noiseSeed()}noise(t,e=0,n=0){t<0&&(t=-t),e<0&&(e=-e),n<0&&(n=-n);let c=Math.floor(t),f=Math.floor(e),u=Math.floor(n),p=t-c,h=e-f,d=n-u,r,m,y=0,x=.5,l,o,g;for(let I=0;I<this._po;I++){let i=c+(f<<H)+(u<<D);r=T(p),m=T(h),l=this._p[i&a],l+=r*(this._p[i+1&a]-l),o=this._p[i+_&a],o+=r*(this._p[i+_+1&a]-o),l+=m*(o-l),i+=v,o=this._p[i&a],o+=r*(this._p[i+1&a]-o),g=this._p[i+_&a],g+=r*(this._p[i+_+1&a]-g),o+=m*(g-o),l+=T(d)*(o-l),y+=l*x,x*=this._pf,c<<=1,p*=2,f<<=1,h*=2,u<<=1,d*=2,p>=1&&(c++,p--),h>=1&&(f++,h--),d>=1&&(u++,d--)}return y}noiseDetail(t,e){t>0&&(this._po=t),e>0&&(this._pf=e)}noiseSeed(t=null){t!=null&&this._e.seed(t);let e=this._e.rand||Math.random;for(let n=0;n<a+1;n++)this._p[n]=e()}};globalThis.utils=Object.assign(globalThis.utils||{},b);})();
|
package/dist/tween.js
CHANGED
|
@@ -137,14 +137,15 @@
|
|
|
137
137
|
}
|
|
138
138
|
/**
|
|
139
139
|
* @param {LitecanvasInstance} [engine]
|
|
140
|
-
* @returns {
|
|
140
|
+
* @returns {this}
|
|
141
141
|
*/
|
|
142
142
|
start(engine) {
|
|
143
|
-
if (
|
|
144
|
-
this
|
|
143
|
+
if (this.running) {
|
|
144
|
+
return this;
|
|
145
145
|
}
|
|
146
146
|
this._cu.stop(false);
|
|
147
147
|
this._ch = this._cu = this;
|
|
148
|
+
this.running = true;
|
|
148
149
|
const fromValue = this._o[this._p] || 0;
|
|
149
150
|
const toValue = this._rel ? fromValue + this._x : this._x;
|
|
150
151
|
this._lc = this._lc || engine || globalThis;
|
|
@@ -161,15 +162,6 @@
|
|
|
161
162
|
this.stop();
|
|
162
163
|
}
|
|
163
164
|
});
|
|
164
|
-
this.running = true;
|
|
165
|
-
return this;
|
|
166
|
-
}
|
|
167
|
-
/**
|
|
168
|
-
* @param {Function} callback
|
|
169
|
-
* @returns {this}
|
|
170
|
-
*/
|
|
171
|
-
onEnd(callback) {
|
|
172
|
-
this._cb.push(callback);
|
|
173
165
|
return this;
|
|
174
166
|
}
|
|
175
167
|
/**
|
|
@@ -177,7 +169,7 @@
|
|
|
177
169
|
* @returns {this}
|
|
178
170
|
*/
|
|
179
171
|
stop(completed = true) {
|
|
180
|
-
if (!this.
|
|
172
|
+
if (!this._u) return this;
|
|
181
173
|
this.running = false;
|
|
182
174
|
this._u();
|
|
183
175
|
this._t = 0;
|
|
@@ -188,6 +180,21 @@
|
|
|
188
180
|
}
|
|
189
181
|
return this;
|
|
190
182
|
}
|
|
183
|
+
/**
|
|
184
|
+
* @param {LitecanvasInstance} [engine]
|
|
185
|
+
* @returns {this}
|
|
186
|
+
*/
|
|
187
|
+
restart(engine = null, completed = false) {
|
|
188
|
+
return this.stop(completed).restart(engine);
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* @param {Function} callback
|
|
192
|
+
* @returns {this}
|
|
193
|
+
*/
|
|
194
|
+
onEnd(callback) {
|
|
195
|
+
this._cb.push(callback);
|
|
196
|
+
return this;
|
|
197
|
+
}
|
|
191
198
|
/**
|
|
192
199
|
* @param {TweenController} another
|
|
193
200
|
* @returns {this}
|
package/dist/tween.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{var h=Object.defineProperty;var p=(t,e)=>{for(var s in e)h(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 c={};p(c,{BACK_IN:()=>E,BACK_IN_OUT:()=>m,BACK_OUT:()=>x,BOUNCE_IN:()=>f,BOUNCE_IN_OUT:()=>y,BOUNCE_OUT:()=>l,EASE_IN:()=>d,EASE_IN_OUT:()=>T,EASE_OUT:()=>g,ELASTIC_IN:()=>I,ELASTIC_IN_OUT:()=>w,ELASTIC_OUT:()=>b,LINEAR:()=>u,tween:()=>_});var n=Math.PI/2,_=(t,e,s,i=1,
|
|
1
|
+
(()=>{var h=Object.defineProperty;var p=(t,e)=>{for(var s in e)h(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 c={};p(c,{BACK_IN:()=>E,BACK_IN_OUT:()=>m,BACK_OUT:()=>x,BOUNCE_IN:()=>f,BOUNCE_IN_OUT:()=>y,BOUNCE_OUT:()=>l,EASE_IN:()=>d,EASE_IN_OUT:()=>T,EASE_OUT:()=>g,ELASTIC_IN:()=>I,ELASTIC_IN_OUT:()=>w,ELASTIC_OUT:()=>b,LINEAR:()=>u,tween:()=>_});var n=Math.PI/2,_=(t,e,s,i=1,r=u)=>new a(t,e,s,i,r),u=t=>t,d=t=>t*t,g=t=>-t*(t-2),T=t=>t<.5?2*t*t:-2*t*t+4*t-1,E=t=>t*t*t-t*Math.sin(t*Math.PI),x=t=>{let e=1-t;return 1-(e*e*e-e*Math.sin(e*Math.PI))},m=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},I=t=>Math.sin(13*n*t)*Math.pow(2,10*(t-1)),b=t=>Math.sin(-13*n*(t+1))*Math.pow(2,-10*t)+1,w=t=>{if(t<.5){let i=Math.sin(13*n*(2*t)),r=Math.pow(2,10*(2*t-1));return .5*i*r}let e=Math.sin(-13*n*(2*t-1+1)),s=Math.pow(2,-10*(2*t-1));return .5*(e*s+2)},f=t=>1-l(1-t),l=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,y=t=>t<.5?.5*f(t*2):.5*l(t*2-1)+.5,a=class{running=!1;_o;_p;_x;_d;_w;_e;_rel;_cb=[];_t=0;_u=0;_ch=this;_cu=this;_lc;constructor(e,s,i,r,o){this._o=e,this._p=s,this._x=i,this._d=r,this._e=o,this._w=0}start(e){if(this.running)return this;this._cu.stop(!1),this._ch=this._cu=this,this.running=!0;let s=this._o[this._p]||0,i=this._rel?s+this._x:this._x;return this._lc=this._lc||e||globalThis,this._u=this._lc.listen("update",r=>{if(this._t<=this._w){this._t+=r;return}let o=this._t-this._w;this._o[this._p]=this._lc.lerp(s,i,this._e(o/this._d)),this._t+=r,o>=this._d&&(this._o[this._p]=i,this.stop())}),this}stop(e=!0){if(!this._u)return this;if(this.running=!1,this._u(),this._t=0,e)for(let s of this._cb)s(this._o);return this}restart(e=null,s=!1){return this.stop(s).restart(e)}onEnd(e){return this._cb.push(e),this}chain(e){return this._ch.onEnd(()=>{this._cu=e.start(this._lc)}),this._ch=e,this}reset(){return this._cb.length=0,this.stop()}relative(e=!0){return this._rel=e,this}delay(e){return this._w=e,this}get current(){return this._cu}get progress(){return this.running&&this._t>this._w?(this._t-this._w)/this._d:0}};globalThis.utils=Object.assign(globalThis.utils||{},c);})();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@litecanvas/utils",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.0",
|
|
4
4
|
"description": "Utilities to help build litecanvas games",
|
|
5
5
|
"author": "Luiz Bills <luizbills@pm.me>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -26,7 +26,8 @@
|
|
|
26
26
|
"dev": "esbuild src/_web.js --bundle --watch --outfile=dist/all.js --servedir=.",
|
|
27
27
|
"build": "node scripts/build.js",
|
|
28
28
|
"prepare": "npm run build",
|
|
29
|
-
"prepublishOnly": "npm run build"
|
|
29
|
+
"prepublishOnly": "npm run build",
|
|
30
|
+
"format": "npx prettier -w ."
|
|
30
31
|
},
|
|
31
32
|
"files": [
|
|
32
33
|
"src",
|
|
@@ -36,6 +37,8 @@
|
|
|
36
37
|
"litecanvas": "*"
|
|
37
38
|
},
|
|
38
39
|
"devDependencies": {
|
|
39
|
-
"esbuild": "^0.23.1"
|
|
40
|
+
"esbuild": "^0.23.1",
|
|
41
|
+
"gzip-size": "^7.0.0",
|
|
42
|
+
"prettier": "^3.3.3"
|
|
40
43
|
}
|
|
41
44
|
}
|
package/src/collision/resolve.js
CHANGED
package/src/index.js
CHANGED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Noise utils
|
|
2
|
+
|
|
3
|
+
**CDN**: https://unpkg.com/@litecanvas/utils/dist/noise.js
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
Generate procedural Perlin noise to use in your projects, such as terrain generation, animations, or particle effects.
|
|
8
|
+
|
|
9
|
+
```js
|
|
10
|
+
import litecanvas from "litecanvas"
|
|
11
|
+
import { Noise } from "@litecanvas/utils"
|
|
12
|
+
|
|
13
|
+
const e = litecanvas()
|
|
14
|
+
|
|
15
|
+
// Create a new Noise instance
|
|
16
|
+
const noise = new Noise(e)
|
|
17
|
+
|
|
18
|
+
// Generate a noise value at 2D coordinates (x, y)
|
|
19
|
+
const value = noise.noise(0.5, 0.8)
|
|
20
|
+
console.log("Noise value at (0.5, 0.8):", value)
|
|
21
|
+
|
|
22
|
+
// Generate a noise value at 3D coordinates (x, y, z)
|
|
23
|
+
const value3D = noise.noise(1.2, 0.4, 0.9)
|
|
24
|
+
console.log("Noise value at (1.2, 0.4, 0.9):", value3D)
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Adjusting Noise Detail
|
|
28
|
+
|
|
29
|
+
You can configure the number of octaves and amplitude falloff to control the detail of the noise.
|
|
30
|
+
|
|
31
|
+
```js
|
|
32
|
+
// Set 8 octaves and a 60% amplitude falloff
|
|
33
|
+
noise.noiseDetail(8, 0.6)
|
|
34
|
+
|
|
35
|
+
// Generate a new noise value with the updated settings
|
|
36
|
+
const detailedValue = noise.noise(0.3, 0.7)
|
|
37
|
+
console.log("Detailed noise value:", detailedValue)
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Seeding Noise
|
|
41
|
+
|
|
42
|
+
Ensure deterministic results by setting a seed for the noise generator.
|
|
43
|
+
|
|
44
|
+
```js
|
|
45
|
+
// Set a specific seed
|
|
46
|
+
noise.noiseSeed(42)
|
|
47
|
+
|
|
48
|
+
// Generate consistent noise values
|
|
49
|
+
const seededValue = noise.noise(0.1, 0.1)
|
|
50
|
+
console.log("Seeded noise value at (0.1, 0.1):", seededValue)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## 2D Noise Grid
|
|
54
|
+
|
|
55
|
+
Create a grid of Perlin noise values and display them as ASCII art.
|
|
56
|
+
|
|
57
|
+
```js
|
|
58
|
+
const noise = new utils.Noise()
|
|
59
|
+
noise.noiseDetail(4, 0.5)
|
|
60
|
+
|
|
61
|
+
// Generate a 8 by 8 noise grid
|
|
62
|
+
const gridSize = 8
|
|
63
|
+
let grid = ""
|
|
64
|
+
|
|
65
|
+
for (let y = 0; y < gridSize; y++) {
|
|
66
|
+
for (let x = 0; x < gridSize; x++) {
|
|
67
|
+
const value = noise.noise(x / gridSize, y / gridSize)
|
|
68
|
+
grid += value > 0.5 ? "#" : "."
|
|
69
|
+
}
|
|
70
|
+
grid += "\n"
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
console.log(grid)
|
|
74
|
+
```
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Further adapted from p5 Noise module
|
|
3
|
+
* https://github.com/processing/p5.js/blob/v1.11.1/src/math/noise.js
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// import litecanvas types
|
|
7
|
+
import "litecanvas"
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Constants for Perlin noise calculations.
|
|
11
|
+
*/
|
|
12
|
+
const PERLIN_YWRAPB = 4
|
|
13
|
+
const PERLIN_YWRAP = 1 << PERLIN_YWRAPB
|
|
14
|
+
const PERLIN_ZWRAPB = 8
|
|
15
|
+
const PERLIN_ZWRAP = 1 << PERLIN_ZWRAPB
|
|
16
|
+
const PERLIN_SIZE = 4095
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Scaled cosine function used for smoothing transitions in Perlin noise.
|
|
20
|
+
* @param {number} i - Input value.
|
|
21
|
+
* @returns {number} Scaled cosine value.
|
|
22
|
+
*/
|
|
23
|
+
const scaled_cosine = (i) => 0.5 * (1.0 - Math.cos(i * Math.PI))
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Class for generating Perlin noise, a type of gradient noise often used in procedural generation.
|
|
27
|
+
*/
|
|
28
|
+
export class Noise {
|
|
29
|
+
/**
|
|
30
|
+
* Array to store Perlin noise values.
|
|
31
|
+
* @type {number[]}
|
|
32
|
+
* @private
|
|
33
|
+
*/
|
|
34
|
+
_p = []
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Number of octaves for the Perlin noise. Higher values create more detail.
|
|
38
|
+
* @type {number}
|
|
39
|
+
* @private
|
|
40
|
+
*/
|
|
41
|
+
_po = 4
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Amplitude falloff factor for Perlin noise. Determines the reduction of amplitude per octave.
|
|
45
|
+
* @type {number}
|
|
46
|
+
* @private
|
|
47
|
+
*/
|
|
48
|
+
_pf = 0.5
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @type {LitecanvasInstance}
|
|
52
|
+
* @private
|
|
53
|
+
*/
|
|
54
|
+
_e = null
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @param {LitecanvasInstance} engine
|
|
58
|
+
*/
|
|
59
|
+
constructor(engine) {
|
|
60
|
+
this._e = engine || globalThis
|
|
61
|
+
|
|
62
|
+
this.noiseSeed()
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Generates Perlin noise for the given coordinates.
|
|
67
|
+
* @param {number} x - X-coordinate.
|
|
68
|
+
* @param {number} [y=0] - Y-coordinate (default is 0).
|
|
69
|
+
* @param {number} [z=0] - Z-coordinate (default is 0).
|
|
70
|
+
* @returns {number} A noise value in the range [0, 1).
|
|
71
|
+
*/
|
|
72
|
+
noise(x, y = 0, z = 0) {
|
|
73
|
+
if (x < 0) {
|
|
74
|
+
x = -x
|
|
75
|
+
}
|
|
76
|
+
if (y < 0) {
|
|
77
|
+
y = -y
|
|
78
|
+
}
|
|
79
|
+
if (z < 0) {
|
|
80
|
+
z = -z
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
let xi = Math.floor(x),
|
|
84
|
+
yi = Math.floor(y),
|
|
85
|
+
zi = Math.floor(z)
|
|
86
|
+
let xf = x - xi
|
|
87
|
+
let yf = y - yi
|
|
88
|
+
let zf = z - zi
|
|
89
|
+
let rxf, ryf
|
|
90
|
+
|
|
91
|
+
let r = 0
|
|
92
|
+
let ampl = 0.5
|
|
93
|
+
|
|
94
|
+
let n1, n2, n3
|
|
95
|
+
|
|
96
|
+
for (let o = 0; o < this._po; o++) {
|
|
97
|
+
let of = xi + (yi << PERLIN_YWRAPB) + (zi << PERLIN_ZWRAPB)
|
|
98
|
+
|
|
99
|
+
rxf = scaled_cosine(xf)
|
|
100
|
+
ryf = scaled_cosine(yf)
|
|
101
|
+
|
|
102
|
+
n1 = this._p[of & PERLIN_SIZE]
|
|
103
|
+
n1 += rxf * (this._p[(of + 1) & PERLIN_SIZE] - n1)
|
|
104
|
+
n2 = this._p[(of + PERLIN_YWRAP) & PERLIN_SIZE]
|
|
105
|
+
n2 += rxf * (this._p[(of + PERLIN_YWRAP + 1) & PERLIN_SIZE] - n2)
|
|
106
|
+
n1 += ryf * (n2 - n1)
|
|
107
|
+
|
|
108
|
+
of += PERLIN_ZWRAP
|
|
109
|
+
n2 = this._p[of & PERLIN_SIZE]
|
|
110
|
+
n2 += rxf * (this._p[(of + 1) & PERLIN_SIZE] - n2)
|
|
111
|
+
n3 = this._p[(of + PERLIN_YWRAP) & PERLIN_SIZE]
|
|
112
|
+
n3 += rxf * (this._p[(of + PERLIN_YWRAP + 1) & PERLIN_SIZE] - n3)
|
|
113
|
+
n2 += ryf * (n3 - n2)
|
|
114
|
+
|
|
115
|
+
n1 += scaled_cosine(zf) * (n2 - n1)
|
|
116
|
+
|
|
117
|
+
r += n1 * ampl
|
|
118
|
+
ampl *= this._pf
|
|
119
|
+
xi <<= 1
|
|
120
|
+
xf *= 2
|
|
121
|
+
yi <<= 1
|
|
122
|
+
yf *= 2
|
|
123
|
+
zi <<= 1
|
|
124
|
+
zf *= 2
|
|
125
|
+
|
|
126
|
+
if (xf >= 1.0) {
|
|
127
|
+
xi++
|
|
128
|
+
xf--
|
|
129
|
+
}
|
|
130
|
+
if (yf >= 1.0) {
|
|
131
|
+
yi++
|
|
132
|
+
yf--
|
|
133
|
+
}
|
|
134
|
+
if (zf >= 1.0) {
|
|
135
|
+
zi++
|
|
136
|
+
zf--
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return r
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Adjusts the detail level of the noise by setting the number of octaves and amplitude falloff.
|
|
144
|
+
* @param {number} lod - Level of detail (number of octaves).
|
|
145
|
+
* @param {number} falloff - Amplitude falloff per octave.
|
|
146
|
+
*/
|
|
147
|
+
noiseDetail(lod, falloff) {
|
|
148
|
+
if (lod > 0) {
|
|
149
|
+
this._po = lod
|
|
150
|
+
}
|
|
151
|
+
if (falloff > 0) {
|
|
152
|
+
this._pf = falloff
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Sets a seed for the Perlin noise generator, ensuring deterministic results.
|
|
158
|
+
* @param {number} value - Seed value.
|
|
159
|
+
*/
|
|
160
|
+
noiseSeed(value = null) {
|
|
161
|
+
if (value != null) {
|
|
162
|
+
this._e.seed(value)
|
|
163
|
+
}
|
|
164
|
+
const random = this._e.rand || Math.random
|
|
165
|
+
for (let i = 0; i < PERLIN_SIZE + 1; i++) {
|
|
166
|
+
this._p[i] = random()
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
package/src/tween/README.md
CHANGED
|
@@ -59,7 +59,7 @@ function draw() {
|
|
|
59
59
|
|
|
60
60
|
Starts the animation.
|
|
61
61
|
|
|
62
|
-
Syntax: `.start(engine?: LitecanvasInstance):
|
|
62
|
+
Syntax: `.start(engine?: LitecanvasInstance): this`
|
|
63
63
|
|
|
64
64
|
```js
|
|
65
65
|
// if your litecanvas has config.global = false
|
|
@@ -69,7 +69,7 @@ const engine = litecanvas({
|
|
|
69
69
|
})
|
|
70
70
|
|
|
71
71
|
function init () {
|
|
72
|
-
|
|
72
|
+
tween(...).start(engine)
|
|
73
73
|
}
|
|
74
74
|
```
|
|
75
75
|
|
|
@@ -81,7 +81,7 @@ const engine = litecanvas({
|
|
|
81
81
|
|
|
82
82
|
function init () {
|
|
83
83
|
// just call start
|
|
84
|
-
|
|
84
|
+
tween(...).start()
|
|
85
85
|
}
|
|
86
86
|
```
|
|
87
87
|
|
|
@@ -89,7 +89,7 @@ function init () {
|
|
|
89
89
|
|
|
90
90
|
If enabled (`flag = true`) the tween we animate from a value to another relative value.
|
|
91
91
|
|
|
92
|
-
Syntax: `.relative(flag?: boolean = true):
|
|
92
|
+
Syntax: `.relative(flag?: boolean = true): this`
|
|
93
93
|
|
|
94
94
|
```js
|
|
95
95
|
const obj = { x: 0 }
|
|
@@ -113,14 +113,13 @@ tween(obj, "x", -100).relative()
|
|
|
113
113
|
|
|
114
114
|
Make another tween start right after this tween ends.
|
|
115
115
|
|
|
116
|
-
Syntax: `.relative(another: TweenController):
|
|
116
|
+
Syntax: `.relative(another: TweenController): this`
|
|
117
117
|
|
|
118
118
|
```js
|
|
119
119
|
const obj = { x: 0, angle: 0 }
|
|
120
120
|
|
|
121
121
|
const moveRight = tween(obj, "x", 100, 1).relative()
|
|
122
122
|
const moveLeft = tween(obj, "x", -100, 1).relative()
|
|
123
|
-
const moveLeft = tween(obj, "angle", Math.PI, 1).relative()
|
|
124
123
|
|
|
125
124
|
// move 100px to right, move 100px to left and rotate
|
|
126
125
|
moveRight.chain(moveLeft)
|
|
@@ -131,7 +130,7 @@ moveRight.start()
|
|
|
131
130
|
|
|
132
131
|
Enqueues a callback to be executed when the animation finishes.
|
|
133
132
|
|
|
134
|
-
Syntax: `.onEnd(callback?: (object:any) => void):
|
|
133
|
+
Syntax: `.onEnd(callback?: (object:any) => void): this`
|
|
135
134
|
|
|
136
135
|
```js
|
|
137
136
|
// lets imagine a animation
|
|
@@ -143,11 +142,17 @@ anim.onEnd(() => {
|
|
|
143
142
|
})
|
|
144
143
|
```
|
|
145
144
|
|
|
145
|
+
### TweenController#restart()
|
|
146
|
+
|
|
147
|
+
Stops and start again the animation.
|
|
148
|
+
|
|
149
|
+
Syntax: `.restart(engine?: LitecanvasInstance, completed: boolean = false): this`
|
|
150
|
+
|
|
146
151
|
### TweenController#stop()
|
|
147
152
|
|
|
148
153
|
Stops the animation.
|
|
149
154
|
|
|
150
|
-
Syntax: `.stop(
|
|
155
|
+
Syntax: `.stop(completed: boolean = true): this`
|
|
151
156
|
|
|
152
157
|
```js
|
|
153
158
|
// lets imagine a animation with 5 seconds of duration
|
|
@@ -167,6 +172,8 @@ anim.stop(false)
|
|
|
167
172
|
|
|
168
173
|
Stops the animation and remove all `.onEnd()` registered callbacks.
|
|
169
174
|
|
|
175
|
+
Syntax: `.reset(): this`
|
|
176
|
+
|
|
170
177
|
### TweenController#progress
|
|
171
178
|
|
|
172
179
|
Returns the percentage of the animation's progress, a number between `0.0` and `1.0`. Where `0` represents 0% and `1` represents 100%.
|
package/src/tween/index.js
CHANGED
|
@@ -8,7 +8,7 @@ const HALF_PI = Math.PI / 2
|
|
|
8
8
|
* @param {number|number} toValue
|
|
9
9
|
* @param {number} [duration]
|
|
10
10
|
* @param {(n: number) => number} [easing]
|
|
11
|
-
* @returns {
|
|
11
|
+
* @returns {this}
|
|
12
12
|
*/
|
|
13
13
|
export const tween = (object, prop, toValue, duration = 1, easing = LINEAR) => {
|
|
14
14
|
return new TweenController(object, prop, toValue, duration, easing)
|
|
@@ -124,15 +124,16 @@ class TweenController {
|
|
|
124
124
|
|
|
125
125
|
/**
|
|
126
126
|
* @param {LitecanvasInstance} [engine]
|
|
127
|
-
* @returns {
|
|
127
|
+
* @returns {this}
|
|
128
128
|
*/
|
|
129
129
|
start(engine) {
|
|
130
|
-
if (
|
|
131
|
-
this
|
|
130
|
+
if (this.running) {
|
|
131
|
+
return this
|
|
132
132
|
}
|
|
133
133
|
|
|
134
134
|
this._cu.stop(false)
|
|
135
135
|
this._ch = this._cu = this
|
|
136
|
+
this.running = true
|
|
136
137
|
|
|
137
138
|
const fromValue = this._o[this._p] || 0
|
|
138
139
|
const toValue = this._rel ? fromValue + this._x : this._x
|
|
@@ -156,17 +157,6 @@ class TweenController {
|
|
|
156
157
|
}
|
|
157
158
|
})
|
|
158
159
|
|
|
159
|
-
this.running = true
|
|
160
|
-
|
|
161
|
-
return this
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* @param {Function} callback
|
|
166
|
-
* @returns {this}
|
|
167
|
-
*/
|
|
168
|
-
onEnd(callback) {
|
|
169
|
-
this._cb.push(callback)
|
|
170
160
|
return this
|
|
171
161
|
}
|
|
172
162
|
|
|
@@ -175,7 +165,7 @@ class TweenController {
|
|
|
175
165
|
* @returns {this}
|
|
176
166
|
*/
|
|
177
167
|
stop(completed = true) {
|
|
178
|
-
if (!this.
|
|
168
|
+
if (!this._u) return this
|
|
179
169
|
|
|
180
170
|
this.running = false
|
|
181
171
|
|
|
@@ -191,6 +181,23 @@ class TweenController {
|
|
|
191
181
|
return this
|
|
192
182
|
}
|
|
193
183
|
|
|
184
|
+
/**
|
|
185
|
+
* @param {LitecanvasInstance} [engine]
|
|
186
|
+
* @returns {this}
|
|
187
|
+
*/
|
|
188
|
+
restart(engine = null, completed = false) {
|
|
189
|
+
return this.stop(completed).restart(engine)
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* @param {Function} callback
|
|
194
|
+
* @returns {this}
|
|
195
|
+
*/
|
|
196
|
+
onEnd(callback) {
|
|
197
|
+
this._cb.push(callback)
|
|
198
|
+
return this
|
|
199
|
+
}
|
|
200
|
+
|
|
194
201
|
/**
|
|
195
202
|
* @param {TweenController} another
|
|
196
203
|
* @returns {this}
|