zimjs 20.0.2 → 20.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/zim.js CHANGED
@@ -5219,6 +5219,75 @@ zim.sortObject = function(obj,property,reverse) {
5219
5219
  return sorted;
5220
5220
  };//-12.1
5221
5221
 
5222
+ /*--
5223
+ zim.orderContainer = function(container, order)
5224
+
5225
+ orderContainer
5226
+ zim function
5227
+
5228
+ DESCRIPTION
5229
+ Arranges original indexed children of a Container to new positions based on provided array.
5230
+
5231
+ NOTE: as of ZIM 5.5.0 the zim namespace is no longer required (unless zns is set to true before running zim)
5232
+
5233
+ EXAMPLE
5234
+ const holder = new Container().loc(20,20);
5235
+
5236
+ new Rectangle(120, 120, red).loc(0, 0, holder);
5237
+ new Rectangle(120, 120, blue).loc(40, 40, holder);
5238
+ new Rectangle(120, 120, green).loc(80, 80, holder);
5239
+ new Rectangle(120, 120, yellow).loc(120, 120, holder);
5240
+
5241
+ S.on("stagemousedown", () => {
5242
+ reorderByIndexes(holder, [3, 1, 0, 2]);
5243
+ // puts old index 3 as the lowest (0)
5244
+ // leaves old index 1 at 1
5245
+ // sets old index 0 to the third highest (2)
5246
+ // and puts old index 2 at the higest(3)
5247
+ S.update();
5248
+ });
5249
+ END EXAMPLE
5250
+
5251
+ PARAMETERS
5252
+ container - an Container
5253
+ order - an array showing the old index numbers in a new order
5254
+ beware, this can be confusing - this is NOT saying the first child will have this new index, etc.
5255
+ but rather which old index is moved to the first level, second level, etc.
5256
+
5257
+ RETURNS the container
5258
+ --*///+12.2
5259
+
5260
+ zim.orderContainer = function(container, order) {
5261
+ z_d("12.2");
5262
+
5263
+ var kids = container.children.slice();
5264
+ var used = {};
5265
+ var ordered = [];
5266
+ var valid = true;
5267
+
5268
+ if (!kids || kids.length !== order.length) return container;
5269
+
5270
+ loop(order, function(index) {
5271
+ if (index < 0 || index >= kids.length || used[index]) {
5272
+ valid = false;
5273
+ return true;
5274
+ }
5275
+ used[index] = true;
5276
+ ordered.push(kids[index]);
5277
+ });
5278
+
5279
+ if (!valid || ordered.length !== kids.length) return container;
5280
+
5281
+ loop(ordered, function(child) {
5282
+ child.top();
5283
+ });
5284
+
5285
+ return container;
5286
+
5287
+
5288
+
5289
+ };//-12.2
5290
+
5222
5291
  /*--
5223
5292
  zim.arraysEqual = function(a, b, strict)
5224
5293
 
@@ -13331,11 +13400,13 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
13331
13400
  return [f,s,ss,a,aa];
13332
13401
  }
13333
13402
 
13334
- function processShape(type, tag) {
13403
+ function processShape(type, tag) {
13404
+
13335
13405
  var shape;
13336
13406
  var g = processGeneral(tag); // want ES6
13337
13407
  var f = g[0], s = g[1], ss = g[2], x = g[5], y = g[6];
13338
13408
  // var a = g[3], aa = g[4];
13409
+
13339
13410
  if (type == "circle") {
13340
13411
  var r = Number(tag.getAttribute("r").trim());
13341
13412
  var d = r*.5523;
@@ -13443,7 +13514,6 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
13443
13514
 
13444
13515
  // beatgammit on StackOverflow
13445
13516
  function ellipse(x, y, xDis, yDis) {
13446
- zog(x, y, xDis, yDis)
13447
13517
  var kappa = 0.5522848, // 4 * ((√(2) - 1) / 3)
13448
13518
  ox = xDis * kappa, // control point offset horizontal
13449
13519
  oy = yDis * kappa, // control point offset vertical
@@ -13504,6 +13574,8 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
13504
13574
 
13505
13575
  }
13506
13576
 
13577
+
13578
+
13507
13579
  function processGeneral(tag) {
13508
13580
  // any styles on the tag overwrites general styles or attributes
13509
13581
  var f,s,ss,a,aa;
@@ -13526,12 +13598,18 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
13526
13598
  a = tag.getAttribute("fill-opacity")?tag.getAttribute("fill-opacity"):!zot(a)?a:generalAlpha;
13527
13599
  aa = tag.getAttribute("stroke-opacity")?tag.getAttribute("stroke-opacity"):!zot(aa)?aa:generalStrokeAlpha;
13528
13600
 
13601
+ f = parseGradients(f, tag);
13602
+ s = parseGradients(s, tag);
13529
13603
  var x = tag.getAttribute("x")?tag.getAttribute("x"):0;
13530
13604
  x = tag.getAttribute("cx")?tag.getAttribute("cx"):x;
13531
13605
  var y = tag.getAttribute("y")?tag.getAttribute("y"):0;
13532
13606
  y = tag.getAttribute("cy")?tag.getAttribute("cy"):y;
13533
- if (!zot(a) && !zot(f)) f = zim.convertColor(f, "rgba", Number(a));
13534
- if (!zot(aa) && !zot(s)) s = zim.convertColor(s, "rgba", Number(aa));
13607
+ if (f && !f.type=="RadialColor" && !f.type=="GradientColor") {
13608
+ if (!zot(a) && !zot(f)) f = zim.convertColor(f, "rgba", Number(a));
13609
+ }
13610
+ if (s && !s.type=="RadialColor" && !s.type=="GradientColor") {
13611
+ if (!zot(aa) && !zot(s)) s = zim.convertColor(s, "rgba", Number(aa));
13612
+ }
13535
13613
  return [f,s,Number(ss),Number(a),Number(aa),Number(x),Number(y)];
13536
13614
  }
13537
13615
 
@@ -14013,7 +14091,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
14013
14091
  if (points.length >= 2)
14014
14092
  // M 100 350 l 150 -300
14015
14093
  if (lastCommand == "z" || lastCommand == "Z") {type = "blob";}
14016
- //if (zot(shape)) {
14094
+ //if (zot(shape)) {
14017
14095
  if (type == "squiggle") shape = new zim.Squiggle(s, ss, points, null, null, null, null, showControls, null, null, null, null, null, null, null, null, null, null, null, null, null, interactive);
14018
14096
  else shape = new zim.Blob(f, s, ss, points, null, null, null, null, showControls, null, null, null, null, null, null, null, null, null, null, null, null, null, interactive);
14019
14097
  shape.loc(0,0,that);
@@ -14057,6 +14135,294 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
14057
14135
  return processPath(path,false);
14058
14136
  };
14059
14137
 
14138
+
14139
+ // AI converting svg gradients to createjs format
14140
+
14141
+ function svgGradientToArray(gradientNode, tag) {
14142
+ // Returns:
14143
+ // linear: [0, [colors, ratios, x0, y0, x1, y1]]
14144
+ // radial: [1, [colors, ratios, x0, y0, r0, x1, y1, r1]]
14145
+ //
14146
+ // Assumes:
14147
+ // - gradient coordinates are based on SVG top-left space
14148
+ // - ZIM shape uses same width/height but centered origin
14149
+ // - tag is the SVG element using the gradient
14150
+
14151
+ if (!gradientNode || !gradientNode.tagName || !tag) return null;
14152
+
14153
+ var type = gradientNode.tagName.toLowerCase();
14154
+ var box = tag.getBBox ? tag.getBBox() : {x:0, y:0, width:0, height:0};
14155
+ var width = box.width || 0;
14156
+ var height = box.height || 0;
14157
+
14158
+ function num(v, fallback) {
14159
+ var n;
14160
+ if (fallback == null) fallback = 0;
14161
+ if (v == null || v === "") return fallback;
14162
+ n = parseFloat(v);
14163
+ return isNaN(n) ? fallback : n;
14164
+ }
14165
+
14166
+ function trim(s) {
14167
+ return String(s).replace(/^\s+|\s+$/g, "");
14168
+ }
14169
+
14170
+ function getAttr(node, name, fallback) {
14171
+ var v;
14172
+ if (fallback == null) fallback = null;
14173
+ if (!node) return fallback;
14174
+ v = node.getAttribute(name);
14175
+ return v != null ? v : fallback;
14176
+ }
14177
+
14178
+ function parseStyle(styleText) {
14179
+ var data = {};
14180
+ var parts;
14181
+ var i;
14182
+ var bit;
14183
+ var key;
14184
+ var value;
14185
+
14186
+ if (!styleText) return data;
14187
+ parts = styleText.split(";");
14188
+
14189
+ for (i = 0; i < parts.length; i++) {
14190
+ bit = parts[i].split(":");
14191
+ if (bit.length < 2) continue;
14192
+ key = trim(bit[0]);
14193
+ value = trim(bit.slice(1).join(":"));
14194
+ data[key] = value;
14195
+ }
14196
+
14197
+ return data;
14198
+ }
14199
+
14200
+ function parseOffset(v) {
14201
+ var s;
14202
+ if (v == null || v === "") return 0;
14203
+ s = trim(v);
14204
+ if (s.charAt(s.length - 1) === "%") return Math.max(0, Math.min(1, num(s) / 100));
14205
+ return Math.max(0, Math.min(1, num(s)));
14206
+ }
14207
+
14208
+ function applyOpacityToColor(color, opacity) {
14209
+ var hex, short, full, r, g, b;
14210
+
14211
+ if (opacity >= 1) return color;
14212
+ hex = trim(color);
14213
+
14214
+ if (/^#([0-9a-f]{3})$/i.test(hex)) {
14215
+ short = hex.slice(1);
14216
+ r = parseInt(short.charAt(0) + short.charAt(0), 16);
14217
+ g = parseInt(short.charAt(1) + short.charAt(1), 16);
14218
+ b = parseInt(short.charAt(2) + short.charAt(2), 16);
14219
+ return "rgba(" + r + "," + g + "," + b + "," + opacity + ")";
14220
+ }
14221
+
14222
+ if (/^#([0-9a-f]{6})$/i.test(hex)) {
14223
+ full = hex.slice(1);
14224
+ r = parseInt(full.slice(0, 2), 16);
14225
+ g = parseInt(full.slice(2, 4), 16);
14226
+ b = parseInt(full.slice(4, 6), 16);
14227
+ return "rgba(" + r + "," + g + "," + b + "," + opacity + ")";
14228
+ }
14229
+
14230
+ return color;
14231
+ }
14232
+
14233
+ function parseStop(stopNode) {
14234
+ var style = parseStyle(getAttr(stopNode, "style", ""));
14235
+ var color = getAttr(stopNode, "stop-color", null) || style["stop-color"] || "#000000";
14236
+ var stopOpacity = getAttr(stopNode, "stop-opacity", null);
14237
+ var opacity;
14238
+ var offset;
14239
+
14240
+ if (stopOpacity == null && style["stop-opacity"] != null) stopOpacity = style["stop-opacity"];
14241
+ if (stopOpacity == null) stopOpacity = 1;
14242
+
14243
+ opacity = Math.max(0, Math.min(1, num(stopOpacity, 1)));
14244
+ offset = parseOffset(getAttr(stopNode, "offset", 0));
14245
+
14246
+ return {
14247
+ color: applyOpacityToColor(color, opacity),
14248
+ offset: offset
14249
+ };
14250
+ }
14251
+
14252
+ function resolveHref(node) {
14253
+ return getAttr(node, "href", null) || getAttr(node, "xlink:href", null) || null;
14254
+ }
14255
+
14256
+ function resolveLinkedGradient(node) {
14257
+ var href;
14258
+ if (!node || !node.ownerDocument) return null;
14259
+ href = resolveHref(node);
14260
+ if (!href || href.charAt(0) !== "#") return null;
14261
+ return node.ownerDocument.getElementById(href.slice(1));
14262
+ }
14263
+
14264
+ function inheritedAttr(node, name, fallback, seen) {
14265
+ var value;
14266
+ var linked;
14267
+
14268
+ if (fallback == null) fallback = null;
14269
+ if (!seen) seen = [];
14270
+ if (!node || seen.indexOf(node) !== -1) return fallback;
14271
+ seen.push(node);
14272
+
14273
+ value = getAttr(node, name, null);
14274
+ if (value != null) return value;
14275
+
14276
+ linked = resolveLinkedGradient(node);
14277
+ if (linked) return inheritedAttr(linked, name, fallback, seen);
14278
+
14279
+ return fallback;
14280
+ }
14281
+
14282
+ function collectStops(node, seen) {
14283
+ var linked;
14284
+ var inheritedStops;
14285
+ var ownStops = [];
14286
+ var children;
14287
+ var i;
14288
+ var child;
14289
+
14290
+ if (!seen) seen = [];
14291
+ if (!node || seen.indexOf(node) !== -1) return [];
14292
+ seen.push(node);
14293
+
14294
+ linked = resolveLinkedGradient(node);
14295
+ inheritedStops = linked ? collectStops(linked, seen) : [];
14296
+
14297
+ children = node.children || [];
14298
+ for (i = 0; i < children.length; i++) {
14299
+ child = children[i];
14300
+ if (child.tagName && child.tagName.toLowerCase() === "stop") {
14301
+ ownStops.push(parseStop(child));
14302
+ }
14303
+ }
14304
+
14305
+ return ownStops.length ? ownStops : inheritedStops;
14306
+ }
14307
+
14308
+ function coordX(v, units) {
14309
+ var s = trim(v);
14310
+ if (s.charAt(s.length - 1) === "%") return width * num(s) / 100 - width / 2;
14311
+ if (units === "objectBoundingBox") return width * num(s) - width / 2;
14312
+ return num(s) - box.x - width / 2;
14313
+ }
14314
+
14315
+ function coordY(v, units) {
14316
+ var s = trim(v);
14317
+ if (s.charAt(s.length - 1) === "%") return height * num(s) / 100 - height / 2;
14318
+ if (units === "objectBoundingBox") return height * num(s) - height / 2;
14319
+ return num(s) - box.y - height / 2;
14320
+ }
14321
+
14322
+ function radius(v, units) {
14323
+ var s = trim(v);
14324
+ var base = Math.min(width, height);
14325
+ if (s.charAt(s.length - 1) === "%") return base * num(s) / 100;
14326
+ if (units === "objectBoundingBox") return base * num(s);
14327
+ return num(s);
14328
+ }
14329
+
14330
+ function applyMatrix(x, y, matrixString) {
14331
+ var m;
14332
+ var vals;
14333
+
14334
+ if (!matrixString) return {x:x, y:y};
14335
+
14336
+ m = trim(matrixString).match(/^matrix\(([^)]+)\)$/i);
14337
+ if (!m) return {x:x, y:y};
14338
+
14339
+ vals = m[1].split(/[\s,]+/);
14340
+ if (vals.length < 6) return {x:x, y:y};
14341
+
14342
+ return {
14343
+ x: num(vals[0], 1) * x + num(vals[2], 0) * y + num(vals[4], 0),
14344
+ y: num(vals[1], 0) * x + num(vals[3], 1) * y + num(vals[5], 0)
14345
+ };
14346
+ }
14347
+
14348
+ var stops = collectStops(gradientNode);
14349
+ var colors = [];
14350
+ var ratios = [];
14351
+ var units = inheritedAttr(gradientNode, "gradientUnits", "objectBoundingBox");
14352
+ var transform = inheritedAttr(gradientNode, "gradientTransform", null);
14353
+ var i;
14354
+ var p0;
14355
+ var p1;
14356
+ var x0;
14357
+ var y0;
14358
+ var x1;
14359
+ var y1;
14360
+ var r0;
14361
+ var r1;
14362
+
14363
+ for (i = 0; i < stops.length; i++) {
14364
+ colors.push(stops[i].color);
14365
+ ratios.push(stops[i].offset);
14366
+ }
14367
+
14368
+ if (type === "lineargradient") {
14369
+ x0 = coordX(inheritedAttr(gradientNode, "x1", units === "objectBoundingBox" ? "0%" : "0"), units);
14370
+ y0 = coordY(inheritedAttr(gradientNode, "y1", units === "objectBoundingBox" ? "0%" : "0"), units);
14371
+ x1 = coordX(inheritedAttr(gradientNode, "x2", units === "objectBoundingBox" ? "100%" : "100"), units);
14372
+ y1 = coordY(inheritedAttr(gradientNode, "y2", units === "objectBoundingBox" ? "0%" : "0"), units);
14373
+
14374
+ p0 = applyMatrix(x0, y0, transform);
14375
+ p1 = applyMatrix(x1, y1, transform);
14376
+
14377
+ return [0, [colors, ratios, p0.x, p0.y, p1.x, p1.y]];
14378
+ }
14379
+
14380
+ x0 = coordX(inheritedAttr(gradientNode, "fx", inheritedAttr(gradientNode, "cx", units === "objectBoundingBox" ? "50%" : "0")), units);
14381
+ y0 = coordY(inheritedAttr(gradientNode, "fy", inheritedAttr(gradientNode, "cy", units === "objectBoundingBox" ? "50%" : "0")), units);
14382
+ x1 = coordX(inheritedAttr(gradientNode, "cx", units === "objectBoundingBox" ? "50%" : "0"), units);
14383
+ y1 = coordY(inheritedAttr(gradientNode, "cy", units === "objectBoundingBox" ? "50%" : "0"), units);
14384
+ r0 = 0;
14385
+ r1 = radius(inheritedAttr(gradientNode, "r", units === "objectBoundingBox" ? "50%" : "0"), units);
14386
+
14387
+ p0 = applyMatrix(x0, y0, transform);
14388
+ p1 = applyMatrix(x1, y1, transform);
14389
+
14390
+ return [1, [colors, ratios, p0.x, p0.y, r0, p1.x, p1.y, r1]];
14391
+ }
14392
+
14393
+ function parseGradients(f, tag) {
14394
+ var match;
14395
+ var id;
14396
+ var gradientTag;
14397
+ var data;
14398
+ var p;
14399
+
14400
+ if (f == null) return f;
14401
+ f = String(f).replace(/^\s+|\s+$/g, "");
14402
+
14403
+ if (!/^url\(/i.test(f)) return f;
14404
+
14405
+ match = f.match(/^url\(\s*#([^)]+)\s*\)$/i);
14406
+ if (!match) return f;
14407
+
14408
+ id = match[1];
14409
+ if (!svg || !svg.querySelector) return f;
14410
+
14411
+ gradientTag = svg.querySelector("#" + id);
14412
+ if (!gradientTag) return f;
14413
+
14414
+ data = svgGradientToArray(gradientTag, tag);
14415
+ if (!data) return f;
14416
+
14417
+ p = data[1];
14418
+
14419
+ if (data[0] === 1) {
14420
+ return new RadialColor(p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
14421
+ }
14422
+
14423
+ return new GradientColor(p[0], p[1], p[2], p[3], p[4], p[5]);
14424
+ }
14425
+
14060
14426
 
14061
14427
 
14062
14428
  if (style!==false) zim.styleTransforms(this, DS); // global function - would have put on DisplayObject if had access to it
@@ -14339,7 +14705,7 @@ zim.extend(zim.Tag, zim.Container, ["clone", "dispose"], "zimContainer", false);
14339
14705
  // SUBSECTION SHADERS
14340
14706
 
14341
14707
  /*--
14342
- zim.Shader = function(width, height, fragment, uniforms, vertex, dynamic, preCall, postCall, rate, version, canvas, vertexPosition, strip, log, channel0, channel1, channel2, channel3, dynamic0, dynamic1, dynamic2, dynamic3, style, group, inherit)
14708
+ zim.Shader = function(width, height, fragment, uniforms, vertex, dynamic, preCall, postCall, rate, version, canvas, vertexPosition, strip, log, channel0, channel1, channel2, channel3, dynamic0, dynamic1, dynamic2, dynamic3, channels, dynamics, style, group, inherit)
14343
14709
 
14344
14710
  Shader
14345
14711
  zim class - extends a zim.Bitmap which extends a createjs.Bitmap
@@ -14350,6 +14716,9 @@ Shaders run on the GPU and are very fast for cool visual effects and are also th
14350
14716
  For 3D, we recommend using three.js with ZIM and the the Three helper module - overlayed or with TextureActive.
14351
14717
  BUT - shaders are also commonly used for amazing 2D effects.
14352
14718
 
14719
+ As of ZIM 020 - there are now 16 channels supported in one Shader instance
14720
+ see just past the numbered channels and dynamics to the channels and dynamics parameters that accept arrays
14721
+
14353
14722
  Also see ShaderOverlay() that overlays the raw WebGL Canvas on ZIM as a Tag() rather than converting to a Bitmap.
14354
14723
 
14355
14724
  The best way to see what shaders are about are to look at the many examples on ShaderToy, for instance:
@@ -14791,6 +15160,13 @@ channel0, channel1, channel2, channel3 - (default null) pass in a ZIM DisplayObj
14791
15160
  see the dynamic parameters below to set if this is a dynamic channel, default is true
14792
15161
  dynamic0, dynamic1, dynamic2, dynamic3 - (default true / false for Pic) if a channel is used, set its matching dynamic parameter to false
14793
15162
  if the channel does not change - for example a Container where nothing is moving.
15163
+ channels - (default null) an Array of up to 16 ZIM DisplayObjects (Container, Pic, Vid, Shader, etc.)
15164
+ used for iChannel0 through iChannel15 in the shader.
15165
+ Alternatively, channel0, channel1, channel2, etc. can be passed individually.
15166
+ Objects are cached and GPU textures are bound and updated automatically.
15167
+ dynamics - (default null) an Array of Booleans matching the channels Array.
15168
+ Set an index to false if that channel does not change (e.g. a static Container or Pic).
15169
+ Defaults to true (or false for Pic). Alternatively, dynamic0, dynamic1, etc. can be passed individually.
14794
15170
  style - (default true) set to false to ignore styles set with the STYLE - will receive original parameter defaults
14795
15171
  group - (default null) set to String (or comma delimited String) so STYLE can set default styles to the group(s) (like a CSS class)
14796
15172
  inherit - (default null) used internally but can receive an {} of styles directly
@@ -14838,13 +15214,13 @@ EVENTS
14838
15214
  See the CreateJS Easel Docs for Bitmap events such as:
14839
15215
  added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmove, pressup, removed, rollout, rollover
14840
15216
  --*///+50.96
