pts 0.10.7 → 0.10.10

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.
Files changed (49) hide show
  1. package/dist/es2015/Canvas.js +27 -12
  2. package/dist/es2015/Canvas.js.map +1 -0
  3. package/dist/es2015/Color.js +1 -1
  4. package/dist/es2015/Color.js.map +1 -0
  5. package/dist/es2015/Create.js +1 -1
  6. package/dist/es2015/Create.js.map +1 -0
  7. package/dist/es2015/Dom.js +1 -1
  8. package/dist/es2015/Dom.js.map +1 -0
  9. package/dist/es2015/Form.js +1 -1
  10. package/dist/es2015/Form.js.map +1 -0
  11. package/dist/es2015/Image.js +78 -12
  12. package/dist/es2015/Image.js.map +1 -0
  13. package/dist/es2015/LinearAlgebra.js +36 -1
  14. package/dist/es2015/LinearAlgebra.js.map +1 -0
  15. package/dist/es2015/Num.js +1 -1
  16. package/dist/es2015/Num.js.map +1 -0
  17. package/dist/es2015/Op.js +1 -1
  18. package/dist/es2015/Op.js.map +1 -0
  19. package/dist/es2015/Physics.js +1 -1
  20. package/dist/es2015/Physics.js.map +1 -0
  21. package/dist/es2015/Play.js.map +1 -0
  22. package/dist/es2015/Pt.js +4 -1
  23. package/dist/es2015/Pt.js.map +1 -0
  24. package/dist/es2015/Space.js +95 -34
  25. package/dist/es2015/Space.js.map +1 -0
  26. package/dist/es2015/Svg.js +1 -1
  27. package/dist/es2015/Svg.js.map +1 -0
  28. package/dist/es2015/Types.js +1 -1
  29. package/dist/es2015/Types.js.map +1 -0
  30. package/dist/es2015/Typography.js +1 -1
  31. package/dist/es2015/Typography.js.map +1 -0
  32. package/dist/es2015/UI.js +6 -2
  33. package/dist/es2015/UI.js.map +1 -0
  34. package/dist/es2015/Util.js +14 -1
  35. package/dist/es2015/Util.js.map +1 -0
  36. package/dist/es2015/_lib.js.map +1 -0
  37. package/dist/es2015/_module.js.map +1 -0
  38. package/dist/es2015/uheprng.js.map +1 -0
  39. package/dist/es5.js +393 -70
  40. package/dist/es5.js.map +1 -0
  41. package/dist/index.js +270 -73
  42. package/dist/index.js.map +1 -0
  43. package/dist/pts.d.ts +42 -7
  44. package/dist/pts.js +271 -74
  45. package/dist/pts.js.map +1 -0
  46. package/dist/pts.min.js +2 -2
  47. package/dist/pts.min.js.map +1 -0
  48. package/dist/pts.module.js.map +1 -0
  49. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * pts.js 0.10.7 - Copyright © 2017-2021 William Ngan and contributors.
2
+ * pts.js 0.10.10 - Copyright © 2017-2022 William Ngan and contributors.
3
3
  * Licensed under Apache 2.0 License.
4
4
  * See https://github.com/williamngan/pts for details.
5
5
  */
