From 451ef378d904c8401cd90066a6625307c210c9f4 Mon Sep 17 00:00:00 2001 From: Luiz Bills Date: Tue, 12 May 2026 13:31:41 -0300 Subject: [PATCH 1/3] expose zzfxX globally --- src/zzfx.js | 111 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 106 insertions(+), 5 deletions(-) diff --git a/src/zzfx.js b/src/zzfx.js index ebc2fd7..9c9cc61 100644 --- a/src/zzfx.js +++ b/src/zzfx.js @@ -1,13 +1,114 @@ // ZzFXMicro - Zuper Zmall Zound Zynth - v1.3.0 by Frank Force | https://github.com/KilledByAPixel/ZzFX -// prettier-ignore /** * @param {Window} global * @returns {Function} the `zzfx()` function */ export const setupZzFX = (global) => { - const zzfxX = new AudioContext() + global.zzfxX = new AudioContext() + global.zzfxV = 1 // volume rate - global.zzfxV = 1 - - return (i=1,d=.05,z=220,e=0,P=0,S=.1,I=0,c=1,T=0,H=0,V=0,J=0,h=0,j=0,K=0,E=0,r=0,B=1,X=0,L=0,D=0)=>{let n=Math,t=2*n.PI,a=44100,F=T*=500*t/a/a,O=z*=(1-d+2*d*n.random(d=[]))*t/a,x=0,_=0,f=0,g=1,$=0,l=0,o=0,s=D<0?-1:1,u=t*s*D*2/a,G=n.cos(u),C=n.sin,Q=C(u)/4,M=1+Q,m=-2*G/M,y=(1-Q)/M,R=(1+s*G)/2/M,A=-(s+G)/M,v=R,U=0,W=0,Y=0,Z=0;for(e=a*e+9,X*=a,P*=a,S*=a,r*=a,H*=500*t/a**3,K*=t/a,V*=t/a,J*=a,h=a*h|0,i*=.3*global.zzfxV,s=e+X+P+S+r|0;ff?0:(fJ&&(z+=V,O+=V,g=0),!h||++$%h||(z=O,T=F,g=g||1);i=zzfxX.createBuffer(1,s,a),i.getChannelData(0).set(d),z=zzfxX.createBufferSource(),z.buffer=i,z.connect(zzfxX.destination),z.start()}; + return ( + i = 1, // volume + d = 0.05, // randomness + z = 220, // frequency + e = 0, // attack + P = 0, // sustain + S = 0.1, // release + I = 0, // shape + c = 1, // shape curve + T = 0, // slide + H = 0, // delta slide + V = 0, // pitch jump + J = 0, // pitch jump time + h = 0, // repeat time + j = 0, // noise + K = 0, // modulation + E = 0, // bit crush + r = 0, // delay + B = 1, // sustain volume + X = 0, // decay + L = 0, // tremolo + D = 0 // filter + ) => { + let n = Math, + t = 2 * n.PI, + a = 44100, + F = (T *= (500 * t) / a / a), + O = (z *= ((1 - d + 2 * d * n.random((d = []))) * t) / a), + x = 0, + _ = 0, + f = 0, + g = 1, + $ = 0, + l = 0, + o = 0, + s = D < 0 ? -1 : 1, + u = (t * s * D * 2) / a, + G = n.cos(u), + C = n.sin, + Q = C(u) / 4, + M = 1 + Q, + m = (-2 * G) / M, + y = (1 - Q) / M, + R = (1 + s * G) / 2 / M, + A = -(s + G) / M, + v = R, + U = 0, + W = 0, + Y = 0, + Z = 0 + for ( + e = a * e + 9, + X *= a, + P *= a, + S *= a, + r *= a, + H *= (500 * t) / a ** 3, + K *= t / a, + V *= t / a, + J *= a, + h = (a * h) | 0, + i *= 0.3 * zzfxV, + s = (e + X + P + S + r) | 0; + f < s; + d[f++] = o * i + ) + (++l % ((100 * E) | 0) || + ((o = I + ? 1 < I + ? 2 < I + ? 3 < I + ? C(x * x) + : n.max(n.min(n.tan(x), 1), -1) + : 1 - (((((2 * x) / t) % 2) + 2) % 2) + : 1 - 4 * n.abs(n.round(x / t) - x / t) + : C(x)), + (o = + (h ? 1 - L + L * C((t * f) / h) : 1) * + (o < 0 ? -1 : 1) * + n.abs(o) ** c * + (f < e + ? f / e + : f < e + X + ? 1 - ((f - e) / X) * (1 - B) + : f < e + X + P + ? B + : f < s - r + ? ((s - f - r) / S) * B + : 0)), + (o = r + ? o / 2 + (r > f ? 0 : ((f < s - r ? 1 : (s - f) / r) * d[(f - r) | 0]) / 2 / i) + : o), + D && (o = Z = v * U + A * (U = W) + R * (W = o) - y * Y - m * (Y = Z))), + (u = (z += T += H) * n.cos(K * _++)), + (x += u + u * j * C(f ** 5)), + g && ++g > J && ((z += V), (O += V), (g = 0)), + !h || ++$ % h || ((z = O), (T = F), (g = g || 1))) + ;((i = zzfxX.createBuffer(1, s, a)), + i.getChannelData(0).set(d), + (z = zzfxX.createBufferSource()), + (z.buffer = i), + z.connect(zzfxX.destination), + z.start()) + } } From 4071e9eda0a55a8a4348e17a462fbaa9e5073a1b Mon Sep 17 00:00:00 2001 From: Luiz Bills Date: Tue, 12 May 2026 13:31:53 -0300 Subject: [PATCH 2/3] minor tweak --- src/index.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/index.js b/src/index.js index 8a1d46f..7aad289 100644 --- a/src/index.js +++ b/src/index.js @@ -17,6 +17,7 @@ export default function litecanvas(settings = {}) { TWO_PI = math.PI * 2, loggerPrefix = '[Litecanvas] ', raf = requestAnimationFrame, + isNumber = Number.isFinite, /** @type {Function[]} */ _browserEventListeners = [], /** @type {(elem: EventTarget, evt: string, callback: (event: Event) => void) => void} */ @@ -30,7 +31,6 @@ export default function litecanvas(settings = {}) { preventDefault = (ev) => ev.preventDefault(), /** @type {(c: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D) => void} */ beginPath = (c) => c.beginPath(), - isNumber = Number.isFinite, zzfx = setupZzFX(root), /** @type {LitecanvasOptions} */ defaults = { @@ -52,7 +52,7 @@ export default function litecanvas(settings = {}) { _initialized = false, /** @type {boolean} */ _paused, - /** @type {HTMLCanvasElement} _canvas */ + /** @type {HTMLCanvasElement} */ _canvas, /** @type {number} */ _canvasScale = 1, @@ -703,6 +703,7 @@ export default function litecanvas(settings = {}) { */ textgap(value) { DEV: assert(isNumber(value), loggerPrefix + 'textgap() 1st param must be a number') + _fontLineHeight = value }, From 8216460bc64e1ad825890ba577f78c733dcafd29 Mon Sep 17 00:00:00 2001 From: Luiz Bills Date: Tue, 12 May 2026 13:33:07 -0300 Subject: [PATCH 3/3] v0.207 * now zzfxX (zzfx audio context) is global --- package.json | 2 +- src/version.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 0a6fbf4..5530709 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "litecanvas", - "version": "0.206.2", + "version": "0.207.0", "description": "Lightweight HTML5 canvas 2D game engine suitable for small projects and creative coding. Inspired by PICO-8 and p5.js/Processing.", "license": "MIT", "author": "Luiz Bills ", diff --git a/src/version.js b/src/version.js index 5db253f..eae9ab9 100644 --- a/src/version.js +++ b/src/version.js @@ -1,2 +1,2 @@ // Generated by genversion. -export const version = '0.206.2' +export const version = '0.207.0'