targetj 1.1.0 → 1.1.1

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.
@@ -6,6 +6,9 @@ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r)
6
6
  function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
7
7
  function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
8
8
  function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
9
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
10
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
11
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
9
12
  function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, catch: function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; }
10
13
  function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
11
14
  function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
@@ -33,12 +36,24 @@ var ParticleRenderer = /*#__PURE__*/function () {
33
36
  this.particleBuffer = undefined;
34
37
  this.targetParticleBuffer = undefined;
35
38
  this.uniformBuffer = undefined;
39
+ this.explodeFragmentBuffer = undefined;
40
+ this.explodeTexture = undefined;
41
+ this.explodeSampler = undefined;
42
+ this.explodeSourceCanvas = undefined;
43
+ this.explodeTextureReady = false;
36
44
  this.transitionStep = 0;
37
45
  this.transitionActive = false;
38
46
  this.particleCount = 0;
39
47
  this.canvasLayer = undefined;
48
+
49
+ // Canvas origin and viewport are in the owning TModel's local content space.
40
50
  this.canvasX = 0;
41
51
  this.canvasY = 0;
52
+ this.canvasBounds = undefined;
53
+ this.canvasSize = undefined;
54
+ this.boundsDirty = true;
55
+ this.currentParticleData = undefined;
56
+ this.targetParticleData = undefined;
42
57
  this.initializationPromise = undefined;
43
58
  }