@@ -110,7 +110,7 @@ return /******/ (function(modules) { // webpackBootstrap
110
110
 
111
111
  "use strict";
112
112
 
113
- /*! Source code licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
113
+ /*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
114
114
  Object.defineProperty(exports, "__esModule", { value: true });
115
115
  exports.CanvasForm = exports.CanvasSpace = void 0;
116
116
  const Space_1 = __webpack_require__(/*! ./Space */ "./src/Space.ts");
@@ -221,13 +221,13 @@ class CanvasSpace extends Space_1.MultiTouchSpace {
221
221
  get autoResize() { return this._autoResize; }
222
222
  resize(b, evt) {
223
223
  this.bound = b;
224
- this._canvas.width = this.bound.size.x * this._pixelScale;
225
- this._canvas.height = this.bound.size.y * this._pixelScale;
226
- this._canvas.style.width = Math.floor(this.bound.size.x) + "px";
227
- this._canvas.style.height = Math.floor(this.bound.size.y) + "px";
224
+ this._canvas.width = Math.ceil(this.bound.size.x) * this._pixelScale;
225
+ this._canvas.height = Math.ceil(this.bound.size.y) * this._pixelScale;
226
+ this._canvas.style.width = Math.ceil(this.bound.size.x) + "px";
227
+ this._canvas.style.height = Math.ceil(this.bound.size.y) + "px";
228
228
  if (this._offscreen) {
229
- this._offCanvas.width = this.bound.size.x * this._pixelScale;
230
- this._offCanvas.height = this.bound.size.y * this._pixelScale;
229
+ this._offCanvas.width = Math.ceil(this.bound.size.x) * this._pixelScale;
230
+ this._offCanvas.height = Math.ceil(this.bound.size.y) * this._pixelScale;
231
231
  }
232
232
  if (this._pixelScale != 1) {
233
233
  this._ctx.scale(this._pixelScale, this._pixelScale);
@@ -282,27 +282,29 @@ class CanvasSpace extends Space_1.MultiTouchSpace {
282
282
  if (bg)
283
283
  this._bgcolor = bg;
284
284
  const lastColor = this._ctx.fillStyle;
285
+ const px = Math.ceil(this.pixelScale);
285
286
  if (!this._bgcolor || this._bgcolor === "transparent") {
286
- this._ctx.clearRect(-1, -1, this._canvas.width + 1, this._canvas.height + 1);
287
+ this._ctx.clearRect(-px, -px, this._canvas.width + px, this._canvas.height + px);
287
288
  }
288
289
  else {
289
290
  if (this._bgcolor.indexOf("rgba") === 0 || (this._bgcolor.length === 9 && this._bgcolor.indexOf("#") === 0)) {
290
- this._ctx.clearRect(-1, -1, this._canvas.width + 1, this._canvas.height + 1);
291
+ this._ctx.clearRect(-px, -px, this._canvas.width + px, this._canvas.height + px);
291
292
  }
292
293
  this._ctx.fillStyle = this._bgcolor;
293
- this._ctx.fillRect(-1, -1, this._canvas.width + 1, this._canvas.height + 1);
294
+ this._ctx.fillRect(-px, -px, this._canvas.width + px, this._canvas.height + px);
294
295
  }
295
296
  this._ctx.fillStyle = lastColor;
296
297
  return this;
297
298
  }
298
299
  clearOffscreen(bg) {
299
300
  if (this._offscreen) {
301
+ const px = Math.ceil(this.pixelScale);
300
302
  if (bg) {
301
303
  this._offCtx.fillStyle = bg;
302
- this._offCtx.fillRect(-1, -1, this._canvas.width + 1, this._canvas.height + 1);
304
+ this._offCtx.fillRect(-px, -px, this._canvas.width + px, this._canvas.height + px);
303
305
  }
304
306
  else {
305
- this._offCtx.clearRect(-1, -1, this._offCanvas.width + 1, this._offCanvas.height + 1);
307
+ this._offCtx.clearRect(-px, -px, this._offCanvas.width + px, this._offCanvas.height + px);
306
308
  }
307
309
  }
308
310
  return this;
@@ -427,6 +429,19 @@ class CanvasForm extends Form_1.VisualForm {
427
429
  }
428
430
  return this;
429
431
  }
432
+ applyFillStroke(filled = true, stroked = true, strokeWidth = 1) {
433
+ if (filled) {
434
+ if (typeof filled === 'string')
435
+ this.fill(filled);
436
+ this._ctx.fill();
437
+ }
438
+ if (stroked) {
439
+ if (typeof stroked === 'string')
440
+ this.stroke(stroked, strokeWidth);
441
+ this._ctx.stroke();
442
+ }
443
+ return this;
444
+ }
430
445
  gradient(stops) {
431
446
  let vals = [];
432
447
  if (stops.length < 2)
@@ -795,7 +810,7 @@ exports.CanvasForm = CanvasForm;
795
810
 
796
811
  "use strict";
797
812
 
798
- /*! Source code licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
813
+ /*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
799
814
  Object.defineProperty(exports, "__esModule", { value: true });
800
815
  exports.Color = void 0;
801
816
  const Pt_1 = __webpack_require__(/*! ./Pt */ "./src/Pt.ts");
@@ -1147,7 +1162,7 @@ Color.ranges = {
1147
1162
 
1148
1163
  "use strict";
1149
1164
 
1150
- /*! Source code licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
1165
+ /*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
1151
1166
  Object.defineProperty(exports, "__esModule", { value: true });
1152
1167
  exports.Delaunay = exports.Noise = exports.Create = void 0;
1153
1168
  const Pt_1 = __webpack_require__(/*! ./Pt */ "./src/Pt.ts");
@@ -1439,7 +1454,7 @@ exports.Delaunay = Delaunay;
1439
1454
 
1440
1455
  "use strict";
1441
1456
 
1442
- /*! Source code licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
1457
+ /*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
1443
1458
  Object.defineProperty(exports, "__esModule", { value: true });
1444
1459
  exports.HTMLForm = exports.HTMLSpace = exports.DOMSpace = void 0;
1445
1460
  const Space_1 = __webpack_require__(/*! ./Space */ "./src/Space.ts");
@@ -1904,7 +1919,7 @@ HTMLForm.domID = 0;
1904
1919
 
1905
1920
  "use strict";
1906
1921
 
1907
- /*! Source code licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
1922
+ /*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
1908
1923
  Object.defineProperty(exports, "__esModule", { value: true });
1909
1924
  exports.Font = exports.VisualForm = exports.Form = void 0;
1910
1925
  class Form {
@@ -2001,29 +2016,62 @@ exports.Font = Font;
2001
2016
 
2002
2017
  "use strict";
2003
2018
 
2019
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2020
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
2021
+ return new (P || (P = Promise))(function (resolve, reject) {
2022
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
2023
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
2024
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
2025
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
2026
+ });
2027
+ };
2004
2028
  Object.defineProperty(exports, "__esModule", { value: true });
2005
2029
  exports.Img = void 0;
2030
+ const Canvas_1 = __webpack_require__(/*! ./Canvas */ "./src/Canvas.ts");
2006
2031
  const Pt_1 = __webpack_require__(/*! ./Pt */ "./src/Pt.ts");
2032
+ const LinearAlgebra_1 = __webpack_require__(/*! ./LinearAlgebra */ "./src/LinearAlgebra.ts");
2007
2033
  class Img {
2008
- constructor(editable = false, pixelScale = 1, crossOrigin) {
2034
+ constructor(editable = false, space, crossOrigin) {
2009
2035
  this._scale = 1;
2010
2036
  this._loaded = false;
2011
2037
  this._editable = editable;
2012
- this._scale = pixelScale;
2038
+ this._space = space;
2039
+ this._scale = this._space ? this._space.pixelScale : 1;
2013
2040
  this._img = new Image();
2014
2041
  if (crossOrigin)
2015
2042
  this._img.crossOrigin = "Anonymous";
2016
2043
  }
2017
- static load(src, editable = false, pixelScale = 1, ready) {
2018
- let img = new Img(editable, pixelScale);
2044
+ static load(src, editable = false, space, ready) {
2045
+ const img = new Img(editable, space);
2019
2046
  img.load(src).then(res => {
2020
2047
  if (ready)
2021
2048
  ready(res);
2022
2049
  });
2023
2050
  return img;
2024
2051
  }
2052
+ static loadAsync(src, editable = false, space) {
2053
+ return __awaiter(this, void 0, void 0, function* () {
2054
+ const img = yield new Img(editable, space).load(src);
2055
+ return img;
2056
+ });
2057
+ }
2058
+ static loadPattern(src, space, repeat = 'repeat', editable = false) {
2059
+ return __awaiter(this, void 0, void 0, function* () {
2060
+ const img = yield Img.loadAsync(src, editable, space);
2061
+ return img.pattern(repeat);
2062
+ });
2063
+ }
2064
+ static blank(size, space, scale) {
2065
+ let img = new Img(true, space);
2066
+ const s = scale ? scale : space.pixelScale;
2067
+ img.initCanvas(size[0], size[1], s);
2068
+ return img;
2069
+ }
2025
2070
  load(src) {
2026
2071
  return new Promise((resolve, reject) => {
2072
+ if (this._editable && !document) {
2073
+ reject("Cannot create html canvas element. document not found.");
2074
+ }
2027
2075
  this._img.src = src;
2028
2076
  this._img.onload = () => {
2029
2077
  if (this._editable) {
@@ -2041,20 +2089,35 @@ class Img {
2041
2089
  });
2042
2090
  }
2043
2091
  _drawToScale(canvasScale, img) {
2044
- const cms = (typeof canvasScale === 'number') ? [canvasScale, canvasScale] : canvasScale;
2045
2092
  const nw = img.width;
2046
2093
  const nh = img.height;
2047
- this._cv.width = nw * cms[0];
2048
- this._cv.height = nh * cms[1];
2049
- this._ctx = this._cv.getContext('2d');
2094
+ this.initCanvas(nw, nh, canvasScale);
2050
2095
  if (img)
2051
2096
  this._ctx.drawImage(img, 0, 0, nw, nh, 0, 0, this._cv.width, this._cv.height);
2052
2097
  }
2098
+ initCanvas(width, height, canvasScale = 1) {
2099
+ if (!this._editable) {
2100
+ console.error('Cannot initiate canvas because this Img is not set to be editable');
2101
+ return;
2102
+ }
2103
+ if (!this._cv)
2104
+ this._cv = document.createElement("canvas");
2105
+ const cms = (typeof canvasScale === 'number') ? [canvasScale, canvasScale] : canvasScale;
2106
+ this._cv.width = width * cms[0];
2107
+ this._cv.height = height * cms[1];
2108
+ this._ctx = this._cv.getContext('2d');
2109
+ this._loaded = true;
2110
+ }
2053
2111
  bitmap(size) {
2054
2112
  const w = (size) ? size[0] : this._cv.width;
2055
2113
  const h = (size) ? size[1] : this._cv.height;
2056
2114
  return createImageBitmap(this._cv, 0, 0, w, h);
2057
2115
  }
2116
+ pattern(reptition = 'repeat', dynamic = false) {
2117
+ if (!this._space)
2118
+ throw "Cannot find CanvasSpace ctx to create image pattern";
2119
+ return this._space.ctx.createPattern(dynamic ? this._cv : this._img, reptition);
2120
+ }
2058
2121
  sync() {
2059
2122
  if (this._scale !== 1) {
2060
2123
  this.bitmap().then(b => {
@@ -2104,12 +2167,15 @@ class Img {
2104
2167
  this._img.remove();
2105
2168
  this._data = null;
2106
2169
  }
2107
- static fromBlob(blob, editable = false, pixelScale = 1) {
2170
+ static fromBlob(blob, editable = false, space) {
2108
2171
  let url = URL.createObjectURL(blob);
2109
- return new Img(editable, pixelScale).load(url);
2172
+ return new Img(editable, space).load(url);
2110
2173
  }
2111
2174
  static imageDataToBlob(data) {
2112
- return new Promise(function (resolve) {
2175
+ return new Promise(function (resolve, reject) {
2176
+ if (!document) {
2177
+ reject("Cannot create html canvas element. document not found.");
2178
+ }
2113
2179
  let cv = document.createElement("canvas");
2114
2180
  cv.width = data.width;
2115
2181
  cv.height = data.height;
@@ -2128,6 +2194,12 @@ class Img {
2128
2194
  this._cv.toBlob(blob => resolve(blob));
2129
2195
  });
2130
2196
  }
2197
+ getForm() {
2198
+ if (!this._editable) {
2199
+ console.error("Cannot get a CanvasForm because this Img is not editable");
2200
+ }
2201
+ return this._ctx ? new Canvas_1.CanvasForm(this._ctx) : undefined;
2202
+ }
2131
2203
  get current() {
2132
2204
  return this._editable ? this._cv : this._img;
2133
2205
  }
@@ -2150,11 +2222,20 @@ class Img {
2150
2222
  return this._scale;
2151
2223
  }
2152
2224
  get imageSize() {
2153
- return new Pt_1.Pt(this._img.width, this._img.height);
2225
+ if (!this._img.width || !this._img.height) {
2226
+ return this.canvasSize.$divide(this._scale);
2227
+ }
2228
+ else {
2229
+ return new Pt_1.Pt(this._img.width, this._img.height);
2230
+ }
2154
2231
  }
2155
2232
  get canvasSize() {
2156
2233
  return new Pt_1.Pt(this._cv.width, this._cv.height);
2157
2234
  }
2235
+ get scaledMatrix() {
2236
+ const s = 1 / this._scale;
2237
+ return new LinearAlgebra_1.Mat().scale2D([s, s]);
2238
+ }
2158
2239
  }
2159
2240
  exports.Img = Img;
2160
2241
 
@@ -2170,7 +2251,7 @@ exports.Img = Img;
2170
2251
 
2171
2252
  "use strict";
2172
2253
 
2173
- /*! Source code licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
2254
+ /*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
2174
2255
  Object.defineProperty(exports, "__esModule", { value: true });
2175
2256
  exports.Mat = exports.Vec = void 0;
2176
2257
  const Pt_1 = __webpack_require__(/*! ./Pt */ "./src/Pt.ts");
@@ -2299,6 +2380,38 @@ class Vec {
2299
2380
  }
2300
2381
  exports.Vec = Vec;
2301
2382
  class Mat {
2383
+ constructor() {
2384
+ this.reset();
2385
+ }
2386
+ get value() {
2387
+ return this._33;
2388
+ }
2389
+ get domMatrix() {
2390
+ return new DOMMatrix(Mat.toDOMMatrix(this._33));
2391
+ }
2392
+ reset() {
2393
+ this._33 = Mat.scale2DMatrix(1, 1);
2394
+ }
2395
+ scale2D(val, at = [0, 0]) {
2396
+ const m = Mat.scaleAt2DMatrix(val[0] || 1, val[1] || 1, at);
2397
+ this._33 = Mat.multiply(this._33, m);
2398
+ return this;
2399
+ }
2400
+ rotate2D(ang, at = [0, 0]) {
2401
+ const m = Mat.rotateAt2DMatrix(Math.cos(ang), Math.sin(ang), at);
2402
+ this._33 = Mat.multiply(this._33, m);
2403
+ return this;
2404
+ }
2405
+ translate2D(val) {
2406
+ const m = Mat.translate2DMatrix(val[0] || 0, val[1] || 0);
2407
+ this._33 = Mat.multiply(this._33, m);
2408
+ return this;
2409
+ }
2410
+ shear2D(val, at = [0, 0]) {
2411
+ const m = Mat.shearAt2DMatrix(Math.tan(val[0] || 0), Math.tan(val[1] || 1), at);
2412
+ this._33 = Mat.multiply(this._33, m);
2413
+ return this;
2414
+ }
2302
2415
  static add(a, b) {
2303
2416
  if (typeof b != "number") {
2304
2417
  if (a[0].length != b[0].length)
@@ -2366,6 +2479,9 @@ class Mat {
2366
2479
  static transpose(g, defaultValue = false, useLongest = false) {
2367
2480
  return Mat.zip(g, defaultValue, useLongest);
2368
2481
  }
2482
+ static toDOMMatrix(m) {
2483
+ return [m[0][0], m[0][1], m[1][0], m[1][1], m[2][0], m[2][1]];
2484
+ }
2369
2485
  static transform2D(pt, m) {
2370
2486
  let x = pt[0] * m[0][0] + pt[1] * m[1][0] + m[2][0];
2371
2487
  let y = pt[0] * m[0][1] + pt[1] * m[1][1] + m[2][1];
@@ -2437,7 +2553,7 @@ exports.Mat = Mat;
2437
2553
 
2438
2554
  "use strict";
2439
2555
 
2440
- /*! Source code licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
2556
+ /*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
2441
2557
  Object.defineProperty(exports, "__esModule", { value: true });
2442
2558
  exports.Range = exports.Shaping = exports.Geom = exports.Num = void 0;
2443
2559
  const Util_1 = __webpack_require__(/*! ./Util */ "./src/Util.ts");
@@ -2932,7 +3048,7 @@ exports.Range = Range;
2932
3048
 
2933
3049
  "use strict";
2934
3050
 
2935
- /*! Source code licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
3051
+ /*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
2936
3052
  Object.defineProperty(exports, "__esModule", { value: true });
2937
3053
  exports.Curve = exports.Polygon = exports.Triangle = exports.Circle = exports.Rectangle = exports.Line = void 0;
2938
3054
  const Util_1 = __webpack_require__(/*! ./Util */ "./src/Util.ts");
@@ -3930,7 +4046,7 @@ exports.Curve = Curve;
3930
4046
 
3931
4047
  "use strict";
3932
4048
 
3933
- /*! Source code licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
4049
+ /*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
3934
4050
  Object.defineProperty(exports, "__esModule", { value: true });
3935
4051
  exports.Body = exports.Particle = exports.World = void 0;
3936
4052
  const Pt_1 = __webpack_require__(/*! ./Pt */ "./src/Pt.ts");
@@ -4685,7 +4801,7 @@ exports.Sound = Sound;
4685
4801
 
4686
4802
  "use strict";
4687
4803
 
4688
- /*! Source code licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
4804
+ /*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
4689
4805
  Object.defineProperty(exports, "__esModule", { value: true });
4690
4806
  exports.Bound = exports.Group = exports.Pt = void 0;
4691
4807
  const Util_1 = __webpack_require__(/*! ./Util */ "./src/Util.ts");
@@ -5036,6 +5152,9 @@ class Group extends Array {
5036
5152
  $zip(defaultValue = undefined, useLongest = false) {
5037
5153
  return LinearAlgebra_1.Mat.zip(this, defaultValue, useLongest);
5038
5154
  }
5155
+ toBound() {
5156
+ return Bound.fromGroup(this);
5157
+ }
5039
5158
  toString() {
5040
5159
  return "Group[ " + this.reduce((p, c) => p + c.toString() + " ", "") + " ]";
5041
5160
  }
@@ -5162,7 +5281,7 @@ exports.Bound = Bound;
5162
5281
 
5163
5282
  "use strict";
5164
5283
 
5165
- /*! Source code licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
5284
+ /*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
5166
5285
  Object.defineProperty(exports, "__esModule", { value: true });
5167
5286
  exports.MultiTouchSpace = exports.Space = void 0;
5168
5287
  const Pt_1 = __webpack_require__(/*! ./Pt */ "./src/Pt.ts");
@@ -5171,7 +5290,7 @@ class Space {
5171
5290
  constructor() {
5172
5291
  this.id = "space";
5173
5292
  this.bound = new Pt_1.Bound();
5174
- this._time = { prev: 0, diff: 0, end: -1 };
5293
+ this._time = { prev: 0, diff: 0, end: -1, min: 0 };
5175
5294
  this.players = {};
5176
5295
  this.playerCount = 0;
5177
5296
  this._animID = -1;
@@ -5185,6 +5304,9 @@ class Space {
5185
5304
  this._refresh = b;
5186
5305
  return this;
5187
5306
  }
5307
+ minFrameTime(ms = 0) {
5308
+ this._time.min = ms;
5309
+ }
5188
5310
  add(p) {
5189
5311
  let player = (typeof p == "function") ? { animate: p } : p;
5190
5312
  let k = this.playerCount++;
@@ -5213,6 +5335,8 @@ class Space {
5213
5335
  if (this._pause)
5214
5336
  return this;
5215
5337
  this._time.diff = time - this._time.prev;
5338
+ if (this._time.diff < this._time.min)
5339
+ return this;
5216
5340
  this._time.prev = time;
5217
5341
  try {
5218
5342
  this.playItems(time);
@@ -5257,7 +5381,7 @@ class Space {
5257
5381
  this._time.end = t;
5258
5382
  return this;
5259
5383
  }
5260
- playOnce(duration = 5000) {
5384
+ playOnce(duration = 0) {
5261
5385
  this.play();
5262
5386
  this.stop(duration);
5263
5387
  return this;
@@ -5285,58 +5409,93 @@ class MultiTouchSpace extends Space {
5285
5409
  this._dragged = false;
5286
5410
  this._hasMouse = false;
5287
5411
  this._hasTouch = false;
5412
+ this._hasKeyboard = false;
5288
5413
  }
5289
5414
  get pointer() {
5290
5415
  let p = this._pointer.clone();
5291
5416
  p.id = this._pointer.id;
5292
5417
  return p;
5293
5418
  }
5294
- bindCanvas(evt, callback, options = {}) {
5295
- this._canvas.addEventListener(evt, callback, options);
5296
- }
5297
- unbindCanvas(evt, callback, options = {}) {
5298
- this._canvas.removeEventListener(evt, callback, options);
5299
- }
5300
- bindMouse(_bind = true) {
5301
- if (_bind) {
5302
- this.bindCanvas("mousedown", this._mouseDown.bind(this));
5303
- this.bindCanvas("mouseup", this._mouseUp.bind(this));
5304
- this.bindCanvas("mouseover", this._mouseOver.bind(this));
5305
- this.bindCanvas("mouseout", this._mouseOut.bind(this));
5306
- this.bindCanvas("mousemove", this._mouseMove.bind(this));
5307
- this.bindCanvas("click", this._mouseClick.bind(this));
5308
- this.bindCanvas("contextmenu", this._contextMenu.bind(this));
5419
+ bindCanvas(evt, callback, options = {}, customTarget) {
5420
+ const target = customTarget ? customTarget : this._canvas;
5421
+ target.addEventListener(evt, callback, options);
5422
+ }
5423
+ unbindCanvas(evt, callback, options = {}, customTarget) {
5424
+ const target = customTarget ? customTarget : this._canvas;
5425
+ target.removeEventListener(evt, callback, options);
5426
+ }
5427
+ bindDoc(evt, callback, options = {}) {
5428
+ if (document) {
5429
+ document.addEventListener(evt, callback, options);
5430
+ }
5431
+ }
5432
+ unbindDoc(evt, callback, options = {}) {
5433
+ if (document) {
5434
+ document.removeEventListener(evt, callback, options);
5435
+ }
5436
+ }
5437
+ bindMouse(bind = true, customTarget) {
5438
+ if (bind) {
5439
+ this._mouseDown = this._mouseDown.bind(this);
5440
+ this._mouseUp = this._mouseUp.bind(this);
5441
+ this._mouseOver = this._mouseOver.bind(this);
5442
+ this._mouseOut = this._mouseOut.bind(this);
5443
+ this._mouseMove = this._mouseMove.bind(this);
5444
+ this._mouseClick = this._mouseClick.bind(this);
5445
+ this._contextMenu = this._contextMenu.bind(this);
5446
+ this.bindCanvas("mousedown", this._mouseDown, {}, customTarget);
5447
+ this.bindCanvas("mouseup", this._mouseUp, {}, customTarget);
5448
+ this.bindCanvas("mouseover", this._mouseOver, {}, customTarget);
5449
+ this.bindCanvas("mouseout", this._mouseOut, {}, customTarget);
5450
+ this.bindCanvas("mousemove", this._mouseMove, {}, customTarget);
5451
+ this.bindCanvas("click", this._mouseClick, {}, customTarget);
5452
+ this.bindCanvas("contextmenu", this._contextMenu, {}, customTarget);
5309
5453
  this._hasMouse = true;
5310
5454
  }
5311
5455
  else {
5312
- this.unbindCanvas("mousedown", this._mouseDown.bind(this));
5313
- this.unbindCanvas("mouseup", this._mouseUp.bind(this));
5314
- this.unbindCanvas("mouseover", this._mouseOver.bind(this));
5315
- this.unbindCanvas("mouseout", this._mouseOut.bind(this));
5316
- this.unbindCanvas("mousemove", this._mouseMove.bind(this));
5317
- this.unbindCanvas("click", this._mouseClick.bind(this));
5318
- this.unbindCanvas("contextmenu", this._contextMenu.bind(this));
5456
+ this.unbindCanvas("mousedown", this._mouseDown, {}, customTarget);
5457
+ this.unbindCanvas("mouseup", this._mouseUp, {}, customTarget);
5458
+ this.unbindCanvas("mouseover", this._mouseOver, {}, customTarget);
5459
+ this.unbindCanvas("mouseout", this._mouseOut, {}, customTarget);
5460
+ this.unbindCanvas("mousemove", this._mouseMove, {}, customTarget);
5461
+ this.unbindCanvas("click", this._mouseClick, {}, customTarget);
5462
+ this.unbindCanvas("contextmenu", this._contextMenu, {}, customTarget);
5319
5463
  this._hasMouse = false;
5320
5464
  }
5321
5465
  return this;
5322
5466
  }
5323
- bindTouch(bind = true, passive = false) {
5467
+ bindTouch(bind = true, passive = false, customTarget) {
5324
5468
  if (bind) {
5325
- this.bindCanvas("touchstart", this._touchStart.bind(this), { passive: passive });
5326
- this.bindCanvas("touchend", this._mouseUp.bind(this));
5327
- this.bindCanvas("touchmove", this._touchMove.bind(this), { passive: passive });
5328
- this.bindCanvas("touchcancel", this._mouseOut.bind(this));
5469
+ this.bindCanvas("touchstart", this._touchStart.bind(this), { passive: passive }, customTarget);
5470
+ this.bindCanvas("touchend", this._mouseUp.bind(this), {}, customTarget);
5471
+ this.bindCanvas("touchmove", this._touchMove.bind(this), { passive: passive }, customTarget);
5472
+ this.bindCanvas("touchcancel", this._mouseOut.bind(this), {}, customTarget);
5329
5473
  this._hasTouch = true;
5330
5474
  }
5331
5475
  else {
5332
- this.unbindCanvas("touchstart", this._touchStart.bind(this), { passive: passive });
5333
- this.unbindCanvas("touchend", this._mouseUp.bind(this));
5334
- this.unbindCanvas("touchmove", this._touchMove.bind(this), { passive: passive });
5335
- this.unbindCanvas("touchcancel", this._mouseOut.bind(this));
5476
+ this.unbindCanvas("touchstart", this._touchStart.bind(this), { passive: passive }, customTarget);
5477
+ this.unbindCanvas("touchend", this._mouseUp.bind(this), {}, customTarget);
5478
+ this.unbindCanvas("touchmove", this._touchMove.bind(this), { passive: passive }, customTarget);
5479
+ this.unbindCanvas("touchcancel", this._mouseOut.bind(this), {}, customTarget);
5336
5480
  this._hasTouch = false;
5337
5481
  }
5338
5482
  return this;
5339
5483
  }
5484
+ bindKeyboard(bind = true) {
5485
+ if (bind) {
5486
+ this._keyDownBind = this._keyDown.bind(this);
5487
+ this._keyUpBind = this._keyUp.bind(this);
5488
+ this.bindDoc("keydown", this._keyDownBind, {});
5489
+ this.bindDoc("keyup", this._keyUpBind, {});
5490
+ this._hasKeyboard = true;
5491
+ }
5492
+ else {
5493
+ this.unbindDoc("keydown", this._keyDownBind, {});
5494
+ this.unbindDoc("keyup", this._keyUpBind, {});
5495
+ this._hasKeyboard = false;
5496
+ }
5497
+ return this;
5498
+ }
5340
5499
  touchesToPoints(evt, which = "touches") {
5341
5500
  if (!evt || !evt[which])
5342
5501
  return [];
@@ -5348,6 +5507,8 @@ class MultiTouchSpace extends Space {
5348
5507
  return ts;
5349
5508
  }
5350
5509
  _mouseAction(type, evt) {
5510
+ if (!this.isPlaying)
5511
+ return;
5351
5512
  let px = 0, py = 0;
5352
5513
  if (evt instanceof MouseEvent) {
5353
5514
  for (let k in this.players) {
@@ -5433,6 +5594,25 @@ class MultiTouchSpace extends Space {
5433
5594
  evt.preventDefault();
5434
5595
  return false;
5435
5596
  }
5597
+ _keyDown(evt) {
5598
+ this._keyboardAction(UI_1.UIPointerActions.keydown, evt);
5599
+ return false;
5600
+ }
5601
+ _keyUp(evt) {
5602
+ this._keyboardAction(UI_1.UIPointerActions.keyup, evt);
5603
+ return false;
5604
+ }
5605
+ _keyboardAction(type, evt) {
5606
+ if (!this.isPlaying)
5607
+ return;
5608
+ for (let k in this.players) {
5609
+ if (this.players.hasOwnProperty(k)) {
5610
+ let v = this.players[k];
5611
+ if (v.action)
5612
+ v.action(type, evt.shiftKey ? 1 : 0, evt.altKey ? 1 : 0, evt);
5613
+ }
5614
+ }
5615
+ }
5436
5616
  }
5437
5617
  exports.MultiTouchSpace = MultiTouchSpace;
5438
5618
 
@@ -5448,7 +5628,7 @@ exports.MultiTouchSpace = MultiTouchSpace;
5448
5628
 
5449
5629
  "use strict";
5450
5630
 
5451
- /*! Source code licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
5631
+ /*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
5452
5632
  Object.defineProperty(exports, "__esModule", { value: true });
5453
5633
  exports.SVGForm = exports.SVGSpace = void 0;
5454
5634
  const Form_1 = __webpack_require__(/*! ./Form */ "./src/Form.ts");
@@ -5831,7 +6011,7 @@ SVGForm.domID = 0;
5831
6011
 
5832
6012
  "use strict";
5833
6013
 
5834
- /*! Source code licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
6014
+ /*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
5835
6015
  Object.defineProperty(exports, "__esModule", { value: true });
5836
6016
  exports.Typography = void 0;
5837
6017
  const Pt_1 = __webpack_require__(/*! ./Pt */ "./src/Pt.ts");
@@ -5886,7 +6066,7 @@ exports.Typography = Typography;
5886
6066
 
5887
6067
  "use strict";
5888
6068
 
5889
- /*! Source code licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
6069
+ /*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
5890
6070
  Object.defineProperty(exports, "__esModule", { value: true });
5891
6071
  exports.UIDragger = exports.UIButton = exports.UI = exports.UIPointerActions = exports.UIShape = void 0;
5892
6072
  const Pt_1 = __webpack_require__(/*! ./Pt */ "./src/Pt.ts");
@@ -5895,7 +6075,11 @@ exports.UIShape = {
5895
6075
  rectangle: "rectangle", circle: "circle", polygon: "polygon", polyline: "polyline", line: "line"
5896
6076
  };
5897
6077
  exports.UIPointerActions = {
5898
- up: "up", down: "down", move: "move", drag: "drag", uidrag: "uidrag", drop: "drop", uidrop: "uidrop", over: "over", out: "out", enter: "enter", leave: "leave", click: "click", contextmenu: "contextmenu", all: "all"
6078
+ up: "up", down: "down", move: "move",
6079
+ drag: "drag", uidrag: "uidrag", drop: "drop", uidrop: "uidrop",
6080
+ over: "over", out: "out", enter: "enter", leave: "leave", click: "click",
6081
+ keydown: 'keydown', keyup: 'keyup',
6082
+ contextmenu: "contextmenu", all: "all"
5899
6083
  };
5900
6084
  class UI {
5901
6085
  constructor(group, shape, states = {}, id) {
@@ -6172,7 +6356,7 @@ exports.UIDragger = UIDragger;
6172
6356
 
6173
6357
  "use strict";
6174
6358
 
6175
- /*! Source code licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
6359
+ /*! Pts.js is licensed under Apache License 2.0. Copyright © 2017-current William Ngan and contributors. (https://github.com/williamngan/pts) */
6176
6360
  Object.defineProperty(exports, "__esModule", { value: true });
6177
6361
  exports.Util = exports.Const = void 0;
6178
6362
  const Num_1 = __webpack_require__(/*! ./Num */ "./src/Num.ts");
@@ -6333,6 +6517,19 @@ class Util {
6333
6517
  };
6334
6518
  request.send();
6335
6519
  }
6520
+ static download(space, filename = 'pts_canvas_image', filetype = "png", quality = 1) {
6521
+ const ftype = filetype === 'jpg' ? 'jpeg' : filetype;
6522
+ space.element.toBlob(function (blob) {
6523
+ const link = document.createElement('a');
6524
+ const url = URL.createObjectURL(blob);
6525
+ link.href = url;
6526
+ link.download = `${filename}.${filetype}`;
6527
+ document.body.appendChild(link);
6528
+ link.click();
6529
+ document.body.removeChild(link);
6530
+ URL.revokeObjectURL(url);
6531
+ }, `image/${ftype}`, quality);
6532
+ }
6336
6533
  static performance(avgFrames = 10) {
6337
6534
  let last = Date.now();
6338
6535
  let avg = [];