pts 0.10.9 → 0.10.12

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_module.js","sourceRoot":"","sources":["../../src/_module.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,iBAAiB,CAAC;AAChC,cAAc,OAAO,CAAC;AACtB,cAAc,MAAM,CAAC;AACrB,cAAc,MAAM,CAAC;AACrB,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,OAAO,CAAC;AACtB,cAAc,OAAO,CAAC;AACtB,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,MAAM,CAAC;AACrB,cAAc,SAAS,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uheprng.js","sourceRoot":"","sources":["../../src/uheprng.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * pts.js 0.10.9 - Copyright © 2017-2021 William Ngan and contributors.
2
+ * pts.js 0.10.12 - 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
  */
@@ -378,7 +378,7 @@ class CanvasForm extends Form_1.VisualForm {
378
378
  }
379
379
  }
380
380
  get space() { return this._space; }
381
- get ctx() { return this._space.ctx; }
381
+ get ctx() { return this._ctx; }
382
382
  useOffscreen(off = true, clear = false) {
383
383
  if (clear)
384
384
  this._space.clearOffscreen((typeof clear == "string") ? clear : null);
@@ -456,8 +456,8 @@ class CanvasForm extends Form_1.VisualForm {
456
456
  if (area2)
457
457
  area2.map(a => a.abs());
458
458
  let grad = area2
459
- ? this.ctx.createRadialGradient(area1[0][0], area1[0][1], area1[1][0], area2[0][0], area2[0][1], area2[1][0])
460
- : this.ctx.createLinearGradient(area1[0][0], area1[0][1], area1[1][0], area1[1][1]);
459
+ ? this._ctx.createRadialGradient(area1[0][0], area1[0][1], area1[1][0], area2[0][0], area2[0][1], area2[1][0])
460
+ : this._ctx.createLinearGradient(area1[0][0], area1[0][1], area1[1][0], area1[1][1]);
461
461
  for (let i = 0, len = vals.length; i < len; i++) {
462
462
  grad.addColorStop(vals[i][0], vals[i][1]);
463
463
  }
@@ -465,11 +465,11 @@ class CanvasForm extends Form_1.VisualForm {
465
465
  };
466
466
  }
467
467
  composite(mode = 'source-over') {
468
- this.ctx.globalCompositeOperation = mode;
468
+ this._ctx.globalCompositeOperation = mode;
469
469
  return this;
470
470
  }
471
471
  clip() {
472
- this.ctx.clip();
472
+ this._ctx.clip();
473
473
  return this;
474
474
  }
475
475
  dash(segments = true, offset = 0) {
@@ -2016,29 +2016,62 @@ exports.Font = Font;
2016
2016
 
2017
2017
  "use strict";
2018
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
+ };
2019
2028
  Object.defineProperty(exports, "__esModule", { value: true });
2020
2029
  exports.Img = void 0;
2030
+ const Canvas_1 = __webpack_require__(/*! ./Canvas */ "./src/Canvas.ts");
2021
2031
  const Pt_1 = __webpack_require__(/*! ./Pt */ "./src/Pt.ts");
2032
+ const LinearAlgebra_1 = __webpack_require__(/*! ./LinearAlgebra */ "./src/LinearAlgebra.ts");
2022
2033
  class Img {
2023
- constructor(editable = false, pixelScale = 1, crossOrigin) {
2034
+ constructor(editable = false, space, crossOrigin) {
2024
2035
  this._scale = 1;
2025
2036
  this._loaded = false;
2026
2037
  this._editable = editable;
2027
- this._scale = pixelScale;
2038
+ this._space = space;
2039
+ this._scale = this._space ? this._space.pixelScale : 1;
2028
2040
  this._img = new Image();
2029
2041
  if (crossOrigin)
2030
2042
  this._img.crossOrigin = "Anonymous";
2031
2043
  }
2032
- static load(src, editable = false, pixelScale = 1, ready) {
2033
- let img = new Img(editable, pixelScale);
2044
+ static load(src, editable = false, space, ready) {
2045
+ const img = new Img(editable, space);
2034
2046
  img.load(src).then(res => {
2035
2047
  if (ready)
2036
2048
  ready(res);
2037
2049
  });
2038
2050
  return img;
2039
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
+ }
2040
2070
  load(src) {
2041
2071
  return new Promise((resolve, reject) => {
2072
+ if (this._editable && !document) {
2073
+ reject("Cannot create html canvas element. document not found.");
2074
+ }
2042
2075
  this._img.src = src;
2043
2076
  this._img.onload = () => {
2044
2077
  if (this._editable) {
@@ -2056,20 +2089,35 @@ class Img {
2056
2089
  });
2057
2090
  }
2058
2091
  _drawToScale(canvasScale, img) {
2059
- const cms = (typeof canvasScale === 'number') ? [canvasScale, canvasScale] : canvasScale;
2060
2092
  const nw = img.width;
2061
2093
  const nh = img.height;
2062
- this._cv.width = nw * cms[0];
2063
- this._cv.height = nh * cms[1];
2064
- this._ctx = this._cv.getContext('2d');
2094
+ this.initCanvas(nw, nh, canvasScale);
2065
2095
  if (img)
2066
2096
  this._ctx.drawImage(img, 0, 0, nw, nh, 0, 0, this._cv.width, this._cv.height);
2067
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
+ }
2068
2111
  bitmap(size) {
2069
2112
  const w = (size) ? size[0] : this._cv.width;
2070
2113
  const h = (size) ? size[1] : this._cv.height;
2071
2114
  return createImageBitmap(this._cv, 0, 0, w, h);
2072
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
+ }
2073
2121
  sync() {
2074
2122
  if (this._scale !== 1) {
2075
2123
  this.bitmap().then(b => {
@@ -2119,12 +2167,15 @@ class Img {
2119
2167
  this._img.remove();
2120
2168
  this._data = null;
2121
2169
  }
2122
- static fromBlob(blob, editable = false, pixelScale = 1) {
2170
+ static fromBlob(blob, editable = false, space) {
2123
2171
  let url = URL.createObjectURL(blob);
2124
- return new Img(editable, pixelScale).load(url);
2172
+ return new Img(editable, space).load(url);
2125
2173
  }
2126
2174
  static imageDataToBlob(data) {
2127
- 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
+ }
2128
2179
  let cv = document.createElement("canvas");
2129
2180
  cv.width = data.width;
2130
2181
  cv.height = data.height;
@@ -2143,6 +2194,12 @@ class Img {
2143
2194
  this._cv.toBlob(blob => resolve(blob));
2144
2195
  });
2145
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
+ }
2146
2203
  get current() {
2147
2204
  return this._editable ? this._cv : this._img;
2148
2205
  }
@@ -2165,11 +2222,20 @@ class Img {
2165
2222
  return this._scale;
2166
2223
  }
2167
2224
  get imageSize() {
2168
- 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
+ }
2169
2231
  }
2170
2232
  get canvasSize() {
2171
2233
  return new Pt_1.Pt(this._cv.width, this._cv.height);
2172
2234
  }
2235
+ get scaledMatrix() {
2236
+ const s = 1 / this._scale;
2237
+ return new LinearAlgebra_1.Mat().scale2D([s, s]);
2238
+ }
2173
2239
  }
2174
2240
  exports.Img = Img;
2175
2241
 
@@ -2314,6 +2380,38 @@ class Vec {
2314
2380
  }
2315
2381
  exports.Vec = Vec;
2316
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
+ }
2317
2415
  static add(a, b) {
2318
2416
  if (typeof b != "number") {
2319
2417
  if (a[0].length != b[0].length)
@@ -2381,6 +2479,9 @@ class Mat {
2381
2479
  static transpose(g, defaultValue = false, useLongest = false) {
2382
2480
  return Mat.zip(g, defaultValue, useLongest);
2383
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
+ }
2384
2485
  static transform2D(pt, m) {
2385
2486
  let x = pt[0] * m[0][0] + pt[1] * m[1][0] + m[2][0];
2386
2487
  let y = pt[0] * m[0][1] + pt[1] * m[1][1] + m[2][1];
@@ -5051,6 +5152,9 @@ class Group extends Array {
5051
5152
  $zip(defaultValue = undefined, useLongest = false) {
5052
5153
  return LinearAlgebra_1.Mat.zip(this, defaultValue, useLongest);
5053
5154
  }
5155
+ toBound() {
5156
+ return Bound.fromGroup(this);
5157
+ }
5054
5158
  toString() {
5055
5159
  return "Group[ " + this.reduce((p, c) => p + c.toString() + " ", "") + " ]";
5056
5160
  }
@@ -5186,7 +5290,7 @@ class Space {
5186
5290
  constructor() {
5187
5291
  this.id = "space";
5188
5292
  this.bound = new Pt_1.Bound();
5189
- this._time = { prev: 0, diff: 0, end: -1 };
5293
+ this._time = { prev: 0, diff: 0, end: -1, min: 0 };
5190
5294
  this.players = {};
5191
5295
  this.playerCount = 0;
5192
5296
  this._animID = -1;
@@ -5200,6 +5304,9 @@ class Space {
5200
5304
  this._refresh = b;
5201
5305
  return this;
5202
5306
  }
5307
+ minFrameTime(ms = 0) {
5308
+ this._time.min = ms;
5309
+ }
5203
5310
  add(p) {
5204
5311
  let player = (typeof p == "function") ? { animate: p } : p;
5205
5312
  let k = this.playerCount++;
@@ -5228,6 +5335,8 @@ class Space {
5228
5335
  if (this._pause)
5229
5336
  return this;
5230
5337
  this._time.diff = time - this._time.prev;
5338
+ if (this._time.diff < this._time.min)
5339
+ return this;
5231
5340
  this._time.prev = time;
5232
5341
  try {
5233
5342
  this.playItems(time);
@@ -5300,20 +5409,33 @@ class MultiTouchSpace extends Space {
5300
5409
  this._dragged = false;
5301
5410
  this._hasMouse = false;
5302
5411
  this._hasTouch = false;
5412
+ this._hasKeyboard = false;
5303
5413
  }
5304
5414
  get pointer() {
5305
5415
  let p = this._pointer.clone();
5306
5416
  p.id = this._pointer.id;
5307
5417
  return p;
5308
5418
  }
5309
- bindCanvas(evt, callback, options = {}) {
5310
- this._canvas.addEventListener(evt, callback, options);
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);
5311
5426
  }
5312
- unbindCanvas(evt, callback, options = {}) {
5313
- this._canvas.removeEventListener(evt, callback, options);
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
+ }
5314
5436
  }
5315
- bindMouse(_bind = true) {
5316
- if (_bind) {
5437
+ bindMouse(bind = true, customTarget) {
5438
+ if (bind) {
5317
5439
  this._mouseDown = this._mouseDown.bind(this);
5318
5440
  this._mouseUp = this._mouseUp.bind(this);
5319
5441
  this._mouseOver = this._mouseOver.bind(this);
@@ -5321,44 +5443,59 @@ class MultiTouchSpace extends Space {
5321
5443
  this._mouseMove = this._mouseMove.bind(this);
5322
5444
  this._mouseClick = this._mouseClick.bind(this);
5323
5445
  this._contextMenu = this._contextMenu.bind(this);
5324
- this.bindCanvas("mousedown", this._mouseDown);
5325
- this.bindCanvas("mouseup", this._mouseUp);
5326
- this.bindCanvas("mouseover", this._mouseOver);
5327
- this.bindCanvas("mouseout", this._mouseOut);
5328
- this.bindCanvas("mousemove", this._mouseMove);
5329
- this.bindCanvas("click", this._mouseClick);
5330
- this.bindCanvas("contextmenu", this._contextMenu);
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);
5331
5453
  this._hasMouse = true;
5332
5454
  }
5333
5455
  else {
5334
- this.unbindCanvas("mousedown", this._mouseDown);
5335
- this.unbindCanvas("mouseup", this._mouseUp);
5336
- this.unbindCanvas("mouseover", this._mouseOver);
5337
- this.unbindCanvas("mouseout", this._mouseOut);
5338
- this.unbindCanvas("mousemove", this._mouseMove);
5339
- this.unbindCanvas("click", this._mouseClick);
5340
- this.unbindCanvas("contextmenu", this._contextMenu);
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);
5341
5463
  this._hasMouse = false;
5342
5464
  }
5343
5465
  return this;
5344
5466
  }
5345
- bindTouch(bind = true, passive = false) {
5467
+ bindTouch(bind = true, passive = false, customTarget) {
5346
5468
  if (bind) {
5347
- this.bindCanvas("touchstart", this._touchStart.bind(this), { passive: passive });
5348
- this.bindCanvas("touchend", this._mouseUp.bind(this));
5349
- this.bindCanvas("touchmove", this._touchMove.bind(this), { passive: passive });
5350
- 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);
5351
5473
  this._hasTouch = true;
5352
5474
  }
5353
5475
  else {
5354
- this.unbindCanvas("touchstart", this._touchStart.bind(this), { passive: passive });
5355
- this.unbindCanvas("touchend", this._mouseUp.bind(this));
5356
- this.unbindCanvas("touchmove", this._touchMove.bind(this), { passive: passive });
5357
- 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);
5358
5480
  this._hasTouch = false;
5359
5481
  }
5360
5482
  return this;
5361
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
+ }
5362
5499
  touchesToPoints(evt, which = "touches") {
5363
5500
  if (!evt || !evt[which])
5364
5501
  return [];
@@ -5370,6 +5507,8 @@ class MultiTouchSpace extends Space {
5370
5507
  return ts;
5371
5508
  }
5372
5509
  _mouseAction(type, evt) {
5510
+ if (!this.isPlaying)
5511
+ return;
5373
5512
  let px = 0, py = 0;
5374
5513
  if (evt instanceof MouseEvent) {
5375
5514
  for (let k in this.players) {
@@ -5455,6 +5594,25 @@ class MultiTouchSpace extends Space {
5455
5594
  evt.preventDefault();
5456
5595
  return false;
5457
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
+ }
5458
5616
  }
5459
5617
  exports.MultiTouchSpace = MultiTouchSpace;
5460
5618
 
@@ -5917,7 +6075,11 @@ exports.UIShape = {
5917
6075
  rectangle: "rectangle", circle: "circle", polygon: "polygon", polyline: "polyline", line: "line"
5918
6076
  };
5919
6077
  exports.UIPointerActions = {
5920
- 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"
5921
6083
  };
5922
6084
  class UI {
5923
6085
  constructor(group, shape, states = {}, id) {
@@ -6355,6 +6517,19 @@ class Util {
6355
6517
  };
6356
6518
  request.send();
6357
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
+ }
6358
6533
  static performance(avgFrames = 10) {
6359
6534
  let last = Date.now();
6360
6535
  let avg = [];