14841
- zim.Shader = function(width, height, fragment, uniforms, vertex, dynamic, preCall, postCall, rate, version, canvas, vertexPosition, strip, log, channel0, channel1, channel2, channel3, dynamic0, dynamic1, dynamic2, dynamic3, style, group, inherit) {
14842
- var sig = "width, height, fragment, uniforms, vertex, dynamic, preCall, postCall, rate, version, canvas, vertexPosition, strip, log, channel0, channel1, channel2, channel3, dynamic0, dynamic1, dynamic2, dynamic3, style, group, inherit";
15217
+ zim.Shader = function(width, height, fragment, uniforms, vertex, dynamic, preCall, postCall, rate, version, canvas, vertexPosition, strip, log, channel0, channel1, channel2, channel3, dynamic0, dynamic1, dynamic2, dynamic3, channels, dynamics, style, group, inherit) {
15218
+ var sig = "width, height, fragment, uniforms, vertex, dynamic, preCall, postCall, rate, version, canvas, vertexPosition, strip, log, channel0, channel1, channel2, channel3, dynamic0, dynamic1, dynamic2, dynamic3, channels, dynamics, style, group, inherit";
14843
15219
  var duo; if (duo = zob(zim.Shader, arguments, sig, this)) return duo;
14844
- z_d("50.96");
15220
+ z_d("50.970");
14845
15221
  this.group = group;
14846
15222
  var DS = style===false?group!=null?zim.getStyle(null,null,inherit,this.group):{}:zim.getStyle("Shader", this.group, inherit);
14847
- var s = makeShader(DS, width, height, fragment, uniforms, vertex, dynamic, preCall, postCall, rate, version, canvas, vertexPosition, strip, log, channel0, channel1, channel2, channel3, dynamic0, dynamic1, dynamic2, dynamic3, this);
15223
+ var s = makeShader(DS, width, height, fragment, uniforms, vertex, dynamic, preCall, postCall, rate, version, canvas, vertexPosition, strip, log, channel0, channel1, channel2, channel3, dynamic0, dynamic1, dynamic2, dynamic3, channels, dynamics, this);
14848
15224
 
14849
15225
  this.zimBitmap_constructor(s.canvas);
14850
15226
  this.type = "Shader";
@@ -14852,7 +15228,7 @@ zim.Shader = function(width, height, fragment, uniforms, vertex, dynamic, preCal
14852
15228
  // MONITOR
14853
15229
  var mID = this.mID = "z~"+(DS.monitor===false?"-":this.type);
14854
15230
 
14855
- this.uniforms = s.uniforms; // now a Uniforms object - use uniforms.obj to see original
15231
+ this.uniforms = s.uniforms;
14856
15232
  this.canvas = s.canvas;
14857
15233
  this.gl = s.gl;
14858
15234
  this.setUniform = s.setUniform;
@@ -14880,47 +15256,27 @@ zim.Shader = function(width, height, fragment, uniforms, vertex, dynamic, preCal
14880
15256
  }
14881
15257
  });
14882
15258
 
14883
- // var gl = canvas.getContext('webgl2');
14884
- // that.updateChannel = function(index, obj) {
14885
-
14886
- // if (zot(index)) index = 0;
14887
- // if (!that.channels[i]) return that;
14888
- // var channel = that.channels[i];
14889
-
14890
- // channel.dynamic = that["dynamic" + i];
14891
- // if (channel.type && channel.type=="Pic") channel.dynamic = false;
14892
- // if (channel.cache) {
14893
- // if (!channel.cacheCanvas) channel.cache();
14894
- // channel.texture = createTexture(channel.cacheCanvas);
14895
- // } else {
14896
- // channel.texture = createTexture(channel);
14897
- // }
14898
- // gl.uniform1i(gl.getUniformLocation(program, 'iChannel' + i), i);
14899
- // }
14900
-
14901
15259
  if (style!==false) zim.styleTransforms(this, DS);
14902
15260
 
14903
15261
  this.clone = function() {
14904
- return that.cloneProps(new zim.Shader(width, height, fragment, uniforms, vertex, dynamic, preCall, postCall, rate, version, canvas, vertexPosition, strip, log, channel0, channel1, channel2, channel3, dynamic0, dynamic1, dynamic2, dynamic3, style, this.group, inherit));
15262
+ return that.cloneProps(new zim.Shader(width, height, fragment, uniforms, vertex, dynamic, preCall, postCall, rate, version, canvas, vertexPosition, strip, log, channel0, channel1, channel2, channel3, dynamic0, dynamic1, dynamic2, dynamic3, channels, dynamics, style, this.group, inherit));
14905
15263
  };
14906
15264
 
14907
15265
  this.dispose = function(temp, b, disposing) {
14908
15266
  if (this.ticker) zim.Ticker.remove(this.ticker, mID, that);
14909
- // if (this.uniforms) this.uniforms.dispose();
14910
15267
  this.canvas = null;
14911
15268
  this.gl = null;
14912
15269
  this.program = null;
14913
15270
  this.ticker = null;
14914
15271
  if (!disposing) this.zimBitmap_dispose(true);
14915
15272
  return true;
14916
- }
14917
-
14918
- }
15273
+ };
15274
+ };
14919
15275
  zim.extend(zim.Shader, zim.Bitmap, ["clone", "dispose"], "zimBitmap", false);
14920
15276
  //-50.96
14921
15277
 
14922
15278
  /*--
14923
- zim.ShaderOverlay = function(width, height, fragment, uniforms, vertex, dynamic, preCall, postCall, rate, version, canvas, vertexPosition, strip, log, channel0, channel1, channel2, channel3, dynamic0, dynamic1, dynamic2, dynamic3, style, group, inherit)
15279
+ zim.ShaderOverlay = function(width, height, fragment, uniforms, vertex, dynamic, preCall, postCall, rate, version, canvas, vertexPosition, strip, log, channel0, channel1, channel2, channel3, dynamic0, dynamic1, dynamic2, dynamic3, channels, dynamics, style, group, inherit)
14924
15280
 
14925
15281
  ShaderOverlay
14926
15282
  zim class - extends a zim.Tag
@@ -14965,13 +15321,13 @@ function ready() {
14965
15321
  END EXAMPLE
14966
15322
 
14967
15323
  --*///+50.962
