q5 2.24.4 → 2.25.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 +6 -5
- package/deno.json +1 -1
- package/package.json +1 -1
- package/q5.d.ts +157 -22
- package/q5.js +111 -69
- package/q5.min.js +2 -2
package/q5.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* q5.js
|
|
3
|
-
* @version 2.
|
|
3
|
+
* @version 2.25
|
|
4
4
|
* @author quinton-ashley, Tezumie, and LingDong-
|
|
5
5
|
* @license LGPL-3.0
|
|
6
6
|
* @class Q5
|
|
@@ -99,7 +99,6 @@ function Q5(scope, parent, renderer) {
|
|
|
99
99
|
let nextTS = ts + $._targetFrameDuration;
|
|
100
100
|
let frameDelay = nextTS - performance.now();
|
|
101
101
|
while (frameDelay < 0) frameDelay += $._targetFrameDuration;
|
|
102
|
-
log(frameDelay);
|
|
103
102
|
looper = setTimeout(() => $._draw(nextTS), frameDelay);
|
|
104
103
|
}
|
|
105
104
|
} else if ($.frameCount && !$._redraw) return;
|
|
@@ -223,11 +222,23 @@ function Q5(scope, parent, renderer) {
|
|
|
223
222
|
if (n[0] != '_' && typeof $[n] == 'function') $[n] = fn.bind($);
|
|
224
223
|
}
|
|
225
224
|
|
|
225
|
+
for (let [n, fn] of Object.entries(Q5.preloadMethods)) {
|
|
226
|
+
$[n] = function () {
|
|
227
|
+
$._incrementPreload();
|
|
228
|
+
return fn.apply($, arguments);
|
|
229
|
+
// fn is responsible for calling $._decrementPreload
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
|
|
226
233
|
if (scope == 'global') {
|
|
227
234
|
let props = Object.getOwnPropertyNames($);
|
|
228
235
|
for (let p of props) {
|
|
229
236
|
if (p[0] != '_') globalScope[p] = $[p];
|
|
230
237
|
}
|
|
238
|
+
// to support p5.sound
|
|
239
|
+
for (let p of ['_incrementPreload', '_decrementPreload']) {
|
|
240
|
+
globalScope[p] = $[p];
|
|
241
|
+
}
|
|
231
242
|
}
|
|
232
243
|
|
|
233
244
|
if (typeof scope == 'function') scope($);
|
|
@@ -335,7 +346,9 @@ Q5.methods = {
|
|
|
335
346
|
remove: []
|
|
336
347
|
};
|
|
337
348
|
Q5.prototype.registerMethod = (m, fn) => Q5.methods[m].push(fn);
|
|
338
|
-
|
|
349
|
+
|
|
350
|
+
Q5.preloadMethods = {};
|
|
351
|
+
Q5.prototype.registerPreloadMethod = (n, fn) => (Q5.preloadMethods[n] = fn[n]);
|
|
339
352
|
|
|
340
353
|
if (Q5._server) global.p5 ??= global.Q5 = Q5;
|
|
341
354
|
|
|
@@ -349,7 +362,7 @@ function createCanvas(w, h, opt) {
|
|
|
349
362
|
}
|
|
350
363
|
}
|
|
351
364
|
|
|
352
|
-
Q5.version = Q5.VERSION = '2.
|
|
365
|
+
Q5.version = Q5.VERSION = '2.25';
|
|
353
366
|
|
|
354
367
|
if (typeof document == 'object') {
|
|
355
368
|
document.addEventListener('DOMContentLoaded', () => {
|
|
@@ -943,6 +956,9 @@ Q5.renderers.c2d.shapes = ($) => {
|
|
|
943
956
|
w /= 2;
|
|
944
957
|
h /= 2;
|
|
945
958
|
|
|
959
|
+
w = Math.abs(w);
|
|
960
|
+
h = Math.abs(h);
|
|
961
|
+
|
|
946
962
|
if (!$._doFill && mode == $.PIE_OPEN) mode = $.CHORD_OPEN;
|
|
947
963
|
|
|
948
964
|
$.ctx.beginPath();
|
|
@@ -984,7 +1000,7 @@ Q5.renderers.c2d.shapes = ($) => {
|
|
|
984
1000
|
|
|
985
1001
|
function ellipse(x, y, w, h) {
|
|
986
1002
|
$.ctx.beginPath();
|
|
987
|
-
$.ctx.ellipse(x, y, w / 2, h / 2, 0, 0, TAU);
|
|
1003
|
+
$.ctx.ellipse(x, y, Math.abs(w / 2), Math.abs(h / 2), 0, 0, TAU);
|
|
988
1004
|
ink();
|
|
989
1005
|
}
|
|
990
1006
|
|
|
@@ -1015,7 +1031,7 @@ Q5.renderers.c2d.shapes = ($) => {
|
|
|
1015
1031
|
d *= $._da;
|
|
1016
1032
|
}
|
|
1017
1033
|
$.ctx.beginPath();
|
|
1018
|
-
$.ctx.arc(x, y, d / 2, 0, TAU);
|
|
1034
|
+
$.ctx.arc(x, y, Math.abs(d / 2), 0, TAU);
|
|
1019
1035
|
ink();
|
|
1020
1036
|
} else $.ellipse(x, y, d, d);
|
|
1021
1037
|
};
|
|
@@ -1331,7 +1347,7 @@ Q5.renderers.c2d.image = ($, q) => {
|
|
|
1331
1347
|
let img = new window.Image();
|
|
1332
1348
|
img.crossOrigin = 'Anonymous';
|
|
1333
1349
|
|
|
1334
|
-
g.
|
|
1350
|
+
g.promise = new Promise((resolve, reject) => {
|
|
1335
1351
|
img.onload = () => {
|
|
1336
1352
|
img._pixelDensity = pd;
|
|
1337
1353
|
g.defaultWidth = img.width * $._defaultImageScale;
|
|
@@ -1342,16 +1358,16 @@ Q5.renderers.c2d.image = ($, q) => {
|
|
|
1342
1358
|
|
|
1343
1359
|
g.ctx.drawImage(img, 0, 0);
|
|
1344
1360
|
if (cb) cb(g);
|
|
1345
|
-
delete g.
|
|
1361
|
+
delete g.promise;
|
|
1346
1362
|
resolve(g);
|
|
1347
1363
|
};
|
|
1348
1364
|
img.onerror = reject;
|
|
1349
1365
|
});
|
|
1350
|
-
$._preloadPromises.push(g.
|
|
1366
|
+
$._preloadPromises.push(g.promise);
|
|
1351
1367
|
|
|
1352
1368
|
g.src = img.src = url;
|
|
1353
1369
|
|
|
1354
|
-
if (!$._usePreload) return g.
|
|
1370
|
+
if (!$._usePreload) return g.promise;
|
|
1355
1371
|
return g;
|
|
1356
1372
|
};
|
|
1357
1373
|
|
|
@@ -1788,33 +1804,32 @@ Q5.renderers.c2d.text = ($, q) => {
|
|
|
1788
1804
|
fontMod = false,
|
|
1789
1805
|
styleHash = 0,
|
|
1790
1806
|
styleHashes = [],
|
|
1791
|
-
useCache = false,
|
|
1792
1807
|
genTextImage = false,
|
|
1793
|
-
cacheSize = 0
|
|
1794
|
-
cacheMax = 12000;
|
|
1808
|
+
cacheSize = 0;
|
|
1795
1809
|
|
|
1796
1810
|
let cache = ($._textCache = {});
|
|
1811
|
+
$._textCacheMaxSize = 12000;
|
|
1797
1812
|
|
|
1798
1813
|
$.loadFont = (url, cb) => {
|
|
1799
1814
|
let name = url.split('/').pop().split('.')[0].replace(' ', '');
|
|
1800
1815
|
|
|
1801
1816
|
let f = new FontFace(name, `url(${url})`);
|
|
1802
1817
|
document.fonts.add(f);
|
|
1803
|
-
f.
|
|
1818
|
+
f.promise = (async () => {
|
|
1804
1819
|
let err;
|
|
1805
1820
|
try {
|
|
1806
1821
|
await f.load();
|
|
1807
1822
|
} catch (e) {
|
|
1808
1823
|
err = e;
|
|
1809
1824
|
}
|
|
1810
|
-
delete f.
|
|
1825
|
+
delete f.promise;
|
|
1811
1826
|
if (err) throw err;
|
|
1812
1827
|
if (cb) cb(f);
|
|
1813
1828
|
return f;
|
|
1814
1829
|
})();
|
|
1815
|
-
$._preloadPromises.push(f.
|
|
1830
|
+
$._preloadPromises.push(f.promise);
|
|
1816
1831
|
$.textFont(name);
|
|
1817
|
-
if (!$._usePreload) return f.
|
|
1832
|
+
if (!$._usePreload) return f.promise;
|
|
1818
1833
|
return f;
|
|
1819
1834
|
};
|
|
1820
1835
|
|
|
@@ -1900,12 +1915,6 @@ Q5.renderers.c2d.text = ($, q) => {
|
|
|
1900
1915
|
styleHash = hash >>> 0;
|
|
1901
1916
|
};
|
|
1902
1917
|
|
|
1903
|
-
$.textCache = (enable, maxSize) => {
|
|
1904
|
-
if (maxSize) cacheMax = maxSize;
|
|
1905
|
-
if (enable !== undefined) useCache = enable;
|
|
1906
|
-
return useCache;
|
|
1907
|
-
};
|
|
1908
|
-
|
|
1909
1918
|
$.createTextImage = (str, w, h) => {
|
|
1910
1919
|
genTextImage = true;
|
|
1911
1920
|
let img = $.text(str, 0, 0, w, h);
|
|
@@ -1927,7 +1936,7 @@ Q5.renderers.c2d.text = ($, q) => {
|
|
|
1927
1936
|
|
|
1928
1937
|
if (fontMod) updateFont();
|
|
1929
1938
|
|
|
1930
|
-
if (
|
|
1939
|
+
if (genTextImage) {
|
|
1931
1940
|
if (styleHash == -1) updateStyleHash();
|
|
1932
1941
|
|
|
1933
1942
|
img = cache[str];
|
|
@@ -1935,8 +1944,7 @@ Q5.renderers.c2d.text = ($, q) => {
|
|
|
1935
1944
|
|
|
1936
1945
|
if (img) {
|
|
1937
1946
|
if (img._fill == $._fill && img._stroke == $._stroke && img._strokeWeight == $._strokeWeight) {
|
|
1938
|
-
|
|
1939
|
-
return $.textImage(img, x, y);
|
|
1947
|
+
return img;
|
|
1940
1948
|
} else img.clear();
|
|
1941
1949
|
}
|
|
1942
1950
|
}
|
|
@@ -1964,7 +1972,7 @@ Q5.renderers.c2d.text = ($, q) => {
|
|
|
1964
1972
|
lines = wrapped;
|
|
1965
1973
|
}
|
|
1966
1974
|
|
|
1967
|
-
if (!
|
|
1975
|
+
if (!genTextImage) {
|
|
1968
1976
|
tX = x;
|
|
1969
1977
|
tY = y;
|
|
1970
1978
|
} else {
|
|
@@ -2025,12 +2033,12 @@ Q5.renderers.c2d.text = ($, q) => {
|
|
|
2025
2033
|
|
|
2026
2034
|
if (!$._fillSet) ctx.fillStyle = ogFill;
|
|
2027
2035
|
|
|
2028
|
-
if (
|
|
2036
|
+
if (genTextImage) {
|
|
2029
2037
|
styleHashes.push(styleHash);
|
|
2030
2038
|
(cache[str] ??= {})[styleHash] = img;
|
|
2031
2039
|
|
|
2032
2040
|
cacheSize++;
|
|
2033
|
-
if (cacheSize >
|
|
2041
|
+
if (cacheSize > $._textCacheMaxSize) {
|
|
2034
2042
|
let half = Math.ceil(cacheSize / 2);
|
|
2035
2043
|
let hashes = styleHashes.splice(0, half);
|
|
2036
2044
|
for (let s in cache) {
|
|
@@ -2040,8 +2048,7 @@ Q5.renderers.c2d.text = ($, q) => {
|
|
|
2040
2048
|
cacheSize -= half;
|
|
2041
2049
|
}
|
|
2042
2050
|
|
|
2043
|
-
|
|
2044
|
-
$.textImage(img, x, y);
|
|
2051
|
+
return img;
|
|
2045
2052
|
}
|
|
2046
2053
|
};
|
|
2047
2054
|
|
|
@@ -2936,16 +2943,16 @@ Q5.modules.dom = ($, q) => {
|
|
|
2936
2943
|
};
|
|
2937
2944
|
|
|
2938
2945
|
if (src) {
|
|
2939
|
-
el.
|
|
2946
|
+
el.promise = new Promise((resolve) => {
|
|
2940
2947
|
el.addEventListener('loadeddata', () => {
|
|
2941
2948
|
el._load();
|
|
2942
2949
|
resolve(el);
|
|
2943
2950
|
});
|
|
2944
2951
|
el.src = src;
|
|
2945
2952
|
});
|
|
2946
|
-
$._preloadPromises.push(el.
|
|
2953
|
+
$._preloadPromises.push(el.promise);
|
|
2947
2954
|
|
|
2948
|
-
if (!$._usePreload) return el.
|
|
2955
|
+
if (!$._usePreload) return el.promise;
|
|
2949
2956
|
}
|
|
2950
2957
|
return el;
|
|
2951
2958
|
};
|
|
@@ -2972,7 +2979,7 @@ Q5.modules.dom = ($, q) => {
|
|
|
2972
2979
|
vid.pixels = g.pixels;
|
|
2973
2980
|
g.remove();
|
|
2974
2981
|
};
|
|
2975
|
-
vid.
|
|
2982
|
+
vid.promise = (async () => {
|
|
2976
2983
|
let stream;
|
|
2977
2984
|
try {
|
|
2978
2985
|
stream = await navigator.mediaDevices.getUserMedia(constraints);
|
|
@@ -2987,9 +2994,9 @@ Q5.modules.dom = ($, q) => {
|
|
|
2987
2994
|
if (cb) cb(vid);
|
|
2988
2995
|
return vid;
|
|
2989
2996
|
})();
|
|
2990
|
-
$._preloadPromises.push(vid.
|
|
2997
|
+
$._preloadPromises.push(vid.promise);
|
|
2991
2998
|
|
|
2992
|
-
if (!$._usePreload) return vid.
|
|
2999
|
+
if (!$._usePreload) return vid.promise;
|
|
2993
3000
|
return vid;
|
|
2994
3001
|
};
|
|
2995
3002
|
|
|
@@ -4068,28 +4075,28 @@ Q5.modules.sound = ($, q) => {
|
|
|
4068
4075
|
let s = new Q5.Sound();
|
|
4069
4076
|
sounds.push(s);
|
|
4070
4077
|
|
|
4071
|
-
s.
|
|
4078
|
+
s.promise = (async () => {
|
|
4072
4079
|
let err;
|
|
4073
4080
|
try {
|
|
4074
4081
|
await s.load(url);
|
|
4075
4082
|
} catch (e) {
|
|
4076
4083
|
err = e;
|
|
4077
4084
|
}
|
|
4078
|
-
delete s.
|
|
4085
|
+
delete s.promise;
|
|
4079
4086
|
if (err) throw err;
|
|
4080
4087
|
if (cb) cb(s);
|
|
4081
4088
|
return s;
|
|
4082
4089
|
})();
|
|
4083
|
-
$._preloadPromises.push(s.
|
|
4090
|
+
$._preloadPromises.push(s.promise);
|
|
4084
4091
|
|
|
4085
|
-
if (!$._usePreload) return s.
|
|
4092
|
+
if (!$._usePreload) return s.promise;
|
|
4086
4093
|
return s;
|
|
4087
4094
|
};
|
|
4088
4095
|
|
|
4089
4096
|
$.loadAudio = (url, cb) => {
|
|
4090
4097
|
let a = new Audio(url);
|
|
4091
4098
|
a.crossOrigin = 'Anonymous';
|
|
4092
|
-
a.
|
|
4099
|
+
a.promise = new Promise((resolve, reject) => {
|
|
4093
4100
|
a.addEventListener('canplaythrough', () => {
|
|
4094
4101
|
if (!a.loaded) {
|
|
4095
4102
|
a.loaded = true;
|
|
@@ -4100,9 +4107,9 @@ Q5.modules.sound = ($, q) => {
|
|
|
4100
4107
|
a.addEventListener('suspend', resolve);
|
|
4101
4108
|
a.addEventListener('error', reject);
|
|
4102
4109
|
});
|
|
4103
|
-
$._preloadPromises.push(a.
|
|
4110
|
+
$._preloadPromises.push(a.promise);
|
|
4104
4111
|
|
|
4105
|
-
if (!$._usePreload) return a.
|
|
4112
|
+
if (!$._usePreload) return a.promise;
|
|
4106
4113
|
return a;
|
|
4107
4114
|
};
|
|
4108
4115
|
|
|
@@ -4269,7 +4276,7 @@ Q5.Sound = class {
|
|
|
4269
4276
|
Q5.modules.util = ($, q) => {
|
|
4270
4277
|
$._loadFile = (url, cb, type) => {
|
|
4271
4278
|
let ret = {};
|
|
4272
|
-
ret.
|
|
4279
|
+
ret.promise = new Promise((resolve, reject) => {
|
|
4273
4280
|
fetch(url)
|
|
4274
4281
|
.then((res) => {
|
|
4275
4282
|
if (!res.ok) {
|
|
@@ -4283,7 +4290,7 @@ Q5.modules.util = ($, q) => {
|
|
|
4283
4290
|
if (type == 'csv') f = $.CSV.parse(f);
|
|
4284
4291
|
if (typeof f == 'string') ret.text = f;
|
|
4285
4292
|
else Object.assign(ret, f);
|
|
4286
|
-
delete ret.
|
|
4293
|
+
delete ret.promise;
|
|
4287
4294
|
if (cb) cb(f);
|
|
4288
4295
|
resolve(f);
|
|
4289
4296
|
});
|
|
@@ -4295,14 +4302,15 @@ Q5.modules.util = ($, q) => {
|
|
|
4295
4302
|
$.loadJSON = (url, cb) => $._loadFile(url, cb, 'json');
|
|
4296
4303
|
$.loadCSV = (url, cb) => $._loadFile(url, cb, 'csv');
|
|
4297
4304
|
|
|
4298
|
-
const imgRegex = /(jpe?g|png|gif|webp|avif|svg)
|
|
4299
|
-
fontRegex = /(ttf|otf|woff2?|eot|json)
|
|
4300
|
-
|
|
4305
|
+
const imgRegex = /(jpe?g|png|gif|webp|avif|svg)/i,
|
|
4306
|
+
fontRegex = /(ttf|otf|woff2?|eot|json)/i,
|
|
4307
|
+
fontCategoryRegex = /(serif|sans-serif|monospace|cursive|fantasy)/i,
|
|
4308
|
+
audioRegex = /(wav|flac|mp3|ogg|m4a|aac|aiff|weba)/i;
|
|
4301
4309
|
|
|
4302
4310
|
$.load = function (...urls) {
|
|
4303
4311
|
if (Array.isArray(urls[0])) urls = urls[0];
|
|
4304
4312
|
|
|
4305
|
-
let
|
|
4313
|
+
let promises = [];
|
|
4306
4314
|
|
|
4307
4315
|
for (let url of urls) {
|
|
4308
4316
|
let ext = url.split('.').pop().toLowerCase();
|
|
@@ -4314,18 +4322,18 @@ Q5.modules.util = ($, q) => {
|
|
|
4314
4322
|
obj = $.loadCSV(url);
|
|
4315
4323
|
} else if (imgRegex.test(ext)) {
|
|
4316
4324
|
obj = $.loadImage(url);
|
|
4317
|
-
} else if (fontRegex.test(ext)) {
|
|
4325
|
+
} else if (fontRegex.test(ext) || fontCategoryRegex.test(url)) {
|
|
4318
4326
|
obj = $.loadFont(url);
|
|
4319
4327
|
} else if (audioRegex.test(ext)) {
|
|
4320
4328
|
obj = $.loadSound(url);
|
|
4321
4329
|
} else {
|
|
4322
4330
|
obj = $.loadText(url);
|
|
4323
4331
|
}
|
|
4324
|
-
|
|
4332
|
+
promises.push(obj.promise);
|
|
4325
4333
|
}
|
|
4326
4334
|
|
|
4327
|
-
if (urls.length == 1) return
|
|
4328
|
-
return Promise.all(
|
|
4335
|
+
if (urls.length == 1) return promises[0];
|
|
4336
|
+
return Promise.all(promises);
|
|
4329
4337
|
};
|
|
4330
4338
|
|
|
4331
4339
|
async function saveFile(data, name, ext) {
|
|
@@ -4830,6 +4838,8 @@ struct Q5 {
|
|
|
4830
4838
|
$._frameA = frameA = Q5.device.createTexture({ size, format, usage });
|
|
4831
4839
|
$._frameB = frameB = Q5.device.createTexture({ size, format, usage });
|
|
4832
4840
|
|
|
4841
|
+
$.canvas.texture = frameA;
|
|
4842
|
+
|
|
4833
4843
|
$._frameShaderCode =
|
|
4834
4844
|
$._baseShaderCode +
|
|
4835
4845
|
/* wgsl */ `
|
|
@@ -5720,6 +5730,7 @@ fn fragMain(f: FragParams) -> @location(0) vec4f {
|
|
|
5720
5730
|
$.rectMode = (x) => ($._rectMode = x);
|
|
5721
5731
|
|
|
5722
5732
|
$.rect = (x, y, w, h, rr = 0) => {
|
|
5733
|
+
h ??= w;
|
|
5723
5734
|
let [l, r, t, b] = $._calcBox(x, y, w, h, $._rectMode);
|
|
5724
5735
|
let ci, ti;
|
|
5725
5736
|
if ($._matrixDirty) $._saveMatrix();
|
|
@@ -6694,7 +6705,8 @@ struct FragParams {
|
|
|
6694
6705
|
@location(0) texCoord : vec2f,
|
|
6695
6706
|
@location(1) fillColor : vec4f,
|
|
6696
6707
|
@location(2) strokeColor : vec4f,
|
|
6697
|
-
@location(3) strokeWeight : f32
|
|
6708
|
+
@location(3) strokeWeight : f32,
|
|
6709
|
+
@location(4) edge : f32
|
|
6698
6710
|
}
|
|
6699
6711
|
struct Char {
|
|
6700
6712
|
texOffset: vec2f,
|
|
@@ -6708,7 +6720,8 @@ struct Text {
|
|
|
6708
6720
|
matrixIndex: f32,
|
|
6709
6721
|
fillIndex: f32,
|
|
6710
6722
|
strokeIndex: f32,
|
|
6711
|
-
strokeWeight: f32
|
|
6723
|
+
strokeWeight: f32,
|
|
6724
|
+
edge: f32
|
|
6712
6725
|
}
|
|
6713
6726
|
|
|
6714
6727
|
@group(0) @binding(0) var<uniform> q: Q5;
|
|
@@ -6769,12 +6782,13 @@ fn vertexMain(v : VertexParams) -> FragParams {
|
|
|
6769
6782
|
f.fillColor = colors[i32(text.fillIndex)];
|
|
6770
6783
|
f.strokeColor = colors[i32(text.strokeIndex)];
|
|
6771
6784
|
f.strokeWeight = text.strokeWeight;
|
|
6785
|
+
f.edge = text.edge;
|
|
6772
6786
|
return f;
|
|
6773
6787
|
}
|
|
6774
6788
|
|
|
6775
6789
|
@fragment
|
|
6776
6790
|
fn fragMain(f : FragParams) -> @location(0) vec4f {
|
|
6777
|
-
let edge =
|
|
6791
|
+
let edge = f.edge;
|
|
6778
6792
|
let dist = calcDist(f.texCoord, edge);
|
|
6779
6793
|
|
|
6780
6794
|
if (f.strokeWeight == 0.0) {
|
|
@@ -6986,26 +7000,27 @@ fn fragMain(f : FragParams) -> @location(0) vec4f {
|
|
|
6986
7000
|
|
|
6987
7001
|
$.loadFont = (url, cb) => {
|
|
6988
7002
|
let ext = url.slice(url.lastIndexOf('.') + 1);
|
|
7003
|
+
if (url == ext) return $._loadDefaultFont(url, cb);
|
|
6989
7004
|
if (ext != 'json') return $._g.loadFont(url, cb);
|
|
6990
7005
|
let fontName = url.slice(url.lastIndexOf('/') + 1, url.lastIndexOf('-'));
|
|
6991
7006
|
let f = { family: fontName };
|
|
6992
|
-
f.
|
|
6993
|
-
delete f.
|
|
7007
|
+
f.promise = createFont(url, fontName, () => {
|
|
7008
|
+
delete f.promise;
|
|
6994
7009
|
if (cb) cb(f);
|
|
6995
7010
|
});
|
|
6996
|
-
$._preloadPromises.push(f.
|
|
7011
|
+
$._preloadPromises.push(f.promise);
|
|
6997
7012
|
|
|
6998
|
-
if (!$._usePreload) return f.
|
|
7013
|
+
if (!$._usePreload) return f.promise;
|
|
6999
7014
|
return f;
|
|
7000
7015
|
};
|
|
7001
7016
|
|
|
7002
|
-
$._loadDefaultFont = (fontName) => {
|
|
7017
|
+
$._loadDefaultFont = (fontName, cb) => {
|
|
7003
7018
|
fonts[fontName] = null;
|
|
7004
|
-
|
|
7005
|
-
|
|
7006
|
-
|
|
7007
|
-
$.loadFont(`/node_modules/q5/builtinFonts/${fontName}-msdf.json`);
|
|
7019
|
+
let url = `https://q5js.org/fonts/${fontName}-msdf.json`;
|
|
7020
|
+
if (!navigator.onLine) {
|
|
7021
|
+
url = `/node_modules/q5/builtinFonts/${fontName}-msdf.json`;
|
|
7008
7022
|
}
|
|
7023
|
+
return $.loadFont(url, cb);
|
|
7009
7024
|
};
|
|
7010
7025
|
|
|
7011
7026
|
$._textSize = 18;
|
|
@@ -7021,7 +7036,7 @@ fn fragMain(f : FragParams) -> @location(0) vec4f {
|
|
|
7021
7036
|
if (typeof fontName != 'string') fontName = fontName.family;
|
|
7022
7037
|
let font = fonts[fontName];
|
|
7023
7038
|
if (font) $._font = font;
|
|
7024
|
-
else if (font === undefined) $._loadDefaultFont(fontName);
|
|
7039
|
+
else if (font === undefined) return $._loadDefaultFont(fontName);
|
|
7025
7040
|
};
|
|
7026
7041
|
|
|
7027
7042
|
$.textSize = (size) => {
|
|
@@ -7033,6 +7048,33 @@ fn fragMain(f : FragParams) -> @location(0) vec4f {
|
|
|
7033
7048
|
}
|
|
7034
7049
|
};
|
|
7035
7050
|
|
|
7051
|
+
let weights = {
|
|
7052
|
+
thin: 100,
|
|
7053
|
+
extralight: 200,
|
|
7054
|
+
light: 300,
|
|
7055
|
+
normal: 400,
|
|
7056
|
+
regular: 400,
|
|
7057
|
+
medium: 500,
|
|
7058
|
+
semibold: 600,
|
|
7059
|
+
bold: 700,
|
|
7060
|
+
bolder: 800,
|
|
7061
|
+
extrabold: 800,
|
|
7062
|
+
black: 900,
|
|
7063
|
+
heavy: 900
|
|
7064
|
+
};
|
|
7065
|
+
|
|
7066
|
+
// ranges from 0.35 (black) to 0.65 (thin)
|
|
7067
|
+
$._textEdge = 0.5;
|
|
7068
|
+
|
|
7069
|
+
$.textWeight = (weight) => {
|
|
7070
|
+
if (!weight) return $._textWeight;
|
|
7071
|
+
if (typeof weight == 'string') {
|
|
7072
|
+
weight = weights[weight.toLowerCase().replace(/[ _-]/g, '')];
|
|
7073
|
+
if (!weight) throw new Error(`Invalid font weight: ${weight}`);
|
|
7074
|
+
}
|
|
7075
|
+
$._textEdge = 0.6875 - weight * 0.000375;
|
|
7076
|
+
};
|
|
7077
|
+
|
|
7036
7078
|
$.textLeading = (lineHeight) => {
|
|
7037
7079
|
$._font.lineHeight = leading = lineHeight;
|
|
7038
7080
|
leadDiff = leading - $._textSize;
|
|
@@ -7191,12 +7233,12 @@ fn fragMain(f : FragParams) -> @location(0) vec4f {
|
|
|
7191
7233
|
|
|
7192
7234
|
txt[0] = x;
|
|
7193
7235
|
txt[1] = -y;
|
|
7194
|
-
txt[2] = $._textSize /
|
|
7236
|
+
txt[2] = $._textSize / 42;
|
|
7195
7237
|
txt[3] = $._matrixIndex;
|
|
7196
7238
|
txt[4] = $._doFill && $._fillSet ? $._fill : 0;
|
|
7197
7239
|
txt[5] = $._stroke;
|
|
7198
7240
|
txt[6] = $._doStroke && $._strokeSet ? $._strokeWeight : 0;
|
|
7199
|
-
txt[7] =
|
|
7241
|
+
txt[7] = $._textEdge;
|
|
7200
7242
|
|
|
7201
7243
|
textStack.push(txt);
|
|
7202
7244
|
$._drawStack.push($._textPL, measurements.printedCharCount, $._font.index);
|