44
59
  return _createClass(ParticleRenderer, [{
@@ -50,28 +65,29 @@ var ParticleRenderer = /*#__PURE__*/function () {
50
65
  while (1) switch (_context.prev = _context.next) {
51
66
  case 0:
52
67
  if (!this.device) {
53
- _context.next = 2;
68
+ _context.next = 3;
54
69
  break;
55
70
  }
71
+ this.mountCanvasLayer();
56
72
  return _context.abrupt("return", true);
57
- case 2:
73
+ case 3:
58
74
  if (this.tmodel.hasDom()) {
59
- _context.next = 4;
75
+ _context.next = 5;
60
76
  break;
61
77
  }
62
78
  return _context.abrupt("return", false);
63
- case 4:
79
+ case 5:
64
80
  if (!this.initializationPromise) {
65
81
  this.initializationPromise = this.initialize().catch(function (error) {
66
82
  _this.initializationPromise = undefined;
67
83
  throw error;
68
84
  });
69
85
  }
70
- _context.next = 7;
86
+ _context.next = 8;
71
87
  return this.initializationPromise;
72
- case 7:
73
- return _context.abrupt("return", !!this.device);
74
88
  case 8:
89
+ return _context.abrupt("return", !!this.device);
90
+ case 9:
75
91
  case "end":
76
92
  return _context.stop();
77
93
  }
@@ -129,11 +145,13 @@ var ParticleRenderer = /*#__PURE__*/function () {
129
145
  this.context.configure({
130
146
  device: this.device,
131
147
  format: this.format,
132
- alphaMode: "premultiplied"
148
+ alphaMode: "premultiplied",
149
+ usage: globalThis.GPUTextureUsage.RENDER_ATTACHMENT | globalThis.GPUTextureUsage.COPY_SRC
133
150
  });
134
151
  this.createUniformBuffer();
152
+ this.createExplodeResources();
135
153
  this.createPipeline();
136
- case 21:
154
+ case 22:
137
155
  case "end":
138
156
  return _context2.stop();
139
157
  }
@@ -147,21 +165,11 @@ var ParticleRenderer = /*#__PURE__*/function () {
147
165
  }, {
148
166
  key: "createCanvas",
149
167
  value: function createCanvas() {
150
- var _this$tmodel$$dom,
151
- _this2 = this,
152
- _this$tmodel$$dom2,
153
- _this$tmodel$getParen;
168
+ var _this2 = this;
154
169
  if (this.canvas) {
170
+ this.mountCanvasLayer();
155
171
  return;
156
172
  }
157
- var parent = (_this$tmodel$$dom = this.tmodel.$dom) === null || _this$tmodel$$dom === void 0 ? void 0 : _this$tmodel$$dom.element;
158
- if (!parent) {
159
- throw new Error("Unable to create a GPU child layer without a parent DOM element.");
160
- }
161
- var oldLayer = parent.querySelector('[data-targetjs-gpu-layer="true"]');
162
- if (oldLayer) {
163
- oldLayer.remove();
164
- }
165
173
  this.canvasLayer = document.createElement("div");
166
174
  this.canvasLayer.setAttribute("data-targetjs-gpu-layer", "true");
167
175
  Object.assign(this.canvasLayer.style, {
@@ -175,6 +183,9 @@ var ParticleRenderer = /*#__PURE__*/function () {
175
183
  });
176
184
  this.canvas = document.createElement("canvas");
177
185
  this.canvas.setAttribute("data-targetjs-gpu-children", "true");
186
+ this.canvas.captureBitmap = function () {
187
+ return _this2.captureBitmap();
188
+ };
178
189
  Object.assign(this.canvas.style, {
179
190
  position: "absolute",
180
191
  left: "0px",
@@ -185,25 +196,13 @@ var ParticleRenderer = /*#__PURE__*/function () {
185
196
  pointerEvents: "none"
186
197
  });
187
198
  this.canvasLayer.appendChild(this.canvas);
188
- parent.prepend(this.canvasLayer);
199
+ if (!this.mountCanvasLayer()) {
200
+ throw new Error("Unable to mount GPU child layer.");
201
+ }
189
202
  this.onScroll = function () {
190
203
  return _this2.tmodel.requestParticleRender();
191
204
  };
192
- this.scrollElements = _toConsumableArray(new Set([(_this$tmodel$$dom2 = this.tmodel.$dom) === null || _this$tmodel$$dom2 === void 0 ? void 0 : _this$tmodel$$dom2.element, (_this$tmodel$getParen = this.tmodel.getParent()) === null || _this$tmodel$getParen === void 0 || (_this$tmodel$getParen = _this$tmodel$getParen.$dom) === null || _this$tmodel$getParen === void 0 ? void 0 : _this$tmodel$getParen.element].filter(Boolean)));
193
- var _iterator = _createForOfIteratorHelper(this.scrollElements),
194
- _step;
195
- try {
196
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
197
- var element = _step.value;
198
- element.addEventListener("scroll", this.onScroll, {
199
- passive: true
200
- });
201
- }
202
- } catch (err) {
203
- _iterator.e(err);
204
- } finally {
205
- _iterator.f();
206
- }
205
+ this.updateScrollElements();
207
206
  }
208
207
  }, {
209
208
  key: "createUniformBuffer",
@@ -213,11 +212,38 @@ var ParticleRenderer = /*#__PURE__*/function () {
213
212
  usage: globalThis.GPUBufferUsage.UNIFORM | globalThis.GPUBufferUsage.COPY_DST
214
213
  });
215
214
  }
215
+ }, {
216
+ key: "createExplodeResources",
217
+ value: function createExplodeResources() {
218
+ this.explodeSampler = this.device.createSampler({
219
+ addressModeU: "clamp-to-edge",
220
+ addressModeV: "clamp-to-edge",
221
+ magFilter: "linear",
222
+ minFilter: "linear"
223
+ });
224
+ this.explodeTexture = this.device.createTexture({
225
+ size: {
226
+ width: 1,
227
+ height: 1
228
+ },
229
+ format: "rgba8unorm",
230
+ usage: globalThis.GPUTextureUsage.TEXTURE_BINDING | globalThis.GPUTextureUsage.COPY_DST
231
+ });
232
+ this.device.queue.writeTexture({
233
+ texture: this.explodeTexture
234
+ }, new Uint8Array([0, 0, 0, 0]), {
235
+ bytesPerRow: 4
236
+ }, {
237
+ width: 1,
238
+ height: 1
239
+ });
240
+ this.explodeTextureReady = false;
241
+ }
216
242
  }, {
217
243
  key: "createPipeline",
218
244
  value: function createPipeline() {
219
245
  var shaderModule = this.device.createShaderModule({
220
- code: "\n struct Uniforms {\n viewport: vec2f,\n contentOffset: vec2f,\n step: f32,\n transitionActive: f32,\n padding: vec2f,\n }\n\n @group(0) @binding(0)\n var<uniform> uniforms: Uniforms;\n\n struct VertexOutput {\n @builtin(position) position: vec4f,\n @location(0) localPosition: vec2f,\n @location(1) backgroundColor: vec4f,\n @location(2) size: vec2f,\n @location(3) borderRadius: f32,\n }\n\n fn getProgress(step: f32, steps: f32) -> f32 {\n if (uniforms.transitionActive < 0.5) {\n return 0.0;\n }\n\n if (steps < 0.0) {\n return 0.0;\n }\n\n if (steps == 0.0) {\n return 1.0;\n }\n\n return clamp(step / steps, 0.0, 1.0);\n }\n\n @vertex\n fn vertexMain(\n @location(0) childPosition: vec2f,\n @location(1) childSize: vec2f,\n @location(2) childBackgroundColor: vec4f,\n @location(3) childGeometry: vec2f,\n @location(4) targetPosition: vec2f,\n @location(5) targetSize: vec2f,\n @location(6) targetBackgroundColor: vec4f,\n @location(7) targetGeometry: vec2f,\n @location(8) targetPositionSteps: vec2f,\n @location(9) targetSizeSteps: vec2f,\n @location(10) targetBackgroundColorSteps: f32,\n @location(11) targetGeometrySteps: vec2f,\n @location(12) childScale: f32,\n @location(13) targetScale: f32,\n @location(14) targetScaleSteps: f32,\n @builtin(vertex_index) vertexIndex: u32\n ) -> VertexOutput {\n let corners = array<vec2f, 6>(\n vec2f(-1.0, -1.0),\n vec2f( 1.0, -1.0),\n vec2f(-1.0, 1.0),\n vec2f(-1.0, 1.0),\n vec2f( 1.0, -1.0),\n vec2f( 1.0, 1.0)\n );\n\n let xProgress = getProgress(uniforms.step, targetPositionSteps.x);\n let yProgress = getProgress(uniforms.step, targetPositionSteps.y);\n let widthProgress = getProgress(uniforms.step, targetSizeSteps.x);\n let heightProgress = getProgress(uniforms.step, targetSizeSteps.y);\n let backgroundColorProgress = getProgress(uniforms.step, targetBackgroundColorSteps);\n let borderRadiusProgress = getProgress(uniforms.step, targetGeometrySteps.x);\n let rotateProgress = getProgress(uniforms.step, targetGeometrySteps.y);\n let scaleProgress = getProgress(uniforms.step, targetScaleSteps);\n \n let position = vec2f(\n mix(childPosition.x, targetPosition.x, xProgress),\n mix(childPosition.y, targetPosition.y, yProgress)\n );\n\n let size = vec2f(\n mix(childSize.x, targetSize.x, widthProgress),\n mix(childSize.y, targetSize.y, heightProgress)\n );\n\n let backgroundColor = mix(childBackgroundColor, targetBackgroundColor, backgroundColorProgress);\n let borderRadius = mix(childGeometry.x, targetGeometry.x, borderRadiusProgress);\n let rotate = mix(childGeometry.y, targetGeometry.y, rotateProgress);\n let scale = mix(childScale, targetScale, scaleProgress);\n\n let localPosition = corners[vertexIndex];\n let localPixelPosition = localPosition * size * 0.5 * scale;\n\n let angle = rotate * 3.141592653589793 / 180.0;\n let cosine = cos(angle);\n let sine = sin(angle);\n\n let rotatedPosition = vec2f(\n localPixelPosition.x * cosine - localPixelPosition.y * sine,\n localPixelPosition.x * sine + localPixelPosition.y * cosine\n );\n\n let elementCenter = position - uniforms.contentOffset + size * 0.5;\n let pixelPosition = elementCenter + rotatedPosition;\n\n let clipPosition = vec2f(\n pixelPosition.x / uniforms.viewport.x * 2.0 - 1.0,\n 1.0 - pixelPosition.y / uniforms.viewport.y * 2.0\n );\n\n var output: VertexOutput;\n\n output.position = vec4f(clipPosition, 0.0, 1.0);\n output.localPosition = localPosition;\n output.backgroundColor = backgroundColor;\n output.size = size;\n output.borderRadius = borderRadius;\n\n return output;\n }\n @fragment\n fn fragmentMain(input: VertexOutput) -> @location(0) vec4f {\n let halfSize = max(input.size * 0.5, vec2f(0.0001));\n let radius = clamp(input.borderRadius, 0.0, min(halfSize.x, halfSize.y));\n let pixelPosition = input.localPosition * halfSize;\n let q = abs(pixelPosition) - (halfSize - vec2f(radius));\n let distance = length(max(q, vec2f(0.0))) + min(max(q.x, q.y), 0.0) - radius;\n let aa = max(fwidth(distance), 0.0001);\n\n if (radius <= 0.0) {\n return input.backgroundColor;\n }\n\n let coverage = 1.0 - smoothstep(-aa, aa, distance);\n\n if (coverage <= 0.0) {\n discard;\n }\n\n let alpha = input.backgroundColor.a * coverage;\n\n return vec4f(input.backgroundColor.rgb * alpha, alpha);\n }\n "
246
+ code: "\n struct Uniforms {\n viewport: vec2f,\n contentOffset: vec2f,\n step: f32,\n transitionActive: f32,\n padding: vec2f,\n }\n\n @group(0) @binding(0)\n var<uniform> uniforms: Uniforms;\n \n @group(0) @binding(1)\n var explodeSampler: sampler;\n\n @group(0) @binding(2)\n var explodeTexture: texture_2d<f32>;\n\n struct VertexOutput {\n @builtin(position) position: vec4f,\n @location(0) localPosition: vec2f,\n @location(1) backgroundColor: vec4f,\n @location(2) size: vec2f,\n @location(3) borderRadius: f32,\n @location(4) sourceUv: vec2f,\n @location(5) useImage: f32,\n @location(6) opacity: f32,\n }\n \n fn getProgress(step: f32, steps: f32) -> f32 {\n if (uniforms.transitionActive < 0.5) {\n return 0.0;\n }\n\n if (steps < 0.0) {\n return 0.0;\n }\n\n if (steps == 0.0) {\n return 1.0;\n }\n\n return clamp(step / steps, 0.0, 1.0);\n }\n\n @vertex\n fn vertexMain(\n @location(0) childPosition: vec2f,\n @location(1) childSize: vec2f,\n @location(2) childBackgroundColor: vec4f,\n @location(3) childGeometry: vec2f,\n @location(4) targetPosition: vec2f,\n @location(5) targetSize: vec2f,\n @location(6) targetBackgroundColor: vec4f,\n @location(7) targetGeometry: vec2f,\n @location(8) targetPositionSteps: vec2f,\n @location(9) targetSizeSteps: vec2f,\n @location(10) targetColorOpacitySteps: vec2f,\n @location(11) targetGeometrySteps: vec2f,\n @location(12) childScaleOpacity: vec2f,\n @location(13) targetScaleOpacity: vec2f,\n @location(14) targetScaleSteps: f32,\n @location(15) explodeData: vec4f,\n @builtin(vertex_index) vertexIndex: u32\n ) -> VertexOutput {\n let corners = array<vec2f, 6>(\n vec2f(-1.0, -1.0),\n vec2f( 1.0, -1.0),\n vec2f(-1.0, 1.0),\n vec2f(-1.0, 1.0),\n vec2f( 1.0, -1.0),\n vec2f( 1.0, 1.0)\n );\n\n let xProgress = getProgress(uniforms.step, targetPositionSteps.x);\n let yProgress = getProgress(uniforms.step, targetPositionSteps.y);\n let widthProgress = getProgress(uniforms.step, targetSizeSteps.x);\n let heightProgress = getProgress(uniforms.step, targetSizeSteps.y);\n let backgroundColorProgress = getProgress(uniforms.step, targetColorOpacitySteps.x);\n let opacityProgress = getProgress(uniforms.step, targetColorOpacitySteps.y);\n let borderRadiusProgress = getProgress(uniforms.step, targetGeometrySteps.x);\n let rotateProgress = getProgress(uniforms.step, targetGeometrySteps.y);\n let scaleProgress = getProgress(uniforms.step, targetScaleSteps);\n \n let position = vec2f(\n mix(childPosition.x, targetPosition.x, xProgress),\n mix(childPosition.y, targetPosition.y, yProgress)\n );\n\n let size = vec2f(\n mix(childSize.x, targetSize.x, widthProgress),\n mix(childSize.y, targetSize.y, heightProgress)\n );\n\n let backgroundColor = mix(childBackgroundColor, targetBackgroundColor, backgroundColorProgress);\n let borderRadius = mix(childGeometry.x, targetGeometry.x, borderRadiusProgress);\n let rotate = mix(childGeometry.y, targetGeometry.y, rotateProgress);\n let scale = mix(childScaleOpacity.x, targetScaleOpacity.x, scaleProgress);\n let opacity = mix(childScaleOpacity.y, targetScaleOpacity.y, opacityProgress);\n\n let localPosition = corners[vertexIndex];\n \n let useImage = explodeData.w >= 0.0;\n let sourceV1 = select(-explodeData.w - 1.0, explodeData.w, useImage);\n let localUv = localPosition * 0.5 + vec2f(0.5);\n let sourceUv = mix(explodeData.xy, vec2f(explodeData.z, sourceV1), localUv);\n \n let localPixelPosition = localPosition * size * 0.5 * scale;\n\n let angle = rotate * 3.141592653589793 / 180.0;\n let cosine = cos(angle);\n let sine = sin(angle);\n\n let rotatedPosition = vec2f(\n localPixelPosition.x * cosine - localPixelPosition.y * sine,\n localPixelPosition.x * sine + localPixelPosition.y * cosine\n );\n\n let elementCenter = position - uniforms.contentOffset + size * 0.5;\n let pixelPosition = elementCenter + rotatedPosition;\n\n let clipPosition = vec2f(\n pixelPosition.x / uniforms.viewport.x * 2.0 - 1.0,\n 1.0 - pixelPosition.y / uniforms.viewport.y * 2.0\n );\n\n var output: VertexOutput;\n\n output.position = vec4f(clipPosition, 0.0, 1.0);\n output.localPosition = localPosition;\n output.backgroundColor = backgroundColor;\n output.size = size;\n output.borderRadius = borderRadius;\n output.opacity = opacity;\n \n output.sourceUv = sourceUv;\n output.useImage = select(0.0, 1.0, useImage);\n\n return output;\n }\n\n @fragment\n fn fragmentMain(input: VertexOutput) -> @location(0) vec4f {\n var color = input.backgroundColor;\n\n if (input.useImage > 0.5) {\n color = textureSampleLevel(explodeTexture, explodeSampler, input.sourceUv, 0.0);\n }\n\n let halfSize = max(input.size * 0.5, vec2f(0.0001));\n let radius = clamp(input.borderRadius, 0.0, min(halfSize.x, halfSize.y));\n let pixelPosition = input.localPosition * halfSize;\n let q = abs(pixelPosition) - (halfSize - vec2f(radius));\n let distance = length(max(q, vec2f(0.0))) + min(max(q.x, q.y), 0.0) - radius;\n let aa = max(fwidth(distance), 0.0001);\n let roundedCoverage = 1.0 - smoothstep(-aa, aa, distance);\n let coverage = select(1.0, roundedCoverage, radius > 0.0);\n\n if (coverage <= 0.0) {\n discard;\n }\n\n let alpha = color.a * input.opacity * coverage;\n\n return vec4f(color.rgb * alpha, alpha);\n }\n "
221
247
  });
222
248
  this.pipeline = this.device.createRenderPipeline({
223
249
  layout: "auto",
@@ -225,7 +251,7 @@ var ParticleRenderer = /*#__PURE__*/function () {
225
251
  module: shaderModule,
226
252
  entryPoint: "vertexMain",
227
253
  buffers: [{
228
- arrayStride: 80,
254
+ arrayStride: 84,
229
255
  stepMode: "instance",
230
256
  attributes: [{
231
257
  shaderLocation: 0,
@@ -245,11 +271,11 @@ var ParticleRenderer = /*#__PURE__*/function () {
245
271
  format: "float32x2"
246
272
  }, {
247
273
  shaderLocation: 12,
248
- offset: 68,
249
- format: "float32"
274
+ offset: 72,
275
+ format: "float32x2"
250
276
  }]
251
277
  }, {
252
- arrayStride: 80,
278
+ arrayStride: 84,
253
279
  stepMode: "instance",
254
280
  attributes: [{
255
281
  shaderLocation: 4,
@@ -278,20 +304,28 @@ var ParticleRenderer = /*#__PURE__*/function () {
278
304
  }, {
279
305
  shaderLocation: 10,
280
306
  offset: 56,
281
- format: "float32"
307
+ format: "float32x2"
282
308
  }, {
283
309
  shaderLocation: 11,
284
- offset: 60,
310
+ offset: 64,
285
311
  format: "float32x2"
286
312
  }, {
287
313
  shaderLocation: 13,
288
- offset: 68,
289
- format: "float32"
314
+ offset: 72,
315
+ format: "float32x2"
290
316
  }, {
291
317
  shaderLocation: 14,
292
- offset: 72,
318
+ offset: 80,
293
319
  format: "float32"
294
320
  }]
321
+ }, {
322
+ arrayStride: 16,
323
+ stepMode: "instance",
324
+ attributes: [{
325
+ shaderLocation: 15,
326
+ offset: 0,
327
+ format: "float32x4"
328
+ }]
295
329
  }]
296
330
  },
297
331
  fragment: {
@@ -317,6 +351,11 @@ var ParticleRenderer = /*#__PURE__*/function () {
317
351
  topology: "triangle-list"
318
352
  }
319
353
  });
354
+ this.createBindGroup();
355
+ }
356
+ }, {
357
+ key: "createBindGroup",
358
+ value: function createBindGroup() {
320
359
  this.bindGroup = this.device.createBindGroup({
321
360
  layout: this.pipeline.getBindGroupLayout(0),
322
361
  entries: [{
@@ -324,9 +363,151 @@ var ParticleRenderer = /*#__PURE__*/function () {
324
363
  resource: {
325
364
  buffer: this.uniformBuffer
326
365
  }
366
+ }, {
367
+ binding: 1,
368
+ resource: this.explodeSampler
369
+ }, {
370
+ binding: 2,
371
+ resource: this.explodeTexture.createView()
327
372
  }]
328
373
  });
329
374
  }
375
+ }, {
376
+ key: "createExplodeSourceCanvas",
377
+ value: function createExplodeSourceCanvas(source) {
378
+ var width = source === null || source === void 0 ? void 0 : source.width;
379
+ var height = source === null || source === void 0 ? void 0 : source.height;
380
+ if (!width || !height) {
381
+ return;
382
+ }
383
+ var canvas = document.createElement("canvas");
384
+ canvas.width = width;
385
+ canvas.height = height;
386
+ var context = canvas.getContext("2d");
387
+ if (!context) {
388
+ throw new Error("Could not create a 2D context for the explode source copy.");
389
+ }
390
+ context.drawImage(source, 0, 0, width, height);
391
+ return canvas;
392
+ }
393
+ }, {
394
+ key: "setExplodeSource",
395
+ value: function () {
396
+ var _setExplodeSource = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(capture) {
397
+ var _capture$bitmap, _capture$canvas, _this$explodeTexture;
398
+ var source, sourceCanvas, initialized, width, height, texture;
399
+ return _regeneratorRuntime().wrap(function _callee3$(_context3) {
400
+ while (1) switch (_context3.prev = _context3.next) {
401
+ case 0:
402
+ source = (_capture$bitmap = capture === null || capture === void 0 ? void 0 : capture.bitmap) !== null && _capture$bitmap !== void 0 ? _capture$bitmap : capture === null || capture === void 0 ? void 0 : capture.canvas;
403
+ if (source) {
404
+ _context3.next = 3;
405
+ break;
406
+ }
407
+ return _context3.abrupt("return", false);
408
+ case 3:
409
+ sourceCanvas = (_capture$canvas = capture === null || capture === void 0 ? void 0 : capture.canvas) !== null && _capture$canvas !== void 0 ? _capture$canvas : this.createExplodeSourceCanvas(source);
410
+ if (sourceCanvas) {
411
+ _context3.next = 6;
412
+ break;
413
+ }
414
+ return _context3.abrupt("return", false);
415
+ case 6:
416
+ _context3.next = 8;
417
+ return this.init();
418
+ case 8:
419
+ initialized = _context3.sent;
420
+ if (initialized) {
421
+ _context3.next = 11;
422
+ break;
423
+ }
424
+ return _context3.abrupt("return", false);
425
+ case 11:
426
+ width = sourceCanvas.width;
427
+ height = sourceCanvas.height;
428
+ texture = this.device.createTexture({
429
+ size: {
430
+ width: width,
431
+ height: height
432
+ },
433
+ format: "rgba8unorm",
434
+ usage: globalThis.GPUTextureUsage.TEXTURE_BINDING | globalThis.GPUTextureUsage.COPY_DST | globalThis.GPUTextureUsage.RENDER_ATTACHMENT
435
+ });
436
+ this.device.queue.copyExternalImageToTexture({
437
+ source: sourceCanvas
438
+ }, {
439
+ texture: texture
440
+ }, {
441
+ width: width,
442
+ height: height
443
+ });
444
+ (_this$explodeTexture = this.explodeTexture) === null || _this$explodeTexture === void 0 || _this$explodeTexture.destroy();
445
+ this.explodeSourceCanvas = sourceCanvas;
446
+ this.explodeTexture = texture;
447
+ this.explodeTextureReady = true;
448
+ this.updateExplodeFragmentBuffer(this.tmodel.childHandles);
449
+ this.createBindGroup();
450
+ this.render();
451
+ return _context3.abrupt("return", true);
452
+ case 23:
453
+ case "end":
454
+ return _context3.stop();
455
+ }
456
+ }, _callee3, this);
457
+ }));
458
+ function setExplodeSource(_x) {
459
+ return _setExplodeSource.apply(this, arguments);
460
+ }
461
+ return setExplodeSource;
462
+ }()
463
+ }, {
464
+ key: "captureExplodeSourceBitmap",
465
+ value: function captureExplodeSourceBitmap() {
466
+ if (!this.explodeSourceCanvas) {
467
+ return;
468
+ }
469
+ return createImageBitmap(this.explodeSourceCanvas);
470
+ }
471
+ }, {
472
+ key: "createExplodeFragmentData",
473
+ value: function createExplodeFragmentData(children) {
474
+ var data = new Float32Array(children.length * 4);
475
+ var state = this.tmodel.explodeChildrenState;
476
+ var sourceWidth = (state === null || state === void 0 ? void 0 : state.width) || 1;
477
+ var sourceHeight = (state === null || state === void 0 ? void 0 : state.height) || 1;
478
+ for (var index = 0; index < children.length; index++) {
479
+ var child = children[index];
480
+ var childIndex = Number.isInteger(child === null || child === void 0 ? void 0 : child.index) ? child.index : index;
481
+ var fragment = this.tmodel.getExplodeFragment(childIndex);
482
+ var offset = index * 4;
483
+ if (!fragment) {
484
+ data[offset] = 0;
485
+ data[offset + 1] = 0;
486
+ data[offset + 2] = 0;
487
+ data[offset + 3] = -1;
488
+ continue;
489
+ }
490
+ var u0 = fragment.x / sourceWidth;
491
+ var v0 = fragment.y / sourceHeight;
492
+ var u1 = (fragment.x + fragment.width) / sourceWidth;
493
+ var v1 = (fragment.y + fragment.height) / sourceHeight;
494
+ var hasBackground = TUtil.isDefined(child.actualValues.backgroundColor);
495
+ var useImage = this.explodeTextureReady && !hasBackground;
496
+ data[offset] = u0;
497
+ data[offset + 1] = v0;
498
+ data[offset + 2] = u1;
499
+
500
+ // A negative fourth value means image:false.
501
+ data[offset + 3] = useImage ? v1 : -(v1 + 1);
502
+ }
503
+ return data;
504
+ }
505
+ }, {
506
+ key: "updateExplodeFragmentBuffer",
507
+ value: function updateExplodeFragmentBuffer(children) {
508
+ var data = this.createExplodeFragmentData(children);
509
+ this.explodeFragmentBuffer = this.uploadParticleBuffer(this.explodeFragmentBuffer, data);
510
+ }
330
511
  }, {
331
512
  key: "toNumber",
332
513
  value: function toNumber(value) {
@@ -377,45 +558,45 @@ var ParticleRenderer = /*#__PURE__*/function () {
377
558
  particleData[offset + 4] = backgroundColor[0];
378
559
  particleData[offset + 5] = backgroundColor[1];
379
560
  particleData[offset + 6] = backgroundColor[2];
380
- particleData[offset + 7] = backgroundColor[3] * opacity;
561
+ particleData[offset + 7] = backgroundColor[3];
381
562
  particleData[offset + 8] = Math.max(0, this.toNumber(values.borderRadius, 0));
382
563
  particleData[offset + 9] = this.toNumber(values.rotate, 0);
383
564
  particleData[offset + 10] = this.getTargetStep(steps, "x");
384
565
  particleData[offset + 11] = this.getTargetStep(steps, "y");
385
566
  particleData[offset + 12] = this.getTargetStep(steps, "width");
386
567
  particleData[offset + 13] = this.getTargetStep(steps, "height");
387
- var backgroundColorSteps = this.getTargetStep(steps, "backgroundColor");
388
- var opacitySteps = this.getTargetStep(steps, "opacity");
389
- particleData[offset + 14] = opacitySteps >= 0 ? opacitySteps : backgroundColorSteps;
390
- particleData[offset + 15] = this.getTargetStep(steps, "borderRadius");
391
- particleData[offset + 16] = this.getTargetStep(steps, "rotate");
392
- particleData[offset + 17] = this.toNumber(values.scale, 1);
393
- particleData[offset + 18] = this.getTargetStep(steps, "scale");
568
+ particleData[offset + 14] = this.getTargetStep(steps, "backgroundColor");
569
+ particleData[offset + 15] = this.getTargetStep(steps, "opacity");
570
+ particleData[offset + 16] = this.getTargetStep(steps, "borderRadius");
571
+ particleData[offset + 17] = this.getTargetStep(steps, "rotate");
572
+ particleData[offset + 18] = this.toNumber(values.scale, 1);
573
+ particleData[offset + 19] = opacity;
574
+ particleData[offset + 20] = this.getTargetStep(steps, "scale");
394
575
  }
395
576
  }, {
396
577
  key: "createChildData",
397
578
  value: function createChildData(children) {
398
- var particleData = new Float32Array(children.length * 20);
579
+ var particleData = new Float32Array(children.length * 21);
399
580
  for (var i = 0; i < children.length; i++) {
400
581
  var child = children[i];
401
582
  var values = child.actualValues;
402
583
  var _this$getParticlePosi = this.getParticlePosition(child, values),
403
584
  x = _this$getParticlePosi.x,
404
585
  y = _this$getParticlePosi.y;
405
- this.writeParticleData(particleData, i * 20, values, undefined, x, y);
586
+ this.writeParticleData(particleData, i * 21, values, undefined, x, y);
406
587
  }
407
588
  return particleData;
408
589
  }
409
590
  }, {
410
591
  key: "createParticleData",
411
592
  value: function createParticleData(values, targetSteps) {
412
- var particleData = new Float32Array(values.length * 20);
593
+ var particleData = new Float32Array(values.length * 21);
413
594
  for (var i = 0; i < values.length; i++) {
414
595
  var child = this.tmodel.childHandles[i];
415
596
  var _this$getParticlePosi2 = this.getParticlePosition(child, values[i]),
416
597
  x = _this$getParticlePosi2.x,
417
598
  y = _this$getParticlePosi2.y;
418
- this.writeParticleData(particleData, i * 20, values[i], targetSteps === null || targetSteps === void 0 ? void 0 : targetSteps[i], x, y);
599
+ this.writeParticleData(particleData, i * 21, values[i], targetSteps === null || targetSteps === void 0 ? void 0 : targetSteps[i], x, y);
419
600
  }
420
601
  return particleData;
421
602
  }
@@ -441,37 +622,41 @@ var ParticleRenderer = /*#__PURE__*/function () {
441
622
  }, {
442
623
  key: "setParticles",
443
624
  value: function () {
444
- var _setParticles = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(children) {
625
+ var _setParticles = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(children) {
445
626
  var initialized, particleData;
446
- return _regeneratorRuntime().wrap(function _callee3$(_context3) {
447
- while (1) switch (_context3.prev = _context3.next) {
627
+ return _regeneratorRuntime().wrap(function _callee4$(_context4) {
628
+ while (1) switch (_context4.prev = _context4.next) {
448
629
  case 0:
449
630
  children = Array.isArray(children) ? children : [children];
450
- _context3.next = 3;
631
+ _context4.next = 3;
451
632
  return this.init();
452
633
  case 3:
453
- initialized = _context3.sent;
634
+ initialized = _context4.sent;
454
635
  if (initialized) {
455
- _context3.next = 6;
636
+ _context4.next = 6;
456
637
  break;
457
638
  }
458
- return _context3.abrupt("return", false);
639
+ return _context4.abrupt("return", false);
459
640
  case 6:
460
641
  particleData = this.createChildData(children);
642
+ this.updateExplodeFragmentBuffer(children);
461
643
  this.particleCount = children.length;
644
+ this.currentParticleData = particleData;
645
+ this.targetParticleData = particleData;
462
646
  this.particleBuffer = this.uploadParticleBuffer(this.particleBuffer, particleData);
463
647
  this.targetParticleBuffer = this.uploadParticleBuffer(this.targetParticleBuffer, particleData);
464
648
  this.transitionStep = 0;
465
649
  this.transitionActive = false;
650
+ this.boundsDirty = true;
466
651
  this.render();
467
- return _context3.abrupt("return", true);
468
- case 14:
652
+ return _context4.abrupt("return", true);
653
+ case 18:
469
654
  case "end":
470
- return _context3.stop();
655
+ return _context4.stop();
471
656
  }
472
- }, _callee3, this);
657
+ }, _callee4, this);
473
658
  }));
474
- function setParticles(_x) {
659
+ function setParticles(_x2) {
475
660
  return _setParticles.apply(this, arguments);
476
661
  }
477
662
  return setParticles;
@@ -479,41 +664,45 @@ var ParticleRenderer = /*#__PURE__*/function () {
479
664
  }, {
480
665
  key: "updateParticles",
481
666
  value: function () {
482
- var _updateParticles = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(children) {
667
+ var _updateParticles = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(children) {
483
668
  var initialized, particleData;
484
- return _regeneratorRuntime().wrap(function _callee4$(_context4) {
485
- while (1) switch (_context4.prev = _context4.next) {
669
+ return _regeneratorRuntime().wrap(function _callee5$(_context5) {
670
+ while (1) switch (_context5.prev = _context5.next) {
486
671
  case 0:
487
672
  children = Array.isArray(children) ? children : [children];
488
- _context4.next = 3;
673
+ _context5.next = 3;
489
674
  return this.init();
490
675
  case 3:
491
- initialized = _context4.sent;
676
+ initialized = _context5.sent;
492
677
  if (initialized) {
493
- _context4.next = 6;
678
+ _context5.next = 6;
494
679
  break;
495
680
  }
496
- return _context4.abrupt("return", false);
681
+ return _context5.abrupt("return", false);
497
682
  case 6:
498
683
  particleData = this.createChildData(children);
684
+ this.updateExplodeFragmentBuffer(children);
499
685
  this.particleCount = children.length;
686
+ this.currentParticleData = particleData;
500
687
  this.particleBuffer = this.uploadParticleBuffer(this.particleBuffer, particleData);
501
688
  if (!children.length || !this.transitionActive) {
689
+ this.targetParticleData = particleData;
502
690
  this.targetParticleBuffer = this.uploadParticleBuffer(this.targetParticleBuffer, particleData);
503
691
  }
504
692
  if (!children.length) {
505
693
  this.transitionStep = 0;
506
694
  this.transitionActive = false;
507
695
  }
696
+ this.boundsDirty = true;
508
697
  this.render();
509
- return _context4.abrupt("return", true);
510
- case 13:
698
+ return _context5.abrupt("return", true);
699
+ case 16:
511
700
  case "end":
512
- return _context4.stop();
701
+ return _context5.stop();
513
702
  }
514
- }, _callee4, this);
703
+ }, _callee5, this);
515
704
  }));
516
- function updateParticles(_x2) {
705
+ function updateParticles(_x3) {
517
706
  return _updateParticles.apply(this, arguments);
518
707
  }
519
708
  return updateParticles;
@@ -521,53 +710,56 @@ var ParticleRenderer = /*#__PURE__*/function () {
521
710
  }, {
522
711
  key: "setTargetParticles",
523
712
  value: function () {
524
- var _setTargetParticles = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(values, steps) {
713
+ var _setTargetParticles = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(values, steps) {
525
714
  var generation,
526
715
  initialized,
527
716
  currentChildren,
528
717
  currentParticleData,
529
718
  particleData,
530
- _args5 = arguments;
531
- return _regeneratorRuntime().wrap(function _callee5$(_context5) {
532
- while (1) switch (_context5.prev = _context5.next) {
719
+ _args6 = arguments;
720
+ return _regeneratorRuntime().wrap(function _callee6$(_context6) {
721
+ while (1) switch (_context6.prev = _context6.next) {
533
722
  case 0:
534
- generation = _args5.length > 2 && _args5[2] !== undefined ? _args5[2] : this.tmodel.childGeneration;
723
+ generation = _args6.length > 2 && _args6[2] !== undefined ? _args6[2] : this.tmodel.childGeneration;
535
724
  values = Array.isArray(values) ? values : [values];
536
- _context5.next = 4;
725
+ _context6.next = 4;
537
726
  return this.init();
538
727
  case 4:
539
- initialized = _context5.sent;
728
+ initialized = _context6.sent;
540
729
  if (!(!initialized || generation !== this.tmodel.childGeneration)) {
541
- _context5.next = 7;
730
+ _context6.next = 7;
542
731
  break;
543
732
  }
544
- return _context5.abrupt("return", false);
733
+ return _context6.abrupt("return", false);
545
734
  case 7:
546
735
  currentChildren = this.tmodel.childHandles;
547
736
  if (!(values.length !== currentChildren.length)) {
548
- _context5.next = 10;
737
+ _context6.next = 10;
549
738
  break;
550
739
  }
551
- return _context5.abrupt("return", false);
740
+ return _context6.abrupt("return", false);
552
741
  case 10:
553
742
  if (this.particleCount !== currentChildren.length || !this.particleBuffer) {
554
743
  currentParticleData = this.createChildData(currentChildren);
555
744
  this.particleCount = currentChildren.length;
745
+ this.currentParticleData = currentParticleData;
556
746
  this.particleBuffer = this.uploadParticleBuffer(this.particleBuffer, currentParticleData);
557
747
  }
558
748
  particleData = this.createParticleData(values, steps);
749
+ this.targetParticleData = particleData;
559
750
  this.targetParticleBuffer = this.uploadParticleBuffer(this.targetParticleBuffer, particleData);
560
751
  this.transitionStep = 0;
561
752
  this.transitionActive = true;
753
+ this.boundsDirty = true;
562
754
  this.render();
563
- return _context5.abrupt("return", true);
564
- case 17:
755
+ return _context6.abrupt("return", true);
756
+ case 19:
565
757
  case "end":
566
- return _context5.stop();
758
+ return _context6.stop();
567
759
  }
568
- }, _callee5, this);
760
+ }, _callee6, this);
569
761
  }));
570
- function setTargetParticles(_x3, _x4) {
762
+ function setTargetParticles(_x4, _x5) {
571
763
  return _setTargetParticles.apply(this, arguments);
572
764
  }
573
765
  return setTargetParticles;
@@ -585,17 +777,77 @@ var ParticleRenderer = /*#__PURE__*/function () {
585
777
  }, {
586
778
  key: "getRenderWidth",
587
779
  value: function getRenderWidth() {
588
- var modelWidth = Number(this.tmodel.getWidth()) || 1;
589
- var parentWidth = Number(this.tmodel.getParent().getWidth()) || window.innerWidth || 1;
590
- return Math.max(1, Math.min(modelWidth, parentWidth));
780
+ return Math.max(1, Number(this.tmodel.getWidth()) || 1);
591
781
  }
592
782
  }, {
593
783
  key: "getRenderHeight",
594
784
  value: function getRenderHeight() {
595
- var _this$tmodel$getParen2;
596
- var modelHeight = Number(this.tmodel.getHeight()) || 1;
597
- var parentHeight = Number((_this$tmodel$getParen2 = this.tmodel.getParent()) === null || _this$tmodel$getParen2 === void 0 ? void 0 : _this$tmodel$getParen2.getHeight()) || window.innerHeight || 1;
598
- return Math.max(1, Math.min(modelHeight, parentHeight));
785
+ return Math.max(1, Number(this.tmodel.getHeight()) || 1);
786
+ }
787
+ }, {
788
+ key: "getParticleBounds",
789
+ value: function getParticleBounds() {
790
+ var modelWidth = this.getRenderWidth();
791
+ var modelHeight = this.getRenderHeight();
792
+ var viewport = this.tmodel.managesOwnScroll();
793
+ var bounds = this.canvasBounds;
794
+ if (!this.boundsDirty && (bounds === null || bounds === void 0 ? void 0 : bounds.modelWidth) === modelWidth && (bounds === null || bounds === void 0 ? void 0 : bounds.modelHeight) === modelHeight && (bounds === null || bounds === void 0 ? void 0 : bounds.viewport) === viewport) {
795
+ return bounds;
796
+ }
797
+ var calculated = viewport ? {
798
+ x: 0,
799
+ y: 0,
800
+ width: modelWidth,
801
+ height: modelHeight
802
+ } : this.calculateParticleBounds();
803
+ this.canvasBounds = _objectSpread(_objectSpread({}, calculated), {}, {
804
+ modelWidth: modelWidth,
805
+ modelHeight: modelHeight,
806
+ viewport: viewport
807
+ });
808
+ this.boundsDirty = false;
809
+ return this.canvasBounds;
810
+ }
811
+ }, {
812
+ key: "calculateParticleBounds",
813
+ value: function calculateParticleBounds() {
814
+ var _this$targetParticleD, _current$length;
815
+ var left = 0;
816
+ var top = 0;
817
+ var right = this.getRenderWidth();
818
+ var bottom = this.getRenderHeight();
819
+ var current = this.currentParticleData;
820
+ var target = (_this$targetParticleD = this.targetParticleData) !== null && _this$targetParticleD !== void 0 ? _this$targetParticleD : current;
821
+ var stride = 21;
822
+ var count = Math.min(this.particleCount, ((_current$length = current === null || current === void 0 ? void 0 : current.length) !== null && _current$length !== void 0 ? _current$length : 0) / stride);
823
+ var safety = 2;
824
+ for (var i = 0; i < count; i++) {
825
+ var j = i * stride;
826
+ var a = current;
827
+ var b = target && target.length >= j + stride ? target : current;
828
+ var minX = Math.min(a[j], b[j]);
829
+ var maxX = Math.max(a[j], b[j]);
830
+ var minY = Math.min(a[j + 1], b[j + 1]);
831
+ var maxY = Math.max(a[j + 1], b[j + 1]);
832
+ var minWidth = Math.min(a[j + 2], b[j + 2]);
833
+ var maxWidth = Math.max(a[j + 2], b[j + 2]);
834
+ var minHeight = Math.min(a[j + 3], b[j + 3]);
835
+ var maxHeight = Math.max(a[j + 3], b[j + 3]);
836
+ var maxScale = Math.max(Math.abs(a[j + 18]), Math.abs(b[j + 18]));
837
+ var radius = Math.hypot(Math.max(Math.abs(a[j + 2]), Math.abs(b[j + 2])), Math.max(Math.abs(a[j + 3]), Math.abs(b[j + 3]))) * maxScale * 0.5 + safety;
838
+ left = Math.min(left, minX + minWidth / 2 - radius);
839
+ right = Math.max(right, maxX + maxWidth / 2 + radius);
840
+ top = Math.min(top, minY + minHeight / 2 - radius);
841
+ bottom = Math.max(bottom, maxY + maxHeight / 2 + radius);
842
+ }
843
+ var x = Math.floor(left);
844
+ var y = Math.floor(top);
845
+ return {
846
+ x: x,
847
+ y: y,
848
+ width: Math.max(1, Math.ceil(right) - x),
849
+ height: Math.max(1, Math.ceil(bottom) - y)
850
+ };
599
851
  }
600
852
  }, {
601
853
  key: "updateCanvasLayerWidthHeight",
@@ -603,15 +855,16 @@ var ParticleRenderer = /*#__PURE__*/function () {
603
855
  if (!this.canvasLayer) {
604
856
  return;
605
857
  }
606
- var height = Math.max(this.getRenderHeight(), Number(this.tmodel.getContentHeight()) || 0);
607
- var width = Math.max(this.getRenderWidth(), Number(this.tmodel.getContentWidth()) || 0);
608
- var cssHeight = "".concat(height, "px");
609
- var cssWidth = "".concat(width, "px");
610
- if (this.canvasLayer.style.height !== cssHeight) {
611
- this.canvasLayer.style.height = cssHeight;
858
+ var viewport = this.getParticleBounds().viewport;
859
+ var modelWidth = this.getRenderWidth();
860
+ var modelHeight = this.getRenderHeight();
861
+ var width = viewport ? Math.max(modelWidth, Number(this.tmodel.getContentWidth()) || 0) : modelWidth;
862
+ var height = viewport ? Math.max(modelHeight, Number(this.tmodel.getContentHeight()) || 0) : modelHeight;
863
+ if (this.canvasLayer.style.width !== "".concat(width, "px")) {
864
+ this.canvasLayer.style.width = "".concat(width, "px");
612
865
  }
613
- if (this.canvasLayer.style.width !== cssWidth) {
614
- this.canvasLayer.style.width = cssWidth;
866
+ if (this.canvasLayer.style.height !== "".concat(height, "px")) {
867
+ this.canvasLayer.style.height = "".concat(height, "px");
615
868
  }
616
869
  }
617
870
  }, {
@@ -619,22 +872,27 @@ var ParticleRenderer = /*#__PURE__*/function () {
619
872
  value: function resizeCanvas() {
620
873
  var _this$device$limits;
621
874
  if (!this.canvas || !this.device) {
622
- return;
875
+ return false;
623
876
  }
624
- var width = this.getRenderWidth();
625
- var height = this.getRenderHeight();
626
- var requestedPixelRatio = window.devicePixelRatio || 1;
627
- var maxTextureDimension = ((_this$device$limits = this.device.limits) === null || _this$device$limits === void 0 ? void 0 : _this$device$limits.maxTextureDimension2D) || 8192;
628
- var pixelRatio = Math.min(requestedPixelRatio, maxTextureDimension / width, maxTextureDimension / height);
877
+ var bounds = this.getParticleBounds();
878
+ var width = bounds.width,
879
+ height = bounds.height,
880
+ modelWidth = bounds.modelWidth,
881
+ modelHeight = bounds.modelHeight;
882
+ var devicePixelRatio = window.devicePixelRatio || 1;
883
+ var maxDimension = ((_this$device$limits = this.device.limits) === null || _this$device$limits === void 0 ? void 0 : _this$device$limits.maxTextureDimension2D) || 8192;
884
+ var pixelRatio = Math.min(devicePixelRatio, maxDimension / width, maxDimension / height);
629
885
  var pixelWidth = Math.max(1, Math.round(width * pixelRatio));
630
886
  var pixelHeight = Math.max(1, Math.round(height * pixelRatio));
631
- var cssWidth = "".concat(width, "px");
632
- var cssHeight = "".concat(height, "px");
633
- if (this.canvas.style.width !== cssWidth) {
634
- this.canvas.style.width = cssWidth;
887
+ var previous = this.canvasSize;
888
+ if (previous && previous.width === width && previous.height === height && previous.pixelWidth === pixelWidth && previous.pixelHeight === pixelHeight && previous.modelWidth === modelWidth && previous.modelHeight === modelHeight) {
889
+ return false;
635
890
  }
636
- if (this.canvas.style.height !== cssHeight) {
637
- this.canvas.style.height = cssHeight;
891
+ if (!previous || previous.width !== width) {
892
+ this.canvas.style.width = "".concat(width, "px");
893
+ }
894
+ if (!previous || previous.height !== height) {
895
+ this.canvas.style.height = "".concat(height, "px");
638
896
  }
639
897
  if (this.canvas.width !== pixelWidth) {
640
898
  this.canvas.width = pixelWidth;
@@ -642,31 +900,58 @@ var ParticleRenderer = /*#__PURE__*/function () {
642
900
  if (this.canvas.height !== pixelHeight) {
643
901
  this.canvas.height = pixelHeight;
644
902
  }
645
- this.updateCanvasLayerWidthHeight();
903
+ if (!previous || previous.modelWidth !== modelWidth || previous.modelHeight !== modelHeight) {
904
+ this.updateCanvasLayerWidthHeight();
905
+ }
906
+ this.canvasSize = {
907
+ width: width,
908
+ height: height,
909
+ pixelWidth: pixelWidth,
910
+ pixelHeight: pixelHeight,
911
+ modelWidth: modelWidth,
912
+ modelHeight: modelHeight
913
+ };
914
+ return true;
646
915
  }
647
916
  }, {
648
917
  key: "repositionCanvas",
649
918
  value: function repositionCanvas() {
650
- var _parent$$dom, _parent$$dom2;
919
+ var _ref, _this$tmodel$$dom$get, _this$tmodel$$dom, _ref2, _this$tmodel$$dom$get2, _this$tmodel$$dom2;
651
920
  if (!this.canvas || !this.canvasLayer || !this.tmodel.hasDom()) {
652
921
  return false;
653
922
  }
654
- var tmodel = this.tmodel;
655
- var parent = tmodel.getParent();
656
- var domScrollLeft = (parent === null || parent === void 0 || (_parent$$dom = parent.$dom) === null || _parent$$dom === void 0 ? void 0 : _parent$$dom.getScrollLeft()) || tmodel.$dom.getScrollLeft() || 0;
657
- var domScrollTop = (parent === null || parent === void 0 || (_parent$$dom2 = parent.$dom) === null || _parent$$dom2 === void 0 ? void 0 : _parent$$dom2.getScrollTop()) || tmodel.$dom.getScrollTop() || 0;
658
- var scrollLeft = tmodel.getScrollLeft();
659
- var scrollTop = tmodel.getScrollTop();
660
- var x = domScrollLeft - tmodel.x;
661
- var y = domScrollTop - tmodel.y;
662
- this.canvasX = scrollLeft + x;
663
- this.canvasY = scrollTop + y;
664
- var transform = "translate3d(".concat(x, "px, ").concat(y, "px, 0px)");
665
- if (this.canvas.style.transform !== transform) {
666
- this.canvas.style.transform = transform;
667
- return true;
923
+ var bounds = this.getParticleBounds();
924
+ var scrollLeft = Number((_ref = (_this$tmodel$$dom$get = (_this$tmodel$$dom = this.tmodel.$dom) === null || _this$tmodel$$dom === void 0 ? void 0 : _this$tmodel$$dom.getScrollLeft()) !== null && _this$tmodel$$dom$get !== void 0 ? _this$tmodel$$dom$get : this.tmodel.getScrollLeft()) !== null && _ref !== void 0 ? _ref : 0) || 0;
925
+ var scrollTop = Number((_ref2 = (_this$tmodel$$dom$get2 = (_this$tmodel$$dom2 = this.tmodel.$dom) === null || _this$tmodel$$dom2 === void 0 ? void 0 : _this$tmodel$$dom2.getScrollTop()) !== null && _this$tmodel$$dom$get2 !== void 0 ? _this$tmodel$$dom$get2 : this.tmodel.getScrollTop()) !== null && _ref2 !== void 0 ? _ref2 : 0) || 0;
926
+
927
+ // Canvas origin in the scroller's content coordinates.
928
+ var contentX = bounds.x + (this.tmodel.managesOwnScroll() ? scrollLeft : 0);
929
+ var contentY = bounds.y + (this.tmodel.managesOwnScroll() ? scrollTop : 0);
930
+
931
+ // Internally mounted canvases scroll with their DOM parent.
932
+ // External canvases do not, so their CSS position remains fixed.
933
+ var x = this.tmodel.managesOwnScroll() && !this.externalCanvasHost ? contentX : bounds.x;
934
+ var y = this.tmodel.managesOwnScroll() && !this.externalCanvasHost ? contentY : bounds.y;
935
+ var nextX = this.tmodel.managesOwnScroll() ? contentX : bounds.x + (this.externalCanvasHost ? scrollLeft : 0);
936
+ var nextY = this.tmodel.managesOwnScroll() ? contentY : bounds.y + (this.externalCanvasHost ? scrollTop : 0);
937
+ var changed = nextX !== this.canvasX || nextY !== this.canvasY;
938
+ this.canvasX = nextX;
939
+ this.canvasY = nextY;
940
+ var left = "".concat(x, "px");
941
+ var top = "".concat(y, "px");
942
+ if (this.canvas.style.left !== left) {
943
+ this.canvas.style.left = left;
944
+ changed = true;
668
945
  }
669
- return false;
946
+ if (this.canvas.style.top !== top) {
947
+ this.canvas.style.top = top;
948
+ changed = true;
949
+ }
950
+ if (this.canvas.style.transform !== "none") {
951
+ this.canvas.style.transform = "none";
952
+ changed = true;
953
+ }
954
+ return changed;
670
955
  }
671
956
  }, {
672
957
  key: "getParticlePosition",
@@ -682,25 +967,25 @@ var ParticleRenderer = /*#__PURE__*/function () {
682
967
  }, {
683
968
  key: "updateUniforms",
684
969
  value: function updateUniforms() {
685
- var width = this.getRenderWidth();
686
- var height = this.getRenderHeight();
687
- this.device.queue.writeBuffer(this.uniformBuffer, 0, new Float32Array([width, height, this.canvasX, this.canvasY, this.transitionStep, this.transitionActive ? 1 : 0, 0, 0]));
970
+ var _this$canvasBounds;
971
+ var bounds = (_this$canvasBounds = this.canvasBounds) !== null && _this$canvasBounds !== void 0 ? _this$canvasBounds : this.getParticleBounds();
972
+ this.device.queue.writeBuffer(this.uniformBuffer, 0, new Float32Array([bounds.width, bounds.height, this.canvasX, this.canvasY, this.transitionStep, this.transitionActive ? 1 : 0, 0, 0]));
688
973
  }
689
974
  }, {
690
975
  key: "waitForPresentedFrame",
691
976
  value: function () {
692
- var _waitForPresentedFrame = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6() {
693
- return _regeneratorRuntime().wrap(function _callee6$(_context6) {
694
- while (1) switch (_context6.prev = _context6.next) {
977
+ var _waitForPresentedFrame = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee7() {
978
+ return _regeneratorRuntime().wrap(function _callee7$(_context7) {
979
+ while (1) switch (_context7.prev = _context7.next) {
695
980
  case 0:
696
981
  if (!this.device) {
697
- _context6.next = 3;
982
+ _context7.next = 3;
698
983
  break;
699
984
  }
700
- _context6.next = 3;
985
+ _context7.next = 3;
701
986
  return this.device.queue.onSubmittedWorkDone();
702
987
  case 3:
703
- _context6.next = 5;
988
+ _context7.next = 5;
704
989
  return new Promise(function (resolve) {
705
990
  requestAnimationFrame(function () {
706
991
  requestAnimationFrame(resolve);
@@ -708,9 +993,9 @@ var ParticleRenderer = /*#__PURE__*/function () {
708
993
  });
709
994
  case 5:
710
995
  case "end":
711
- return _context6.stop();
996
+ return _context7.stop();
712
997
  }
713
- }, _callee6, this);
998
+ }, _callee7, this);
714
999
  }));
715
1000
  function waitForPresentedFrame() {
716
1001
  return _waitForPresentedFrame.apply(this, arguments);
@@ -723,16 +1008,215 @@ var ParticleRenderer = /*#__PURE__*/function () {
723
1008
  if (!this.device || !this.context) {
724
1009
  return;
725
1010
  }
1011
+ if (!this.mountCanvasLayer()) {
1012
+ return;
1013
+ }
726
1014
  this.resizeCanvas();
727
1015
  this.repositionCanvas();
728
- var canDraw = this.pipeline && this.bindGroup && this.particleBuffer && this.targetParticleBuffer && this.particleCount > 0;
1016
+ var commandEncoder = this.device.createCommandEncoder();
1017
+ this.encodeRenderPass(commandEncoder, this.context.getCurrentTexture().createView());
1018
+ this.device.queue.submit([commandEncoder.finish()]);
1019
+ }
1020
+ }, {
1021
+ key: "completeTransition",
1022
+ value: function completeTransition() {
1023
+ if (!this.targetParticleBuffer || !this.transitionActive) {
1024
+ return;
1025
+ }
1026
+ var previousBuffer = this.particleBuffer;
1027
+ this.particleBuffer = this.targetParticleBuffer;
1028
+ this.targetParticleBuffer = previousBuffer;
1029
+ this.currentParticleData = this.targetParticleData;
1030
+ this.transitionStep = 0;
1031
+ this.transitionActive = false;
1032
+ this.boundsDirty = true;
1033
+ this.render();
1034
+ }
1035
+ }, {
1036
+ key: "captureBitmap",
1037
+ value: function () {
1038
+ var _captureBitmap = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee8() {
1039
+ var width, height, bytesPerRow, buffer, texture, commandEncoder, mapped, pixels, rowSize, y, i, red, _i, alpha, scale, canvas, context;
1040
+ return _regeneratorRuntime().wrap(function _callee8$(_context8) {
1041
+ while (1) switch (_context8.prev = _context8.next) {
1042
+ case 0:
1043
+ if (!(!this.canvas || !this.device || !this.context)) {
1044
+ _context8.next = 2;
1045
+ break;
1046
+ }
1047
+ return _context8.abrupt("return");
1048
+ case 2:
1049
+ this.resizeCanvas();
1050
+ this.repositionCanvas();
1051
+ width = this.canvas.width;
1052
+ height = this.canvas.height;
1053
+ bytesPerRow = Math.ceil(width * 4 / 256) * 256;
1054
+ buffer = this.device.createBuffer({
1055
+ size: bytesPerRow * height,
1056
+ usage: globalThis.GPUBufferUsage.COPY_DST | globalThis.GPUBufferUsage.MAP_READ
1057
+ });
1058
+ texture = this.context.getCurrentTexture();
1059
+ commandEncoder = this.device.createCommandEncoder();
1060
+ this.encodeRenderPass(commandEncoder, texture.createView());
1061
+ commandEncoder.copyTextureToBuffer({
1062
+ texture: texture
1063
+ }, {
1064
+ buffer: buffer,
1065
+ bytesPerRow: bytesPerRow
1066
+ }, {
1067
+ width: width,
1068
+ height: height
1069
+ });
1070
+ this.device.queue.submit([commandEncoder.finish()]);
1071
+ _context8.next = 15;
1072
+ return buffer.mapAsync(globalThis.GPUMapMode.READ);
1073
+ case 15:
1074
+ mapped = new Uint8Array(buffer.getMappedRange());
1075
+ pixels = new Uint8ClampedArray(width * height * 4);
1076
+ rowSize = width * 4;
1077
+ for (y = 0; y < height; y++) {
1078
+ pixels.set(mapped.subarray(y * bytesPerRow, y * bytesPerRow + rowSize), y * rowSize);
1079
+ }
1080
+ buffer.unmap();
1081
+ buffer.destroy();
1082
+ if (this.format.startsWith("bgra")) {
1083
+ for (i = 0; i < pixels.length; i += 4) {
1084
+ red = pixels[i];
1085
+ pixels[i] = pixels[i + 2];
1086
+ pixels[i + 2] = red;
1087
+ }
1088
+ }
1089
+ for (_i = 0; _i < pixels.length; _i += 4) {
1090
+ alpha = pixels[_i + 3];
1091
+ if (alpha > 0 && alpha < 255) {
1092
+ scale = 255 / alpha;
1093
+ pixels[_i] = Math.min(255, Math.round(pixels[_i] * scale));
1094
+ pixels[_i + 1] = Math.min(255, Math.round(pixels[_i + 1] * scale));
1095
+ pixels[_i + 2] = Math.min(255, Math.round(pixels[_i + 2] * scale));
1096
+ }
1097
+ }
1098
+ canvas = document.createElement("canvas");
1099
+ canvas.width = width;
1100
+ canvas.height = height;
1101
+ context = canvas.getContext("2d");
1102
+ context.putImageData(new ImageData(pixels, width, height), 0, 0);
1103
+ return _context8.abrupt("return", createImageBitmap(canvas));
1104
+ case 29:
1105
+ case "end":
1106
+ return _context8.stop();
1107
+ }
1108
+ }, _callee8, this);
1109
+ }));
1110
+ function captureBitmap() {
1111
+ return _captureBitmap.apply(this, arguments);
1112
+ }
1113
+ return captureBitmap;
1114
+ }()
1115
+ }, {
1116
+ key: "updateScrollElements",
1117
+ value: function updateScrollElements() {
1118
+ var _this$tmodel$$dom3, _this$tmodel$getParen, _this$scrollElements;
1119
+ var nextElements = _toConsumableArray(new Set([(_this$tmodel$$dom3 = this.tmodel.$dom) === null || _this$tmodel$$dom3 === void 0 ? void 0 : _this$tmodel$$dom3.element, (_this$tmodel$getParen = this.tmodel.getParent()) === null || _this$tmodel$getParen === void 0 || (_this$tmodel$getParen = _this$tmodel$getParen.$dom) === null || _this$tmodel$getParen === void 0 ? void 0 : _this$tmodel$getParen.element].filter(Boolean)));
1120
+ var _iterator = _createForOfIteratorHelper((_this$scrollElements = this.scrollElements) !== null && _this$scrollElements !== void 0 ? _this$scrollElements : []),
1121
+ _step;
1122
+ try {
1123
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
1124
+ var element = _step.value;
1125
+ if (!nextElements.includes(element)) {
1126
+ element.removeEventListener("scroll", this.onScroll);
1127
+ }
1128
+ }
1129
+ } catch (err) {
1130
+ _iterator.e(err);
1131
+ } finally {
1132
+ _iterator.f();
1133
+ }
1134
+ var _iterator2 = _createForOfIteratorHelper(nextElements),
1135
+ _step2;
1136
+ try {
1137
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
1138
+ var _this$scrollElements2;
1139
+ var _element = _step2.value;
1140
+ if (!((_this$scrollElements2 = this.scrollElements) !== null && _this$scrollElements2 !== void 0 ? _this$scrollElements2 : []).includes(_element)) {
1141
+ _element.addEventListener("scroll", this.onScroll, {
1142
+ passive: true
1143
+ });
1144
+ }
1145
+ }
1146
+ } catch (err) {
1147
+ _iterator2.e(err);
1148
+ } finally {
1149
+ _iterator2.f();
1150
+ }
1151
+ this.scrollElements = nextElements;
1152
+ }
1153
+ }, {
1154
+ key: "canHostCanvasLayer",
1155
+ value: function canHostCanvasLayer(element) {
1156
+ return !new Set(["IMG", "INPUT", "CANVAS", "VIDEO", "IFRAME", "OBJECT", "EMBED"]).has(element.tagName);
1157
+ }
1158
+ }, {
1159
+ key: "getCanvasMount",
1160
+ value: function getCanvasMount() {
1161
+ var _this$tmodel$$dom4;
1162
+ var source = (_this$tmodel$$dom4 = this.tmodel.$dom) === null || _this$tmodel$$dom4 === void 0 ? void 0 : _this$tmodel$$dom4.element;
1163
+ if (!source) {
1164
+ return;
1165
+ }
1166
+ var external = !!this.tmodel.explodeChildrenState || !this.canHostCanvasLayer(source);
1167
+ return {
1168
+ source: source,
1169
+ host: external ? source.parentElement : source,
1170
+ external: external
1171
+ };
1172
+ }
1173
+ }, {
1174
+ key: "mountCanvasLayer",
1175
+ value: function mountCanvasLayer() {
1176
+ if (!this.canvasLayer) {
1177
+ return false;
1178
+ }
1179
+ var mount = this.getCanvasMount();
1180
+ if (!(mount !== null && mount !== void 0 && mount.host)) {
1181
+ return false;
1182
+ }
1183
+ var source = mount.source,
1184
+ host = mount.host,
1185
+ external = mount.external;
1186
+ if (this.canvasLayer.parentElement !== host) {
1187
+ if (external) {
1188
+ source.after(this.canvasLayer);
1189
+ } else {
1190
+ host.prepend(this.canvasLayer);
1191
+ }
1192
+ }
1193
+ this.canvasHost = host;
1194
+ this.externalCanvasHost = external;
1195
+ if (external) {
1196
+ this.canvasLayer.style.left = source.style.left || "0px";
1197
+ this.canvasLayer.style.top = source.style.top || "0px";
1198
+ this.canvasLayer.style.transform = source.style.transform || "none";
1199
+ this.canvasLayer.style.transformOrigin = source.style.transformOrigin || "50% 50%";
1200
+ this.canvasLayer.style.zIndex = this.tmodel.explodeChildrenState ? String((Number(source.style.zIndex) || 0) + 1) : source.style.zIndex || "0";
1201
+ } else {
1202
+ this.canvasLayer.style.left = "0px";
1203
+ this.canvasLayer.style.top = "0px";
1204
+ this.canvasLayer.style.transform = "none";
1205
+ this.canvasLayer.style.zIndex = "0";
1206
+ }
1207
+ this.updateScrollElements();
1208
+ return true;
1209
+ }
1210
+ }, {
1211
+ key: "encodeRenderPass",
1212
+ value: function encodeRenderPass(commandEncoder, view) {
1213
+ var canDraw = this.pipeline && this.bindGroup && this.particleBuffer && this.targetParticleBuffer && this.explodeFragmentBuffer && this.particleCount > 0;
729
1214
  if (canDraw) {
730
1215
  this.updateUniforms();
731
1216
  }
732
- var commandEncoder = this.device.createCommandEncoder();
733
1217
  var renderPass = commandEncoder.beginRenderPass({
734
1218
  colorAttachments: [{
735
- view: this.context.getCurrentTexture().createView(),
1219
+ view: view,
736
1220
  clearValue: {
737
1221
  r: 0,
738
1222
  g: 0,
@@ -744,53 +1228,40 @@ var ParticleRenderer = /*#__PURE__*/function () {
744
1228
  }]
745
1229
  });
746
1230
  if (canDraw) {
1231
+ var _explodeState$firstEx;
747
1232
  renderPass.setPipeline(this.pipeline);
748
1233
  renderPass.setBindGroup(0, this.bindGroup);
749
1234
  renderPass.setVertexBuffer(0, this.particleBuffer);
750
1235
  renderPass.setVertexBuffer(1, this.targetParticleBuffer);
751
- renderPass.draw(6, this.particleCount);
1236
+ renderPass.setVertexBuffer(2, this.explodeFragmentBuffer);
1237
+ var explodeState = this.tmodel.explodeChildrenState;
1238
+ var firstInstance = this.explodeTextureReady && explodeState ? (_explodeState$firstEx = explodeState.firstExplodeChild) !== null && _explodeState$firstEx !== void 0 ? _explodeState$firstEx : 0 : 0;
1239
+ var instanceCount = this.particleCount - firstInstance;
1240
+ if (instanceCount > 0) {
1241
+ renderPass.draw(6, instanceCount, 0, firstInstance);
1242
+ }
752
1243
  }
753
1244
  renderPass.end();
754
- this.device.queue.submit([commandEncoder.finish()]);
755
- }
756
- }, {
757
- key: "completeTransition",
758
- value: function completeTransition() {
759
- if (!this.targetParticleBuffer || !this.transitionActive) {
760
- return;
761
- }
762
- var previousBuffer = this.particleBuffer;
763
- this.particleBuffer = this.targetParticleBuffer;
764
- this.targetParticleBuffer = previousBuffer;
765
- this.transitionStep = 0;
766
- this.transitionActive = false;
767
- this.render();
768
- }
769
- }, {
770
- key: "captureBitmap",
771
- value: function captureBitmap() {
772
- if (!this.canvas || !this.device) {
773
- return;
774
- }
775
- this.render();
776
- return createImageBitmap(this.canvas);
777
1245
  }
778
1246
  }, {
779
1247
  key: "destroy",
780
1248
  value: function destroy() {
781
- var _this$particleBuffer, _this$targetParticleB, _this$uniformBuffer, _this$context, _this$canvasLayer, _this$scrollElements;
782
- var _iterator2 = _createForOfIteratorHelper((_this$scrollElements = this.scrollElements) !== null && _this$scrollElements !== void 0 ? _this$scrollElements : []),
783
- _step2;
1249
+ var _this$particleBuffer, _this$targetParticleB, _this$uniformBuffer, _this$context, _this$canvasLayer, _this$explodeFragment, _this$explodeTexture2, _this$scrollElements3;
1250
+ var _iterator3 = _createForOfIteratorHelper((_this$scrollElements3 = this.scrollElements) !== null && _this$scrollElements3 !== void 0 ? _this$scrollElements3 : []),
1251
+ _step3;
784
1252
  try {
785
- for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
786
- var element = _step2.value;
1253
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
1254
+ var element = _step3.value;
787
1255
  element.removeEventListener("scroll", this.onScroll);
788
1256
  }
789
1257
  } catch (err) {
790
- _iterator2.e(err);
1258
+ _iterator3.e(err);
791
1259
  } finally {
792
- _iterator2.f();
1260
+ _iterator3.f();
793
1261
  }
1262
+ this.canvasSize = undefined;
1263
+ this.canvasBounds = undefined;
1264
+ this.boundsDirty = true;
794
1265
  this.scrollElements = undefined;
795
1266
  this.onScroll = undefined;
796
1267
  (_this$particleBuffer = this.particleBuffer) === null || _this$particleBuffer === void 0 || _this$particleBuffer.destroy();
@@ -798,6 +1269,8 @@ var ParticleRenderer = /*#__PURE__*/function () {
798
1269
  (_this$uniformBuffer = this.uniformBuffer) === null || _this$uniformBuffer === void 0 || _this$uniformBuffer.destroy();
799
1270
  (_this$context = this.context) === null || _this$context === void 0 || _this$context.unconfigure();
800
1271
  (_this$canvasLayer = this.canvasLayer) === null || _this$canvasLayer === void 0 || _this$canvasLayer.remove();
1272
+ (_this$explodeFragment = this.explodeFragmentBuffer) === null || _this$explodeFragment === void 0 || _this$explodeFragment.destroy();
1273
+ (_this$explodeTexture2 = this.explodeTexture) === null || _this$explodeTexture2 === void 0 || _this$explodeTexture2.destroy();
801
1274
  this.particleBuffer = undefined;
802
1275
  this.targetParticleBuffer = undefined;
803
1276
  this.uniformBuffer = undefined;
@@ -811,6 +1284,14 @@ var ParticleRenderer = /*#__PURE__*/function () {
811
1284
  this.transitionStep = 0;
812
1285
  this.transitionActive = false;
813
1286
  this.particleCount = 0;
1287
+ this.canvasBounds = undefined;
1288
+ this.currentParticleData = undefined;
1289
+ this.targetParticleData = undefined;
1290
+ this.explodeFragmentBuffer = undefined;
1291
+ this.explodeTexture = undefined;
1292
+ this.explodeSampler = undefined;
1293
+ this.explodeSourceCanvas = undefined;
1294
+ this.explodeTextureReady = false;
814
1295
  this.initializationPromise = undefined;
815
1296
  }
816
1297
  }]);