14968
- zim.ShaderOverlay = function(width, height, fragment, uniforms, vertex, dynamic, preCall, postCall, rate, version, canvas, vertexPosition, strip, log, channel0, channel1, channel2, channel3, dynamic0, dynamic1, dynamic2, dynamic3, style, group, inherit) {
14969
- var sig = "width, height, fragment, uniforms, vertex, dynamic, preCall, postCall, rate, version, canvas, vertexPosition, strip, log, channel0, channel1, channel2, channel3, dynamic0, dynamic1, dynamic2, dynamic3, style, group, inherit";
15324
+ zim.ShaderOverlay = function(width, height, fragment, uniforms, vertex, dynamic, preCall, postCall, rate, version, canvas, vertexPosition, strip, log, channel0, channel1, channel2, channel3, dynamic0, dynamic1, dynamic2, dynamic3, channels, dynamics, style, group, inherit) {
15325
+ var sig = "width, height, fragment, uniforms, vertex, dynamic, preCall, postCall, rate, version, canvas, vertexPosition, strip, log, channel0, channel1, channel2, channel3, dynamic0, dynamic1, dynamic2, dynamic3, channels, dynamics, style, group, inherit";
14970
15326
  var duo; if (duo = zob(zim.ShaderOverlay, arguments, sig, this)) return duo;
14971
- z_d("50.962");
15327
+ z_d("50.970");
14972
15328
  this.group = group;
14973
15329
  var DS = style===false?group!=null?zim.getStyle(null,null,inherit,this.group):{}:zim.getStyle("ShaderOverlay", this.group, inherit);
14974
- var s = makeShader(DS, width, height, fragment, uniforms, vertex, dynamic, preCall, postCall, rate, version, canvas, vertexPosition, strip, log, channel0, channel1, channel2, channel3, dynamic0, dynamic1, dynamic2, dynamic3, this);
15330
+ var s = makeShader(DS, width, height, fragment, uniforms, vertex, dynamic, preCall, postCall, rate, version, canvas, vertexPosition, strip, log, channel0, channel1, channel2, channel3, dynamic0, dynamic1, dynamic2, dynamic3, channels, dynamics, this);
14975
15331
 
14976
15332
  this.zimTag_constructor(width, height);
14977
15333
  this.type = "ShaderOverlay";
@@ -14979,7 +15335,7 @@ zim.ShaderOverlay = function(width, height, fragment, uniforms, vertex, dynamic,
14979
15335
  // MONITOR
14980
15336
  var mID = this.mID = "z~"+(DS.monitor===false?"-":this.type);
14981
15337
 
14982
- this.uniforms = s.uniforms; // now a Uniforms object - use uniforms.obj to see original
15338
+ this.uniforms = s.uniforms;
14983
15339
  this.canvas = s.canvas;
14984
15340
  this.gl = s.gl;
14985
15341
  this.setUniform = s.setUniform;
@@ -15004,7 +15360,7 @@ zim.ShaderOverlay = function(width, height, fragment, uniforms, vertex, dynamic,
15004
15360
  if (value) {
15005
15361
  zim.Ticker.add(this.ticker, null, mID, that);
15006
15362
  } else {
15007
- if (this.ticker) zim.Ticker.remove(this.ticker, mID, that, that);
15363
+ if (this.ticker) zim.Ticker.remove(this.ticker, mID, that);
15008
15364
  }
15009
15365
  _dynamic = value?true:false;
15010
15366
  }
@@ -15013,7 +15369,7 @@ zim.ShaderOverlay = function(width, height, fragment, uniforms, vertex, dynamic,
15013
15369
  if (style!==false) zim.styleTransforms(this, DS);
15014
15370
 
15015
15371
  this.clone = function() {
15016
- return that.cloneProps(new zim.Shader(width, height, fragment, uniforms, vertex, dynamic, preCall, postCall, rate, version, canvas, vertexPosition, strip, log, channel0, channel1, channel2, channel3, dynamic0, dynamic1, dynamic2, dynamic3, style, this.group, inherit));
15372
+ return that.cloneProps(new zim.ShaderOverlay(width, height, fragment, uniforms, vertex, dynamic, preCall, postCall, rate, version, canvas, vertexPosition, strip, log, channel0, channel1, channel2, channel3, dynamic0, dynamic1, dynamic2, dynamic3, channels, dynamics, style, this.group, inherit));
15017
15373
  };
15018
15374
 
15019
15375
  this.dispose = function(temp, b, disposing) {
@@ -15025,14 +15381,13 @@ zim.ShaderOverlay = function(width, height, fragment, uniforms, vertex, dynamic,
15025
15381
  this.ticker = null;
15026
15382
  if (!disposing) this.zimTag_dispose(true);
15027
15383
  return true;
15028
- }
15029
-
15030
- }
15384
+ };
15385
+ };
15031
15386
  zim.extend(zim.ShaderOverlay, zim.Tag, ["clone", "dispose"], "zimTag", false);
15032
15387
  //-50.962
15033
15388
 
15034
15389
  /*--
15035
- makeShader = function(DS, width, height, fragment, uniforms, vertex, dynamic, preCall, postCall, rate, version, canvas, vertexPosition, strip, log, tether)
15390
+ makeShader = function(DS, width, height, fragment, uniforms, vertex, dynamic, preCall, postCall, rate, version, canvas, vertexPosition, strip, log, channel0, channel1, channel2, channel3, dynamic0, dynamic1, dynamic2, dynamic3, channels, dynamics, tether)
15036
15391
 
15037
15392
  makeShader
15038
15393
  function - used internally only
@@ -15050,13 +15405,13 @@ primarily to match default uniforms at ShaderToy https://www.shadertoy.com/
15050
15405
  Introduced in ZIM 016
15051
15406
 
15052
15407
  --*///+50.964
15053
- function makeShader(DS, width, height, fragment, uniforms, vertex, dynamic, preCall, postCall, rate, version, canvas, vertexPosition, strip, log, channel0, channel1, channel2, channel3, dynamic0, dynamic1, dynamic2, dynamic3, tether) {
15054
- z_d("50.964");
15408
+ function makeShader(DS, width, height, fragment, uniforms, vertex, dynamic, preCall, postCall, rate, version, canvas, vertexPosition, strip, log, channel0, channel1, channel2, channel3, dynamic0, dynamic1, dynamic2, dynamic3, channels, dynamics, tether) {
15409
+ z_d("50.970");
15055
15410
 
15056
15411
  var mID = "z~Shader";
15057
15412
 
15058
15413
  if (zot(width)) width = DS.width!=null?DS.width:500;
15059
- if (zot(height)) height = DS.radius!=null?DS.height:500;
15414
+ if (zot(height)) height = DS.height!=null?DS.height:500;
15060
15415
  if (zot(rate)) rate = DS.rate!=null?DS.rate:1;
15061
15416
  if (zot(version)) version = DS.version!=null?DS.version:"#version 300 es";
15062
15417
  var defaultV;
@@ -15075,46 +15430,108 @@ function makeShader(DS, width, height, fragment, uniforms, vertex, dynamic, preC
15075
15430
  if (zot(vertexPosition)) vertexPosition = DS.vertexPosition!=null?DS.vertexPosition:"vertexPosition";
15076
15431
  if (zot(strip)) strip = DS.strip!=null?DS.strip:true;
15077
15432
  if (zot(log)) log = DS.log!=null?DS.log:null;
15078
- if (zot(channel0)) channel0 = DS.channel0!=null?DS.channel0:null;
15079
- if (zot(channel1)) channel1 = DS.channel1!=null?DS.channel1:null;
15080
- if (zot(channel2)) channel2 = DS.channel2!=null?DS.channel2:null;
15081
- if (zot(channel3)) channel3 = DS.channel3!=null?DS.channel3:null;
15082
- if (zot(dynamic0)) dynamic0 = DS.dynamic0!=null?DS.dynamic0:true;
15083
- if (zot(dynamic1)) dynamic1 = DS.dynamic1!=null?DS.dynamic1:true;
15084
- if (zot(dynamic2)) dynamic2 = DS.dynamic2!=null?DS.dynamic2:true;
15085
- if (zot(dynamic3)) dynamic3 = DS.dynamic3!=null?DS.dynamic3:true;
15086
-
15087
15433
 
15088
15434
  if (zot(canvas)) {
15089
15435
  canvas = document.createElement("canvas");
15090
15436
  canvas.setAttribute("width", width);
15091
15437
  canvas.setAttribute("height", height);
15092
- canvas.setAttribute("id", "shaderCanvas");
15438
+ canvas.setAttribute("id", "shaderCanvas_" + zim.makeID());
15093
15439
  }
15094
15440
 
15095
- function createTexture(source) {
15441
+ function getSource(channel) {
15442
+ if (!channel) return null;
15443
+ if (channel.tagName === "VIDEO" || channel.tagName === "IMG" || channel.tagName === "CANVAS") return channel;
15444
+ if (channel.source && (channel.source.tagName === "VIDEO" || channel.source.tagName === "IMG")) return channel.source;
15445
+ if (channel.video && channel.video.tagName === "VIDEO") return channel.video;
15446
+ if (channel.tag && (channel.tag.tagName === "VIDEO" || channel.tag.tagName === "IMG" || channel.tag.tagName === "CANVAS")) return channel.tag;
15447
+ if (channel.bitmap && channel.bitmap.image) return channel.bitmap.image;
15448
+ if (channel.image) return channel.image;
15449
+ if (channel.cacheCanvas) return channel.cacheCanvas;
15450
+ return channel;
15451
+ }
15452
+
15453
+ function isVideo(source, channel) {
15454
+ if (source && source.tagName === "VIDEO") return true;
15455
+ if (channel && channel.type === "Vid") return true;
15456
+ return false;
15457
+ }
15458
+
15459
+ var gl = canvas.getContext('webgl2');
15460
+ gl.enable(gl.CULL_FACE);
15461
+ gl.cullFace(gl.BACK);
15462
+ gl.frontFace(gl.CCW);
15463
+ gl.clearColor(0.0, 0.0, 0.0, 0.0);
15464
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
15465
+
15466
+ function createTexture(source, unit) {
15467
+ if (zot(unit)) unit = 0;
15468
+ gl.activeTexture(gl["TEXTURE" + unit]);
15096
15469
  var tex = gl.createTexture();
15097
15470
  gl.bindTexture(gl.TEXTURE_2D, tex);
15098
15471
  gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
15099
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);
15472
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
15473
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
15100
15474
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
15101
15475
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
15476
+ if (source && (source.readyState == null || source.readyState >= 2)) {
15477
+ try {
15478
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);
15479
+ } catch(e) {
15480
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([0,0,0,0]));
15481
+ }
15482
+ } else {
15483
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([0,0,0,0]));
15484
+ }
15102
15485
  return tex;
15103
15486
  }
15104
15487
 
15105
- var channels = [channel0, channel1, channel2, channel3];
15106
- var dynamics = [dynamic0, dynamic1, dynamic2, dynamic3];
15488
+ // Build 16-Channel list from array or individual parameters
15489
+ var channelList = new Array(16).fill(null);
15490
+ var dynamicList = new Array(16).fill(true);
15491
+
15492
+ if (channels && Array.isArray(channels)) {
15493
+ for (var k = 0; k < Math.min(channels.length, 16); k++) channelList[k] = channels[k];
15494
+ } else if (DS.channels && Array.isArray(DS.channels)) {
15495
+ for (var k = 0; k < Math.min(DS.channels.length, 16); k++) channelList[k] = DS.channels[k];
15496
+ } else {
15497
+ channelList[0] = channel0 != null ? channel0 : DS.channel0;
15498
+ channelList[1] = channel1 != null ? channel1 : DS.channel1;
15499
+ channelList[2] = channel2 != null ? channel2 : DS.channel2;
15500
+ channelList[3] = channel3 != null ? channel3 : DS.channel3;
15501
+ for (var k = 4; k < 16; k++) {
15502
+ if (DS["channel" + k] != null) channelList[k] = DS["channel" + k];
15503
+ }
15504
+ }
15505
+
15506
+ if (dynamics && Array.isArray(dynamics)) {
15507
+ for (var k = 0; k < Math.min(dynamics.length, 16); k++) dynamicList[k] = dynamics[k];
15508
+ } else if (DS.dynamics && Array.isArray(DS.dynamics)) {
15509
+ for (var k = 0; k < Math.min(DS.dynamics.length, 16); k++) dynamicList[k] = DS.dynamics[k];
15510
+ } else {
15511
+ dynamicList[0] = dynamic0 != null ? dynamic0 : (DS.dynamic0 != null ? DS.dynamic0 : true);
15512
+ dynamicList[1] = dynamic1 != null ? dynamic1 : (DS.dynamic1 != null ? DS.dynamic1 : true);
15513
+ dynamicList[2] = dynamic2 != null ? dynamic2 : (DS.dynamic2 != null ? DS.dynamic2 : true);
15514
+ dynamicList[3] = dynamic3 != null ? dynamic3 : (DS.dynamic3 != null ? DS.dynamic3 : true);
15515
+ for (var k = 4; k < 16; k++) {
15516
+ if (DS["dynamic" + k] != null) dynamicList[k] = DS["dynamic" + k];
15517
+ }
15518
+ }
15519
+
15107
15520
  var channelOutput = "";
15108
- zim.loop(channels, function(channel, i) {
15109
- if (channel) channelOutput+="uniform sampler2D iChannel"+i+";\n";
15110
- });
15521
+ for (var i = 0; i < 16; i++) {
15522
+ if (channelList[i] || fragment.indexOf("iChannel" + i) !== -1) {
15523
+ var reg = new RegExp("uniform\\s+sampler2D\\s+iChannel" + i + "\\s*;", "g");
15524
+ if (!reg.test(fragment)) {
15525
+ channelOutput += "uniform sampler2D iChannel" + i + ";\n";
15526
+ }
15527
+ }
15528
+ }
15111
15529
 
15112
15530
  fragment = version + "\nprecision mediump float;\n\n// ZIM Default Uniforms\nuniform vec3 iResolution;\nuniform float iTime;\nuniform float iTimeDelta;\nuniform float iFrameRate;\nuniform float iFrame;\nuniform vec4 iMouse;\nuniform vec4 iDate;\nuniform float iChange;\n" + channelOutput + fragment;
15113
15531
  vertex = version + "\nprecision mediump float;\n\n// ZIM Default Uniforms\nprecision mediump float;\nuniform vec3 iResolution;\nuniform float iTime;\nuniform float iTimeDelta;\nuniform float iFrameRate;\nuniform float iFrame;\nuniform vec4 iMouse;\nuniform vec4 iDate;\nuniform float iChange;\n\n" + vertex;
15114
15532
 
15115
- // Replace ShaderToy mainImage
15116
15533
  var matches = fragment.match(/(void |.*)mainImage\(\s*(out\s*vec4\s*([^,]*)),\s*in\s*(vec[234]\s*[^)\s]*)\s*\)/i);
15117
- fragment = fragment.replace(/(void |.*)mainImage\(\s*(out\s*vec4\s*[^,]*),\s*in\s*(vec[234]\s*[^)\s]*)\s*\)/i, "$2;\nvoid main()");
15534
+ fragment = fragment.replace(/(void |.*)mainImage\(\s*(out\s*vec4\s*([^,]*)),\s*in\s*(vec[234]\s*[^)\s]*)\s*\)/i, "$2;\nvoid main()");
15118
15535
  if (matches && matches[4]) {
15119
15536
  var append = "main() {\n\t"+matches[4]+" = gl_FragCoord.xy; // ZIM shadertoy adjust";
15120
15537
  fragment = fragment.replace(/main\(\)\s*{/i, append);
@@ -15126,10 +15543,6 @@ function makeShader(DS, width, height, fragment, uniforms, vertex, dynamic, preC
15126
15543
  zogd("FRAGMENT SHADER:\n\n" + fragment);
15127
15544
  }
15128
15545
 
15129
- if (zot(canvas)) {
15130
- canvas = document.createElement("canvas");
15131
- canvas.setAttribute(id, "shaderCanvas_" + zim.makeID());
15132
- }
15133
15546
  if (!zot(uniforms)) {
15134
15547
  if (uniforms.type != "Uniforms") {
15135
15548
  uniforms = new zim.Uniforms(uniforms);
@@ -15140,24 +15553,16 @@ function makeShader(DS, width, height, fragment, uniforms, vertex, dynamic, preC
15140
15553
  tether.rate = zik(rate);
15141
15554
  tether.change = 0;
15142
15555
 
15143
- // base code from https://medium.com/@banksysan_10088/webgl-checkerboard-42e15490603c
15144
- var gl = canvas.getContext('webgl2');
15145
- gl.enable(gl.CULL_FACE);
15146
- gl.cullFace(gl.BACK);
15147
- gl.frontFace(gl.CCW);
15148
- gl.clearColor(1.0, 1.0, 1.0, 1.0);
15149
- gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
15150
-
15151
15556
  var program = createProgram(gl, vertex, fragment);
15152
- if (preCall && typeof preCall=="function") preCall(program, gl, canvas); // ZIM
15557
+ if (preCall && typeof preCall=="function") preCall(program, gl, canvas);
15153
15558
  gl.useProgram(program);
15154
15559
  var vertexData = [];
15155
- if (postCall && typeof postCall=="function") postCall(program, gl, canvas, vertexData); // ZIM
15560
+ if (postCall && typeof postCall=="function") postCall(program, gl, canvas, vertexData);
15156
15561
 
15157
15562
  if (strip) {
15158
- if (vertexData.length == 0) vertexData = [1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0]; // two triangles strips
15563
+ if (vertexData.length == 0) vertexData = [1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0];
15159
15564
  } else {
15160
- if (vertexData.length == 0) vertexData = [-1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0]; // two triangles
15565
+ if (vertexData.length == 0) vertexData = [-1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0];
15161
15566
  }
15162
15567
  var vertexBuffer = gl.createBuffer();
15163
15568
  gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
@@ -15166,79 +15571,113 @@ function makeShader(DS, width, height, fragment, uniforms, vertex, dynamic, preC
15166
15571
  gl.vertexAttribPointer(vertexAttributeLocation, 2, gl.FLOAT, false, 2 * Float32Array.BYTES_PER_ELEMENT, 0);
15167
15572
  gl.enableVertexAttribArray(vertexAttributeLocation);
15168
15573
 
15169
- // ZIM
15574
+ function initChannel(channel, i) {
15575
+ if (!channel) return;
15576
+ channel.dynamic = dynamicList[i];
15577
+ var source = getSource(channel);
15578
+ var isV = isVideo(source, channel);
15579
+ var isPic = (channel.type && channel.type=="Pic") || (source && source.tagName=="IMG");
15580
+ if (isPic) channel.dynamic = false;
15170
15581
 
15171
- zim.loop(channels, function(channel, i) {
15172
- if (channel) {
15173
- channel.dynamic = dynamics[i];
15174
- if (channel.type && channel.type=="Pic") channel.dynamic = false;
15175
- if (channel.cache) {
15176
- if (!channel.cacheCanvas) channel.cache();
15177
- channel.texture = createTexture(channel.cacheCanvas);
15178
- } else {
15179
- channel.texture = createTexture(channel);
15180
- }
15181
- gl.uniform1i(gl.getUniformLocation(program, 'iChannel' + i), i);
15582
+ if (!isV && !isPic && channel.cache && !channel.cacheCanvas) {
15583
+ channel.cache();
15584
+ source = channel.cacheCanvas;
15182
15585
  }
15183
- });
15184
15586
 
15185
- function replaceChannel(obj, i, dynamic) {
15186
- if (zot(dynamic)) dynamic = true;
15187
- channels[i] = obj;
15188
- var channel = obj;
15189
- channel.dynamic = dynamic;
15190
- if (channel.type && channel.type=="Pic") channel.dynamic = false;
15191
- dynamics[i] = channel.dynamic;
15192
- if (channel.cache) {
15193
- if (!channel.cacheCanvas) channel.cache();
15194
- channel.texture = createTexture(channel.cacheCanvas);
15195
- } else {
15196
- channel.texture = createTexture(channel);
15587
+ if (isV && source && source.requestVideoFrameCallback) {
15588
+ channel._hasNewFrame = true;
15589
+ var rVFC = function() {
15590
+ channel._hasNewFrame = true;
15591
+ if (source && source.requestVideoFrameCallback && !tether.disposed) {
15592
+ source.requestVideoFrameCallback(rVFC);
15593
+ }
15594
+ };
15595
+ source.requestVideoFrameCallback(rVFC);
15197
15596
  }
15597
+
15598
+ channel.texture = createTexture(source, i);
15599
+ gl.activeTexture(gl["TEXTURE" + i]);
15600
+ gl.bindTexture(gl.TEXTURE_2D, channel.texture);
15198
15601
  gl.uniform1i(gl.getUniformLocation(program, 'iChannel' + i), i);
15199
15602
  }
15200
15603
 
15604
+ for (var i = 0; i < 16; i++) {
15605
+ if (channelList[i]) {
15606
+ initChannel(channelList[i], i);
15607
+ } else if (fragment.indexOf("iChannel" + i) !== -1) {
15608
+ var blankTex = createTexture(null, i);
15609
+ gl.activeTexture(gl["TEXTURE" + i]);
15610
+ gl.bindTexture(gl.TEXTURE_2D, blankTex);
15611
+ gl.uniform1i(gl.getUniformLocation(program, 'iChannel' + i), i);
15612
+ }
15613
+ }
15614
+
15615
+ function replaceChannel(obj, i, dyn) {
15616
+ if (zot(i)) i = 0;
15617
+ if (zot(dyn)) dyn = true;
15618
+ channelList[i] = obj;
15619
+ dynamicList[i] = dyn;
15620
+ initChannel(obj, i);
15621
+ }
15622
+
15201
15623
  function setUniform(type, name, v1, v2, v3, v4) {
15202
15624
  if (zot(type)) type = "1f";
15203
15625
  if (zot(name)) {zogf("uniform - must have name"); return;}
15204
15626
  gl["uniform"+type](gl.getUniformLocation(program, name), v1, v2, v3, v4);
15205
15627
  }
15628
+
15206
15629
  var frameNum = 0;
15207
15630
  function update(e) {
15208
-
15209
- // process uniforms
15210
15631
  if (!zot(uniforms)) {
15211
- uniforms.update(); // takes from properties and updates obj
15632
+ uniforms.update();
15212
15633
  zim.loop(uniforms.obj, function(name,val) {
15213
15634
  var n = 1;
15214
15635
  if (Array.isArray(val)) n = val.length;
15215
15636
  else val = [val];
15216
- // if (name=="time") zog(val[0])
15217
15637
  setUniform(n+"f", name, val[0], val[1], val[2], val[3]);
15218
15638
  });
15219
15639
  }
15220
15640
 
15221
- // process channels
15222
- for (var i=0; i<4; i++) {
15223
- var channel = channels[i];
15224
- if (channel) {
15641
+ // Process up to 16 texture units
15642
+ for (var i = 0; i < 16; i++) {
15643
+ var channel = channelList[i];
15644
+ if (channel && channel.texture) {
15225
15645
  gl.activeTexture(gl["TEXTURE"+i]);
15226
15646
  gl.bindTexture(gl.TEXTURE_2D, channel.texture);
15227
15647
  if (channel.dynamic) {
15228
- if (channel.cacheCanvas) channel.updateCache();
15229
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, channel.cacheCanvas?channel.cacheCanvas:channel);
15648
+ var source = getSource(channel);
15649
+ var isV = isVideo(source, channel);
15650
+ var shouldUpload = false;
15651
+
15652
+ if (isV) {
15653
+ if (source && source.readyState >= 2 && !source.paused && !source.ended) {
15654
+ if (source.requestVideoFrameCallback) {
15655
+ shouldUpload = channel._hasNewFrame;
15656
+ channel._hasNewFrame = false;
15657
+ } else {
15658
+ shouldUpload = true;
15659
+ }
15660
+ }
15661
+ } else if (channel.cacheCanvas) {
15662
+ channel.updateCache();
15663
+ source = channel.cacheCanvas;
15664
+ shouldUpload = true;
15665
+ }
15666
+
15667
+ if (shouldUpload && source) {
15668
+ try {
15669
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);
15670
+ } catch(err) {}
15671
+ }
15230
15672
  }
15231
15673
  }
15232
15674
  }
15233
-
15234
15675
 
15235
- // DEFAULT UNIFORMS
15236
15676
  var date = new Date();
15237
15677
  setUniform("3f", "iResolution", width, height);
15238
15678
  var time = zim.decimals(date.getHours()*60*60+date.getMinutes()*60+date.getSeconds()+date.getMilliseconds()/1000, 4);
15239
15679
  setUniform("4f", "iDate", date.getFullYear(), date.getMonth(), time);
15240
15680
  setUniform("1f", "iTime", e?zim.decimals(e.runTime/1000, 4):0);
15241
- setUniform("1f", "iChange", tether.rate);
15242
15681
  setUniform("1f", "iChange", tether.change+=tether.rate/60);
15243
15682
  setUniform("1f", "iTimeDelta", e?zim.decimals(e.delta/1000, 4):0);
15244
15683
  setUniform("1f", "iFrame", e?frameNum++:0);
@@ -15250,8 +15689,8 @@ function makeShader(DS, width, height, fragment, uniforms, vertex, dynamic, preC
15250
15689
  }
15251
15690
  if (strip) gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
15252
15691
  else gl.drawArrays(gl.TRIANGLES, 0, vertexData.length);
15253
-
15254
15692
  }
15693
+
15255
15694
  var downCheck = false;
15256
15695
  var clickCheck = false;
15257
15696
  setTimeout(function() {
@@ -15259,6 +15698,7 @@ function makeShader(DS, width, height, fragment, uniforms, vertex, dynamic, preC
15259
15698
  tether.on("pressup", function() {downCheck = false;}, null, null, null, null, mID);
15260
15699
  tether.tap({call:function() {clickCheck = true;}, cursor:false});
15261
15700
  }, 50);
15701
+
15262
15702
  update();
15263
15703
  var ticker = zim.Ticker.add(update, null, mID, tether);
15264
15704
  if (!dynamic) {
@@ -15266,81 +15706,66 @@ function makeShader(DS, width, height, fragment, uniforms, vertex, dynamic, preC
15266
15706
  setTimeout(update, 50);
15267
15707
  if (tether.stage) tether.stage.update();
15268
15708
  }
15269
- return {dynamic:dynamic, fragment:fragment, vertex:vertex, program:program, uniforms:uniforms, gl:gl, canvas:canvas, update:update, setUniform:setUniform, ticker:ticker, replaceChannel:replaceChannel};
15270
15709
 
15271
- // private
15710
+ return {
15711
+ dynamic: dynamic,
15712
+ fragment: fragment,
15713
+ vertex: vertex,
15714
+ program: program,
15715
+ uniforms: uniforms,
15716
+ gl: gl,
15717
+ canvas: canvas,
15718
+ update: update,
15719
+ setUniform: setUniform,
15720
+ ticker: ticker,
15721
+ replaceChannel: replaceChannel
15722
+ };
15723
+
15272
15724
  function createProgram(webGlContext, vertexShaderText, fragmentShaderText, verify) {
15273
15725
  if (zot(verify)) verify = true;
15274
- if (!webGlContext) {
15275
- console.error("This browser doesn't support WebGL");
15276
- }
15726
+ if (!webGlContext) console.error("This browser doesn't support WebGL");
15277
15727
 
15278
15728
  webGlContext.clearColor(0.0, 0.0, 0.0, 0.0);
15279
- webGlContext.clear(
15280
- webGlContext.COLOR_BUFFER_BIT | webGlContext.DEPTH_BUFFER_BIT
15281
- );
15729
+ webGlContext.clear(webGlContext.COLOR_BUFFER_BIT | webGlContext.DEPTH_BUFFER_BIT);
15282
15730
 
15283
15731
  var vertexShader = webGlContext.createShader(webGlContext.VERTEX_SHADER);
15284
- var fragmentShader = webGlContext.createShader(
15285
- webGlContext.FRAGMENT_SHADER
15286
- );
15732
+ var fragmentShader = webGlContext.createShader(webGlContext.FRAGMENT_SHADER);
15287
15733
 
15288
15734
  webGlContext.shaderSource(vertexShader, vertexShaderText);
15289
15735
  webGlContext.shaderSource(fragmentShader, fragmentShaderText);
15290
15736
 
15291
15737
  webGlContext.compileShader(vertexShader);
15292
- webGlContext.compileShader(fragmentShader);
15293
-
15294
- var compileStatus = {
15295
- vertexStatus:
15296
- webGlContext.getShaderParameter(
15297
- vertexShader,
15298
- webGlContext.COMPILE_STATUS
15299
- ) || webGlContext.getShaderInfoLog(vertexShader),
15300
- fragmentStatus:
15301
- webGlContext.getShaderParameter(
15302
- fragmentShader,
15303
- webGlContext.COMPILE_STATUS
15304
- ) || webGlContext.getShaderInfoLog(fragmentShader),
15305
- };
15738
+ if (!webGlContext.getShaderParameter(vertexShader, webGlContext.COMPILE_STATUS)) {
15739
+ var vLog = webGlContext.getShaderInfoLog(vertexShader);
15740
+ throw new Error("Vertex Shader Compile Error: " + vLog);
15741
+ }
15306
15742
 
15307
- if (
15308
- compileStatus.vertexStatus !== true ||
15309
- compileStatus.fragmentStatus !== true
15310
- ) {
15311
- throw new Error("Failed to compile. " + JSON.stringify(compileStatus, null, 2));
15743
+ webGlContext.compileShader(fragmentShader);
15744
+ if (!webGlContext.getShaderParameter(fragmentShader, webGlContext.COMPILE_STATUS)) {
15745
+ var fLog = webGlContext.getShaderInfoLog(fragmentShader);
15746
+ throw new Error("Fragment Shader Compile Error: " + fLog);
15312
15747
  }
15313
15748
 
15314
15749
  var program = webGlContext.createProgram();
15315
-
15316
15750
  webGlContext.attachShader(program, vertexShader);
15317
15751
  webGlContext.attachShader(program, fragmentShader);
15318
15752
  webGlContext.linkProgram(program);
15319
15753
 
15320
- var linkingStatus =
15321
- webGlContext.getProgramParameter(program, webGlContext.LINK_STATUS) ||
15322
- webGlContext.getProgramInfoLog(program);
15323
-
15324
- if (linkingStatus !== true) {
15325
- throw new Error("Linking filed:\n" + linkingStatus);
15754
+ if (!webGlContext.getProgramParameter(program, webGlContext.LINK_STATUS)) {
15755
+ var pLog = webGlContext.getProgramInfoLog(program);
15756
+ throw new Error("Shader Program Link Error: " + pLog);
15326
15757
  }
15327
15758
 
15328
15759
  if (verify) {
15329
15760
  webGlContext.validateProgram(program);
15330
- var validationStatus =
15331
- webGlContext.getProgramParameter(
15332
- program,
15333
- webGlContext.VALIDATE_STATUS
15334
- ) || webGlContext.getProgramInfoLog(program);
15335
-
15336
- if (validationStatus !== true) {
15337
- throw new Error("Validation failed.\n" + validationStatus);
15761
+ if (!webGlContext.getProgramParameter(program, webGlContext.VALIDATE_STATUS)) {
15762
+ var valLog = webGlContext.getProgramInfoLog(program);
15763
+ throw new Error("Shader Program Validate Error: " + valLog);
15338
15764
  }
15339
15765
  }
15340
-
15341
15766
  return program;
15342
15767
  }
15343
- } // end makeShader
15768
+ }
15344
15769
  //-50.964
15345
15770
 
15346
15771
  /*--
@@ -18084,6 +18509,7 @@ Note the points property has been split into points and pointObjects (and there
18084
18509
  // points is an array of [[setX, setY, ballX, ballY, handleX, handleY, handle2X, handle2Y, type], etc.]
18085
18510
 
18086
18511
  setInfo = points[i];
18512
+ if (!setInfo) setInfo = [0,0,0,0,0,0,0,0,null];
18087
18513
  type = setInfo[8] ? setInfo[8] : controlType;
18088
18514
  set.loc({x:setInfo[0], y:setInfo[1]});
18089
18515
  ball = new zim.Circle(ballS, that.circleColor, that.circleBorderColor, 2, null, null, null, null, null, false)
@@ -25910,7 +26336,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
25910
26336
 
25911
26337
 
25912
26338
  /*--
25913
- zim.Emoji = function(code, size, monochrome, italic, backgroundColor, backgroundBorderColor, backgroundBorderWidth, corner, backing, padding, paddingH, paddingV, shiftH, shiftV, color, borderColor, style, group, inherit)
26339
+ zim.Emoji = function(code, size, monochrome, italic, backgroundColor, backgroundBorderColor, backgroundBorderWidth, corner, backing, padding, paddingH, paddingV, shiftH, shiftV, color, borderColor, order, style, group, inherit)
25914
26340
 
25915
26341
  Emoji
25916
26342
  zim class - extends a zim.Container
@@ -25922,10 +26348,11 @@ If color or borderColor is provided, the SVG will be an SVGContainer so independ
25922
26348
 
25923
26349
  SEE: ZIM EmojiPicker() in COMPONENTS below ColorPicker().
25924
26350
 
25925
- SEE: https://zimjs.com/emoji/ - Emoji Picker Tool
26351
+ SEE: https://zimjs.com/emoji/ - Emoji Picker Tool with added SVG Editor
25926
26352
  SEE: https://zimjs.com/nft/bubbling/emoji.html
25927
26353
  SEE: https://zimjs.com/020/noto.html
25928
26354
 
26355
+
25929
26356
  NOTE: as of ZIM 5.5.0 the zim namespace is no longer required (unless zns is set to true before running zim)
25930
26357
 
25931
26358
  EXAMPLE
@@ -25977,13 +26404,15 @@ code - |ZIM VEE| (default \ud83d\ude42") the Unicode Character or the Emoji from
25977
26404
  This will add a ZIM Label with the character to the Emoji Container
25978
26405
  As of ZIM 020, this supports Noto (by Google) Color Emojis which stay consistent across platforms (Windows, Linux, Android, iOS)
25979
26406
  To turn the emoji into Noto emojis, use "noto_code" where code is the emoji character or a code described above
25980
- This will add a ZIM SVG of the character to the Emoji Container
25981
- If color or borderColor paramters are used, the SVG will be in the form of an SVGContainer holding ZIM Blob and Squiggle objects
26407
+ This will lazy load a ZIM SVG of the character to the Emoji Container
26408
+ If color or borderColor parameters are used, the SVG will be in the form of an SVGContainer holding ZIM Blob and Squiggle objects
25982
26409
  then each part can be colored, dragged, wiggled, or animated
25983
26410
  If using the Emoji in a Tile() or Wrapper() then preload the emoji in the Frame assets or zapp_assets using "noto_code"
25984
26411
  This will preload the SVG from the Google GitHub repository - the location is set in ZIM (similar to using "gf_" for Google fonts)
25985
26412
  NOTE: many of the parameters below will not work on the SVG as they were made for text based emojis (but color and borderColor will)
25986
26413
  see https://symbl.cc/en/platforms/google/ to see all - not easily searched though
26414
+ see https://zimjs.com/020/dpad.html for examples of changing parts of the SVG emoji (hide, position, color)
26415
+ see https://zimjs.com/emoji and choose Noto Edit Tool to edit and save an SVG emoji
25987
26416
  size - |ZIM VEE| (default 36) the size of the font in pixels
25988
26417
  monochrome - (default false) set to true to make black outline - this is actually the bold version of the icon
25989
26418
  italic - (default false) set the font to italic
@@ -26008,6 +26437,8 @@ color - |ZIM VEE| (default null) for when color is set, set to a color or an arr
26008
26437
  usually a series() would be used here for colors in order, or an array for random colors
26009
26438
  setting this will make an SVG with bitmap:false - so blobs and squiggles so parts of SVG can be colored
26010
26439
  borderColor - |ZIM VEE| (default null) for when borderColor is set to a color or an array of colors to apply to border of children - in order of the children
26440
+ order - and array showing a new order of the old index numbers
26441
+ eg [3,1,2,0] means the old index 3 is now at level 0, old index 1 stays the same, old index 2 is now third, and old index 0 is at the top
26011
26442
  style - (default true) set to false to ignore styles set with the STYLE - will receive original parameter defaults
26012
26443
  group - (default null) set to String (or comma delimited String) so STYLE can set default styles to the group(s) (like a CSS class)
26013
26444
  inherit - (default null) used internally but can receive an {} of styles directly
@@ -26027,6 +26458,8 @@ PROPERTIES
26027
26458
  type - the name of the class as a String
26028
26459
  veeObj - an object with ZIM VEE original parameters:value allowing the ZIM VEE values to be referenced
26029
26460
  for instance, obj.prop = Pick.choose(obj.veeObj.prop); will reset the the prop to the result of the original ZIM VEE value
26461
+ label - reference to the ZIM Label if emoji is a string
26462
+ svg - reference to the SVG if the emoji is SVG or SVGContainer (color set) - if emoji is an SVGContainer then it has children
26030
26463
 
26031
26464
  ALSO: see ZIM Container for properties such as:
26032
26465
  width, height, widthOnly, heightOnly, draggable, level, depth, group
@@ -26041,8 +26474,8 @@ See the CreateJS Easel Docs for Container events such as:
26041
26474
  added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmove, pressup, removed, rollout, rollover
26042
26475
  --*///+54.58
26043
26476
 
26044
- zim.Emoji = function(code, size, monochrome, italic, backgroundColor, backgroundBorderColor, backgroundBorderWidth, corner, backing, padding, paddingH, paddingV, shiftH, shiftV, color, borderColor, style, group, inherit) {
26045
- var sig = "code, size, monochrome, italic, backgroundColor, backgroundBorderColor, backgroundBorderWidth, corner, backing, padding, paddingH, paddingV, shiftH, shiftV, color, borderColor, style, group, inherit";
26477
+ zim.Emoji = function(code, size, monochrome, italic, backgroundColor, backgroundBorderColor, backgroundBorderWidth, corner, backing, padding, paddingH, paddingV, shiftH, shiftV, color, borderColor, order, style, group, inherit) {
26478
+ var sig = "code, size, monochrome, italic, backgroundColor, backgroundBorderColor, backgroundBorderWidth, corner, backing, padding, paddingH, paddingV, shiftH, shiftV, color, borderColor, order, style, group, inherit";
26046
26479
  var duo; if (duo = zob(zim.Emoji, arguments, sig, this)) return duo;
26047
26480
  z_d("54.58");
26048
26481
 
@@ -26063,6 +26496,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
26063
26496
  if (zot(shiftV)) shiftV = DS.shiftV!=null?DS.shiftV:0;
26064
26497
  if (zot(color)) color = DS.color!=null?DS.color:null;
26065
26498
  if (zot(borderColor)) borderColor = DS.borderColor!=null?DS.borderColor:null;
26499
+ if (zot(order)) order = DS.order!=null?DS.order:null;
26066
26500
 
26067
26501
  // PICK
26068
26502
  var oa = remember(code, size);
@@ -26081,7 +26515,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
26081
26515
  var match;
26082
26516
  if (code.match) match = code.match(/^noto_(.*)/);
26083
26517
  if (match) {
26084
- var svg = that.svg = new zim.SVG({svg:code, interactive:!(color||borderColor), bitmap:!(color||borderColor), color:color, borderColor:borderColor});
26518
+ var svg = that.svg = new zim.SVG({svg:code, interactive:!(color||borderColor), bitmap:!(color||borderColor), color:color, borderColor:borderColor, order:order});
26085
26519
  svg.addTo(this);
26086
26520
  } else {
26087
26521
  var label = this.label = new zim.Label(code, size, null, null, null, null, null, null, null, null, italic, null, null, null, backing, null, null, backgroundColor, null, null, corner, null, padding, paddingH, paddingV, shiftH, shiftV);
@@ -26134,7 +26568,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
26134
26568
 
26135
26569
  if (style!==false) zim.styleTransforms(this, DS);
26136
26570
  this.clone = function (exact) {
26137
- return that.cloneProps(new zim.Emoji((exact||!zim.isPick(oa[0]))?code:oa[0], (exact||!zim.isPick(oa[1]))?that.size:oa[1], monochrome, italic, backgroundColor, backgroundBorderColor, backgroundBorderWidth, corner, backing, padding, paddingH, paddingV, shiftH, shiftV, color, borderColor, style, that.group, inherit));
26571
+ return that.cloneProps(new zim.Emoji((exact||!zim.isPick(oa[0]))?code:oa[0], (exact||!zim.isPick(oa[1]))?that.size:oa[1], monochrome, italic, backgroundColor, backgroundBorderColor, backgroundBorderWidth, corner, backing, padding, paddingH, paddingV, shiftH, shiftV, color, borderColor, order, style, that.group, inherit));
26138
26572
  };
26139
26573
 
26140
26574
  };
@@ -26952,9 +27386,8 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
26952
27386
  that.pressed = onCheck = pressCheck = false;
26953
27387
 
26954
27388
  if (reallyOn) buttonOn(); // will recall the roll ZIM01
26955
- else if (that.rollPersist) removeRoll();
26956
-
26957
- if (e.nativeEvent && (e.nativeEvent.type == "touchend" || e.nativeEvent == "touchcancel")) { // touch screen
27389
+ else if (that.rollPersist) removeRoll();
27390
+ if (WW.M || (e.nativeEvent && (e.nativeEvent.type == "touchend" || e.nativeEvent.type == "touchcancel"))) { // Mobile or touch screen
26958
27391
  buttonOff();
26959
27392
  }
26960
27393
  }, null, null, null, null, mID);
@@ -51251,7 +51684,7 @@ RETURNS obj for chaining
51251
51684
  zim.addTo = function(obj, container, index, still) {
51252
51685
  var sig = "obj, container, index, still";
51253
51686
  var duo; if (duo = zob(zim.addTo, arguments, sig)) return duo;
51254
- // if (obj.type=="AC"&&zdf) {zdf.ac("addTo", arguments); return obj;}
51687
+ // if ((obj.type=="AC"||(obj.type=="Emoji"&&obj.svg&&obj.svg.type=="AC"))&&zdf) {zdf.ac("addTo", arguments); return obj;}
51255
51688
  z_d("47.5");
51256
51689
  if (zot(obj)) {zogy("zim methods - addTo(): please provide object"); return;}
51257
51690
  if (zot(container)) {
@@ -51425,7 +51858,7 @@ RETURNS obj for chaining
51425
51858
  zim.centerReg = function(obj, container, index, add) {
51426
51859
  var sig = "obj, container, index, add";
51427
51860
  var duo; if (duo = zob(zim.centerReg, arguments, sig)) return duo;
51428
- if (obj.type=="AC"&&WW.zdf) {WW.zdf.ac("centerReg", arguments); return obj.addTo(container, index);}
51861
+ if ((obj.type=="AC"||(obj.type=="Emoji"&&obj.svg&&obj.svg.type=="AC"))&&WW.zdf) {WW.zdf.ac("centerReg", arguments); return obj.addTo(container, index);}
51429
51862
  z_d("48");
51430
51863
  if (zot(obj) || !obj.getBounds || !obj.getBounds()) {zogy("zim methods - centerReg(): please provide object with bounds set"); return obj;}
51431
51864
  if (zot(add)) add = true;
@@ -51481,7 +51914,7 @@ RETURNS obj for chaining
51481
51914
  zim.center = function(obj, container, index, add) {
51482
51915
  var sig = "obj, container, index, add";
51483
51916
  var duo; if (duo = zob(zim.center, arguments, sig)) return duo;
51484
- if (obj.type=="AC"&&WW.zdf) {WW.zdf.ac("center", arguments); return obj.addTo(container, index);}
51917
+ if ((obj.type=="AC"||(obj.type=="Emoji"&&obj.svg&&obj.svg.type=="AC"))&&WW.zdf) {WW.zdf.ac("center", arguments); return obj.addTo(container, index);}
51485
51918
  if (!zim.centerCheck) {z_d("48.1"); zim.centerCheck=true;}
51486
51919
  if (zot(obj) || !obj.getBounds) {zogy("zim.center(): please provide object with bounds"); return obj;}
51487
51920
  if (zot(container)) {
@@ -51751,7 +52184,7 @@ RETURNS obj for chaining
51751
52184
  zim.pos = function(obj, x, y, horizontal, vertical, container, index, add, reg, regX, regY) {
51752
52185
  var sig = "obj, x, y, horizontal, vertical, container, index, add, reg, regX, regY";
51753
52186
  var duo; if (duo = zob(zim.pos, arguments, sig)) return duo;
51754
- if (obj.type=="AC"&&WW.zdf) {WW.zdf.ac("pos", arguments); return obj.addTo(container, index);}
52187
+ if ((obj.type=="AC"||(obj.type=="Emoji"&&obj.svg&&obj.svg.type=="AC"))&&WW.zdf) {WW.zdf.ac("pos", arguments); return obj.addTo(container, index);}
51755
52188
  z_d("41.5");
51756
52189
 
51757
52190
  // handle DIR effect
@@ -51998,7 +52431,7 @@ RETURNS obj for chaining
51998
52431
  zim.loc = function(obj, target, y, container, index, add, localToLocal, x) {
51999
52432
  var sig = "obj, target, y, container, index, add, localToLocal, x";
52000
52433
  var duo; if (duo = zob(zim.loc, arguments, sig)) return duo;
52001
- if (obj.type=="AC"&&WW.zdf) {WW.zdf.ac("loc", arguments); return obj.addTo(container, index);}
52434
+ if ((obj.type=="AC"||(obj.type=="Emoji"&&obj.svg&&obj.svg.type=="AC"))&&WW.zdf) {WW.zdf.ac("loc", arguments); return obj.addTo(container, index);}
52002
52435
  z_d("41.55");
52003
52436
  if (zot(obj)) return;
52004
52437
  if (typeof target == "number") {
@@ -52070,7 +52503,7 @@ RETURNS obj for chaining
52070
52503
  zim.mov = function(obj, x, y) {
52071
52504
  var sig = "obj, x, y";
52072
52505
  var duo; if (duo = zob(zim.mov, arguments, sig)) return duo;
52073
- if (obj.type=="AC"&&WW.zdf) {WW.zdf.ac("mov", arguments); return obj;}
52506
+ if ((obj.type=="AC"||(obj.type=="Emoji"&&obj.svg&&obj.svg.type=="AC"))&&WW.zdf) {WW.zdf.ac("mov", arguments); return obj;}
52074
52507
  z_d("41.6");
52075
52508
  if (zot(obj)) return;
52076
52509
  if (!zot(x)) obj.x += x;
@@ -52102,7 +52535,7 @@ scaleY - (default null) pass this in to scale x and y independently
52102
52535
  RETURNS obj for chaining
52103
52536
  --*///+41.97
52104
52537
  zim.sca = function(obj, scale, scaleY) {
52105
- if (obj.type=="AC"&&WW.zdf) {WW.zdf.ac("sca", arguments); return obj;}
52538
+ if ((obj.type=="AC"||(obj.type=="Emoji"&&obj.svg&&obj.svg.type=="AC"))&&WW.zdf) {WW.zdf.ac("sca", arguments); return obj;}
52106
52539
  z_d("41.97");
52107
52540
  if (zot(obj) || zot(obj.scaleX)) return obj;
52108
52541
  if (zot(scale)) scale = obj.scaleX;
@@ -52337,7 +52770,7 @@ RETURNS obj for chaining
52337
52770
  zim.rot = function(obj, rotation, x, y) {
52338
52771
  z_d("41.8");
52339
52772
  if (zot(obj)) return;
52340
- if (obj.type=="AC"&&WW.zdf) {WW.zdf.ac("rot", arguments); return obj;}
52773
+ if ((obj.type=="AC"||(obj.type=="Emoji"&&obj.svg&&obj.svg.type=="AC"))&&WW.zdf) {WW.zdf.ac("rot", arguments); return obj;}
52341
52774
  if (!zot(rotation)) {
52342
52775
  if (obj.parent && (!zot(x) || !zot(y))) {
52343
52776
  if (zot(x)) x = obj.x;
@@ -52395,7 +52828,7 @@ RETURNS obj for chaining
52395
52828
  zim.siz = function(obj, width, height, only) {
52396
52829
  z_d("41.85");
52397
52830
  if (zot(obj)) return;
52398
- if (obj.type=="AC"&&WW.zdf) {WW.zdf.ac("siz", arguments); return obj;}
52831
+ if ((obj.type=="AC"||(obj.type=="Emoji"&&obj.svg&&obj.svg.type=="AC"))&&WW.zdf) {WW.zdf.ac("siz", arguments); return obj;}
52399
52832
  if (zot(only)) only = false;
52400
52833
  if (!zot(width) && !zot(height)) {
52401
52834
  obj.widthOnly = width; obj.heightOnly = height;
@@ -52430,7 +52863,7 @@ RETURNS obj for chaining
52430
52863
  zim.ske = function(obj, skewX, skewY) {
52431
52864
  z_d("41.9");
52432
52865
  if (zot(obj)) return;
52433
- if (obj.type=="AC"&&WW.zdf) {WW.zdf.ac("ske", arguments); return obj;}
52866
+ if ((obj.type=="AC"||(obj.type=="Emoji"&&obj.svg&&obj.svg.type=="AC"))&&WW.zdf) {WW.zdf.ac("ske", arguments); return obj;}
52434
52867
  if (!zot(skewX)) obj.skewX = skewX;
52435
52868
  if (!zot(skewY)) obj.skewY = skewY;
52436
52869
  return obj;
@@ -52478,7 +52911,7 @@ RETURNS obj for chaining
52478
52911
  zim.reg = function(obj, regX, regY, still) {
52479
52912
  z_d("41.95");
52480
52913
  if (zot(obj)) return;
52481
- if (obj.type=="AC"&&WW.zdf) {WW.zdf.ac("reg", arguments); return obj;}
52914
+ if ((obj.type=="AC"||(obj.type=="Emoji"&&obj.svg&&obj.svg.type=="AC"))&&WW.zdf) {WW.zdf.ac("reg", arguments); return obj;}
52482
52915
  var lastRegX = obj.regX;
52483
52916
  var lastRegY = obj.regY;
52484
52917
  var originalX = regX;
@@ -53515,7 +53948,7 @@ RETURNS obj for chaining
53515
53948
  zim.drag = function(obj, boundary, axis, overCursor, dragCursor, all, swipe, localBoundary, onTop, surround, slide, slideFactor, slideSnap, slideSnapDamp, reg, removeTweens, startBounds, rect, currentTarget, offStage, immediateBoundary, singleTouch, dropTargets, dropCopy, dropSnap, dropBack, dropEnd, dropFull, dropHitTest, dropScale, dropWidth, dropHeight, dropOriginal, style, group) {
53516
53949
  var sig = "obj, boundary, axis, overCursor, dragCursor, all, swipe, localBoundary, onTop, surround, slide, slideFactor, slideSnap, slideSnapDamp, reg, removeTweens, startBounds, rect, currentTarget, offStage, immediateBoundary, singleTouch, dropTargets, dropCopy, dropSnap, dropBack, dropEnd, dropFull, dropHitTest, dropScale, dropWidth, dropHeight, dropOriginal, style, group";
53517
53950
  var duo; if (duo = zob(zim.drag, arguments, sig)) return duo;
53518
- if (obj.type=="AC"&&WW.zdf) {WW.zdf.ac("drag", arguments); return obj;}
53951
+ if ((obj.type=="AC"||(obj.type=="Emoji"&&obj.svg&&obj.svg.type=="AC"))&&WW.zdf) {WW.zdf.ac("drag", arguments); return obj;}
53519
53952
  z_d("31");
53520
53953
 
53521
53954
  var DS = style===false?group!=null?zim.getStyle(null,null,inherit,this.group):{}:zim.getStyle("Drag", group);
@@ -55198,7 +55631,7 @@ RETURNS obj for chaining
55198
55631
  zim.transform = function(obj, move, stretchX, stretchY, scale, rotate, allowToggle, visible, onTop, showStretch, showRotate, showScale, showReg, showBorder, borderColor, borderWidth, dashed, customCursors, handleSize, regSize, snapDistance, snapRotation, cache, events, ghostColor, ghostWidth, ghostDashed, ghostHidden, frame, container, minScaleX, maxScaleX, minScaleY, maxScaleY, sliceX, sliceY) {
55199
55632
  var sig = "obj, move, stretchX, stretchY, scale, rotate, allowToggle, visible, onTop, showStretch, showRotate, showScale, showReg, showBorder, borderColor, borderWidth, dashed, customCursors, handleSize, regSize, snapDistance, snapRotation, cache, events, ghostColor, ghostWidth, ghostDashed, ghostHidden, frame, container, minScaleX, maxScaleX, minScaleY, maxScaleY, sliceX, sliceY";
55200
55633
  var duo; if (duo = zob(zim.transform, arguments, sig)) return duo;
55201
- if (obj.type=="AC"&&WW.zdf) {WW.zdf.ac("transform", arguments); return obj;}
55634
+ if ((obj.type=="AC"||(obj.type=="Emoji"&&obj.svg&&obj.svg.type=="AC"))&&WW.zdf) {WW.zdf.ac("transform", arguments); return obj;}
55202
55635
  z_d("33.5");
55203
55636
 
55204
55637
  // MONITOR
@@ -56443,7 +56876,7 @@ RETURNS obj for chaining
56443
56876
  zim.gesture = function(obj, move, scale, rotate, boundary, minScale, maxScale, snapRotate, localBoundary, slide, slideFactor, regControl, onTop, surround, circularBounds, rect, trackpad) {
56444
56877
  var sig = "obj, move, scale, rotate, boundary, minScale, maxScale, snapRotate, localBoundary, slide, slideFactor, regControl, onTop, surround, circularBounds, rect, trackpad";
56445
56878
  var duo; if (duo = zob(zim.gesture, arguments, sig)) return duo;
56446
- if (obj.type=="AC"&&WW.zdf) {WW.zdf.ac("gesture", arguments); return obj;}
56879
+ if ((obj.type=="AC"||(obj.type=="Emoji"&&obj.svg&&obj.svg.type=="AC"))&&WW.zdf) {WW.zdf.ac("gesture", arguments); return obj;}
56447
56880
  z_d("34.5");
56448
56881
 
56449
56882
  // MONITOR
@@ -56987,8 +57420,15 @@ zim.gesture = function(obj, move, scale, rotate, boundary, minScale, maxScale, s
56987
57420
  // Applied incrementally so it tracks the finger naturally.
56988
57421
  e.preventDefault();
56989
57422
 
57423
+ // var newX = obj.x - dx / (zim.scaX || 1);
57424
+ // var newY = obj.y - dy / (zim.scaY || 1);
57425
+
57426
+ // Chromebook adjust
57427
+ var isChromeOS = /CrOS/i.test(navigator.userAgent);
56990
57428
  var newX = obj.x - dx / (zim.scaX || 1);
56991
- var newY = obj.y - dy / (zim.scaY || 1);
57429
+ var newY = isChromeOS
57430
+ ? obj.y + dy / (zim.scaY || 1)
57431
+ : obj.y - dy / (zim.scaY || 1);
56992
57432
 
56993
57433
  var panResult = obj.zimTouch.checkBounds(newX, newY);
56994
57434
  obj.x = panResult.x;
@@ -62757,7 +63197,7 @@ RETURNS obj for chaining
62757
63197
  zim.scaleTo = function(obj, boundObj, percentX, percentY, type, boundsOnly, simple) {
62758
63198
  var sig = "obj, boundObj, percentX, percentY, type, boundsOnly, simple";
62759
63199
  var duo; if (duo = zob(zim.scaleTo, arguments, sig)) return duo;
62760
- if (obj.type=="AC"&&WW.zdf) {WW.zdf.ac("scaleTo", arguments); return obj;}
63200
+ if ((obj.type=="AC"||(obj.type=="Emoji"&&obj.svg&&obj.svg.type=="AC"))&&WW.zdf) {WW.zdf.ac("scaleTo", arguments); return obj;}
62761
63201
  z_d("43");
62762
63202
  if (zot(boundObj)) boundObj = WW.zdf&&WW.zdf.stage?WW.zdf.stage:null;
62763
63203
  if (zot(obj) || !obj.getBounds || !obj.getBounds()) {zog ("zim methods - scaleTo(): please provide an object (with setBounds) to scale"); return obj;}
@@ -62849,7 +63289,7 @@ RETURNS an Object literal with the new and old details (bX is rectangle x, etc.)
62849
63289
  zim.fit = function(obj, left, top, width, height, type) {
62850
63290
  var sig = "obj, left, top, width, height, type";
62851
63291
  var duo; if (duo = zob(zim.fit, arguments, sig)) return duo;
62852
- if (obj.type=="AC"&&WW.zdf) {WW.zdf.ac("fit", arguments); return obj;}
63292
+ if ((obj.type=="AC"||(obj.type=="Emoji"&&obj.svg&&obj.svg.type=="AC"))&&WW.zdf) {WW.zdf.ac("fit", arguments); return obj;}
62853
63293
  z_d("46");
62854
63294
  if (zot(obj) || !obj.getBounds) return;
62855
63295
  if (!obj.getBounds()) {
@@ -63192,7 +63632,7 @@ RETURNS obj for chaining
63192
63632
  zim.expand = function(obj, padding, paddingV, paddingRight, paddingBottom) {
63193
63633
  var sig = "obj, padding, paddingV, paddingRight, paddingBottom";
63194
63634
  var duo; if (duo = zob(zim.expand, arguments, sig)) return duo;
63195
- if (obj.type=="AC"&&WW.zdf) {WW.zdf.ac("expand", arguments); return obj;}
63635
+ if ((obj.type=="AC"||(obj.type=="Emoji"&&obj.svg&&obj.svg.type=="AC"))&&WW.zdf) {WW.zdf.ac("expand", arguments); return obj;}
63196
63636
  z_d("50");
63197
63637
  if (zot(obj) || !obj.getBounds || !obj.getBounds()) {zogy("zim methods - expand(): please provide object with bounds set"); return obj;}
63198
63638
  if (zot(padding)) padding = 20;
@@ -63458,7 +63898,7 @@ RETURNS the obj for chaining;
63458
63898
  zim.outline = function(obj, color, size, boundsOnly, reg, origin, whiteSize) {
63459
63899
  var sig = "obj, color, size, boundsOnly, reg, origin, whiteSize";
63460
63900
  var duo; if (duo = zob(zim.outline, arguments, sig)) return duo;
63461
- if (obj.type=="AC"&&WW.zdf) {WW.zdf.ac("outline", arguments); return obj;}
63901
+ if ((obj.type=="AC"||(obj.type=="Emoji"&&obj.svg&&obj.svg.type=="AC"))&&WW.zdf) {WW.zdf.ac("outline", arguments); return obj;}
63462
63902
  z_d("47");
63463
63903
  if (obj.type && obj.type == "zimOultineShape") {
63464
63904
  if (zon) zogy ("zim.outline() - warning, you are trying to outline an outline - do not outline in a loop");
@@ -70544,7 +70984,7 @@ alpha, cursor, shadow, name, mouseChildren, mouseEnabled, parent, numChildren, e
70544
70984
 
70545
70985
 
70546
70986
  /*--
70547
- zim.Bullets(list, bulletType, size, color, cols, font, italic, bold, variant, shiftH, shiftV, spacing, spacingH, spacingV, colSpacing, bulletAlign, style, group, inherit)
70987
+ zim.Bullets(list, bulletType, size, color, cols, font, italic, bold, variant, shiftH, shiftV, spacing, spacingH, spacingV, colSpacing, bulletAlign, rtl, style, group, inherit)
70548
70988
 
70549
70989
  Bullets
70550
70990
  zim class - extends a zim.Tile which extends a zim.Container
@@ -70609,6 +71049,7 @@ spacingH - (default spacing) horizontal spacing between bullet and text
70609
71049
  spacingV - (default spacing) vertical spacing
70610
71050
  colSpacing - (default spacingH) spacing between columns
70611
71051
  bulletAlign - (default LEFT) alignment of bullets
71052
+ rtl - (default false (unless zim.DIR=true)) set to true to put bullets on the right
70612
71053
  style - (default true) set to false to ignore styles set with the STYLE
70613
71054
  group - (default null) set to String (or comma delimited String) so STYLE can set default styles to the group(s)
70614
71055
  inherit - (default null) used internally but can receive an {} of styles directly
@@ -70643,8 +71084,8 @@ alpha, cursor, shadow, name, mouseChildren, mouseEnabled, parent, numChildren, e
70643
71084
 
70644
71085
  --*///+67.8
70645
71086
 
70646
- zim.Bullets = function(list, bulletType, size, color, cols, font, italic, bold, variant, shiftH, shiftV, spacing, spacingH, spacingV, colSpacing, bulletAlign, style, group, inherit) {
70647
- var sig = "list, bulletType, size, color, cols, font, italic, bold, variant, shiftH, shiftV, spacing, spacingH, spacingV, colSpacing, bulletAlign, style, group, inherit";
71087
+ zim.Bullets = function(list, bulletType, size, color, cols, font, italic, bold, variant, shiftH, shiftV, spacing, spacingH, spacingV, colSpacing, bulletAlign, rtl, style, group, inherit) {
71088
+ var sig = "list, bulletType, size, color, cols, font, italic, bold, variant, shiftH, shiftV, spacing, spacingH, spacingV, colSpacing, bulletAlign, rtl, style, group, inherit";
70648
71089
  var duo; if (duo = zob(zim.Bullets, arguments, sig, this)) return duo;
70649
71090
  z_d("67.8");
70650
71091
 
@@ -70670,26 +71111,44 @@ alpha, cursor, shadow, name, mouseChildren, mouseEnabled, parent, numChildren, e
70670
71111
  if (zot(spacingH)) spacingH = DS.spacingH!=null?DS.spacingH:spacing;
70671
71112
  if (zot(spacingV)) spacingV = DS.spacingV!=null?DS.spacingV:spacing;
70672
71113
  if (zot(colSpacing)) colSpacing = DS.colSpacing!=null?DS.colSpacing:spacingH;
70673
- if (zot(bulletAlign)) bulletAlign = DS.bulletAlign!=null?DS.bulletAlign:LEFT;
71114
+ if (zot(rtl)) rtl = DS.rtl!=null?DS.rtl:WW.DIR=="rtl"||zim.DIR=="rtl";
71115
+ if (zot(bulletAlign)) bulletAlign = DS.bulletAlign!=null?DS.bulletAlign:rtl?RIGHT:LEFT;
70674
71116
  var tileList = [];
70675
71117
  var num = 1;
70676
71118
  this.list = list;
70677
71119
  var icons = [];
70678
- zim.loop(list, function(words, i) {
70679
- if (words.type=="Bullets") { // nested Bullets
70680
- tileList.push(new zim.Container(1,1));
70681
- tileList.push(words);
70682
- return;
70683
- }
71120
+ zim.loop(list, function(words, i) {
70684
71121
  const bt = zik(bulletType);
70685
71122
  icons.push(bt);
71123
+ if (rtl) {
71124
+ if (words.type=="Bullets") { // nested Bullets
71125
+ tileList.push(words);
71126
+ tileList.push(new zim.Container(1,1));
71127
+ } else {
71128
+ makeLabel(words);
71129
+ makeIcon(bt);
71130
+ }
71131
+ } else {
71132
+ if (words.type=="Bullets") { // nested Bullets
71133
+ tileList.push(new zim.Container(1,1));
71134
+ tileList.push(words);
71135
+ return;
71136
+ }
71137
+ makeIcon(bt);
71138
+ makeLabel(words);
71139
+ }
71140
+ });
71141
+
71142
+ function makeIcon(bt) {
70686
71143
  if (bt.type && bt.clone) tileList.push(bt.clone());
70687
71144
  else if (bt == "circle") tileList.push(new zim.Circle(5, color));
70688
71145
  else if (bt == "square") tileList.push(new zim.Rectangle(10, 10, color));
70689
71146
  else if (bt == "dash") tileList.push(new zim.Label({text:"-", size:size, font:font, color:color, italic:italic, bold:bold, variant:variant, shiftH:shiftH, shiftV:shiftV-2}));
70690
71147
  else if (bt == "number" || bt == "numbers") tileList.push(new zim.Label({text:(num++)+".", size:size, font:font, color:color, italic:italic, bold:bold, variant:variant, shiftH:shiftH, shiftV:shiftV}));
71148
+ }
71149
+ function makeLabel(words) {
70691
71150
  tileList.push(new zim.Label({text:words, size:size, font:font, color:color, italic:italic, bold:bold, variant:variant, shiftH:shiftH, shiftV:shiftV}));
70692
- })
71151
+ }
70693
71152
  if (cols > 1 ) {
70694
71153
  // need to shift pairs
70695
71154
  // [b1, w1, b2, w2, b3, w3, b4, w4, b5, w5]
@@ -70707,6 +71166,7 @@ alpha, cursor, shadow, name, mouseChildren, mouseEnabled, parent, numChildren, e
70707
71166
  })
70708
71167
  }, null, null, 2); // steps of 2
70709
71168
  }
71169
+
70710
71170
  this.zimTile_constructor(tileList, cols*2, Math.ceil(list.length/cols), series(spacingH,colSpacing), spacingV, true, null, null, null, null, null, null, series(bulletAlign, LEFT), CENTER);
70711
71171
  this.type = "Bullets";
70712
71172
 
@@ -70718,7 +71178,7 @@ alpha, cursor, shadow, name, mouseChildren, mouseEnabled, parent, numChildren, e
70718
71178
  exactItems.push(icon.clone?icon.clone(true):icon);
70719
71179
  }
70720
71180
  }
70721
- return that.cloneProps(new zim.Bullets(list, exact?zim.series(exactItems):bulletType, size, color, cols, font, italic, bold, variant, shiftH, shiftV, spacing, spacingH, spacingV, colSpacing, bulletAlign, this.style, this.group));
71181
+ return that.cloneProps(new zim.Bullets(list, exact?zim.series(exactItems):bulletType, size, color, cols, font, italic, bold, variant, shiftH, shiftV, spacing, spacingH, spacingV, colSpacing, bulletAlign, rtl, this.style, this.group));
70722
71182
  };
70723
71183
  };
70724
71184
  zim.extend(zim.Bullets, zim.Tile, ["clone"], "zimTile", false);
@@ -80758,7 +81218,7 @@ alpha, cursor, shadow, name, mouseChildren, mouseEnabled, parent, numChildren, e
80758
81218
  //-69.9747
80759
81219
 
80760
81220
  /*--
80761
- zim.Perspective = function(obj, points, interactive, showControls, allowToggle, move, borderColor, borderWidth, dashed, plane, fade, dynamic, frame, style, group, inherit)
81221
+ zim.Perspective = function(obj, points, interactive, showControls, allowToggle, move, borderColor, borderWidth, dashed, plane, fade, dynamic, frame, resolution, maskShape, feather, onTop, overlay, clipping, passthrough, passthroughScale, passthroughShiftX, passthroughShiftY, style, group, inherit)
80762
81222
 
80763
81223
  Perspective
80764
81224
  zim class extends ZIM Container which extends CreateJS Container
@@ -80896,6 +81356,22 @@ plane - (default false) set to true to repeat the object making a plane to infin
80896
81356
  fade - (default true) if a plane is set, this will fade the distance
80897
81357
  dynamic - (default true unless obj is Pic, then false) set to false if a Container, etc. does not change or animate
80898
81358
  frame - (default zimDefaultFrame) set the zim Frame the perspective is in if in a different frame than the default frame
81359
+ resolution - (default 1) the resolution multiplier for the internal WebGL shader canvas (e.g. 0.5 for half-resolution to boost GPU performance on laptops and mobile).
81360
+ maskShape - (default "rect") the cutout mask shape: "rect" (standard 4-corner quad), "circle" (1:1 true circle with aspect-ratio correction), or "ellipse" (stretches to the quad bounds)
81361
+ or a ZIM DisplayObject (such as a Blob, Circle, or Container) to use as a dynamic GPU alpha mask texture (passed into iChannel1 with multi-tap blur spread).
81362
+ feather - (default 0) edge softness from 0 to 1 applied to the quad edges, circle/ellipse borders, or texture mask in the GPU shader.
81363
+ onTop - (default true) set to false to not bring the object to the top of its container when pressed
81364
+ overlay - (default false) set to true to use a DOM ShaderOverlay (Tag) rather than an in-canvas Shader (Bitmap)
81365
+ this bypasses 2D canvas blitting for maximum GPU performance and automatically
81366
+ hides controls for presentation mode.
81367
+ By default, this overlays above the stage canvas z-index = 100
81368
+ can be adjusted with perspective.shader.tag.style.zIndex
81369
+ if placed under the canvas, ensure the Frame color is set to clear (also see overlay property)
81370
+ clipping - (default true) when overlay is true, clamps the shader canvas to the stage bounds to optimize GPU fill rate by trimming off-stage pixels - set to false if animating or moving across stage boundaries to avoid edge clipping
81371
+ passthrough - (default false) set to true to display the asset unwarped (at original 1:1 aspect ratio), centered at the 4-point centroid and cropped by the perspective boundary.
81372
+ passthroughScale - (default 1) scale multiplier for the asset when passthrough is true, scaling from the center of the asset.
81373
+ passthroughShiftX - (default 0) horizontal pixel offset for the asset beneath the crop window when passthrough is true.
81374
+ passthroughShiftY - (default 0) vertical pixel offset for the asset beneath the crop window when passthrough is true.
80899
81375
  style - (default true) set to false to ignore styles set with the STYLE - will receive original parameter defaults
80900
81376
  group - (default null) set to String (or comma delimited String) so STYLE can set default styles to the group(s) (like a CSS class)
80901
81377
  inherit - (default null) used internally but can receive an {} of styles directly
@@ -80938,6 +81414,17 @@ uniforms - refernce to the ZIM Uniforms for the Shader
80938
81414
  use perspective.uniforms.plane to get or set the plane setting of the perspective
80939
81415
  use perspective.uniforms.fade to get or set the fade setting of plane
80940
81416
  toggled - get control state - true if showing and false if not - see toggle() method to set toggled
81417
+ maskShape - get or set the cutout shape "rect", "circle", "ellipse", or the DisplayObject provided
81418
+ feather - get or set the edge softness / feathering amount (0 to 1).
81419
+ resolution - the resolution multiplier of the shader canvas.
81420
+ mask - reference to the mask DisplayObject container if a mask was provided.
81421
+ onTop - get or set whether the perspective comes to the top of its container when pressed
81422
+ overlay - get or set whether to render as a DOM ShaderOverlay - see overlay parameter
81423
+ clipping - get or set whether the overlay canvas bounding box is clamped to the stage boundaries
81424
+ passthrough - get or set whether the asset is displayed unwarped and cropped by the quad boundary.
81425
+ passthroughScale - get or set the scale of the asset when passthrough is true.
81426
+ passthroughShiftX - get or set the horizontal pixel offset of the asset beneath the crop window when passthrough is true.
81427
+ passthroughShiftY - get or set the vertical pixel offset of the asset beneath the crop window when passthrough is true.
80941
81428
 
80942
81429
  ALSO: see ZIM Container for properties such as:
80943
81430
  width, height, widthOnly, heightOnly, draggable, level, depth, group
@@ -80948,463 +81435,872 @@ x, y, rotation, scaleX, scaleY, regX, regY, skewX, skewY,
80948
81435
  alpha, cursor, shadow, name, mouseChildren, mouseEnabled, parent, numChildren, etc.
80949
81436
 
80950
81437
  --*///+69.9748
80951
- zim.Perspective = function(obj, points, interactive, showControls, allowToggle, move, borderColor, borderWidth, dashed, plane, fade, dynamic, frame, style, group, inherit) {
80952
- var sig = "obj, points, interactive, showControls, allowToggle, move, borderColor, borderWidth, dashed, plane, fade, dynamic, frame, style, group, inherit";
80953
- var duo; if (duo = zob(zim.Perspective, arguments, sig, this)) return duo;
80954
- z_d("69.9748");
80955
- this.group = group;
80956
- var DS = style === false ? {} : zim.getStyle("Perspective", group, inherit);
81438
+ zim.Perspective = function(obj, points, interactive, showControls, allowToggle, move, borderColor, borderWidth, dashed, plane, fade, dynamic, frame, resolution, maskShape, feather, onTop, overlay, clipping, passthrough, passthroughScale, passthroughShiftX, passthroughShiftY, style, group, inherit) {
81439
+ var sig = "obj, points, interactive, showControls, allowToggle, move, borderColor, borderWidth, dashed, plane, fade, dynamic, frame, resolution, maskShape, feather, onTop, overlay, clipping, passthrough, passthroughScale, passthroughShiftX, passthroughShiftY, style, group, inherit";
81440
+ var duo; if (duo = zob(zim.Perspective, arguments, sig, this)) return duo;
81441
+ z_d("69.9770");
81442
+ this.group = group;
81443
+ var DS = style === false ? {} : zim.getStyle("Perspective", group, inherit);
81444
+
81445
+ if (zot(obj)) obj = DS.obj != null ? DS.obj : new zim.Tile(new zim.Rectangle(50, 50, [purple, pink, white]), 5, 5, 10, 10);
81446
+ if (zot(points)) points = DS.points != null ? DS.points : null;
81447
+ if (zot(interactive)) interactive = DS.interactive != null ? DS.interactive : true;
81448
+ if (zot(showControls)) showControls = DS.showControls != null ? DS.showControls : true;
81449
+ if (zot(allowToggle)) allowToggle = DS.allowToggle != null ? DS.allowToggle : true;
81450
+ if (zot(move)) move = DS.move != null ? DS.move : true;
81451
+ if (zot(borderColor)) borderColor = DS.borderColor != null ? DS.borderColor : red;
81452
+ if (zot(borderWidth)) borderWidth = DS.borderWidth != null ? DS.borderWidth : 2;
81453
+ if (borderColor < 0 || borderWidth < 0) borderColor = borderWidth = null;
81454
+ else if (borderColor != null && borderWidth == null) borderWidth = 2;
81455
+ if (zot(dashed)) dashed = DS.dashed != null ? DS.dashed : false;
81456
+ if (zot(plane)) plane = DS.plane != null ? DS.plane : false;
81457
+ if (zot(fade)) fade = DS.fade != null ? DS.fade : true;
81458
+ if (zot(dynamic)) dynamic = DS.dynamic != null ? DS.dynamic : true;
81459
+ if (zot(frame)) frame = DS.frame != null ? DS.frame : zdf;
81460
+ if (zot(resolution)) resolution = DS.resolution != null ? DS.resolution : 1;
81461
+ if (zot(maskShape)) maskShape = DS.maskShape != null ? DS.maskShape : "rect";
81462
+ if (zot(feather)) feather = DS.feather != null ? DS.feather : 0;
81463
+ if (zot(onTop)) onTop = DS.onTop != null ? DS.onTop : true;
81464
+ if (zot(overlay)) overlay = DS.overlay != null ? DS.overlay : false;
81465
+ if (zot(clipping)) clipping = DS.clipping != null ? DS.clipping : true;
81466
+ if (zot(passthrough)) passthrough = DS.passthrough != null ? DS.passthrough : false;
81467
+ if (zot(passthroughScale)) passthroughScale = DS.passthroughScale != null ? DS.passthroughScale : 1;
81468
+ if (zot(passthroughShiftX)) passthroughShiftX = DS.passthroughShiftX != null ? DS.passthroughShiftX : 0;
81469
+ if (zot(passthroughShiftY)) passthroughShiftY = DS.passthroughShiftY != null ? DS.passthroughShiftY : 0;
81470
+
81471
+ var size = Math.max(frame.width, frame.height);
80957
81472
 
80958
- if (zot(obj)) obj=DS.obj!=null?DS.obj:new zim.Tile(new zim.Rectangle(50, 50, [purple,pink,white]), 5, 5, 10, 10);
80959
- if (zot(points)) points=DS.points!=null?DS.points:null;
80960
- if (zot(interactive)) interactive=DS.interactive!=null?DS.interactive:true;
80961
- if (zot(showControls)) showControls=DS.showControls!=null?DS.showControls:true;
80962
- if (zot(allowToggle)) allowToggle=DS.allowToggle!=null?DS.allowToggle:true;
80963
- if (zot(move)) move=DS.move!=null?DS.move:true;
80964
- if (zot(borderColor)) borderColor = DS.borderColor!=null?DS.borderColor:red;
80965
- if (zot(borderWidth)) borderWidth = DS.borderWidth!=null?DS.borderWidth:2;
80966
- if (borderColor < 0 || borderWidth < 0) borderColor = borderWidth = null;
80967
- else if (borderColor!=null && borderWidth==null) borderWidth = 2;
80968
- if (zot(dashed)) dashed=DS.dashed!=null?DS.dashed:false;
80969
- if (zot(plane)) plane=DS.plane!=null?DS.plane:false;
80970
- if (zot(fade)) fade=DS.fade!=null?DS.fade:true;
80971
- if (zot(dynamic)) dynamic=DS.dynamic!=null?DS.dynamic:true;
80972
- if (zot(frame)) frame=DS.frame!=null?DS.frame:zdf;
80973
-
80974
- // PICK
80975
- var oa = remember(obj, borderColor, borderWidth, dashed);
80976
- this.veeObj = {obj:oa[0], borderColor:oa[1], borderWidth:oa[2], dashed:oa[3]};
80977
- function remember() {return arguments;} // for cloning PICK
80978
- obj = zim.Pick.choose(obj);
80979
- borderColor = zim.Pick.choose(borderColor);
80980
- borderWidth = zim.Pick.choose(borderWidth);
80981
- dashed = zim.Pick.choose(dashed);
80982
-
80983
- var size = frame.width;
80984
- var mobile = zim.mobile();
80985
-
80986
- // 2D Homography, Matthew Arcus, mla, 2022 - reduced by Dr Abstract 2026
80987
- // https://www.shadertoy.com/view/7dXfDH
80988
- var frag = "uniform vec2 a;uniform vec2 b;uniform vec2 c;uniform vec2 d;uniform bool plane;uniform bool fade;\n";
80989
- frag += "#define map(screenpos) ((2.0*(screenpos)-iResolution.xy)/iResolution.y)\n";
80990
- frag += "mat3 rproject(vec3 p0, vec3 p1, vec3 p2, vec3 p3) {mat3 m = inverse(mat3(p0,p1,p2));vec3 t = 1.0/(m*p3);return mat3(t[0],0,0, 0,t[1],0, 0,0,t[2])*m;}mat3 rproject(vec2 p0, vec2 p1, vec2 p2, vec2 p3) {return rproject(vec3(p0,1),vec3(p1,1),vec3(p2,1),vec3(p3,1));}\n";
80991
- frag += "void mainImage(out vec4 fragColor, in vec2 fragCoord) {\n";
80992
- frag += "vec2 p = map(fragCoord.xy);float px = fwidth(p.x);vec2 p0 = d;vec2 p1 = a;vec2 p2 = b;vec2 p3 = c;mat3 m = rproject(p0,p1,p2,p3);mat3 n = rproject(vec2(0,0),vec2(0,1),vec2(1,1),vec2(1,0));mat3 t = inverse(n)*m;vec3 uv = t*vec3(p,1);float z = uv.z;uv /= z;mat3x2 tt = transpose(mat2x3(t));vec2 nx0 = tt*vec3(0,1,0);vec2 ny0 = tt*vec3(1,0,0);vec2 nx1 = tt*vec3(0,1,-1);vec2 ny1 = tt*vec3(1,0,-1);vec3 color = pow(texture(iChannel0,uv.xy).xyz,vec3(2.2));vec4 final;if (!(uv.x >= 0.0 && uv.x <= 1.0 && uv.y >= 0.0 && uv.y <= 1.0) && !plane) {final = vec4(0.0,0.0,0.0,0.0);} else {color = pow(color, vec3(0.4545)); if (fade && plane) {color *= min(2.5*z*z,1.0);} if (plane) final = vec4(color,min(2.5*z*z,texture(iChannel0,uv.xy).a)); else final = vec4(color,texture(iChannel0,uv.xy).a);} fragColor = final;}";
81473
+ // PICK
81474
+ var oa = remember(obj, borderColor, borderWidth, dashed);
81475
+ this.veeObj = {obj: oa[0], borderColor: oa[1], borderWidth: oa[2], dashed: oa[3]};
81476
+ function remember() {return arguments;}
81477
+ obj = zim.Pick.choose(obj);
81478
+ borderColor = zim.Pick.choose(borderColor);
81479
+ borderWidth = zim.Pick.choose(borderWidth);
81480
+ dashed = zim.Pick.choose(dashed);
81481
+
81482
+ var mobile = zim.mobile();
80993
81483
 
80994
- this.zimContainer_constructor(size, size, null, null, false);
80995
- this.type = "Perspective";
80996
-
80997
- // MONITOR
80998
- var mID = this.mID = "z~"+(DS.monitor===false?"-":this.type);
81484
+ var frag = "uniform vec2 a; uniform vec2 b; uniform vec2 c; uniform vec2 d;\n";
81485
+ frag += "uniform float plane;\nuniform float fade;\n";
81486
+ frag += "uniform float shape;\nuniform float feather;\nuniform float aspect;\nuniform float useMaskTex;\n";
81487
+ frag += "uniform float passthrough;\nuniform float passthroughScale;\nuniform vec2 passthroughCenter;\nuniform vec2 passthroughShift;\nuniform vec2 assetNormSize;\n";
81488
+ frag += "#define map(screenpos) ((2.0*(screenpos)-iResolution.xy)/iResolution.y)\n";
81489
+ frag += "mat3 rproject(vec3 p0, vec3 p1, vec3 p2, vec3 p3) {\n";
81490
+ frag += " mat3 m = inverse(mat3(p0,p1,p2));\n";
81491
+ frag += " vec3 t = vec3(1.0)/(m*p3);\n";
81492
+ frag += " return mat3(t.x,0.0,0.0, 0.0,t.y,0.0, 0.0,0.0,t.z)*m;\n";
81493
+ frag += "}\n";
81494
+ frag += "mat3 rproject(vec2 p0, vec2 p1, vec2 p2, vec2 p3) {\n";
81495
+ frag += " return rproject(vec3(p0,1.0), vec3(p1,1.0), vec3(p2,1.0), vec3(p3,1.0));\n";
81496
+ frag += "}\n";
81497
+ frag += "void mainImage(out vec4 fragColor, in vec2 fragCoord) {\n";
81498
+ frag += " vec2 p = map(fragCoord.xy);\n";
81499
+ frag += " mat3 m = rproject(d, a, b, c);\n";
81500
+ frag += " mat3 n = rproject(vec2(0.0,0.0), vec2(0.0,1.0), vec2(1.0,1.0), vec2(1.0,0.0));\n";
81501
+ frag += " mat3 t = inverse(n)*m;\n";
81502
+ frag += " vec3 uv = t*vec3(p, 1.0);\n";
81503
+ frag += " float z = uv.z;\n";
81504
+ frag += " // 1. Horizon & In-Bounds Checks\n";
81505
+ frag += " if (plane > 0.5) {\n";
81506
+ frag += " if (z <= 0.0) { fragColor = vec4(0.0); return; }\n";
81507
+ frag += " }\n";
81508
+ frag += " uv /= z;\n";
81509
+ frag += " bool inBounds = (uv.x >= 0.0 && uv.x <= 1.0 && uv.y >= 0.0 && uv.y <= 1.0);\n";
81510
+ frag += " if (!inBounds && plane < 0.5) {\n";
81511
+ frag += " fragColor = vec4(0.0);\n";
81512
+ frag += " return;\n";
81513
+ frag += " }\n";
81514
+ frag += " // 2. Tile UV (Repeats across plane with fract)\n";
81515
+ frag += " vec2 tileUV = (plane > 0.5) ? fract(uv.xy) : uv.xy;\n";
81516
+ frag += " vec2 texUV;\n";
81517
+ frag += " if (passthrough > 0.5) {\n";
81518
+ frag += " vec2 pScale = max(vec2(0.0001), assetNormSize * passthroughScale);\n";
81519
+ frag += " texUV = (p - passthroughCenter - passthroughShift) / pScale + vec2(0.5);\n";
81520
+ frag += " if (texUV.x < 0.0 || texUV.x > 1.0 || texUV.y < 0.0 || texUV.y > 1.0) {\n";
81521
+ frag += " fragColor = vec4(0.0);\n";
81522
+ frag += " return;\n";
81523
+ frag += " }\n";
81524
+ frag += " } else {\n";
81525
+ frag += " texUV = tileUV;\n";
81526
+ frag += " }\n";
81527
+ frag += " vec4 texColor = texture(iChannel0, texUV);\n";
81528
+ frag += " vec3 color = pow(texColor.rgb, vec3(2.2));\n";
81529
+ frag += " color = pow(color, vec3(0.4545));\n";
81530
+ frag += " float alpha = texColor.a;\n";
81531
+ frag += " // 3. Circle / Ellipse Feather (applied to tileUV)\n";
81532
+ frag += " if (shape > 0.5) {\n";
81533
+ frag += " vec2 centerCoord = (tileUV - vec2(0.5)) * 2.0;\n";
81534
+ frag += " if (shape < 1.5) {\n";
81535
+ frag += " if (aspect >= 1.0) centerCoord.x *= aspect;\n";
81536
+ frag += " else centerCoord.y /= aspect;\n";
81537
+ frag += " }\n";
81538
+ frag += " float dist = length(centerCoord);\n";
81539
+ frag += " float f = max(feather, 0.001);\n";
81540
+ frag += " float circleAlpha = 1.0 - smoothstep(1.0 - f, 1.0, dist);\n";
81541
+ frag += " color *= circleAlpha;\n";
81542
+ frag += " alpha *= circleAlpha;\n";
81543
+ frag += " if (alpha <= 0.0) { fragColor = vec4(0.0); return; }\n";
81544
+ frag += " }\n";
81545
+ frag += " // 4. Texture Mask (Blob) Feather (applied to tileUV)\n";
81546
+ frag += " if (useMaskTex > 0.5) {\n";
81547
+ frag += " float maskAlpha = texture(iChannel1, tileUV).a;\n";
81548
+ frag += " if (feather > 0.001) {\n";
81549
+ frag += " float spread = feather * 0.03;\n";
81550
+ frag += " float total = maskAlpha * 2.0;\n";
81551
+ frag += " total += texture(iChannel1, tileUV + vec2(spread, 0.0)).a;\n";
81552
+ frag += " total += texture(iChannel1, tileUV - vec2(spread, 0.0)).a;\n";
81553
+ frag += " total += texture(iChannel1, tileUV + vec2(0.0, spread)).a;\n";
81554
+ frag += " total += texture(iChannel1, tileUV - vec2(0.0, spread)).a;\n";
81555
+ frag += " total += texture(iChannel1, tileUV + vec2(spread, spread) * 0.707).a;\n";
81556
+ frag += " total += texture(iChannel1, tileUV - vec2(spread, spread) * 0.707).a;\n";
81557
+ frag += " total += texture(iChannel1, tileUV + vec2(-spread, spread) * 0.707).a;\n";
81558
+ frag += " total += texture(iChannel1, tileUV + vec2(spread, -spread) * 0.707).a;\n";
81559
+ frag += " maskAlpha = total / 10.0;\n";
81560
+ frag += " }\n";
81561
+ frag += " color *= maskAlpha;\n";
81562
+ frag += " alpha *= maskAlpha;\n";
81563
+ frag += " if (alpha <= 0.0) { fragColor = vec4(0.0); return; }\n";
81564
+ frag += " }\n";
81565
+ frag += " // 5. Standard Quad Edge Feather (applied to tileUV)\n";
81566
+ frag += " if (feather > 0.001 && shape < 0.5 && useMaskTex < 0.5) {\n";
81567
+ frag += " float f = max(feather, 0.001);\n";
81568
+ frag += " float edgeX = smoothstep(0.0, f, tileUV.x) * (1.0 - smoothstep(1.0 - f, 1.0, tileUV.x));\n";
81569
+ frag += " float edgeY = smoothstep(0.0, f, tileUV.y) * (1.0 - smoothstep(1.0 - f, 1.0, tileUV.y));\n";
81570
+ frag += " float edgeAlpha = edgeX * edgeY;\n";
81571
+ frag += " color *= edgeAlpha;\n";
81572
+ frag += " alpha *= edgeAlpha;\n";
81573
+ frag += " if (alpha <= 0.0) { fragColor = vec4(0.0); return; }\n";
81574
+ frag += " }\n";
81575
+ frag += " // 6. Horizon Distance Fade\n";
81576
+ frag += " if (fade > 0.5 && plane > 0.5) {\n";
81577
+ frag += " float distFade = min(2.5 * z * z, 1.0);\n";
81578
+ frag += " color *= distFade;\n";
81579
+ frag += " alpha *= distFade;\n";
81580
+ frag += " }\n";
81581
+ frag += " fragColor = vec4(color, alpha);\n";
81582
+ frag += "}\n";
81583
+
81584
+ this.zimContainer_constructor(size, size, null, null, false);
81585
+ this.type = "Perspective";
81586
+
81587
+ var mID = this.mID = "z~" + (DS.monitor === false ? "-" : this.type);
81588
+ var that = this;
81589
+ var pps = [];
81590
+ var sides = [];
81591
+ var _onTop = onTop;
81592
+ var _overlay = overlay;
81593
+ var _clipping = clipping;
81594
+ var _maskShape = maskShape;
81595
+ var _passthrough = Boolean(passthrough);
81596
+ var _passthroughScale = Number(passthroughScale) || 1;
81597
+ var _passthroughShiftX = Number(passthroughShiftX) || 0;
81598
+ var _passthroughShiftY = Number(passthroughShiftY) || 0;
81599
+ var _passthroughCenter = null;
81600
+
81601
+ var controls = that.sides = new zim.Container(size, size).center(that).mov(size/2, -size/2);
81602
+ obj.center(this);
81603
+
81604
+ var p;
81605
+ if (!points) {
81606
+ var b = obj.getBounds();
81607
+ var tl = obj.localToLocal(b.x, b.y, this);
81608
+ var tr = obj.localToLocal(b.x + b.width, b.y, this);
81609
+ var br = obj.localToLocal(b.x + b.width, b.y + b.height, this);
81610
+ var bl = obj.localToLocal(b.x, b.y + b.height, this);
81611
+ p = [tl, tr, br, bl];
81612
+ } else {
81613
+ p = points;
81614
+ zim.loop(points, function(pp, i) {
81615
+ p[i] = {x: pp.x + size/2, y: pp.y + size/2};
81616
+ });
81617
+ }
80999
81618
 
81000
- var that = this;
81619
+ var blob = that.blob = new zim.Blob({
81620
+ points: [
81621
+ [p[0].x, p[0].y, 0, 0, 0, 0, 0, 0, "none"],
81622
+ [p[1].x, p[1].y, 0, 0, 0, 0, 0, 0, "none"],
81623
+ [p[2].x, p[2].y, 0, 0, 0, 0, 0, 0, "none"],
81624
+ [p[3].x, p[3].y, 0, 0, 0, 0, 0, 0, "none"]
81625
+ ],
81626
+ color: !interactive && !move ? clear : faint,
81627
+ borderColor: interactive ? borderColor : clear,
81628
+ borderWidth: borderWidth,
81629
+ showControls: !interactive ? false : showControls,
81630
+ allowToggle: !interactive ? false : allowToggle,
81631
+ dashed: dashed,
81632
+ move: false,
81633
+ lockControlType: true,
81634
+ editPoints: false
81635
+ }).addTo(this);
81636
+
81637
+ blob.on("controlsshow", function() {
81638
+ blob.borderColor = borderColor;
81639
+ controls.vis(true);
81640
+ zim.loop(sides, function(side) {
81641
+ side.inside.vis(true);
81642
+ });
81643
+ blob.selectionManager.enabled = true;
81644
+ }, null, null, null, null, mID);
81645
+ blob.on("controlshide", function() {
81646
+ blob.borderColor = clear;
81647
+ controls.vis(false);
81648
+ zim.loop(sides, function(side) {
81649
+ side.inside.vis(false);
81650
+ });
81651
+ }, null, null, null, null, mID);
81652
+ if (move) blob.shape.cur();
81001
81653
 
81002
- // seems to maximize on each side if we move half the size and half the -size
81003
- var controls = that.sides = new zim.Container(size, size).center(that).mov(size/2,-size/2);
81004
- obj.center(this);
81654
+ function syncOverlayZ() {
81655
+ if (that.shader && that.shader.tag) {
81656
+ var idx = that.parent ? that.parent.getChildIndex(that) : 0;
81657
+ that.shader.tag.style.zIndex = -100 + idx;
81658
+ if (that.shader.tag.parentNode) {
81659
+ that.shader.tag.parentNode.appendChild(that.shader.tag);
81660
+ }
81661
+ }
81662
+ }
81005
81663
 
81006
- // make it so we can pass in points too as alternative
81007
- // to start with a perspective
81008
- // also have a recordPoints
81664
+ function bringToFront() {
81665
+ if (_onTop) {
81666
+ that.top();
81667
+ syncOverlayZ();
81668
+ }
81669
+ }
81009
81670
 
81010
- var p;
81011
- if (!points) {
81012
- var b = obj.getBounds();
81013
- var tl = obj.localToLocal(b.x, b.y, this);
81014
- var tr = obj.localToLocal(b.x + b.width, b.y, this);
81015
- var br = obj.localToLocal(b.x + b.width, b.y + b.height, this);
81016
- var bl = obj.localToLocal(b.x, b.y + b.height, this);
81017
- p = [tl, tr, br, bl];
81671
+ blob.shape.on("mousedown", function() {
81672
+ activate();
81673
+ bringToFront();
81674
+ zim.loop(sides, function(side) {
81675
+ side.color = black;
81676
+ });
81677
+ blob.selectionManager.enabled = true;
81678
+ if (!move) return;
81679
+ that.diffX = that.x - frame.mouseX;
81680
+ that.diffY = that.y - frame.mouseY;
81681
+ }, null, null, null, null, mID);
81682
+
81683
+ blob.shape.on("pressmove", function() {
81684
+ if (!move) return;
81685
+ that.x = frame.mouseX + that.diffX;
81686
+ that.y = frame.mouseY + that.diffY;
81687
+ }, null, null, null, null, mID);
81688
+
81689
+ that.selectCorner = function(index, state) {
81690
+ if (zot(index)) index = 0;
81691
+ if (index > 3) index = 3;
81692
+ var corner = that.blob.pointControls[index];
81693
+ if (zot(state)) state = true;
81694
+ if (state) {
81695
+ that.blob.selectPoint(index, true, true);
81018
81696
  } else {
81019
- p = points;
81020
- zim.loop(points, function(pp, i) {
81021
- p[i] = {x:pp.x+size/2, y:pp.y+size/2};
81022
- })
81697
+ that.blob.selectPoint(index, false, true);
81023
81698
  }
81699
+ return corner;
81700
+ };
81024
81701
 
81025
- var blob = that.blob = new zim.Blob({
81026
- points: [
81027
- [p[0].x, p[0].y, 0, 0, 0, 0, 0, 0, "none"],
81028
- [p[1].x, p[1].y, 0, 0, 0, 0, 0, 0, "none"],
81029
- [p[2].x, p[2].y, 0, 0, 0, 0, 0, 0, "none"],
81030
- [p[3].x, p[3].y, 0, 0, 0, 0, 0, 0, "none"]],
81031
- color: !interactive&&!move?clear:faint,
81032
- borderColor: interactive?borderColor:clear,
81033
- borderWidth: borderWidth,
81034
- showControls:!interactive?false:showControls,
81035
- allowToggle:!interactive?false:allowToggle,
81036
- dashed:dashed,
81037
- move: false,
81038
- // interactive:interactive, // can;t manipulate points if interactive is false
81039
- lockControlType: true,
81040
- editPoints: false
81041
- }).addTo(this); //.vis(false);
81042
-
81043
- blob.on("controlsshow", function() {
81044
- blob.borderColor = borderColor;
81045
- controls.vis(true);
81046
- zim.loop(sides, function(side) {
81047
- side.inside.vis(true);
81048
- });
81049
- blob.selectionManager.enabled = true;
81050
- }, null, null, null, null, mID);
81051
- blob.on("controlshide", function() {
81052
- blob.borderColor = clear;
81053
- controls.vis(false);
81054
- zim.loop(sides, function(side) {
81055
- side.inside.vis(false);
81056
- });
81057
- }, null, null, null, null, mID);
81058
- if (move) blob.shape.cur()
81059
-
81702
+ that.updateCorner = function(corner, refresh) {
81703
+ if (zot(refresh)) refresh = true;
81704
+ updatePoint(corner);
81705
+ if (refresh) {
81706
+ blob.update();
81707
+ update();
81708
+ }
81709
+ return corner;
81710
+ };
81060
81711
 
81061
- // dragging - fix for within containers
81062
- blob.shape.on("mousedown", function() {
81063
- zim.loop(sides, function(side) {
81064
- side.color = black;
81065
- });
81066
- blob.selectionManager.enabled = true;
81067
- if (!move) return;
81068
- that.diffX = that.x - frame.mouseX;
81069
- that.diffY = that.y - frame.mouseY;
81070
- }, null, null, null, null, mID);
81071
- blob.shape.on("pressmove", function() {
81072
- if (!move) return;
81073
- that.x = frame.mouseX + that.diffX;
81074
- that.y = frame.mouseY + that.diffY;
81075
- }, null, null, null, null, mID);
81712
+ that.deselectPoints = function() {
81713
+ zim.loop(4, function(i) {
81714
+ that.selectCorner(i, false);
81715
+ that.selectSide(i, false);
81716
+ });
81717
+ return that;
81718
+ };
81719
+ that.deselect = that.deselectPoints;
81076
81720
 
81077
- that.selectCorner = function(index, state) {
81078
- if (zot(index)) index = 0;
81079
- if (index > 3) index = 3;
81080
- var corner = that.blob.pointControls[index];
81081
- if (zot(state)) state = true
81082
- if (state) {
81083
- that.blob.selectPoint(index, true, true);
81721
+ that.toggled = showControls && interactive;
81722
+ that.toggle = function(state) {
81723
+ if (!interactive) return that;
81724
+ if (zot(state)) that.toggled = !that.toggled;
81725
+ else that.toggled = state;
81726
+ if (that.toggled) activate();
81727
+ blob.toggle(that.toggled);
81728
+ controls.vis(that.toggled);
81729
+ zim.loop(sides, function(side) {
81730
+ if (side.inside) side.inside.vis(that.toggled);
81731
+ });
81732
+ if (that.toggled) blob.borderColor = borderColor;
81733
+ else blob.borderColor = clear;
81734
+ return that;
81735
+ };
81736
+
81737
+ var sp = [];
81738
+ sp[0] = this.localToLocal(p[0].x, p[0].y, controls);
81739
+ sp[1] = this.localToLocal(p[1].x, p[1].y, controls);
81740
+ sp[2] = this.localToLocal(p[2].x, p[2].y, controls);
81741
+ sp[3] = this.localToLocal(p[3].x, p[3].y, controls);
81742
+
81743
+ var objW = obj.width || (obj.getBounds ? (obj.getBounds() ? obj.getBounds().width : size) : size);
81744
+ var objH = obj.height || (obj.getBounds ? (obj.getBounds() ? obj.getBounds().height : size) : size);
81745
+ var aspect = objW / objH;
81746
+
81747
+ var shapeVal = 0;
81748
+ var useMaskTexVal = 0;
81749
+ if (typeof _maskShape === "string") {
81750
+ if (_maskShape === "circle") shapeVal = 1;
81751
+ else if (_maskShape === "ellipse") shapeVal = 2;
81752
+ } else if (_maskShape) {
81753
+ useMaskTexVal = 1;
81754
+ }
81755
+
81756
+ var initCx = (sp[0].x + sp[1].x + sp[2].x + sp[3].x) / (4 * size);
81757
+ var initCy = 1 - (sp[0].y + sp[1].y + sp[2].y + sp[3].y) / (4 * size);
81758
+
81759
+ var uniforms = that.uniforms = new zim.Uniforms({
81760
+ a: [sp[0].x / size, 1 - sp[0].y / size],
81761
+ b: [sp[1].x / size, 1 - sp[1].y / size],
81762
+ c: [sp[2].x / size, 1 - sp[2].y / size],
81763
+ d: [sp[3].x / size, 1 - sp[3].y / size],
81764
+ plane: plane ? 1 : 0,
81765
+ fade: fade ? 1 : 0,
81766
+ shape: shapeVal,
81767
+ feather: Number(feather) || 0,
81768
+ aspect: aspect || 1.0,
81769
+ useMaskTex: useMaskTexVal,
81770
+ passthrough: _passthrough ? 1 : 0,
81771
+ passthroughScale: _passthroughScale,
81772
+ passthroughCenter: [initCx, initCy],
81773
+ passthroughShift: [_passthroughShiftX / size, -_passthroughShiftY / size],
81774
+ assetNormSize: [objW / size, objH / size]
81775
+ });
81776
+
81777
+ // Align Mask into an exact matching 1:1 buffer container
81778
+ var maskSource = null;
81779
+ var maskContainer = null;
81780
+ function setupMaskSource(mObj) {
81781
+ if (!mObj || typeof mObj === "string") {
81782
+ maskSource = null;
81783
+ return;
81784
+ }
81785
+ if (!maskContainer) {
81786
+ maskContainer = new zim.Container(objW, objH);
81787
+ } else {
81788
+ maskContainer.removeAllChildren();
81789
+ }
81790
+ mObj.loc(objW / 2, objH / 2, maskContainer);
81791
+ maskContainer.cache(0, 0, objW, objH);
81792
+ maskSource = maskContainer;
81793
+
81794
+ if (mObj.on) {
81795
+ var updateMaskTex = function() {
81796
+ if (maskContainer.cacheCanvas) maskContainer.updateCache();
81797
+ if (that.shader) that.shader.replaceChannel(maskContainer, 1, false);
81798
+ };
81799
+ mObj.on("update", updateMaskTex, null, null, null, null, mID);
81800
+ mObj.on("pressmove", updateMaskTex, null, null, null, null, mID);
81801
+ mObj.on("change", updateMaskTex, null, null, null, null, mID);
81802
+ }
81803
+ }
81804
+ if (_maskShape && typeof _maskShape !== "string") setupMaskSource(_maskShape);
81805
+
81806
+ var pc = blob.pointCircles;
81807
+ var pct = blob.pointControls;
81808
+
81809
+ function calculatePassthroughCenter() {
81810
+ pps[0] = pc[0].localToLocal(0, 0, controls);
81811
+ pps[1] = pc[1].localToLocal(0, 0, controls);
81812
+ pps[2] = pc[2].localToLocal(0, 0, controls);
81813
+ pps[3] = pc[3].localToLocal(0, 0, controls);
81814
+ var cx = (pps[0].x + pps[1].x + pps[2].x + pps[3].x) / (4 * size);
81815
+ var cy = 1 - (pps[0].y + pps[1].y + pps[2].y + pps[3].y) / (4 * size);
81816
+ _passthroughCenter = [cx, cy];
81817
+ uniforms.passthroughCenter_A = cx;
81818
+ uniforms.passthroughCenter_B = cy;
81819
+ }
81820
+
81821
+ function buildShader(isOverlay) {
81822
+ if (that.shader) {
81823
+ that.shader.removeFrom();
81824
+ that.shader.dispose();
81825
+ that.shader = null;
81826
+ }
81827
+
81828
+ if (isOverlay) {
81829
+ var p0 = pc[0].localToGlobal(0, 0);
81830
+ var p1 = pc[1].localToGlobal(0, 0);
81831
+ var p2 = pc[2].localToGlobal(0, 0);
81832
+ var p3 = pc[3].localToGlobal(0, 0);
81833
+
81834
+ var minX = Math.min(p0.x, p1.x, p2.x, p3.x);
81835
+ var minY = Math.min(p0.y, p1.y, p2.y, p3.y);
81836
+ var maxX = Math.max(p0.x, p1.x, p2.x, p3.x);
81837
+ var maxY = Math.max(p0.y, p1.y, p2.y, p3.y);
81838
+
81839
+ var stageW = frame.width;
81840
+ var stageH = frame.height;
81841
+ var cMinX, cMinY, cMaxX, cMaxY;
81842
+
81843
+ if (_clipping) {
81844
+ cMinX = Math.max(0, Math.floor(minX));
81845
+ cMinY = Math.max(0, Math.floor(minY));
81846
+ cMaxX = Math.min(stageW, Math.ceil(maxX));
81847
+ cMaxY = Math.min(stageH, Math.ceil(maxY));
81084
81848
  } else {
81085
- that.blob.selectPoint(index, false, true);
81086
- }
81087
- return corner;
81849
+ cMinX = Math.floor(minX);
81850
+ cMinY = Math.floor(minY);
81851
+ cMaxX = Math.ceil(maxX);
81852
+ cMaxY = Math.ceil(maxY);
81853
+ }
81854
+
81855
+ var cW = Math.max(2, cMaxX - cMinX);
81856
+ var cH = Math.max(2, cMaxY - cMinY);
81857
+
81858
+ function toP(pt) {
81859
+ var lx = pt.x - cMinX;
81860
+ var ly = pt.y - cMinY;
81861
+ var gx = (2.0 * lx - cW) / cH;
81862
+ var gy = (2.0 * (cH - ly) - cH) / cH;
81863
+ return [gx, gy];
81864
+ }
81865
+
81866
+ var g0 = toP(p0);
81867
+ var g1 = toP(p1);
81868
+ var g2 = toP(p2);
81869
+ var g3 = toP(p3);
81870
+
81871
+ uniforms.a_A = g0[0]; uniforms.a_B = g0[1];
81872
+ uniforms.b_A = g1[0]; uniforms.b_B = g1[1];
81873
+ uniforms.c_A = g2[0]; uniforms.c_B = g2[1];
81874
+ uniforms.d_A = g3[0]; uniforms.d_B = g3[1];
81875
+
81876
+ var shW = Math.round(cW * resolution);
81877
+ var shH = Math.round(cH * resolution);
81878
+
81879
+ var locInParent = that.globalToLocal(cMinX, cMinY);
81880
+
81881
+ that.shader = new zim.ShaderOverlay({
81882
+ width: shW,
81883
+ height: shH,
81884
+ fragment: frag,
81885
+ uniforms: uniforms,
81886
+ channel0: obj,
81887
+ channel1: maskSource,
81888
+ dynamic: dynamic,
81889
+ dynamic1: false
81890
+ })
81891
+ .sca(1 / resolution)
81892
+ .addTo(that, 0)
81893
+ .loc(locInParent.x, locInParent.y);
81894
+
81895
+ syncOverlayZ();
81896
+ } else {
81897
+ var shaderW = Math.round(2 * size * resolution);
81898
+ var shaderH = Math.round(2 * size * resolution);
81899
+
81900
+ that.shader = new zim.Shader({
81901
+ width: shaderW,
81902
+ height: shaderH,
81903
+ fragment: frag,
81904
+ uniforms: uniforms,
81905
+ channel0: obj,
81906
+ channel1: maskSource,
81907
+ dynamic: dynamic,
81908
+ dynamic1: false
81909
+ })
81910
+ .sca(1 / resolution)
81911
+ .addTo(that, 0)
81912
+ .mov(-size)
81913
+ .mov(size/2, -size/2);
81914
+
81915
+ if (sides && sides.length > 0) update();
81088
81916
  }
81917
+ }
81089
81918
 
81090
- that.updateCorner = function(corner, refresh) {
81091
- if (zot(refresh)) refresh = true;
81092
- updatePoint(corner);
81093
- if (refresh) {
81094
- blob.update();
81095
- update();
81096
- }
81097
- return corner;
81098
- }
81919
+ buildShader(_overlay);
81099
81920
 
81100
- that.deselectPoints = function() {
81101
- zim.loop(4, function(i) {
81102
- that.selectCorner(i, false);
81103
- that.selectSide(i, false);
81104
- });
81105
- return that;
81921
+ obj.removeFrom();
81922
+
81923
+ Object.defineProperty(this, "maskShape", {
81924
+ get: function() {
81925
+ return _maskShape;
81926
+ },
81927
+ set: function(value) {
81928
+ _maskShape = value;
81929
+ if (typeof value === "string") {
81930
+ if (value === "circle") uniforms.shape = 1;
81931
+ else if (value === "ellipse") uniforms.shape = 2;
81932
+ else uniforms.shape = 0;
81933
+ uniforms.useMaskTex = 0;
81934
+ } else if (value) {
81935
+ uniforms.shape = 0;
81936
+ uniforms.useMaskTex = 1;
81937
+ setupMaskSource(value);
81938
+ if (that.shader) that.shader.replaceChannel(maskContainer, 1, false);
81939
+ }
81106
81940
  }
81941
+ });
81107
81942
 
81108
- that.toggled = showControls && interactive;
81109
- that.toggle = function(state) {
81110
- if (!interactive) return that;
81111
- if (zot(state)) that.toggled = !that.toggled;
81112
- else that.toggled = state;
81113
- blob.toggle(that.toggled);
81114
- controls.vis(that.toggled);
81115
- if (that.toggled) blob.borderColor = borderColor;
81116
- else blob.borderColor = clear;
81117
- return that;
81943
+ Object.defineProperty(this, "feather", {
81944
+ get: function() {
81945
+ return uniforms.feather;
81946
+ },
81947
+ set: function(value) {
81948
+ uniforms.feather = Number(value) || 0;
81118
81949
  }
81950
+ });
81119
81951
 
81952
+ Object.defineProperty(this, "passthrough", {
81953
+ get: function() {
81954
+ return _passthrough;
81955
+ },
81956
+ set: function(value) {
81957
+ _passthrough = Boolean(value);
81958
+ uniforms.passthrough = _passthrough ? 1 : 0;
81959
+ if (_passthrough) calculatePassthroughCenter();
81960
+ }
81961
+ });
81120
81962
 
81121
- var sp = [];
81122
- sp[0] = this.localToLocal(p[0].x, p[0].y, controls);
81123
- sp[1] = this.localToLocal(p[1].x, p[1].y, controls);
81124
- sp[2] = this.localToLocal(p[2].x, p[2].y, controls);
81125
- sp[3] = this.localToLocal(p[3].x, p[3].y, controls);
81126
- var uniforms = that.uniforms = new zim.Uniforms({
81127
- a: [sp[0].x / size, 1-sp[0].y / size], // top left
81128
- b: [sp[1].x / size, 1-sp[1].y / size], // top right
81129
- c: [sp[2].x / size, 1-sp[2].y / size], // bottom right
81130
- d: [sp[3].x / size, 1-sp[3].y / size], // bottom left
81131
- plane: plane,
81132
- fade: fade
81133
- });
81134
- that.shader = new zim.Shader({
81135
- width: 2*size,
81136
- height:2*size,
81137
- fragment: frag,
81138
- uniforms: uniforms,
81139
- channel0: obj,
81140
- dynamic: dynamic
81141
- })
81142
- .addTo(this, 0)
81143
- .mov(-size)
81144
- // seems to maximize on each side if we move half the size and half the -size
81145
- .mov(size/2,-size/2);
81963
+ Object.defineProperty(this, "passthroughScale", {
81964
+ get: function() {
81965
+ return _passthroughScale;
81966
+ },
81967
+ set: function(value) {
81968
+ _passthroughScale = Number(value) || 1;
81969
+ uniforms.passthroughScale = _passthroughScale;
81970
+ }
81971
+ });
81146
81972
 
81147
- obj.removeFrom();
81148
- var pc = blob.pointCircles;
81149
- var pct = blob.pointControls;
81150
-
81151
- that.update = function() {
81152
- blob.update();
81153
- update();
81973
+ Object.defineProperty(this, "passthroughShiftX", {
81974
+ get: function() {
81975
+ return _passthroughShiftX;
81976
+ },
81977
+ set: function(value) {
81978
+ _passthroughShiftX = Number(value) || 0;
81979
+ uniforms.passthroughShift_A = _passthroughShiftX / size;
81154
81980
  }
81981
+ });
81155
81982
 
81156
- // ~~~~~~~~~~~~~~~~~~~~~~
81157
- // MAKE SIDES
81983
+ Object.defineProperty(this, "passthroughShiftY", {
81984
+ get: function() {
81985
+ return _passthroughShiftY;
81986
+ },
81987
+ set: function(value) {
81988
+ _passthroughShiftY = Number(value) || 0;
81989
+ uniforms.passthroughShift_B = -_passthroughShiftY / size;
81990
+ }
81991
+ });
81158
81992
 
81159
- that.selectSide = function(index, state) {
81160
- if (zot(index)) index = 0;
81161
- if (index > 3) index = 3;
81162
- var side = sides[index];
81163
- if (zot(state)) state = true
81164
- if (state) {
81165
- blob.selectionManager.enabled = false;
81166
- side.color = white;
81167
- side.aX = side.inside.x-side.pctA.x;
81168
- side.aY = side.inside.y-side.pctA.y;
81169
- side.bX = side.inside.x-side.pctB.x;
81170
- side.bY = side.inside.y-side.pctB.y;
81993
+ Object.defineProperty(this, "overlay", {
81994
+ get: function() {
81995
+ return _overlay;
81996
+ },
81997
+ set: function(value) {
81998
+ value = Boolean(value);
81999
+ if (value === _overlay && that.shader) return;
82000
+ _overlay = value;
82001
+ if (_overlay) {
82002
+ blob.vis(false);
82003
+ controls.vis(false);
82004
+ buildShader(true);
81171
82005
  } else {
81172
- side.color = black;
81173
- var notSelected = zim.loop(sides, function(s) {
81174
- if (s.color == white) return false;
81175
- });
81176
- if (notSelected) blob.selectionManager.enabled = true;
82006
+ buildShader(false);
82007
+ if (interactive && that.toggled) {
82008
+ blob.vis(true);
82009
+ controls.vis(true);
82010
+ blob.borderColor = borderColor;
82011
+ }
81177
82012
  }
81178
- return side;
81179
82013
  }
81180
-
81181
- that.updateSide = function(side, refresh) {
81182
- if (zot(side.aX)) return;
81183
- if (zot(refresh)) refresh = true;
81184
- side.inside.loc(side,null,blob);
81185
- side.pctA.x = side.inside.x - side.aX;
81186
- side.pctA.y = side.inside.y - side.aY;
81187
- side.pctB.x = side.inside.x - side.bX;
81188
- side.pctB.y = side.inside.y - side.bY;
81189
- if (refresh) {
81190
- blob.update();
81191
- update();
81192
- }
81193
- return side;
81194
- }
82014
+ });
81195
82015
 
81196
- var sidePoints = [
81197
- [pct[0], pct[1], pc[0], pc[1]],
81198
- [pct[1], pct[2], pc[1], pc[2]],
81199
- [pct[2], pct[3], pc[2], pc[3]],
81200
- [pct[3], pct[0], pc[3], pc[0]]
81201
- ];
81202
-
81203
- var sides = [];
81204
- zim.loop(4, function(i) {
81205
- var side = new zim.Circle(7*(mobile?1.5:1),black,red,2).addTo(controls).drag();
81206
- side.update = true;
81207
- // pc - pointCircles (second and third index)
81208
- side.pcA = sidePoints[i][2];
81209
- side.pcB = sidePoints[i][3];
81210
- // pct - pointControls (the rest in this function)
81211
- var pctA = side.pctA = sidePoints[i][0];
81212
- var pctB = side.pctB = sidePoints[i][1];
81213
- pctA.sideA = side;
81214
- pctB.sideB = side;
81215
-
81216
- side.inside = new zim.Circle(8*(mobile?1.5:1),black);
81217
- sides.push(side);
82016
+ Object.defineProperty(this, "clipping", {
82017
+ get: function() {
82018
+ return _clipping;
82019
+ },
82020
+ set: function(value) {
82021
+ _clipping = Boolean(value);
82022
+ if (_overlay) buildShader(true);
82023
+ }
82024
+ });
81218
82025
 
81219
- setTimeout(function() {
81220
- side.aX = side.inside.x-side.pctA.x;
81221
- side.aY = side.inside.y-side.pctA.y;
81222
- side.bX = side.inside.x-side.pctB.x;
81223
- side.bY = side.inside.y-side.pctB.y;
81224
- },60);
81225
-
81226
- // MID MOVES
81227
- side.on("mousedown", function() {
81228
- that.selectSide(i);
81229
- }, null, null, null, null, mID);
81230
- side.on("pressmove", function() {
81231
- that.updateSide(side);
81232
- }, null, null, null, null, mID);
81233
- if (!interactive){
81234
- side.vis(false);
81235
- side.inside.vis(false);
81236
- }
81237
- });
82026
+ Object.defineProperty(this, "onTop", {
82027
+ get: function() {
82028
+ return _onTop;
82029
+ },
82030
+ set: function(value) {
82031
+ _onTop = Boolean(value);
82032
+ }
82033
+ });
81238
82034
 
81239
- if (!showControls) {
81240
- blob.borderColor = clear;
81241
- controls.vis(false);
81242
- zim.loop(sides, function(side) {
81243
- side.inside.vis(false);
82035
+ if (_overlay) {
82036
+ blob.vis(false);
82037
+ controls.vis(false);
82038
+ }
82039
+
82040
+ that.update = function() {
82041
+ blob.update();
82042
+ update();
82043
+ };
82044
+
82045
+ that.selectSide = function(index, state) {
82046
+ if (zot(index)) index = 0;
82047
+ if (index > 3) index = 3;
82048
+ var side = sides[index];
82049
+ if (zot(state)) state = true;
82050
+ if (state) {
82051
+ blob.selectionManager.enabled = false;
82052
+ side.color = white;
82053
+ side.aX = side.inside.x - side.pctA.x;
82054
+ side.aY = side.inside.y - side.pctA.y;
82055
+ side.bX = side.inside.x - side.pctB.x;
82056
+ side.bY = side.inside.y - side.pctB.y;
82057
+ } else {
82058
+ side.color = black;
82059
+ var notSelected = zim.loop(sides, function(s) {
82060
+ if (s.color == white) return false;
81244
82061
  });
82062
+ if (notSelected) blob.selectionManager.enabled = true;
81245
82063
  }
81246
-
81247
-
81248
- blob.selectionManager.multipleKey = null;
81249
- blob.on("update", function() {
81250
- // HANDLE KEY ARROWS
81251
- if (blob.selectionManager.currentSet && blob.selectionManager.currentSet.selections) {
81252
- var s = blob.selectionManager.currentSet.selections;
81253
- if (s.length > 0) {
81254
- zim.loop(s, function(index) {
81255
- updatePoint(pct[index]);
81256
- });
81257
- blob.update();
81258
- }
81259
- }
81260
- }, null, null, null, null, mID);
82064
+ return side;
82065
+ };
82066
+
82067
+ that.updateSide = function(side, refresh) {
82068
+ if (zot(side.aX)) return;
82069
+ if (zot(refresh)) refresh = true;
82070
+ side.inside.loc(side, null, blob);
82071
+ side.pctA.x = side.inside.x - side.aX;
82072
+ side.pctA.y = side.inside.y - side.aY;
82073
+ side.pctB.x = side.inside.x - side.bX;
82074
+ side.pctB.y = side.inside.y - side.bY;
82075
+ if (refresh) {
82076
+ blob.update();
82077
+ update();
82078
+ }
82079
+ return side;
82080
+ };
81261
82081
 
81262
- that.keyDE = frame.on("keydown", function(e) {
81263
- if (e.keyCode >= 37 && e.keyCode <= 40) {
81264
- var x = 0;
81265
- var y = 0;
81266
- if (e.keyCode == 37) x -= blob.selectionManager.shiftKey?10:1;
81267
- else if (e.keyCode == 39) x += blob.selectionManager.shiftKey?10:1;
81268
- else if (e.keyCode == 38) y -= blob.selectionManager.shiftKey?10:1;
81269
- else if (e.keyCode == 40) y += blob.selectionManager.shiftKey?10:1;
81270
- var changed = false; // batch updates if multiple sides
81271
-
81272
- zim.loop(sides, function(side) {
81273
- if (side.color==white) {
81274
- side.update = false;
81275
- changed = true;
81276
- side.x += x;
81277
- side.y += y;
81278
- that.updateSide(side, false);
81279
- }
81280
- })
81281
- if (changed) {
81282
- blob.selectionManager.enabled = false;
81283
- blob.update();
81284
- update();
81285
- }
81286
- }
81287
- }, null, null, null, null, mID);
82082
+ var sidePoints = [
82083
+ [pct[0], pct[1], pc[0], pc[1]],
82084
+ [pct[1], pct[2], pc[1], pc[2]],
82085
+ [pct[2], pct[3], pc[2], pc[3]],
82086
+ [pct[3], pct[0], pc[3], pc[0]]
82087
+ ];
82088
+
82089
+ zim.loop(4, function(i) {
82090
+ var side = new zim.Circle(7 * (mobile ? 1.5 : 1), black, red, 2).addTo(controls).drag();
82091
+ side.update = true;
82092
+ side.pcA = sidePoints[i][2];
82093
+ side.pcB = sidePoints[i][3];
82094
+ var pctA = side.pctA = sidePoints[i][0];
82095
+ var pctB = side.pctB = sidePoints[i][1];
82096
+ pctA.sideA = side;
82097
+ pctB.sideB = side;
82098
+
82099
+ side.inside = new zim.Circle(8 * (mobile ? 1.5 : 1), black);
82100
+ sides.push(side);
81288
82101
 
81289
- that.keyUE = frame.on("keyup", function(e) {
81290
- if (e.keyCode >= 37 && e.keyCode <= 40) {
81291
- zim.loop(sides, function(side) {
81292
- side.update = true;
81293
- })
81294
- }
82102
+ setTimeout(function() {
82103
+ side.aX = side.inside.x - side.pctA.x;
82104
+ side.aY = side.inside.y - side.pctA.y;
82105
+ side.bX = side.inside.x - side.pctB.x;
82106
+ side.bY = side.inside.y - side.pctB.y;
82107
+ }, 60);
82108
+
82109
+ side.on("mousedown", function() {
82110
+ activate();
82111
+ bringToFront();
82112
+ that.selectSide(i);
81295
82113
  }, null, null, null, null, mID);
82114
+ side.on("pressmove", function() {
82115
+ that.updateSide(side);
82116
+ }, null, null, null, null, mID);
82117
+ if (!interactive || _overlay) {
82118
+ side.vis(false);
82119
+ side.inside.vis(false);
82120
+ }
82121
+ });
81296
82122
 
81297
- zim.loop(pct, function(point, i) {
81298
- point.on("mousedown", function() {
81299
- if (point.sideA.color==white) point.sideA.update = false;
81300
- if (point.sideB.color==white) point.sideB.update = false;
81301
- }, null, null, null, null, mID)
81302
- point.on("pressmove", function() {
81303
- updatePoint(point);
81304
- }, null, null, null, null, mID);
81305
-
81306
- point.on("pressup", function() {
81307
- zim.loop(sides, function(side, i) {
81308
- if (side.color == white) {
81309
- zim.timeout(.1, function() {
81310
- side.aX = side.inside.x-side.pctA.x;
81311
- side.aY = side.inside.y-side.pctA.y;
81312
- side.bX = side.inside.x-side.pctB.x;
81313
- side.bY = side.inside.y-side.pctB.y;
81314
- });
81315
- }
81316
- });
81317
- point.sideA.update = true;
81318
- point.sideB.update = true;
81319
- }, null, null, null, null, mID);
82123
+ if (!showControls && !_overlay) {
82124
+ blob.borderColor = clear;
82125
+ controls.vis(false);
82126
+ zim.loop(sides, function(side) {
82127
+ side.inside.vis(false);
81320
82128
  });
82129
+ }
81321
82130
 
81322
- function updatePoint(point) {
81323
- var sideA = point.sideA;
81324
- var sideB = point.sideB;
81325
- if (sideA.color==white || sideB.color==white) {
81326
- // MIRRORS
81327
- var p;
81328
- if (sideA.color==white) {
81329
- p = sideA.pcA.localToLocal(0,0,controls); // note pointCircle (pcA) not pointControl (pctA)
81330
- sideA.pctB.x = sideA.inside.x - (p.x-sideA.x); // note pointControl (pctB) not pointCircle (pcB)
81331
- sideA.pctB.y = sideA.inside.y - (p.y-sideA.y);
81332
- }
81333
- if (sideB.color==white) {
81334
- p = sideB.pcB.localToLocal(0,0,controls);
81335
- sideB.pctA.x = sideB.inside.x - (p.x-sideB.x); // change the opposite point to the dragged point
81336
- sideB.pctA.y = sideB.inside.y - (p.y-sideB.y);
81337
- }
82131
+ blob.selectionManager.multipleKey = null;
82132
+ blob.on("update", function() {
82133
+ if (blob.selectionManager.currentSet && blob.selectionManager.currentSet.selections) {
82134
+ var s = blob.selectionManager.currentSet.selections;
82135
+ if (s.length > 0) {
82136
+ zim.loop(s, function(index) {
82137
+ updatePoint(pct[index]);
82138
+ });
82139
+ blob.update();
81338
82140
  }
81339
82141
  }
82142
+ }, null, null, null, null, mID);
81340
82143
 
81341
-
81342
- var pps = [];
81343
- function update() {
81344
- pps[0] = pc[0].localToLocal(0, 0, controls);
81345
- pps[1] = pc[1].localToLocal(0, 0, controls);
81346
- pps[2] = pc[2].localToLocal(0, 0, controls);
81347
- pps[3] = pc[3].localToLocal(0, 0, controls);
81348
- uniforms.a_A = pps[0].x / size;
81349
- uniforms.a_B = 1-pps[0].y / size;
81350
- uniforms.b_A = pps[1].x / size;
81351
- uniforms.b_B = 1-pps[1].y / size;
81352
- uniforms.c_A = pps[2].x / size;
81353
- uniforms.c_B = 1-pps[2].y / size;
81354
- uniforms.d_A = pps[3].x / size;
81355
- uniforms.d_B = 1-pps[3].y / size;
81356
-
81357
- var ps = [
81358
- [pps[0], pps[1]],
81359
- [pps[1], pps[2]],
81360
- [pps[2], pps[3]],
81361
- [pps[3], pps[0]]
81362
- ];
81363
- zim.loop(sides, function(side,i) {
81364
- // KEEP SIDES CENTERED
81365
- if (side.update) {
81366
- var pA = ps[i][0];
81367
- var pB = ps[i][1];
81368
- side.x = pB.x+(pA.x-pB.x)/2;
81369
- side.y = pB.y+(pA.y-pB.y)/2;
81370
- side.inside.loc(side,null,blob);
82144
+ that.keyDE = frame.on("keydown", function(e) {
82145
+ if (_overlay) return;
82146
+ if (e.keyCode >= 37 && e.keyCode <= 40) {
82147
+ var x = 0;
82148
+ var y = 0;
82149
+ if (e.keyCode == 37) x -= blob.selectionManager.shiftKey ? 10 : 1;
82150
+ else if (e.keyCode == 39) x += blob.selectionManager.shiftKey ? 10 : 1;
82151
+ else if (e.keyCode == 38) y -= blob.selectionManager.shiftKey ? 10 : 1;
82152
+ else if (e.keyCode == 40) y += blob.selectionManager.shiftKey ? 10 : 1;
82153
+ var changed = false;
82154
+
82155
+ zim.loop(sides, function(side) {
82156
+ if (side.color == white) {
82157
+ side.update = false;
82158
+ changed = true;
82159
+ side.x += x;
82160
+ side.y += y;
82161
+ that.updateSide(side, false);
81371
82162
  }
81372
- });
81373
-
82163
+ });
82164
+ if (changed) {
82165
+ blob.selectionManager.enabled = false;
82166
+ blob.update();
82167
+ update();
82168
+ }
81374
82169
  }
81375
- update();
81376
- controls.top();
82170
+ }, null, null, null, null, mID);
81377
82171
 
81378
- if (interactive) {
81379
- blob.on("update", update, null, null, null, null, mID);
81380
- blob.on("pressmove", update, null, null, null, null, mID);
82172
+ that.keyUE = frame.on("keyup", function(e) {
82173
+ if (_overlay) return;
82174
+ if (e.keyCode >= 37 && e.keyCode <= 40) {
82175
+ zim.loop(sides, function(side) {
82176
+ side.update = true;
82177
+ });
81381
82178
  }
82179
+ }, null, null, null, null, mID);
81382
82180
 
81383
- Object.defineProperty(this, "obj", {
81384
- get : function() {
81385
- return obj;
81386
- },
81387
- set : function(value) {
81388
- obj = value;
81389
- that.shader.replaceChannel(value, 0);
82181
+ zim.loop(pct, function(point, i) {
82182
+ point.on("mousedown", function() {
82183
+ activate();
82184
+ bringToFront();
82185
+ if (point.sideA.color == white) point.sideA.update = false;
82186
+ if (point.sideB.color == white) point.sideB.update = false;
82187
+ }, null, null, null, null, mID);
82188
+ point.on("pressmove", function() {
82189
+ updatePoint(point);
82190
+ }, null, null, null, null, mID);
82191
+
82192
+ point.on("pressup", function() {
82193
+ zim.loop(sides, function(side, i) {
82194
+ if (side.color == white) {
82195
+ zim.timeout(.1, function() {
82196
+ side.aX = side.inside.x - side.pctA.x;
82197
+ side.aY = side.inside.y - side.pctA.y;
82198
+ side.bX = side.inside.x - side.pctB.x;
82199
+ side.bY = side.inside.y - side.pctB.y;
82200
+ });
82201
+ }
82202
+ });
82203
+ point.sideA.update = true;
82204
+ point.sideB.update = true;
82205
+ }, null, null, null, null, mID);
82206
+ });
82207
+
82208
+ function updatePoint(point) {
82209
+ var sideA = point.sideA;
82210
+ var sideB = point.sideB;
82211
+ if (sideA.color == white || sideB.color == white) {
82212
+ var p;
82213
+ if (sideA.color == white) {
82214
+ p = sideA.pcA.localToLocal(0, 0, controls);
82215
+ sideA.pctB.x = sideA.inside.x - (p.x - sideA.x);
82216
+ sideA.pctB.y = sideA.inside.y - (p.y - sideA.y);
82217
+ }
82218
+ if (sideB.color == white) {
82219
+ p = sideB.pcB.localToLocal(0, 0, controls);
82220
+ sideB.pctA.x = sideB.inside.x - (p.x - sideB.x);
82221
+ sideB.pctA.y = sideB.inside.y - (p.y - sideB.y);
82222
+ }
82223
+ }
82224
+ }
82225
+
82226
+ function update() {
82227
+ if (_overlay) return;
82228
+ pps[0] = pc[0].localToLocal(0, 0, controls);
82229
+ pps[1] = pc[1].localToLocal(0, 0, controls);
82230
+ pps[2] = pc[2].localToLocal(0, 0, controls);
82231
+ pps[3] = pc[3].localToLocal(0, 0, controls);
82232
+ uniforms.a_A = pps[0].x / size;
82233
+ uniforms.a_B = 1 - pps[0].y / size;
82234
+ uniforms.b_A = pps[1].x / size;
82235
+ uniforms.b_B = 1 - pps[1].y / size;
82236
+ uniforms.c_A = pps[2].x / size;
82237
+ uniforms.c_B = 1 - pps[2].y / size;
82238
+ uniforms.d_A = pps[3].x / size;
82239
+ uniforms.d_B = 1 - pps[3].y / size;
82240
+
82241
+ if (!_passthroughCenter) {
82242
+ calculatePassthroughCenter();
82243
+ }
82244
+
82245
+ var ps = [
82246
+ [pps[0], pps[1]],
82247
+ [pps[1], pps[2]],
82248
+ [pps[2], pps[3]],
82249
+ [pps[3], pps[0]]
82250
+ ];
82251
+ zim.loop(sides, function(side, i) {
82252
+ if (side.update) {
82253
+ var pA = ps[i][0];
82254
+ var pB = ps[i][1];
82255
+ side.x = pB.x + (pA.x - pB.x) / 2;
82256
+ side.y = pB.y + (pA.y - pB.y) / 2;
82257
+ side.inside.loc(side, null, blob);
81390
82258
  }
81391
82259
  });
81392
-
81393
- this.dispose = function(a,b,disposing) {
81394
- frame.off("keydown", that.keyDE, null, mID);
81395
- frame.off("keyup", that.keyUE, null, mID);
81396
- if (!disposing) {this.zimContainer_dispose();}
81397
- return true;
81398
- };
81399
-
81400
- if (style!==false) zim.styleTransforms(this, DS); // global function - would have put on DisplayObject if had access to it
81401
-
81402
- this.clone = function(exact) {
81403
- return that.cloneProps(new zim.Perspective((exact||!zim.isPick(oa[0]))?obj:oa[0], points, interactive, showControls, allowToggle, move, (exact||!zim.isPick(oa[1]))?amount:oa[1], (exact||!zim.isPick(oa[2]))?amountY:oa[2], (exact||!zim.isPick(oa[3]))?blur:oa[3], plane, fade, dynamic, frame, style, this.group, inherit));
81404
- };
82260
+ }
82261
+ update();
82262
+ controls.top();
82263
+
82264
+ if (interactive) {
82265
+ blob.on("update", update, null, null, null, null, mID);
82266
+ blob.on("pressmove", update, null, null, null, null, mID);
82267
+ }
82268
+
82269
+ Object.defineProperty(this, "obj", {
82270
+ get: function() {
82271
+ return obj;
82272
+ },
82273
+ set: function(value) {
82274
+ obj = value;
82275
+ that.shader.replaceChannel(value, 0);
82276
+ }
82277
+ });
81405
82278
 
82279
+ function activate() {
82280
+ if (zim.Perspective.active && zim.Perspective.active !== that) {
82281
+ zim.Perspective.active.deselectPoints();
82282
+ zim.Perspective.active.toggle(false);
82283
+ }
82284
+ zim.Perspective.active = that;
82285
+ }
82286
+
82287
+ this.dispose = function(a, b, disposing) {
82288
+ frame.off("keydown", that.keyDE, null, mID);
82289
+ frame.off("keyup", that.keyUE, null, mID);
82290
+ if (maskContainer && maskContainer.dispose) maskContainer.dispose();
82291
+ if (that.shader && that.shader.dispose) that.shader.dispose();
82292
+ if (!disposing) {this.zimContainer_dispose();}
82293
+ return true;
81406
82294
  };
81407
- zim.extend(zim.Perspective, zim.Container, ["clone", "dispose"], "zimContainer", false);
82295
+
82296
+ if (style !== false) zim.styleTransforms(this, DS);
82297
+
82298
+ this.clone = function(exact) {
82299
+ return that.cloneProps(new zim.Perspective((exact || !zim.isPick(oa[0])) ? obj : oa[0], points, interactive, showControls, allowToggle, move, (exact || !zim.isPick(oa[1])) ? borderColor : oa[1], (exact || !zim.isPick(oa[2])) ? borderWidth : oa[2], (exact || !zim.isPick(oa[3])) ? dashed : oa[3], plane, fade, dynamic, frame, resolution, _maskShape, feather, _onTop, _overlay, _clipping, _passthrough, _passthroughScale, _passthroughShiftX, _passthroughShiftY, style, this.group, inherit));
82300
+ };
82301
+ };
82302
+ zim.extend(zim.Perspective, zim.Container, ["clone", "dispose"], "zimContainer", false);
82303
+ zim.Perspective.active = null;
81408
82304
  //-69.9748
81409
82305
 
81410
82306
 
@@ -85576,8 +86472,8 @@ zim.Emitter = function(obj, width, height, interval, num, life, fade, shrink, wa
85576
86472
  cache = zim.mobile();
85577
86473
  }
85578
86474
  }
85579
- if (cache) stage.snapToPixelEnabled = true;
85580
86475
  if (stage) {
86476
+ if (cache) stage.snapToPixelEnabled = true;
85581
86477
  var myIndex = that.parent.getChildIndex(that);
85582
86478
  that.parent.addChildAt(particles, myIndex); // add particles beneath emitter in emitter's container
85583
86479
  // particles.x = that.x;
@@ -85991,7 +86887,7 @@ zim.Emitter = function(obj, width, height, interval, num, life, fade, shrink, wa
85991
86887
  if (p.trace?p.getChildAt(0).endSpurt:p.endSpurt) {
85992
86888
  sendEvent("spurtfizzed", p);
85993
86889
  that.spurting = false;
85994
- if (cache) stage.snapToPixelEnabled = false;
86890
+ if (cache && stage) stage.snapToPixelEnabled = false;
85995
86891
  }
85996
86892
  if (that.pool) {
85997
86893
  if (p.pooled == "end") {
@@ -86053,14 +86949,14 @@ zim.Emitter = function(obj, width, height, interval, num, life, fade, shrink, wa
86053
86949
  // that.removeFrom();
86054
86950
  if (that.parent) that.parent.removeChild(that);
86055
86951
  that.particles.removeFrom();
86056
- if (cache) stage.snapToPixelEnabled = false;
86952
+ if (cache && stage) stage.snapToPixelEnabled = false;
86057
86953
  };
86058
86954
 
86059
86955
  this.spurting = false;
86060
86956
  this.spurt = function(num, time, restart) {
86061
86957
  var sig = "num, time, restart";
86062
86958
  var duo; if (duo = zob(that.spurt, arguments, sig)) return duo;
86063
- if (cache) stage.snapToPixelEnabled = true;
86959
+ if (cache && stage) stage.snapToPixelEnabled = true;
86064
86960
  if (!zot(time)) {
86065
86961
  zim.timeout(zim.Pick.choose(time), function() {
86066
86962
  lastSpurt(that.currentParticle);
@@ -86109,7 +87005,7 @@ zim.Emitter = function(obj, width, height, interval, num, life, fade, shrink, wa
86109
87005
  }
86110
87006
  that.zimInterval.pause();
86111
87007
  that.emitterPaused = true;
86112
- if (cache) stage.snapToPixelEnabled = false;
87008
+ if (cache && stage) stage.snapToPixelEnabled = false;
86113
87009
  } else { // unpausing
86114
87010
  if (!that.emitterPaused) return that;
86115
87011
  if (restart) {
@@ -86130,7 +87026,7 @@ zim.Emitter = function(obj, width, height, interval, num, life, fade, shrink, wa
86130
87026
  }
86131
87027
  if (that.zimInterval) that.zimInterval.pause(false, immediate);
86132
87028
  that.emitterPaused = false;
86133
- if (cache) stage.snapToPixelEnabled = true;
87029
+ if (cache && stage) stage.snapToPixelEnabled = true;
86134
87030
  }
86135
87031
 
86136
87032
  if (that.zimInterval) that.zimInterval.pauseOnBlurPaused = state; // ZIM 019 Patch - in case being paused when tab not active
@@ -86162,7 +87058,7 @@ zim.Emitter = function(obj, width, height, interval, num, life, fade, shrink, wa
86162
87058
 
86163
87059
 
86164
87060
  this.dispose = function() {
86165
- if (cache) stage.snapToPixelEnabled = true;
87061
+ if (cache && stage) stage.snapToPixelEnabled = true;
86166
87062
  if (that.zimInterval) that.zimInterval.clear();
86167
87063
  if (emitterTicker) zim.Ticker.remove(emitterTicker, mID, that);
86168
87064
  zim.loop(poolList, function(particle) {
@@ -93113,7 +94009,7 @@ zim.Frame = function(scaling, width, height, color, outerColor, ready, assets, p
93113
94009
  };
93114
94010
 
93115
94011
  // called by asset if auto loading (ac is Asset Container)
93116
- this.ac = function(method, args, obj) {
94012
+ this.ac = function(method, args, obj) {
93117
94013
  if (obj) {
93118
94014
  if (!obj.commands) obj.commands = [];
93119
94015
  obj.commands.push([method,args,obj]);
@@ -95331,7 +96227,7 @@ zim.Dat = function(file) {
95331
96227
  zim.extend(zim.Dat, createjs.EventDispatcher, null, "cjsEventDispatcher", false);//-83.08
95332
96228
 
95333
96229
  /*--
95334
- SVG = function(svg, width, height, bitmap, splitTypes, geometric, showControls, interactive, color, borderColor, style, group, inherit)
96230
+ SVG = function(svg, width, height, bitmap, splitTypes, geometric, showControls, interactive, color, borderColor, order, style, group, inherit)
95335
96231
 
95336
96232
  SVG
95337
96233
  zim class - extends a zim.Container which extends a createjs.Container
@@ -95478,6 +96374,8 @@ interactive - (default true) for bitmap:false, set to false to turn off controls
95478
96374
  color - |ZIM VEE| (default null) for bitmap:false, set to a color or an array of colors to apply to fill of children - in order of the children
95479
96375
  usually a series() would be used here for colors in order, or an array for random colors
95480
96376
  borderColor - |ZIM VEE| (default null) set to a color or an array of colors to apply to border of children - in order of the children
96377
+ order - and array showing a new order of the old index numbers
96378
+ eg [3,1,2,0] means the old index 3 is now at level 0, old index 1 stays the same, old index 2 is now third, and old index 0 is at the top
95481
96379
  style - (default true) set to false to ignore styles set with the STYLE - will receive original parameter defaults
95482
96380
  group - (default null) set to String (or comma delimited String) so STYLE can set default styles to the group(s) (like a CSS class)
95483
96381
  inherit - (default null) used internally but can receive an {} of styles directly
@@ -95525,8 +96423,8 @@ dispatches a "complete" and a "ready" event (use either one) when the SVG is loa
95525
96423
  See the CreateJS Easel Docs for Container events such as:
95526
96424
  added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmove, pressup, removed, rollout, rollover
95527
96425
  --*///+83.09
95528
- zim.SVG = function(svg, width, height, bitmap, splitTypes, geometric, showControls, interactive, color, borderColor, style, group, inherit) {
95529
- var sig = "svg, width, height, bitmap, splitTypes, geometric, showControls, interactive, color, borderColor, style, group, inherit";
96426
+ zim.SVG = function(svg, width, height, bitmap, splitTypes, geometric, showControls, interactive, color, borderColor, order, style, group, inherit) {
96427
+ var sig = "svg, width, height, bitmap, splitTypes, geometric, showControls, interactive, color, borderColor, order, style, group, inherit";
95530
96428
  var duo; if (duo = zob(zim.SVG, arguments, sig, this)) return duo;
95531
96429
  z_d("83.09");
95532
96430
 
@@ -95542,6 +96440,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
95542
96440
  if (zot(interactive)) interactive = DS.interactive!=null?DS.interactive:true;
95543
96441
  if (zot(color)) color = DS.color!=null?DS.color:null;
95544
96442
  if (zot(borderColor)) borderColor = DS.borderColor!=null?DS.borderColor:null;
96443
+ if (zot(order)) order = DS.order!=null?DS.order:null;
95545
96444
 
95546
96445
  var setColors = [];
95547
96446
  var setBorderColors = [];
@@ -95623,6 +96522,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
95623
96522
  if (that.stage) that.stage.update();
95624
96523
  }
95625
96524
  setTimeout(function () {
96525
+ doOrder();
95626
96526
  doColors();
95627
96527
  that.dispatchEvent("ready");
95628
96528
  that.dispatchEvent("complete");
@@ -95632,6 +96532,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
95632
96532
  that.bitmap = bitmap;
95633
96533
  that.bitmap.addTo(that);
95634
96534
  applyCommands();
96535
+ doOrder();
95635
96536
  doColors();
95636
96537
  that.dispatchEvent("ready");
95637
96538
  that.dispatchEvent("complete");
@@ -95645,6 +96546,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
95645
96546
  svgContainer.loop(function (obj) {
95646
96547
  if (obj) obj.addTo(that);
95647
96548
  }, true);
96549
+ doOrder();
95648
96550
  doColors();
95649
96551
  if (second) {
95650
96552
  applyCommands();
@@ -95662,6 +96564,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
95662
96564
  if (obj) obj.addTo(that);
95663
96565
  }, true);
95664
96566
  applyCommands();
96567
+ doOrder();
95665
96568
  doColors();
95666
96569
  that.dispatchEvent("ready");
95667
96570
  that.dispatchEvent("complete");
@@ -95676,7 +96579,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
95676
96579
  if (color.index) color.index = 0; // not sure where it was setting to 1 when being cloned?
95677
96580
  that.loop(function(obj) {
95678
96581
  var c = zik(color);
95679
- if (c!=null) obj.color = c;
96582
+ if (c!=null && c!="") obj.color = c;
95680
96583
  setColors.push(c);
95681
96584
  });
95682
96585
  }
@@ -95689,17 +96592,23 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
95689
96592
  });
95690
96593
  }
95691
96594
  }
96595
+
96596
+ function doOrder() {
96597
+ if (order) zim.orderContainer(that, order);
96598
+ }
95692
96599
 
95693
96600
  function applyCommands() {
95694
96601
  if (zot(width) && zot(height)) that.setBounds(null); // resets size
95695
96602
  that.type = "SVG";
95696
- if (that.commands) {
95697
- for (var i=0; i<that.commands.length; i++) {
95698
- if (that.commands[i][2]) that[that.commands[i][0]].apply(that, that.commands[i][1]);
95699
- else zim[that.commands[i][0]].apply(that, that.commands[i][1]);
95700
- }
95701
- }
95702
- that.commands = null;
96603
+ var os = that; // adjusted 020 for Lazy Load Noto SVG Emoji
96604
+ if (that.parent && that.parent.type == "Emoji") os = that.parent;
96605
+ if (os.commands) {
96606
+ for (var i=0; i<os.commands.length; i++) {
96607
+ if (os.commands[i][2]) os[os.commands[i][0]].apply(os, os.commands[i][1]);
96608
+ else zim[os.commands[i][0]].apply(os, os.commands[i][1]);
96609
+ }
96610
+ }
96611
+ os.commands = null;
95703
96612
  }
95704
96613
 
95705
96614
  that.keyOut = function(color, tolerance, replacement) {
@@ -95913,11 +96822,14 @@ Note: there are more features to the Web Speech API - see the HTML docs
95913
96822
  if (zot(rate)) rate = 1;
95914
96823
 
95915
96824
  utter.text = text;
95916
- utter.voice = M=="ios"?null:voice;
95917
- utter.lang = lang;
95918
- utter.volume = volume;
95919
- utter.rate = rate;
95920
- utter.pitch = pitch;
96825
+ // utter.voice = M=="ios"?null:voice;
96826
+ // if (voice instanceof SpeechSynthesisVoice && M != "ios") utter.voice = voice;
96827
+ if (voice instanceof SpeechSynthesisVoice) utter.voice = voice;
96828
+ if (lang != null) utter.lang = lang;
96829
+ if (volume != null) utter.volume = volume;
96830
+ if (rate != null) utter.rate = rate;
96831
+ if (pitch != null) utter.pitch = pitch;
96832
+
95921
96833
  speechSynthesis.speak(utter);
95922
96834
 
95923
96835
  return utter;
@@ -95955,7 +96867,283 @@ Note: there are more features to the Web Speech API - see the HTML docs
95955
96867
  }
95956
96868
 
95957
96869
  }
95958
- zim.extend(zim.Speech, createjs.EventDispatcher, null, "cjsEventDispatcher", false);//-83.095
96870
+ zim.extend(zim.Speech, createjs.EventDispatcher, null, "cjsEventDispatcher", false);
96871
+ //-83.095
96872
+
96873
+ /*--
96874
+ Hardware = function(callback, baudRate, delimiter)
96875
+
96876
+ Hardware
96877
+ zim class - extends a createjs.EventDispatcher
96878
+
96879
+ DESCRIPTION
96880
+ Reads from and writes to a device such as an Ardiuno
96881
+ Wraps the JS Web Serial API
96882
+ https://developer.mozilla.org/en-US/docs/Web/API/Web_Serial_API
96883
+ Coded primarily by Gemini AI
96884
+
96885
+ See: https://zimjs.com/hardware/
96886
+
96887
+ NOTE: as of ZIM 5.5.0 the zim namespace is no longer required (unless zns is set to true before running zim)
96888
+
96889
+ EXAMPLE
96890
+ // USING ZIM as INPUT to ARDUINO
96891
+
96892
+ // would need an arduino connected
96893
+ // with the following .ino file loaded onto it
96894
+
96895
+ // ------------------------
96896
+ // ---- Arduinin Code -----
96897
+
96898
+ const int LED_PIN = 13; // Built-in LED on your Uno R3 board
96899
+ void setup() {
96900
+ Serial.begin(9600); // Initialize background channel at matching speed
96901
+ pinMode(LED_PIN, OUTPUT); // Configure Pin 13 as an output light source
96902
+ }
96903
+ void loop() {
96904
+ // Check if ZIM has sent a data character over the USB cable
96905
+ if (Serial.available() > 0) {
96906
+ char incomingChar = Serial.read(); // Read the character data fragment
96907
+ if (incomingChar == '1') {
96908
+ digitalWrite(LED_PIN, HIGH); // Turn physical light ON
96909
+ }
96910
+ else if (incomingChar == '0') {
96911
+ digitalWrite(LED_PIN, LOW); // Turn physical light OFF
96912
+ }
96913
+ }
96914
+ }
96915
+
96916
+ // -------------------
96917
+ // ---- ZIM Code -----
96918
+
96919
+ const device = new Hardware();
96920
+
96921
+ const toggle = new Toggle({
96922
+ label: "LED POWER",
96923
+ toggleBackgroundColor: green,
96924
+ color: white
96925
+ })
96926
+ .center()
96927
+ .change(() => {
96928
+ if (toggle.toggled) {
96929
+ device.write("1"); // note a \n will be automatically added if missing
96930
+ } else {
96931
+ device.write("0");
96932
+ }
96933
+ });
96934
+
96935
+ // must interact to connect
96936
+ const pane = new Pane("CONNECT", yellow).show(() => {
96937
+ device.connect()
96938
+ });
96939
+
96940
+ device.on("disconnected", () => {
96941
+ pane.show(() => { // remember to add the callback again
96942
+ device.connect();
96943
+ });
96944
+ });
96945
+ END EXAMPLE
96946
+
96947
+ EXAMPLE
96948
+ // USING ZIM AS OUTPUT FROM ARDUINO
96949
+ See: https://zimjs.com/hardware/
96950
+
96951
+ // would need an arduino connected
96952
+ // with a potentiometer (pot) dial
96953
+ // (probably on a breadboard)
96954
+ // with outside pins goint to ground and 5V
96955
+ // and middle pin goint to analogue A0
96956
+ // with the following .ino file loaded onto it
96957
+
96958
+ // ------------------------
96959
+ // ---- Arduinin Code -----
96960
+
96961
+ const int potPin = A0;
96962
+ void setup() {
96963
+ Serial.begin(9600);
96964
+ }
96965
+ void loop() {
96966
+ int potValue = analogRead(potPin);
96967
+ Serial.println(potValue);
96968
+ delay(20);
96969
+ }
96970
+
96971
+ // -------------------
96972
+ // ---- ZIM Code -----
96973
+
96974
+ const device = new Hardware(data => {
96975
+ zog(data); // gives values from 0-1023
96976
+ });
96977
+
96978
+ // must interact to connect
96979
+ const pane = new Pane("CONNECT", yellow).show(()=>{
96980
+ device.connect();
96981
+ });
96982
+
96983
+ device.on("disconnected", () => {
96984
+ pane.show(()=>{ // remember to add the callback again
96985
+ device.connect();
96986
+ });
96987
+ });
96988
+ END EXAMPLE
96989
+
96990
+ PARAMETERS
96991
+ callback - the function to call when data is received and will receive the data in its single parameter
96992
+ baudRate - (default 9600) Port speed matching the microcontroller
96993
+ delimiter - (default \n) Character used to split data lines
96994
+
96995
+ METHODS
96996
+ connect() - must interact before connecting - will receive a connected event
96997
+ write(data) - write to the device - also see the data event for reading from the device
96998
+ disconnect() - disconnect from the device
96999
+
97000
+ PROPERTIES
97001
+ type - holds the class name as a String
97002
+ port - readonly the port the hardware is connected on
97003
+ reader - readonly the textDecoder.readable.getReader()
97004
+ writer - readonly the textEncoder.writable.getWriter()
97005
+ textDecoder - readonly the JavaScript TextEncoderStream()
97006
+ textEncoder - readonly the JavaScript TextEncoderStream()
97007
+ isListening - whether actively reading on port
97008
+ baudRate - readonly baud rate - see parameter
97009
+ delimiter - end character for outgoing data
97010
+
97011
+ EVENTS
97012
+ dispatches "connected" when connected
97013
+ dispatches "disconnected" when disconnected
97014
+ --*///+83.097
97015
+ zim.Hardware = function(callback, baudRate, delimiter) {
97016
+ z_d("83.097");
97017
+ this.cjsEventDispatcher_constructor();
97018
+ this.type = "Hardware";
97019
+ var that = this;
97020
+
97021
+ // MONITOR
97022
+ this.mID = "z~"+this.type;
97023
+
97024
+ // Core Properties
97025
+ that.baudRate = baudRate || 9600;
97026
+ that.delimiter = delimiter || "\n";
97027
+
97028
+ that.port = null
97029
+ that.reader = null
97030
+ that.writer = null
97031
+ that.textDecoder = null
97032
+ that.isListening = false
97033
+
97034
+ // GLOBAL HARDWARE DISCONNECT MONITOR
97035
+ if (navigator.serial) {
97036
+ navigator.serial.addEventListener("disconnect", function (event) {
97037
+ if (event.target === that.port) {
97038
+ zogy("ZIM Harware - hardware physically disconnected!")
97039
+ that.isListening = false;
97040
+
97041
+ // Clean break: release locks and clear active streams
97042
+ if (that.reader) {
97043
+ try { that.reader.releaseLock() } catch (e) { }
97044
+ that.reader = null
97045
+ }
97046
+ if (that.writer) {
97047
+ try { that.writer.releaseLock() } catch (e) { }
97048
+ that.writer = null
97049
+ }
97050
+ that.port = null;
97051
+ that.dispatchEvent("disconnected");
97052
+ }
97053
+ });
97054
+ }
97055
+
97056
+ // CONNECT METHOD
97057
+ that.connect = function () {
97058
+ if (!navigator.serial) {
97059
+ console.error("Web Serial API is not supported in this browser. Please use Chrome or Edge.")
97060
+ return;
97061
+ }
97062
+
97063
+ navigator.serial.requestPort()
97064
+ .then(function (selectedPort) {
97065
+ that.port = selectedPort;
97066
+ return that.port.open({ baudRate: that.baudRate });s
97067
+ })
97068
+ .then(function () {
97069
+ zogy("ZIM Hardware - connected successfully!")
97070
+ that.isListening = true
97071
+
97072
+ // Set up Output Stream (Browser to Microcontroller)
97073
+ var textEncoder = new TextEncoderStream()
97074
+ textEncoder.readable.pipeTo(that.port.writable)
97075
+ that.writer = textEncoder.writable.getWriter()
97076
+
97077
+ // Set up Input Stream (Microcontroller to Browser)
97078
+ that.textDecoder = new TextDecoderStream()
97079
+ that.port.readable.pipeTo(that.textDecoder.writable)
97080
+ that.reader = that.textDecoder.readable.getReader()
97081
+
97082
+ // Start recursive background reader
97083
+ that._readLoop("");
97084
+ that.dispatchEvent("connected");
97085
+ })
97086
+ .catch(function (error) {
97087
+ console.error("Hardware connection failed:", error)
97088
+ })
97089
+ }
97090
+
97091
+ that.write = function (data) {
97092
+ if (that.writer && that.isListening) {
97093
+ var message = String(data);
97094
+ if (message.charAt(str.length - 1) != that.delimeter) {
97095
+ message += that.delimiter;
97096
+ }
97097
+ that.writer.write(message)
97098
+ .catch(function (error) {
97099
+ console.error("Failed to transmit data to hardware:", error);
97100
+ })
97101
+ } else {
97102
+ console.warn("Cannot write data: Hardware is not connected.");
97103
+ }
97104
+ }
97105
+
97106
+ // DISCONNECT METHOD (Manual Shutdown)
97107
+ that.disconnect = function () {
97108
+ that.isListening = false
97109
+ if (that.reader && that.writer) {
97110
+ that.reader.cancel()
97111
+ .then(function () { return that.writer.close() })
97112
+ .then(function () { if (that.port) return that.port.close() })
97113
+ .then(function () { zogy("ZIM Hardware: cleanly disconnected.") })
97114
+ .catch(function (err) { console.error("Error during disconnect process:", err) })
97115
+ }
97116
+ }
97117
+
97118
+ // INTERNAL RECURSIVE LOOP METHOD
97119
+ that._readLoop = function (buffer) {
97120
+ if (!that.isListening) return;
97121
+
97122
+ that.reader.read()
97123
+ .then(function (result) {
97124
+ if (result.done) {
97125
+ that.isListening = false;
97126
+ return;
97127
+ }
97128
+ buffer += result.value;
97129
+ var delimiterPattern = that.delimiter === "\n" ? /\r?\n/ : new RegExp(that.delimiter)
97130
+ var lines = buffer.split(delimiterPattern)
97131
+ buffer = lines.pop()
97132
+ for (var i = 0; i < lines.length; i++) {
97133
+ var cleanLine = lines[i].trim()
97134
+ if (cleanLine.length > 0 && typeof callback === "function") (callback)(cleanLine);
97135
+ }
97136
+ that._readLoop(buffer);
97137
+ })
97138
+ .catch(function (error) {
97139
+ // If it crashes due to a sudden cable pull, let the event listener handle the cleanup
97140
+ that.isListening = false
97141
+ });
97142
+ }
97143
+ }
97144
+ zim.extend(zim.Hardware, createjs.EventDispatcher, null, "cjsEventDispatcher", false);
97145
+ //-83.097
97146
+
95959
97147
 
95960
97148
  /*--
95961
97149
  Fonts - loaded into Frame()
@@ -97930,7 +99118,7 @@ RETURNS - null
97930
99118
  --*///+83.27
97931
99119
  zim.svgToBitmap = function(svg, callback, width, height, params) {
97932
99120
  z_d("83.27");
97933
-
99121
+
97934
99122
  if (!zot(svg.draggable)) {
97935
99123
  // CreateJS seems to wrap up an SVG with loadAssets as an SVG object
97936
99124
  var parser = new DOMParser();
@@ -104364,41 +105552,42 @@ END EXAMPLE
104364
105552
  PARAMETERS
104365
105553
  ** supports DUO - parameters or single object with properties below
104366
105554
  ** supports OCT - parameter defaults can be set with STYLE control (like CSS)
104367
- width - (400) width in pixels
104368
- height - (width) height in pixels (defaults to width)
104369
- info - (null) ***** array of label objects with name and backgroundColor properties
104370
- data - (null) ***** array of numbers representing pie slice values
104371
- units - (null) ***** unit label appended to data values
104372
- title - (null) title label or text displayed at top
104373
- footer - (null) footer label or text displayed at bottom in italics
104374
- backgroundColor - (white) background color
104375
- color - (dark) text color
104376
- size - (14) title/footer label font size
104377
- dataSize - (size) font size for data labels
104378
- font - (null) font family name
104379
- spacing - (5) spacing between elements in pixels
104380
- iconOrient - (true) ***** whether icon graphics are oriented to angle
104381
- iconFlip - (true) ***** whether icons are flipped
104382
- iconWidth - (null) ***** width of icon graphics if used
104383
- iconScale - (null) ***** scale factor for icon graphics
104384
- dec - (0) decimal places for displayed data values
104385
- padding - (10) padding around chart edges
104386
- showData - (true) whether to display data values
104387
- showInfo - (true) whether to display info labels
104388
- exchange - (false) ***** whether to exchange display positions of data and info
104389
- shiftForWedge - (true) whether labels shift when wedge is raised
105555
+ width - (default 400) width in pixels
105556
+ height - (default width) height in pixels (defaults to width)
105557
+ info - (default null) array of label objects with name and backgroundColor properties
105558
+ data - (default null) array of numbers representing pie slice values
105559
+ units - (default null) unit label appended to data values
105560
+ title - (default null) title label or text displayed at top
105561
+ footer - (default null) footer label or text displayed at bottom in italics
105562
+ backgroundColor - (default white) background color
105563
+ color - (default dark) text color
105564
+ size - (default 14) title/footer label font size
105565
+ dataSize - (default size) font size for data labels
105566
+ font - (default null) font family name
105567
+ spacing - (default 5) spacing between elements in pixels
105568
+ iconOrient - (default true) whether icon graphics are oriented to angle
105569
+ iconFlip - (default true) whether icons are flipped
105570
+ iconWidth - (default null) width of icon graphics if used
105571
+ iconScale - (default null) scale factor for icon graphics
105572
+ dec - (default 0) decimal places for displayed data values
105573
+ padding - (default 10) padding around chart edges
105574
+ showData - (default true) whether to display data values
105575
+ showInfo - (default true) whether to display info labels
105576
+ exchange - (default false) whether to exchange display positions of data and info
105577
+ shiftForWedge - (default true) whether labels shift when wedge is raised
104390
105578
 
104391
105579
  METHODS
104392
105580
  clone() - returns a clone of the PieChart
104393
105581
  getIndex(x, y) - returns the pie wedge index at the given local coordinates
104394
105582
  raiseWedge(index, factor) - raises a wedge by the specified factor
104395
105583
  lowerWedge(index) - lowers the raised wedge(s) back to flat
104396
- setChart(obj) - ***** redraws chart with new data or configuration
105584
+ setChart(obj) - redraws chart with new data or configuration
104397
105585
 
104398
105586
  PROPERTIES
104399
105587
  index - the currently selected wedge index from mouse click
104400
105588
  rollIndex - the wedge index currently under the mouse
104401
105589
  angles - array of angle values for each wedge
105590
+ angleWedges - array of start and stop angles, the two labelOnArc objects, and the icon holder container
104402
105591
  info - info labels array
104403
105592
  data - data values array
104404
105593
  title - title label
@@ -105063,7 +106252,7 @@ for (z_i = 0; z_i < globalFunctions.length; z_i++) {
105063
106252
  ["FILL", zim.FILL],
105064
106253
  ["FULL", zim.FULL],
105065
106254
  ["LEFT", zim.LEFT],
105066
- ["RIGHT", zim.RIGHT],
106255
+ ["RIGHT", zim.RIGHT],s
105067
106256
  ["CENTER", zim.CENTER],
105068
106257
  ["MIDDLE", zim.MIDDLE],
105069
106258
  ["JUSTIFY", zim.JUSTIFY],
@@ -105170,6 +106359,7 @@ export let extend = zim.extend;
105170
106359
  export let copy = zim.copy;
105171
106360
  export let merge = zim.merge;
105172
106361
  export let sortObject = zim.sortObject;
106362
+ export let orderContainer = zim.orderContainer;
105173
106363
  export let arraysEqual = zim.arraysEqual;
105174
106364
  export let arrayMinMax = zim.arrayMinMax;
105175
106365
  export let isEmpty = zim.isEmpty;
@@ -105431,6 +106621,7 @@ export let Vid = zim.Vid;
105431
106621
  export let Dat = zim.Dat;
105432
106622
  export let SVG = zim.SVG;
105433
106623
  export let Speech = zim.Speech;
106624
+ export let Hardware = zim.Hardware;
105434
106625
  export let PermissionAsk = zim.PermissionAsk;
105435
106626
  export let Monitor = zim.Monitor;
105436
106627
  export let distill = zim.distill;