zimjs 19.1.6 → 20.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/zim.js CHANGED
@@ -55,11 +55,11 @@ var z_i; // iterator i in global namespace
55
55
  // We then introduced ZIM Distill (tree-shaking) as a more efficient way to reduce code
56
56
  // but we have kept the modules as follows:
57
57
 
58
- // WRAP, CODE, DISPLAY, METHODS, CONTROLS, FRAME, META, and docs only: GAME, THREE, SOCKET, CAM, PIZZAZZ
58
+ // WRAP, CODE, DISPLAY, METHODS, CONTROLS, FRAME, META, and docs only: GAME, THREE, SOCKET, CAM, PIZZAZZ, CHART
59
59
  // You can text search a bunch of ////... to get to these.
60
60
 
61
61
  // The docs also have these modules but ordered differently
62
- // FRAME, DISPLAY, METHODS, CONTROLS, CODE, WRAP, META, GAME, THREE, SOCKET, PIZZAZZ.
62
+ // FRAME, DISPLAY, METHODS, CONTROLS, CODE, WRAP, META, GAME, THREE, SOCKET, PIZZAZZ, CHART.
63
63
  // Each entry in the Docs has a VIEW button at the bottom
64
64
  // that will nicely display the code for that entry - from this document.
65
65
  // So... there is perhaps, little need to be here ;-).
@@ -4499,7 +4499,7 @@ NOTE: as of ZIM 5.5.0 the zim namespace is no longer required (unless zns is set
4499
4499
 
4500
4500
  EXAMPLE
4501
4501
  const id1 = makeID(); // five random letters and numbers (starts with letter)
4502
- const id2 = makeID("strings"); // five random uppercase letters
4502
+ const id2 = makeID("letters"); // five random uppercase letters
4503
4503
  const id3 = makeID("numbers", 10); // ten random numbers
4504
4504
  const id4 = makeID(["Z", "I", "M", 1, 2, 3, 4, 5, "-"], 5); // random five characters from array (possibly repeating)
4505
4505
  END EXAMPLE
@@ -23479,7 +23479,7 @@ rollColor - (default color) the rollover color of the font
23479
23479
  shadowColor - (default -1) for no shadow - set to any css color to see
23480
23480
  shadowBlur - (default 14) if shadow is present
23481
23481
  align - ((default LEFT) text registration point alignment also CENTER/MIDDLE and RIGHT
23482
- set to START to align LEFT for ZIM DIR constant is "ltr" or RIGHT when DIR="rtl" - END is the opposite
23482
+ set to START to align LEFT when ZIM DIR constant is "ltr" or RIGHT when DIR="rtl" - END is the opposite
23483
23483
  valign - (default TOP) vertical registration point alignment alse CENTER/MIDDLE, BOTTOM
23484
23484
  bold - (default false) set the font to bold - note: fontOptions has been removed as of ZIM Cat
23485
23485
  italic - (default false) set the font to italic - note: fontOptions has been removed as of ZIM Cat
@@ -24625,6 +24625,7 @@ letterHeight - get the height of letters
24625
24625
  color - get or set the text color
24626
24626
  circle - access to the circle object
24627
24627
  arc - access to the arc object
24628
+ angle - the angle the letters make
24628
24629
  angles - access to the array angles for letter positioning
24629
24630
  use angles.toString() to log angle data (for kerning)
24630
24631
  this can be modified and passed in as an angles property to start
@@ -24691,7 +24692,6 @@ zim.LabelOnArc = function(label, size, font, color, radius, flip, spacing, lette
24691
24692
  var rev = label.text.split("").reverse().join("");
24692
24693
  label.text = rev;
24693
24694
  }
24694
- zog(that.width, that.height)
24695
24695
  letters = that.letters = new zim.Container(100,100).center(that);
24696
24696
 
24697
24697
  that.numLetters = label.text.length;
@@ -24745,6 +24745,7 @@ zim.LabelOnArc = function(label, size, font, color, radius, flip, spacing, lette
24745
24745
  else if (zot(arcBorderWidth) && !zot(arcBorderColor)) arcBorderWidth = 2;
24746
24746
  arc.graphics.c().f(null).s(arcBorderColor).ss(arcBorderWidth).arc(0,0,radius, (that.startAngle-90)*Math.PI/180, (that.startAngle-90+totalAngle)*Math.PI/180);
24747
24747
  }
24748
+ that.angle = totalAngle;
24748
24749
  }
24749
24750
 
24750
24751
  function makeAngles() {
@@ -28987,8 +28988,8 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
28987
28988
 
28988
28989
  var accessibilityClicker;
28989
28990
  this.show = function(call, params) {
28990
- if (!zot(call)) that.closeCall = call;
28991
- if (!zot(params)) that.closeParams = params;
28991
+ that.closeCall = call;
28992
+ that.closeParams = params;
28992
28993
  if (center) {
28993
28994
  if (isNaN(that.resetX)) {
28994
28995
  that.x = (that.container.getBounds().width) /2;
@@ -29064,7 +29065,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
29064
29065
  //-58
29065
29066
 
29066
29067
  /*--
29067
- zim.Panel = function(width, height, content, titleBar, titleBarColor, titleBarBackgroundColor, titleBarHeight, backgroundColor, borderColor, borderWidth, corner, close, closeColor, next, nextColor, extraButton, collapse, collapseColor, collapsed, align, shadowColor, shadowBlur, draggable, boundary, style, group, inherit)
29068
+ zim.Panel = function(width, height, content, titleBar, titleBarColor, titleBarBackgroundColor, titleBarHeight, backgroundColor, borderColor, borderWidth, corner, close, closeColor, next, nextColor, extraButton, collapse, collapseColor, collapsed, align, shadowColor, shadowBlur, draggable, boundary, onTop, style, group, inherit)
29068
29069
 
29069
29070
  Panel
29070
29071
  zim class - extends a zim.Container which extends a createjs.Container
@@ -29190,6 +29191,7 @@ shadowColor - (default "rgba(0,0,0,.3)" if shadowBlur) the shadow color - set to
29190
29191
  shadowBlur - (default 14 if shadowColor) the shadow blur - set to -1 for no shadow
29191
29192
  draggable - (default true if titleBar) set to false to not allow dragging titleBar to drag window
29192
29193
  boundary - (default null) set to ZIM Boundary() object - or CreateJS.rectangle()
29194
+ onTop - (default true) set to false to not bring to top if dragging
29193
29195
  style - (default true) set to false to ignore styles set with the STYLE - will receive original parameter defaults
29194
29196
  group - (default null) set to String (or comma delimited String) so STYLE can set default styles to the group(s) (like a CSS class)
29195
29197
  inherit - (default null) used internally but can receive an {} of styles directly
@@ -29267,8 +29269,8 @@ dispatches a "expand" event if expanding after being collapsed
29267
29269
  ALSO: see the CreateJS Easel Docs for Container events such as:
29268
29270
  added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmove, pressup, removed, rollout, rollover
29269
29271
  --*///+57.7
29270
- zim.Panel = function(width, height, content, titleBar, titleBarColor, titleBarBackgroundColor, titleBarHeight, backgroundColor, borderColor, borderWidth, corner, close, closeColor, next, nextColor, extraButton, collapse, collapseColor, collapsed, align, shadowColor, shadowBlur, draggable, boundary, style, group, inherit) {
29271
- var sig = "width, height, content, titleBar, titleBarColor, titleBarBackgroundColor, titleBarHeight, backgroundColor, borderColor, borderWidth, corner, close, closeColor, next, nextColor, extraButton, collapse, collapseColor, collapsed, align, shadowColor, shadowBlur, draggable, boundary, style, group, inherit";
29272
+ zim.Panel = function(width, height, content, titleBar, titleBarColor, titleBarBackgroundColor, titleBarHeight, backgroundColor, borderColor, borderWidth, corner, close, closeColor, next, nextColor, extraButton, collapse, collapseColor, collapsed, align, shadowColor, shadowBlur, draggable, boundary, onTop, style, group, inherit) {
29273
+ var sig = "width, height, content, titleBar, titleBarColor, titleBarBackgroundColor, titleBarHeight, backgroundColor, borderColor, borderWidth, corner, close, closeColor, next, nextColor, extraButton, collapse, collapseColor, collapsed, align, shadowColor, shadowBlur, draggable, boundary, onTop, style, group, inherit";
29272
29274
  var duo; if (duo = zob(zim.Panel, arguments, sig, this)) return duo;
29273
29275
  z_d("57.7");
29274
29276
 
@@ -29307,6 +29309,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
29307
29309
  if (zot(collapse)) collapse=DS.collapse!=null?DS.collapse:false;
29308
29310
  if (zot(collapseColor)) collapseColor = DS.collapseColor != null ? DS.collapseColor:!zot(titleBarColor)?titleBarColor:zim.grey;
29309
29311
  if (zot(collapsed)) collapsed=DS.collapsed!=null?DS.collapsed:false;
29312
+ if (zot(onTop)) onTop=DS.onTop!=null?DS.onTop:true;
29310
29313
 
29311
29314
  var that = this;
29312
29315
 
@@ -29412,7 +29415,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
29412
29415
  if (draggable) {
29413
29416
  titleBar.cur("pointer");
29414
29417
  titleBar.on("mousedown", function() {
29415
- that.drag({rect:boundary, currentTarget:true});
29418
+ that.drag({rect:boundary, currentTarget:true, onTop:onTop});
29416
29419
  var ch,i;
29417
29420
  var tar = that.content||that.contentContainer||that;
29418
29421
  if (tar.type != "Container") tar = that.contentContainer||that;
@@ -29591,7 +29594,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
29591
29594
  if (style !== false) zim.styleTransforms(this, DS);
29592
29595
 
29593
29596
  this.clone = function () {
29594
- return that.cloneProps(new zim.Panel(width, height, content, titleBar ? titleBar.text : null, titleBarColor, titleBarBackgroundColor, titleBarHeight, backgroundColor, borderColor, borderWidth, corner, close, closeColor, next, nextColor, extraButton, collapse, collapseColor, that.collapsed, align, shadowColor, shadowBlur, draggable, boundary, style, this.group, inherit));
29597
+ return that.cloneProps(new zim.Panel(width, height, content, titleBar ? titleBar.text : null, titleBarColor, titleBarBackgroundColor, titleBarHeight, backgroundColor, borderColor, borderWidth, corner, close, closeColor, next, nextColor, extraButton, collapse, collapseColor, that.collapsed, align, shadowColor, shadowBlur, draggable, boundary, onTop, style, this.group, inherit));
29595
29598
  };
29596
29599
  this.doDispose = function(a,b,disposing) {
29597
29600
  // need to dispose properly for Panel
@@ -41362,7 +41365,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
41362
41365
  //-66
41363
41366
 
41364
41367
  /*--
41365
- zim.NumPad = function(advanced, titleBar, titleBarColor, titleBarBackgroundColor, titleBarHeight, backgroundColor, borderColor, borderWidth, corner, numberCorner, close, closeColor, collapse, collapseColor, collapsed, align, shadowColor, shadowBlur, draggable, boundary, style, group, inherit)
41368
+ zim.NumPad = function(advanced, titleBar, titleBarColor, titleBarBackgroundColor, titleBarHeight, backgroundColor, borderColor, borderWidth, corner, numberCorner, close, closeColor, collapse, collapseColor, collapsed, align, shadowColor, shadowBlur, draggable, boundary, onTop, style, group, inherit)
41366
41369
 
41367
41370
  NumPad
41368
41371
  zim class - extends a zim.Panel which extends a zim.Container which extends a createjs.Container
@@ -41420,6 +41423,7 @@ shadowColor - (default "rgba(0,0,0,.3)" if shadowBlur) the shadow color - set to
41420
41423
  shadowBlur - (default 14 if shadowColor) the shadow blur - set to -1 for no shadow
41421
41424
  draggable - (default true if titleBar) set to false to not allow dragging titleBar to drag window
41422
41425
  boundary - (default null) set to ZIM Boundary() object - or CreateJS.rectangle()
41426
+ onTop - (default true) set to false to not bring to top if dragging
41423
41427
  style - (default true) set to false to ignore styles set with the STYLE - will receive original parameter defaults
41424
41428
  group - (default null) set to String (or comma delimited String) so STYLE can set default styles to the group(s) (like a CSS class)
41425
41429
  inherit - (default null) used internally but can receive an {} of styles directly
@@ -41459,8 +41463,8 @@ dispatches a "expand" event if expanding after being collapsed
41459
41463
  ALSO: see the CreateJS Easel Docs for Container events such as:
41460
41464
  added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmove, pressup, removed, rollout, rollover
41461
41465
  --*///+57.7
41462
- zim.NumPad = function(advanced, titleBar, titleBarColor, titleBarBackgroundColor, titleBarHeight, backgroundColor, borderColor, borderWidth, corner, numberCorner, close, closeColor, collapse, collapseColor, collapsed, align, shadowColor, shadowBlur, draggable, boundary, style, group, inherit) {
41463
- var sig = "advanced, titleBar, titleBarColor, titleBarBackgroundColor, titleBarHeight, backgroundColor, borderColor, borderWidth, corner, numberCorner, close, closeColor, collapse, collapseColor, collapsed, align, shadowColor, shadowBlur, draggable, boundary, style, group, inherit";
41466
+ zim.NumPad = function(advanced, titleBar, titleBarColor, titleBarBackgroundColor, titleBarHeight, backgroundColor, borderColor, borderWidth, corner, numberCorner, close, closeColor, collapse, collapseColor, collapsed, align, shadowColor, shadowBlur, draggable, boundary, onTop, style, group, inherit) {
41467
+ var sig = "advanced, titleBar, titleBarColor, titleBarBackgroundColor, titleBarHeight, backgroundColor, borderColor, borderWidth, corner, numberCorner, close, closeColor, collapse, collapseColor, collapsed, align, shadowColor, shadowBlur, draggable, boundary, onTop, style, group, inherit";
41464
41468
  var duo; if (duo = zob(zim.NumPad, arguments, sig, this)) return duo;
41465
41469
  z_d("57.7");
41466
41470
 
@@ -41491,8 +41495,10 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
41491
41495
  if (zot(collapse)) collapse=DS.collapse!=null?DS.collapse:true;
41492
41496
  if (zot(collapseColor)) collapseColor = DS.collapseColor!=null?DS.collapseColor:!zot(titleBarColor)?titleBarColor:zim.grey;
41493
41497
  if (zot(collapsed)) collapsed=DS.collapsed!=null?DS.collapsed:false;
41498
+ if (zot(onTop)) onTop=DS.onTop!=null?DS.onTop:true;
41494
41499
 
41495
- this.zimPanel_constructor(width, height, null, titleBar, titleBarColor, titleBarBackgroundColor, titleBarHeight, backgroundColor, borderColor, borderWidth, corner, close, closeColor, null, null, null, collapse, collapseColor, collapsed, align, shadowColor, shadowBlur, draggable, boundary, style, group, inherit);
41500
+
41501
+ this.zimPanel_constructor(width, height, null, titleBar, titleBarColor, titleBarBackgroundColor, titleBarHeight, backgroundColor, borderColor, borderWidth, corner, close, closeColor, null, null, null, collapse, collapseColor, collapsed, align, shadowColor, shadowBlur, draggable, boundary, onTop, style, group, inherit);
41496
41502
  this.type = "NumPad";
41497
41503
 
41498
41504
  // MONITOR
@@ -41554,7 +41560,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
41554
41560
 
41555
41561
  if (style!==false) zim.styleTransforms(this, DS);
41556
41562
  this.clone = function () {
41557
- return that.cloneProps(new zim.NumPad(advanced, that.titleBar ? titleBar.text : null, titleBarColor, titleBarBackgroundColor, titleBarHeight, backgroundColor, borderColor, borderWidth, corner, numberCorner, close, closeColor, collapse, collapseColor, that.collapsed, align, shadowColor, shadowBlur, draggable, boundary, style, this.group, inherit));
41563
+ return that.cloneProps(new zim.NumPad(advanced, that.titleBar ? titleBar.text : null, titleBarColor, titleBarBackgroundColor, titleBarHeight, backgroundColor, borderColor, borderWidth, corner, numberCorner, close, closeColor, collapse, collapseColor, that.collapsed, align, shadowColor, shadowBlur, draggable, boundary, onTop, style, this.group, inherit));
41558
41564
  };
41559
41565
  };
41560
41566
  zim.extend(zim.NumPad, zim.Panel, ["clone"], "zimPanel", false);
@@ -44159,7 +44165,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
44159
44165
  }
44160
44166
  }
44161
44167
 
44162
- this.zimPanel_constructor(width, 300, null, titleBar, titleBarColor, titleBarBackgroundColor, titleBarHeight, backgroundColor, borderColor, borderWidth, corner, true, null, null, null, null, null, null, null, null, shadowColor, shadowBlur, draggable, boundary, style, group, inherit);
44168
+ this.zimPanel_constructor(width, 300, null, titleBar, titleBarColor, titleBarBackgroundColor, titleBarHeight, backgroundColor, borderColor, borderWidth, corner, true, null, null, null, null, null, null, null, null, shadowColor, shadowBlur, draggable, boundary, true, style, group, inherit);
44163
44169
 
44164
44170
  this.type = "TextEditor";
44165
44171
 
@@ -56282,9 +56288,14 @@ DESCRIPTION
56282
56288
  Sets multi-touch pan, pinch and rotate for position, scale and rotation
56283
56289
  Handles scaled and rotated containers
56284
56290
  Scale and rotation occur from the pinch point (with optional regControl for about the registration point)
56285
- Note - gesture() only works on the currentTarget - not a container's children (like drag() can)
56286
- ZIM Frame should have touch set to true (which is the default for mobile)
56291
+
56292
+ NOTE: gesture() only works on the currentTarget - not a container's children (like drag() can)
56293
+ ZIM Frame should have touch set to true (which is the default for mobile)
56294
+
56295
+ NOTE: as of ZIM 020 - trackpad support has been added - pinch to zoom, swipe both fingers horizontally for rotate
56296
+
56287
56297
  ALSO: see the noGesture() method to remove some or all gestures
56298
+
56288
56299
  ALSO: see the gestureBoundary() method to set or reset the boundary rectangle dynamically
56289
56300
 
56290
56301
  EXAMPLE
@@ -56320,6 +56331,9 @@ surround - (default false) is for dragging a big object that always surrounds th
56320
56331
  circularBounds - (default false) set to true if object is circular with center registration
56321
56332
  set to true to use radius to calculate rotated object in boundary if boundary is set
56322
56333
  rect - (depreciated) same as boundary - kept for backwards compatibility
56334
+ trackPad - (default true) set to false to not handle trackpad on laptop
56335
+ trackpad supports pinch for zoom
56336
+ trackpad supports swipe horizontally with both fingers (the same way) for rotate
56323
56337
 
56324
56338
  EVENTS
56325
56339
  Adds move, scale and rotate events to obj (when associated gesture parameters are set to true)
@@ -56327,417 +56341,736 @@ If slide is true, obj dispatches a "slidestop" event when sliding stops
56327
56341
 
56328
56342
  RETURNS obj for chaining
56329
56343
  --*///+34.5
56330
- zim.gesture = function(obj, move, scale, rotate, boundary, minScale, maxScale, snapRotate, localBoundary, slide, slideFactor, regControl, onTop, surround, circularBounds, rect) {
56331
- var sig = "obj, move, scale, rotate, boundary, minScale, maxScale, snapRotate, localBoundary, slide, slideFactor, regControl, onTop, surround, circularBounds, rect";
56332
- var duo; if (duo = zob(zim.gesture, arguments, sig)) return duo;
56333
- if (obj.type=="AC"&&WW.zdf) {WW.zdf.ac("gesture", arguments); return obj;}
56334
- z_d("34.5");
56335
-
56336
- // MONITOR
56337
- var mID = "z~gesture";
56338
- if (obj && obj.mID && ((obj.mID[2] && obj.mID[2]=="-") || obj.mID[0]=="-")) mID = "z~-";
56339
-
56340
- if (zot(obj) || !obj.on) return;
56341
- if (zot(move)) move = true;
56342
- if (zot(scale)) scale = true;
56343
- if (zot(rotate)) rotate = true;
56344
- if (zot(localBoundary)) localBoundary = false;
56345
- if (zot(snapRotate)) snapRotate = 1;
56346
- if (zot(slide)) slide = false;
56347
- if (zot(slideFactor)) slideFactor = 5;
56348
- if (zot(regControl)) regControl = false;
56349
- if (zot(onTop)) onTop = true;
56350
- if (zot(surround)) surround = false;
56351
- if (surround && rotate) {
56352
- surround = rect = null;
56353
- if (zon) zogy("gesture() - does not support surround when rotate is true");
56354
- }
56355
- if (zot(circularBounds)) circularBounds = false;
56356
- if (zot(boundary) && !zot(rect)) boundary = rect;
56344
+ zim.gesture = function(obj, move, scale, rotate, boundary, minScale, maxScale, snapRotate, localBoundary, slide, slideFactor, regControl, onTop, surround, circularBounds, rect, trackpad) {
56345
+ var sig = "obj, move, scale, rotate, boundary, minScale, maxScale, snapRotate, localBoundary, slide, slideFactor, regControl, onTop, surround, circularBounds, rect, trackpad";
56346
+ var duo; if (duo = zob(zim.gesture, arguments, sig)) return duo;
56347
+ if (obj.type=="AC"&&WW.zdf) {WW.zdf.ac("gesture", arguments); return obj;}
56348
+ z_d("34.5");
56357
56349
 
56358
- var slideData;
56359
- var slideCount;
56360
- var slideSlice;
56361
- var slideTotal;
56350
+ // MONITOR
56351
+ var mID = "z~gesture";
56352
+ if (obj && obj.mID && ((obj.mID[2] && obj.mID[2]=="-") || obj.mID[0]=="-")) mID = "z~-";
56362
56353
 
56354
+ if (zot(obj) || !obj.on) return;
56355
+ if (zot(move)) move = true;
56356
+ if (zot(scale)) scale = true;
56357
+ if (zot(rotate)) rotate = true;
56358
+ if (zot(localBoundary)) localBoundary = false;
56359
+ if (zot(snapRotate)) snapRotate = 1;
56360
+ if (zot(slide)) slide = false;
56361
+ if (zot(slideFactor)) slideFactor = 5;
56362
+ if (zot(regControl)) regControl = false;
56363
+ if (zot(onTop)) onTop = true;
56364
+ if (zot(surround)) surround = false;
56365
+ if (surround && rotate) {
56366
+ surround = rect = null;
56367
+ if (zon) zogy("gesture() - does not support surround when rotate is true");
56368
+ }
56369
+ if (zot(circularBounds)) circularBounds = false;
56370
+ if (zot(boundary) && !zot(rect)) boundary = rect;
56371
+ if (zot(trackpad)) trackpad = true;
56363
56372
 
56364
- var timeType = getTIME();
56373
+ var slideData;
56374
+ var slideCount;
56375
+ var slideSlice;
56376
+ var slideTotal;
56365
56377
 
56366
- // HANDLE MASK if there is one
56367
- if (!zot(obj.zimMaskDynamic)) obj.zimMaskApply(); // set mask set by zimMask to dynamic
56368
56378
 
56369
- if (!obj.zimTouch) {
56379
+ var timeType = getTIME();
56370
56380
 
56371
- var dampScaleX = new zim.Damp(obj.scaleX, .05);
56372
- var dampScaleY = new zim.Damp(obj.scaleY, .05);
56373
- var scaleRatio = obj.scaleX/obj.scaleY;
56381
+ // HANDLE MASK if there is one
56382
+ if (!zot(obj.zimMaskDynamic)) obj.zimMaskApply(); // set mask set by zimMask to dynamic
56374
56383
 
56375
- obj.zimTouch = {
56376
- move:move, // store settings on object to control with noGesture()
56377
- scale:scale,
56378
- rotate:rotate,
56379
- pointers:{}, // holds the current pointer data
56380
- checkBounds:function(x, y) { // used locally and by zim.gestureBoundary
56381
- if (obj.zimTouch.boundary) {
56382
- var boundary = obj.zimTouch.boundary;
56383
- // convert the desired drag position to a global point
56384
- // note that we want the position of the object in its parent
56385
- // so we use the parent as the local frame
56386
- var point = obj.parent.localToLocal(x,y,obj.parent);
56387
- // boundary is the boundary rectangle on the global stage
56388
- // boundary is set during mousedown to allow for global scaling when in localBoundary mode
56389
- // if you scale in localBoundary==false mode, you will need to reset bounds with dragBoundary()
56390
- if (surround) {
56391
- x = Math.min(boundary.x, Math.max(boundary.x+boundary.width, point.x));
56392
- y = Math.min(boundary.y, Math.max(boundary.y+boundary.height, point.y));
56393
- } else {
56394
- x = Math.max(boundary.x, Math.min(boundary.x+boundary.width, point.x));
56395
- y = Math.max(boundary.y, Math.min(boundary.y+boundary.height, point.y));
56396
- }
56397
- // now that the point has been checked on the global scale
56398
- // convert the point back to the obj parent frame of reference
56399
- point = obj.parent.globalToLocal(x, y);
56400
- x = point.x;
56401
- y = point.y;
56384
+ if (!obj.zimTouch) {
56385
+
56386
+ var dampScaleX = new zim.Damp(obj.scaleX, .05);
56387
+ var dampScaleY = new zim.Damp(obj.scaleY, .05);
56388
+ var scaleRatio = obj.scaleX/obj.scaleY;
56389
+
56390
+ obj.zimTouch = {
56391
+ move:move, // store settings on object to control with noGesture()
56392
+ scale:scale,
56393
+ rotate:rotate,
56394
+ pointers:{}, // holds the current pointer data
56395
+ checkBounds:function(x, y) { // used locally and by zim.gestureBoundary
56396
+ if (obj.zimTouch.boundary) {
56397
+ var boundary = obj.zimTouch.boundary;
56398
+ // convert the desired drag position to a global point
56399
+ // note that we want the position of the object in its parent
56400
+ // so we use the parent as the local frame
56401
+ var point = obj.parent.localToLocal(x,y,obj.parent);
56402
+ // boundary is the boundary rectangle on the global stage
56403
+ // boundary is set during mousedown to allow for global scaling when in localBoundary mode
56404
+ // if you scale in localBoundary==false mode, you will need to reset bounds with dragBoundary()
56405
+ if (surround) {
56406
+ x = Math.min(boundary.x, Math.max(boundary.x+boundary.width, point.x));
56407
+ y = Math.min(boundary.y, Math.max(boundary.y+boundary.height, point.y));
56408
+ } else {
56409
+ x = Math.max(boundary.x, Math.min(boundary.x+boundary.width, point.x));
56410
+ y = Math.max(boundary.y, Math.min(boundary.y+boundary.height, point.y));
56402
56411
  }
56403
- return {x:x,y:y};
56412
+ // now that the point has been checked on the global scale
56413
+ // convert the point back to the obj parent frame of reference
56414
+ point = obj.parent.globalToLocal(x, y);
56415
+ x = point.x;
56416
+ y = point.y;
56404
56417
  }
56405
- };
56406
-
56407
- if (boundary) {
56408
- obj.zimTouch.boundary = boundary;
56409
- if (localBoundary) obj.zimTouch.boundary = zim.boundsToGlobal(obj.parent, boundary);
56410
- obj.zimTouch.boundaryStartX = obj.zimTouch.boundary.x;
56411
- obj.zimTouch.boundaryStartY = obj.zimTouch.boundary.y;
56412
- obj.zimTouch.boundaryStartW = obj.zimTouch.boundary.width;
56413
- obj.zimTouch.boundaryStartH = obj.zimTouch.boundary.height;
56414
- var result = obj.zimTouch.checkBounds(obj.x, obj.y); // set in bounds to start
56415
- obj.x = result.x;
56416
- obj.y = result.y;
56418
+ return {x:x,y:y};
56417
56419
  }
56420
+ };
56418
56421
 
56419
- if (slide) {
56420
- slideSlice = 10;
56421
- slideTotal = 5;
56422
- slideCount = 0;
56423
- slideData = [];
56424
-
56425
- obj.zimTouch.slideInterval = zim.interval(slideSlice/(timeType=="s"?1000:1),function() {
56426
- slideData[slideCount++%slideTotal] = [obj.x, obj.y];
56427
- }, null, null, null, null, null, null, null, mID, obj);
56428
- obj.zimTouch.slideInterval.pause();
56429
- obj.animate({x:obj.x, y:obj.y}, 10/(timeType=="s"?1000:1), "quadOut"); // for some reason, first throw is smoother if already animated
56430
- }
56431
-
56432
- var matrixStart;
56433
- var startScaleX;
56434
- var startScaleY;
56435
- var startRotation;
56436
- var startRegX;
56437
- var startRegY;
56438
- var lastPoint;
56439
- var maxTouches;
56440
-
56441
- obj.zimTouch.mousedown = obj.on("mousedown", function(e) {
56442
- if (zot(maxTouches)) maxTouches = 1;
56443
- else maxTouches++;
56444
-
56445
- if (onTop) {
56446
- var nc = obj.parent.numChildren-1;
56447
- if (obj.parent.getChildAt(nc).type=="Keyboard") nc--;
56448
- obj.parent.setChildIndex(obj,nc);
56449
- if (obj.ZIMoutlineShape) obj.outline();
56450
- }
56451
- if (!regControl) {
56452
- lastPoint = null;
56453
- startScaleX = obj.scaleX;
56454
- startScaleY = obj.scaleY;
56455
- startRotation = obj.rotation;
56456
- startRegX = obj.regX;
56457
- startRegY = obj.regY;
56458
- obj.reg(0,0);
56459
- matrixStart = obj.getMatrix();
56460
- obj.regX = startRegX;
56461
- obj.regY = startRegY;
56462
- }
56463
-
56464
- var id = "id"+Math.abs(e.pointerID+1); // some pointers have negative ids
56465
- // convert all pointer x and y to the parent container of the obj
56466
- var local = obj.parent.globalToLocal(e.stageX/zim.scaX, e.stageY/zim.scaY);
56467
- // we compare current pointer to start pointer (rather than increment as we go)
56468
- obj.zimTouch.pointers[id] = {
56469
- startX:local.x, startY:local.y,
56470
- x:local.x, y:local.y
56471
- };
56472
- if (obj.zimTouch.move || obj.zimTouch.rotate) {
56473
- obj.zimTouch.total = 0;
56474
- zim.loop(obj.zimTouch.pointers, function() {
56475
- obj.zimTouch.total++;
56476
- });
56477
- }
56478
- if (slide && obj.zimTouch.total == 1) obj.zimTouch.slideInterval.pause(false);
56479
- setTouches();
56480
- }, null, null, null, null, mID);
56422
+ if (boundary) {
56423
+ obj.zimTouch.boundary = boundary;
56424
+ if (localBoundary) obj.zimTouch.boundary = zim.boundsToGlobal(obj.parent, boundary);
56425
+ obj.zimTouch.boundaryStartX = obj.zimTouch.boundary.x;
56426
+ obj.zimTouch.boundaryStartY = obj.zimTouch.boundary.y;
56427
+ obj.zimTouch.boundaryStartW = obj.zimTouch.boundary.width;
56428
+ obj.zimTouch.boundaryStartH = obj.zimTouch.boundary.height;
56429
+ var result = obj.zimTouch.checkBounds(obj.x, obj.y); // set in bounds to start
56430
+ obj.x = result.x;
56431
+ obj.y = result.y;
56432
+ }
56481
56433
 
56482
- obj.zimTouch.pressmove = obj.on("pressmove", function(e) {
56434
+ if (slide) {
56435
+ slideSlice = 10;
56436
+ slideTotal = 5;
56437
+ slideCount = 0;
56438
+ slideData = [];
56439
+
56440
+ obj.zimTouch.slideInterval = zim.interval(slideSlice/(timeType=="s"?1000:1),function() {
56441
+ slideData[slideCount++%slideTotal] = [obj.x, obj.y];
56442
+ }, null, null, null, null, null, null, null, mID, obj);
56443
+ obj.zimTouch.slideInterval.pause();
56444
+ obj.animate({x:obj.x, y:obj.y}, 10/(timeType=="s"?1000:1), "quadOut"); // for some reason, first throw is smoother if already animated
56445
+ }
56446
+
56447
+ var matrixStart;
56448
+ var startScaleX;
56449
+ var startScaleY;
56450
+ var startRotation;
56451
+ var startRegX;
56452
+ var startRegY;
56453
+ var lastPoint;
56454
+ var maxTouches;
56455
+
56456
+ obj.zimTouch.mousedown = obj.on("mousedown", function(e) {
56457
+ if (zot(maxTouches)) maxTouches = 1;
56458
+ else maxTouches++;
56483
56459
 
56484
- var id = "id"+Math.abs(e.pointerID+1);
56485
- var local = obj.parent.globalToLocal(e.stageX/zim.scaX, e.stageY/zim.scaY);
56486
- // update our pointer data with new x and y
56487
- if (obj.zimTouch.pointers[id]) {
56488
- obj.zimTouch.pointers[id].x = local.x;
56489
- obj.zimTouch.pointers[id].y = local.y;
56490
- }
56491
-
56492
- // average the pointers' movement
56493
- var newX = 0;
56494
- var newY = 0;
56495
- var aveX = 0; // point about which to scale and rotate
56496
- var aveY = 0;
56497
- var deltaX = 0;
56498
- var deltaY = 0;
56499
- zim.loop(obj.zimTouch.pointers, function(id, pointer) {
56500
- newX += pointer.x - pointer.startX;
56501
- newY += pointer.y - pointer.startY;
56502
- aveX += pointer.x;
56503
- aveY += pointer.y;
56460
+ if (onTop) {
56461
+ var nc = obj.parent.numChildren-1;
56462
+ if (obj.parent.getChildAt(nc).type=="Keyboard") nc--;
56463
+ obj.parent.setChildIndex(obj,nc);
56464
+ if (obj.ZIMoutlineShape) obj.outline();
56465
+ }
56466
+ if (!regControl) {
56467
+ lastPoint = null;
56468
+ startScaleX = obj.scaleX;
56469
+ startScaleY = obj.scaleY;
56470
+ startRotation = obj.rotation;
56471
+ startRegX = obj.regX;
56472
+ startRegY = obj.regY;
56473
+ obj.reg(0,0);
56474
+ matrixStart = obj.getMatrix();
56475
+ obj.regX = startRegX;
56476
+ obj.regY = startRegY;
56477
+ }
56478
+
56479
+ var id = "id"+Math.abs(e.pointerID+1); // some pointers have negative ids
56480
+ // convert all pointer x and y to the parent container of the obj
56481
+ var local = obj.parent.globalToLocal(e.stageX/zim.scaX, e.stageY/zim.scaY);
56482
+ // we compare current pointer to start pointer (rather than increment as we go)
56483
+ obj.zimTouch.pointers[id] = {
56484
+ startX:local.x, startY:local.y,
56485
+ x:local.x, y:local.y
56486
+ };
56487
+ if (obj.zimTouch.move || obj.zimTouch.rotate) {
56488
+ obj.zimTouch.total = 0;
56489
+ zim.loop(obj.zimTouch.pointers, function() {
56490
+ obj.zimTouch.total++;
56504
56491
  });
56505
- if (obj.zimTouch.total == 0) return;
56506
- deltaX = newX / obj.zimTouch.total;
56507
- deltaY = newY / obj.zimTouch.total;
56508
- newX = obj.zimTouch.startX + deltaX;
56509
- newY = obj.zimTouch.startY + deltaY;
56510
- aveX = aveX / obj.zimTouch.total;
56511
- aveY = aveY / obj.zimTouch.total;
56512
-
56513
- var proxy = {
56514
- x: obj.x,
56515
- y: obj.y,
56516
- scaleX:obj.scaleX,
56517
- scaleY:obj.scaleY,
56518
- rotation:obj.rotation
56519
- }; // will store desired scale and rotation on this object then apply matrix calculations
56520
-
56521
- if (obj.zimTouch.move) {
56522
- var result = obj.zimTouch.checkBounds(newX, newY); // es6 opportunity
56523
- proxy.x = result.x;
56524
- proxy.y = result.y;
56525
- }
56526
-
56527
- // if we have multitouch as determined by setTouches()
56528
- if (obj.zimTouch.pair.length == 2) {
56529
- var point1 = obj.zimTouch.pair[0];
56530
- var point2 = obj.zimTouch.pair[1];
56531
- if (obj.zimTouch.scale) {
56532
- // use ratio of distance between fingers to start and then current distance between fingers
56533
- var startDistance = Math.sqrt(Math.pow((point2.startX-point1.startX),2) + Math.pow((point2.startY-point1.startY),2));
56534
- var currentDistance = Math.sqrt(Math.pow((point2.x-point1.x),2) + Math.pow((point2.y-point1.y),2));
56535
- var newScaleX = obj.zimTouch.startSX + (currentDistance / startDistance - 1);
56536
- var newScaleY = obj.zimTouch.startSY + (currentDistance / startDistance - 1);
56537
- proxy.scaleX = newScaleX;
56538
- proxy.scaleY = newScaleY;
56539
-
56540
- proxy.scaleX = dampScaleX.convert(newScaleX);
56541
- proxy.scaleY = dampScaleY.convert(newScaleY);
56542
-
56543
- // set to scale min or max if scale would be outside range
56544
- var minBad = (!zot(minScale) && Math.min(newScaleX, newScaleY) < minScale);
56545
- var maxBad = (!zot(maxScale) && Math.max(newScaleX, newScaleY) > maxScale);
56546
- if (minBad || maxBad) {
56547
- if (minBad) {
56548
- if (scaleRatio > 1) {
56549
- proxy.scaleY = minScale;
56550
- proxy.scaleX = minScale*scaleRatio;
56551
- } else {
56552
- proxy.scaleX = minScale;
56553
- proxy.scaleY = minScale/scaleRatio;
56554
- }
56555
- } else if (maxBad) {
56556
- if (scaleRatio > 1) {
56557
- proxy.scaleX = maxScale;
56558
- proxy.scaleY = maxScale/scaleRatio;
56559
- } else {
56560
- proxy.scaleY = maxScale;
56561
- proxy.scaleX = maxScale*scaleRatio;
56562
- }
56492
+ }
56493
+ if (slide && obj.zimTouch.total == 1) obj.zimTouch.slideInterval.pause(false);
56494
+ setTouches();
56495
+ }, null, null, null, null, mID);
56496
+
56497
+ obj.zimTouch.pressmove = obj.on("pressmove", function(e) {
56498
+
56499
+ var id = "id"+Math.abs(e.pointerID+1);
56500
+ var local = obj.parent.globalToLocal(e.stageX/zim.scaX, e.stageY/zim.scaY);
56501
+ // update our pointer data with new x and y
56502
+ if (obj.zimTouch.pointers[id]) {
56503
+ obj.zimTouch.pointers[id].x = local.x;
56504
+ obj.zimTouch.pointers[id].y = local.y;
56505
+ }
56506
+
56507
+ // average the pointers' movement
56508
+ var newX = 0;
56509
+ var newY = 0;
56510
+ var aveX = 0; // point about which to scale and rotate
56511
+ var aveY = 0;
56512
+ var deltaX = 0;
56513
+ var deltaY = 0;
56514
+ zim.loop(obj.zimTouch.pointers, function(id, pointer) {
56515
+ newX += pointer.x - pointer.startX;
56516
+ newY += pointer.y - pointer.startY;
56517
+ aveX += pointer.x;
56518
+ aveY += pointer.y;
56519
+ });
56520
+ if (obj.zimTouch.total == 0) return;
56521
+ deltaX = newX / obj.zimTouch.total;
56522
+ deltaY = newY / obj.zimTouch.total;
56523
+ newX = obj.zimTouch.startX + deltaX;
56524
+ newY = obj.zimTouch.startY + deltaY;
56525
+ aveX = aveX / obj.zimTouch.total;
56526
+ aveY = aveY / obj.zimTouch.total;
56527
+
56528
+ var proxy = {
56529
+ x: obj.x,
56530
+ y: obj.y,
56531
+ scaleX:obj.scaleX,
56532
+ scaleY:obj.scaleY,
56533
+ rotation:obj.rotation
56534
+ }; // will store desired scale and rotation on this object then apply matrix calculations
56535
+
56536
+ if (obj.zimTouch.move) {
56537
+ var result = obj.zimTouch.checkBounds(newX, newY); // es6 opportunity
56538
+ proxy.x = result.x;
56539
+ proxy.y = result.y;
56540
+ }
56541
+
56542
+ // if we have multitouch as determined by setTouches()
56543
+ if (obj.zimTouch.pair.length == 2) {
56544
+ var point1 = obj.zimTouch.pair[0];
56545
+ var point2 = obj.zimTouch.pair[1];
56546
+ if (obj.zimTouch.scale) {
56547
+ // use ratio of distance between fingers to start and then current distance between fingers
56548
+ var startDistance = Math.sqrt(Math.pow((point2.startX-point1.startX),2) + Math.pow((point2.startY-point1.startY),2));
56549
+ var currentDistance = Math.sqrt(Math.pow((point2.x-point1.x),2) + Math.pow((point2.y-point1.y),2));
56550
+ var newScaleX = obj.zimTouch.startSX + (currentDistance / startDistance - 1);
56551
+ var newScaleY = obj.zimTouch.startSY + (currentDistance / startDistance - 1);
56552
+ proxy.scaleX = newScaleX;
56553
+ proxy.scaleY = newScaleY;
56554
+
56555
+ proxy.scaleX = dampScaleX.convert(newScaleX);
56556
+ proxy.scaleY = dampScaleY.convert(newScaleY);
56557
+
56558
+ // set to scale min or max if scale would be outside range
56559
+ var minBad = (!zot(minScale) && Math.min(newScaleX, newScaleY) < minScale);
56560
+ var maxBad = (!zot(maxScale) && Math.max(newScaleX, newScaleY) > maxScale);
56561
+ if (minBad || maxBad) {
56562
+ if (minBad) {
56563
+ if (scaleRatio > 1) {
56564
+ proxy.scaleY = minScale;
56565
+ proxy.scaleX = minScale*scaleRatio;
56566
+ } else {
56567
+ proxy.scaleX = minScale;
56568
+ proxy.scaleY = minScale/scaleRatio;
56569
+ }
56570
+ } else if (maxBad) {
56571
+ if (scaleRatio > 1) {
56572
+ proxy.scaleX = maxScale;
56573
+ proxy.scaleY = maxScale/scaleRatio;
56574
+ } else {
56575
+ proxy.scaleY = maxScale;
56576
+ proxy.scaleX = maxScale*scaleRatio;
56563
56577
  }
56564
- dampScaleX.immediate(proxy.scaleX);
56565
- dampScaleY.immediate(proxy.scaleY);
56566
56578
  }
56567
-
56568
- }
56569
- if (obj.zimTouch.rotate) {
56570
- // rotate based on the difference of angle between the fingers at start and at current
56571
- var startAngle = Math.atan2((point1.startY - point2.startY), (point1.startX - point2.startX)) * (180 / Math.PI);
56572
- var currentAngle = Math.atan2((point1.y - point2.y), (point1.x - point2.x)) * (180 / Math.PI);
56573
- var deltaR = currentAngle - startAngle;
56574
- proxy.rotation = obj.zimTouch.startR + deltaR;
56579
+ dampScaleX.immediate(proxy.scaleX);
56580
+ dampScaleY.immediate(proxy.scaleY);
56575
56581
  }
56576
56582
 
56577
- if (regControl) {
56578
- obj.scaleX = proxy.scaleX;
56579
- obj.scaleY = proxy.scaleY;
56580
- obj.rotation = proxy.rotation;
56581
- if (obj.zimTouch.move) {
56582
- obj.x = proxy.x;
56583
- obj.y = proxy.y;
56584
- }
56585
- } else {
56586
- // transformations seem to ignore registration so need to set to 0 then reset after transformations
56587
- obj.reg(0,0);
56588
-
56589
- // need global data - the transformation about the pinch point is an adjustment of the system
56590
- // originally we wanted calculations in the container of the object
56591
- // these calculations were probably used for min and max of things, etc. so just leaving them
56592
- // and instead, bringing the calculations back into the global - and then eventually into the local for the transformations
56593
- var adjust = obj.parent.localToGlobal(aveX, aveY);
56594
- aveX = adjust.x;
56595
- aveY = adjust.y;
56596
-
56597
- // unfortunately, system goes haywire after a while without adjusting for minor shifts
56598
- // saving the location of the center back to global after the transformation seems to correct this
56599
- // we set lastPoint down below after the transformation
56600
- var point = zot(lastPoint) ? obj.globalToLocal(aveX, aveY) : obj.globalToLocal(lastPoint.x, lastPoint.y);
56601
-
56602
- // the classic Matrix transformation - translate to the pinch point, scale and rotate, and then translate back
56603
- // var matrix = new createjs.Matrix2D()
56604
- var matrix = matrixStart.clone()
56605
- .translate(point.x, point.y)
56606
- .rotate(proxy.rotation-startRotation)
56607
- .scale(proxy.scaleX/startScaleX,proxy.scaleY/startScaleY)
56608
- .translate(-(point.x), -(point.y));
56609
- // .prependMatrix(matrixStart) // would use if started new Matrix each time
56610
-
56611
- matrix.decompose(obj);
56612
-
56613
- if (obj.zimTouch.move) {
56614
- obj.x += deltaX;
56615
- obj.y += deltaY;
56616
- }
56583
+ }
56584
+ if (obj.zimTouch.rotate) {
56585
+ // rotate based on the difference of angle between the fingers at start and at current
56586
+ var startAngle = Math.atan2((point1.startY - point2.startY), (point1.startX - point2.startX)) * (180 / Math.PI);
56587
+ var currentAngle = Math.atan2((point1.y - point2.y), (point1.x - point2.x)) * (180 / Math.PI);
56588
+ var deltaR = currentAngle - startAngle;
56589
+ proxy.rotation = obj.zimTouch.startR + deltaR;
56590
+ }
56617
56591
 
56618
- // correcting for minor shifts which can magnify and set the system haywire
56619
- lastPoint = obj.localToGlobal(point.x, point.y);
56592
+ if (regControl) {
56593
+ obj.scaleX = proxy.scaleX;
56594
+ obj.scaleY = proxy.scaleY;
56595
+ obj.rotation = proxy.rotation;
56596
+ if (obj.zimTouch.move) {
56597
+ obj.x = proxy.x;
56598
+ obj.y = proxy.y;
56599
+ }
56600
+ } else {
56601
+ // transformations seem to ignore registration so need to set to 0 then reset after transformations
56602
+ obj.reg(0,0);
56620
56603
 
56621
- obj.reg(startRegX, startRegY);
56604
+ // need global data - the transformation about the pinch point is an adjustment of the system
56605
+ // originally we wanted calculations in the container of the object
56606
+ // these calculations were probably used for min and max of things, etc. so just leaving them
56607
+ // and instead, bringing the calculations back into the global - and then eventually into the local for the transformations
56608
+ var adjust = obj.parent.localToGlobal(aveX, aveY);
56609
+ aveX = adjust.x;
56610
+ aveY = adjust.y;
56611
+
56612
+ // unfortunately, system goes haywire after a while without adjusting for minor shifts
56613
+ // saving the location of the center back to global after the transformation seems to correct this
56614
+ // we set lastPoint down below after the transformation
56615
+ var point = zot(lastPoint) ? obj.globalToLocal(aveX, aveY) : obj.globalToLocal(lastPoint.x, lastPoint.y);
56616
+
56617
+ // the classic Matrix transformation - translate to the pinch point, scale and rotate, and then translate back
56618
+ // var matrix = new createjs.Matrix2D()
56619
+ var matrix = matrixStart.clone()
56620
+ .translate(point.x, point.y)
56621
+ .rotate(proxy.rotation-startRotation)
56622
+ .scale(proxy.scaleX/startScaleX,proxy.scaleY/startScaleY)
56623
+ .translate(-(point.x), -(point.y));
56624
+ // .prependMatrix(matrixStart) // would use if started new Matrix each time
56625
+
56626
+ matrix.decompose(obj);
56627
+
56628
+ if (obj.zimTouch.move) {
56629
+ obj.x += deltaX;
56630
+ obj.y += deltaY;
56622
56631
  }
56623
56632
 
56624
- if (obj.zimTouch.scale) obj.dispatchEvent("scale");
56625
- if (obj.zimTouch.rotate) obj.dispatchEvent("rotate");
56626
- if (obj.zimTouch.move) obj.dispatchEvent("move");
56633
+ // correcting for minor shifts which can magnify and set the system haywire
56634
+ lastPoint = obj.localToGlobal(point.x, point.y);
56627
56635
 
56628
- } else {
56629
- obj.x = proxy.x;
56630
- obj.y = proxy.y;
56631
- if (obj.zimTouch.move) obj.dispatchEvent("move");
56636
+ obj.reg(startRegX, startRegY);
56632
56637
  }
56633
- if (obj.type == "Tag" || obj.type == "TextArea" || obj.type == "Loader") obj.resize();
56634
56638
 
56635
- if (obj.ZIMoutlineShape) obj.outline();
56636
- if (obj.getStage && obj.stage) obj.stage.update();
56639
+ if (obj.zimTouch.scale) obj.dispatchEvent("scale");
56640
+ if (obj.zimTouch.rotate) obj.dispatchEvent("rotate");
56641
+ if (obj.zimTouch.move) obj.dispatchEvent("move");
56642
+
56643
+ } else {
56644
+ obj.x = proxy.x;
56645
+ obj.y = proxy.y;
56646
+ if (obj.zimTouch.move) obj.dispatchEvent("move");
56647
+ }
56648
+ if (obj.type == "Tag" || obj.type == "TextArea" || obj.type == "Loader") obj.resize();
56649
+
56650
+ if (obj.ZIMoutlineShape) obj.outline();
56651
+ if (obj.getStage && obj.stage) obj.stage.update();
56652
+ }, null, null, null, null, mID);
56653
+
56654
+ obj.on("mousedown", function() {
56655
+ // if an object is removed that is touched, the touch will still be registered
56656
+ // this code makes sure that no ghost touches are left by counting stagemousedown and stagemouseup events
56657
+ var mouseCount = 1;
56658
+ obj.tsmd = obj.stage.on("stagemousedown", function() {
56659
+ mouseCount++;
56637
56660
  }, null, null, null, null, mID);
56661
+ obj.tsmu = obj.stage.on("stagemouseup", function() {
56662
+ mouseCount--;
56663
+ if (mouseCount == 0) {
56664
+ setTimeout(function() {
56665
+ if (obj.zimTouch) obj.zimTouch.total = 0;
56666
+ if (obj.zimTouch) obj.zimTouch.pointers = {};
56667
+ maxTouches = null;
56668
+ }, 50);
56669
+ }
56670
+ }, null, null, null, null, mID);
56671
+ }, null, true, null, null, mID); // once
56638
56672
 
56639
- obj.on("mousedown", function() {
56640
- // if an object is removed that is touched, the touch will still be registered
56641
- // this code makes sure that no ghost touches are left by counting stagemousedown and stagemouseup events
56642
- var mouseCount = 1;
56643
- obj.tsmd = obj.stage.on("stagemousedown", function() {
56644
- mouseCount++;
56645
- }, null, null, null, null, mID);
56646
- obj.tsmu = obj.stage.on("stagemouseup", function() {
56647
- mouseCount--;
56648
- if (mouseCount == 0) {
56649
- setTimeout(function() {
56650
- if (obj.zimTouch) obj.zimTouch.total = 0;
56651
- if (obj.zimTouch) obj.zimTouch.pointers = {};
56652
- maxTouches = null;
56653
- }, 50);
56654
- }
56655
- }, null, null, null, null, mID);
56656
- }, null, true, null, null, mID); // once
56673
+ obj.zimTouch.pressup = obj.on("pressup", function(e) {
56674
+ var id = "id"+Math.abs(e.pointerID+1);
56675
+ // remove touch data for pointer
56676
+ delete obj.zimTouch.pointers[id];
56677
+ if (obj.zimTouch.move || obj.zimTouch.rotate) obj.zimTouch.total--;
56678
+ if (rotate && !zot(snapRotate) && obj.zimTouch.total == 0) {
56679
+ if (snapRotate > 0) {
56680
+ obj.rotation = Math.round(obj.rotation/snapRotate)*snapRotate;
56681
+ } else if (snapRotate == 0) {
56682
+ obj.rotation = Math.round(obj.rotation);
56683
+ }
56684
+ }
56685
+ // spinning was throwing slide off so just slide with single touch for now...
56686
+ if (slide && obj.zimTouch.total == 0 && maxTouches == 1) {
56687
+ obj.zimTouch.slideInterval.pause();
56688
+ var startSlide = slideData[(slideCount+1)%slideData.length];
56689
+ var currentSlide = slideData[(slideCount)%slideData.length];
56690
+ var newX = obj.x + (startSlide[0]-currentSlide[0]) * slideFactor;
56691
+ var newY = obj.y + (startSlide[1]-currentSlide[1]) * slideFactor;
56692
+ var result = obj.zimTouch.checkBounds(newX, newY); // es6 opportunity
56693
+ // if it is being thrown past the bounds, need to reduce time by percentage of blocked movement
56694
+ var newT = slideTotal*slideSlice*slideFactor * Math.min((obj.x-result.x)/(obj.x-newX)||1, (obj.y-result.y)/(obj.y-newY)||1);
56695
+ obj.animate({x:result.x, y:result.y}, newT/(timeType=="s"?1000:1), "quadOut", function(){obj.dispatchEvent("slidestop");});
56696
+ }
56697
+ if (obj.zimTouch.total == 0) maxTouches = null;
56698
+ if (obj.getStage && obj.stage) obj.stage.update();
56699
+ setTouches();
56700
+ }, null, null, null, null, mID);
56701
+
56702
+ if (boundary) {
56703
+ remakeBoundary();
56704
+ obj.on("move", remakeBoundary, null, null, null, null, mID);
56705
+ }
56706
+ }
56657
56707
 
56658
- obj.zimTouch.pressup = obj.on("pressup", function(e) {
56659
- var id = "id"+Math.abs(e.pointerID+1);
56660
- // remove touch data for pointer
56661
- delete obj.zimTouch.pointers[id];
56662
- if (obj.zimTouch.move || obj.zimTouch.rotate) obj.zimTouch.total--;
56663
- if (rotate && !zot(snapRotate) && obj.zimTouch.total == 0) {
56664
- if (snapRotate > 0) {
56665
- obj.rotation = Math.round(obj.rotation/snapRotate)*snapRotate;
56666
- } else if (snapRotate == 0) {
56667
- obj.rotation = Math.round(obj.rotation);
56668
- }
56708
+ // -----------------------------------------------------------------------
56709
+ // TRACKPAD SUPPORT - AI Coded Claude 5
56710
+ // Handles laptop trackpad two-finger gestures via wheel and gesturechange events.
56711
+ // Completely separate from the touch block above - own state, own canvas listeners.
56712
+ // Does not interfere with touchscreen gesture() behaviour.
56713
+ // -----------------------------------------------------------------------
56714
+ if (trackpad && !obj.zimTouch.tpAttached) {
56715
+
56716
+ // Separate matrix state - never shares with the touch block vars above
56717
+ var tpMatrixStart;
56718
+ var tpStartScaleX;
56719
+ var tpStartScaleY;
56720
+ var tpStartRotation;
56721
+ var tpStartRegX;
56722
+ var tpStartRegY;
56723
+ var tpLastPoint;
56724
+ var tpActive = false;
56725
+ var tpEndTimeout = null;
56726
+
56727
+ // Accumulated deltas within one gesture session (wheel burst)
56728
+ // We track total scale factor and total rotation applied since session start
56729
+ var tpAccumScale = 1; // multiplicative accumulator, applied to tpStartScaleX/Y
56730
+ var tpAccumRot = 0; // degrees accumulator, applied to tpStartRotation
56731
+
56732
+ // Pivot in global stage coords - set once per session at first wheel event
56733
+ var tpPivotGX = 0;
56734
+ var tpPivotGY = 0;
56735
+
56736
+ // Safari GestureEvent state
56737
+ var tpGestureBaseScale = 1; // e.scale at gesturestart (always 1 per spec, but captured for safety)
56738
+ var tpGestureBaseRot = 0; // e.rotation at gesturestart (always 0 per spec)
56739
+ var tpGestureLastScale = 1; // e.scale at previous gesturechange, for delta
56740
+ var tpGestureLastRot = 0; // e.rotation at previous gesturechange, for delta
56741
+ var tpGestureActive = false;
56742
+
56743
+ // Begin a trackpad gesture session: snapshot current object state
56744
+ function tpBeginSession(pivotGX, pivotGY) {
56745
+ tpActive = true;
56746
+ tpPivotGX = pivotGX;
56747
+ tpPivotGY = pivotGY;
56748
+ tpAccumScale = 1;
56749
+ tpAccumRot = 0;
56750
+ tpStartScaleX = obj.scaleX;
56751
+ tpStartScaleY = obj.scaleY;
56752
+ tpStartRotation = obj.rotation;
56753
+ tpStartRegX = obj.regX;
56754
+ tpStartRegY = obj.regY;
56755
+ tpLastPoint = null;
56756
+ if (!regControl) {
56757
+ obj.reg(0,0);
56758
+ tpMatrixStart = obj.getMatrix();
56759
+ obj.regX = tpStartRegX;
56760
+ obj.regY = tpStartRegY;
56761
+ }
56762
+ }
56763
+
56764
+ // Apply accumulated scale + rotation to the object using the same
56765
+ // matrix technique as the touch block's pressmove pair path
56766
+ function tpApply() {
56767
+ if (!tpActive) return;
56768
+
56769
+ var newScaleX = tpStartScaleX * tpAccumScale;
56770
+ var newScaleY = tpStartScaleY * tpAccumScale;
56771
+
56772
+ // Enforce min/max scale
56773
+ if (!zot(minScale) && Math.min(newScaleX, newScaleY) < minScale) {
56774
+ if (scaleRatio > 1) { newScaleX = minScale * scaleRatio; newScaleY = minScale; }
56775
+ else { newScaleX = minScale; newScaleY = minScale / scaleRatio; }
56776
+ }
56777
+ if (!zot(maxScale) && Math.max(newScaleX, newScaleY) > maxScale) {
56778
+ if (scaleRatio > 1) { newScaleX = maxScale; newScaleY = maxScale / scaleRatio; }
56779
+ else { newScaleX = maxScale * scaleRatio; newScaleY = maxScale; }
56780
+ }
56781
+
56782
+ var newRotation = tpStartRotation + tpAccumRot;
56783
+
56784
+ if (regControl) {
56785
+ if (obj.zimTouch.scale) {
56786
+ obj.scaleX = newScaleX;
56787
+ obj.scaleY = newScaleY;
56788
+ }
56789
+ if (obj.zimTouch.rotate) {
56790
+ obj.rotation = newRotation;
56791
+ }
56792
+ } else {
56793
+ obj.reg(0,0);
56794
+
56795
+ // Pivot point in global coords -> local to obj
56796
+ var point = zot(tpLastPoint)
56797
+ ? obj.globalToLocal(tpPivotGX, tpPivotGY)
56798
+ : obj.globalToLocal(tpLastPoint.x, tpLastPoint.y);
56799
+
56800
+ var matrix = tpMatrixStart.clone()
56801
+ .translate(point.x, point.y)
56802
+ .rotate(newRotation - tpStartRotation)
56803
+ .scale(newScaleX / tpStartScaleX, newScaleY / tpStartScaleY)
56804
+ .translate(-point.x, -point.y);
56805
+
56806
+ matrix.decompose(obj);
56807
+
56808
+ // Correct minor drift - same technique as touch block
56809
+ tpLastPoint = obj.localToGlobal(point.x, point.y);
56810
+
56811
+ obj.regX = tpStartRegX;
56812
+ obj.regY = tpStartRegY;
56813
+ }
56814
+
56815
+ if (obj.zimTouch.scale) obj.dispatchEvent("scale");
56816
+ if (obj.zimTouch.rotate) obj.dispatchEvent("rotate");
56817
+
56818
+ if (obj.type == "Tag" || obj.type == "TextArea" || obj.type == "Loader") obj.resize();
56819
+ if (obj.ZIMoutlineShape) obj.outline();
56820
+ if (obj.getStage && obj.stage) obj.stage.update();
56821
+ }
56822
+
56823
+ // End session: apply snapRotate and clean up
56824
+ function tpEndSession() {
56825
+ if (!tpActive) return;
56826
+ tpActive = false;
56827
+ tpEndTimeout = null;
56828
+ if (obj.zimTouch.rotate && !zot(snapRotate)) {
56829
+ if (snapRotate > 0) {
56830
+ obj.rotation = Math.round(obj.rotation / snapRotate) * snapRotate;
56831
+ } else if (snapRotate == 0) {
56832
+ obj.rotation = Math.round(obj.rotation);
56669
56833
  }
56670
- // spinning was throwing slide off so just slide with single touch for now...
56671
- if (slide && obj.zimTouch.total == 0 && maxTouches == 1) {
56672
- obj.zimTouch.slideInterval.pause();
56673
- var startSlide = slideData[(slideCount+1)%slideData.length];
56674
- var currentSlide = slideData[(slideCount)%slideData.length];
56675
- var newX = obj.x + (startSlide[0]-currentSlide[0]) * slideFactor;
56676
- var newY = obj.y + (startSlide[1]-currentSlide[1]) * slideFactor;
56677
- var result = obj.zimTouch.checkBounds(newX, newY); // es6 opportunity
56678
- // if it is being thrown past the bounds, need to reduce time by percentage of blocked movement
56679
- var newT = slideTotal*slideSlice*slideFactor * Math.min((obj.x-result.x)/(obj.x-newX)||1, (obj.y-result.y)/(obj.y-newY)||1);
56680
- obj.animate({x:result.x, y:result.y}, newT/(timeType=="s"?1000:1), "quadOut", function(){obj.dispatchEvent("slidestop");});
56681
- }
56682
- if (obj.zimTouch.total == 0) maxTouches = null;
56683
56834
  if (obj.getStage && obj.stage) obj.stage.update();
56684
- setTouches();
56685
- }, null, null, null, null, mID);
56686
-
56687
- if (boundary) {
56688
- remakeBoundary();
56689
- obj.on("move", remakeBoundary, null, null, null, null, mID);
56690
- }
56691
- }
56692
-
56693
- function setTouches() {
56694
- // anytime we add or remove a pointer we reset the start positions
56695
- // this handles cases where single touch would change the start position
56696
- // and handles removing of one of the active pairs of pointers
56697
- // to be replaced with another current pointer
56698
- obj.zimTouch.pair = [];
56699
- zim.loop(obj.zimTouch.pointers, function(id, pointer, i) {
56700
- pointer.startX = pointer.x;
56701
- pointer.startY = pointer.y;
56702
- // just record the first two pointers
56703
- // keep looping as mov uses all pointers
56704
- if (i <= 1) obj.zimTouch.pair.push(pointer);
56705
- });
56706
- // record the start position, scale and rotation
56707
- obj.zimTouch.startX = obj.x;
56708
- obj.zimTouch.startY = obj.y;
56709
- obj.zimTouch.startSX = obj.scaleX;
56710
- obj.zimTouch.startSY = obj.scaleY;
56711
- obj.zimTouch.startR = obj.rotation;
56712
- }
56713
-
56714
- function remakeBoundary() {
56715
- var p = obj.localToGlobal(obj.regX, obj.regY);
56716
- var b;
56717
- if (circularBounds) {
56718
- // assuming cropped if Bitmap and width==height
56719
- var leftTop = obj.parent.localToGlobal(obj.x-obj.width/2, obj.y-obj.height/2);
56720
- var botRight = obj.parent.localToGlobal(obj.x+obj.width/2, obj.y+obj.height/2);
56721
- b = {
56722
- x:leftTop.x,
56723
- y:leftTop.y,
56724
- width:botRight.x-leftTop.x,
56725
- height:botRight.y-leftTop.y
56726
- };
56835
+ }
56836
+ }
56837
+
56838
+ // Debounce end of wheel burst - trackpad fires no "end" event
56839
+ function tpScheduleEnd() {
56840
+ if (tpEndTimeout) clearTimeout(tpEndTimeout);
56841
+ tpEndTimeout = setTimeout(tpEndSession, 100);
56842
+ }
56843
+
56844
+ // Convert a DOM mouse/wheel event position to global stage coords
56845
+ // matching the scaling that the touch block uses (zim.scaX / zim.scaY)
56846
+ function tpEventToStage(e) {
56847
+ var canvas = obj.stage.canvas;
56848
+ obj.canvas = canvas; // for removal
56849
+ var rect = canvas.getBoundingClientRect();
56850
+ var stageX = (e.clientX - rect.left) / (zim.scaX || 1);
56851
+ var stageY = (e.clientY - rect.top) / (zim.scaY || 1);
56852
+ return {x: stageX, y: stageY};
56853
+ }
56854
+
56855
+ // ---- Object selection for trackpad ----
56856
+ // Multiple objects can each have gesture() with trackpad enabled on the
56857
+ // same canvas. Unlike mousedown/pressmove (which ZIM already hit-tests
56858
+ // to a specific display object), wheel and gesture events are not
56859
+ // targeted - they fire for whatever is listening on the canvas. So we
56860
+ // track which gesture object was most recently clicked/tapped on this
56861
+ // stage and ignore trackpad input for any other gesture object there.
56862
+ obj.zimTouch.tpSelectHandler = function() {
56863
+ obj.stage.zimGestureActive = obj;
56864
+ };
56865
+ obj.on("mousedown", obj.zimTouch.tpSelectHandler, null, null, null, null, mID);
56866
+
56867
+ // ---- wheel handler (Chrome, Firefox, and Safari pinch-as-wheel) ----
56868
+ obj.zimTouch.tpWheelHandler = function(e) {
56869
+ if (!obj.stage) return;
56870
+ // Only the last-selected gesture object responds to trackpad input -
56871
+ // otherwise every gesture()-enabled object on the same canvas would
56872
+ // react to the same wheel event at once.
56873
+ if (obj.stage.zimGestureActive !== obj) return;
56874
+
56875
+ var stagePos = tpEventToStage(e);
56876
+
56877
+ if (e.ctrlKey) {
56878
+ // ----- PINCH / SCALE -----
56879
+ // Browser sets ctrlKey=true synthetically for trackpad pinch on all platforms.
56880
+ // Prevent browser zoom.
56881
+ if (!obj.zimTouch.scale) return;
56882
+ e.preventDefault();
56883
+
56884
+ if (!tpActive) tpBeginSession(stagePos.x, stagePos.y);
56885
+ else if (tpEndTimeout) { clearTimeout(tpEndTimeout); tpEndTimeout = null; }
56886
+
56887
+ // deltaY: negative = fingers spreading (zoom in), positive = fingers closing (zoom out)
56888
+ var delta = e.deltaMode === 1 ? e.deltaY * 12 : e.deltaY;
56889
+ tpAccumScale *= Math.pow(1 - delta * 0.005, 1);
56890
+ tpAccumScale = Math.max(0.05, Math.min(20, tpAccumScale));
56891
+
56892
+ tpApply();
56893
+ tpScheduleEnd();
56894
+
56727
56895
  } else {
56728
- b = obj.boundsToGlobal();
56896
+ // ----- PAN and/or ROTATE -----
56897
+ // No modifier key. Split by dominant axis:
56898
+ // horizontal-dominant (|deltaX| > |deltaY|) -> rotate
56899
+ // vertical-dominant or equal -> pan
56900
+ // This works on all platforms without any key held.
56901
+ // Safari rotation also arrives via gesturechange (handled separately below),
56902
+ // so on Safari both paths may fire; they accumulate correctly.
56903
+ var dx = e.deltaMode === 1 ? e.deltaX * 12 : e.deltaX;
56904
+ var dy = e.deltaMode === 1 ? e.deltaY * 12 : e.deltaY;
56905
+ var absDx = Math.abs(dx);
56906
+ var absDy = Math.abs(dy);
56907
+
56908
+ if (obj.zimTouch.rotate && absDx > absDy) {
56909
+ // ----- ROTATE -----
56910
+ // Horizontal two-finger swipe -> rotation.
56911
+ // Sign is flipped so a rightward finger swipe (with thumb anchored)
56912
+ // rotates the way two physical fingers would twist a dial - counter-clockwise.
56913
+ e.preventDefault();
56914
+
56915
+ if (!tpActive) tpBeginSession(stagePos.x, stagePos.y);
56916
+ else if (tpEndTimeout) { clearTimeout(tpEndTimeout); tpEndTimeout = null; }
56917
+
56918
+ tpAccumRot -= dx * 0.3; // degrees per CSS pixel - negative so direction matches natural two-finger twist
56919
+
56920
+ tpApply();
56921
+ tpScheduleEnd();
56922
+
56923
+ } else if (obj.zimTouch.move) {
56924
+ // ----- PAN -----
56925
+ // Vertical-dominant (or purely vertical) two-finger scroll -> translate.
56926
+ // Applied incrementally so it tracks the finger naturally.
56927
+ e.preventDefault();
56928
+
56929
+ var newX = obj.x - dx / (zim.scaX || 1);
56930
+ var newY = obj.y - dy / (zim.scaY || 1);
56931
+
56932
+ var panResult = obj.zimTouch.checkBounds(newX, newY);
56933
+ obj.x = panResult.x;
56934
+ obj.y = panResult.y;
56935
+
56936
+ obj.dispatchEvent("move");
56937
+ if (obj.type == "Tag" || obj.type == "TextArea" || obj.type == "Loader") obj.resize();
56938
+ if (obj.ZIMoutlineShape) obj.outline();
56939
+ if (obj.getStage && obj.stage) obj.stage.update();
56940
+ }
56941
+ }
56942
+ };
56943
+
56944
+ // ---- Safari GestureEvent handlers (scale + rotation without shift key) ----
56945
+ // These fire on Safari desktop (Mac) for two-finger trackpad gestures.
56946
+ // gesturechange gives cumulative .scale and .rotation from gesture start.
56947
+ obj.zimTouch.tpGestureStartHandler = function(e) {
56948
+ if (obj.stage.zimGestureActive !== obj) return;
56949
+ e.preventDefault();
56950
+ tpGestureActive = true;
56951
+ tpGestureBaseScale = e.scale; // should be 1.0
56952
+ tpGestureBaseRot = e.rotation; // should be 0.0
56953
+ tpGestureLastScale = e.scale;
56954
+ tpGestureLastRot = e.rotation;
56955
+ var stagePos = tpEventToStage(e);
56956
+ if (!tpActive) tpBeginSession(stagePos.x, stagePos.y);
56957
+ if (tpEndTimeout) { clearTimeout(tpEndTimeout); tpEndTimeout = null; }
56958
+ };
56959
+
56960
+ obj.zimTouch.tpGestureChangeHandler = function(e) {
56961
+ if (obj.stage.zimGestureActive !== obj) return;
56962
+ e.preventDefault();
56963
+ if (!tpGestureActive) return;
56964
+
56965
+ // e.scale is cumulative ratio from gesturestart (1.0 = no change)
56966
+ // e.rotation is cumulative degrees from gesturestart (0 = no change)
56967
+ // We want the DELTA from the last event so we can accumulate properly
56968
+ var scaleDelta = e.scale / tpGestureLastScale;
56969
+ var rotDelta = e.rotation - tpGestureLastRot;
56970
+ tpGestureLastScale = e.scale;
56971
+ tpGestureLastRot = e.rotation;
56972
+
56973
+ if (obj.zimTouch.scale) {
56974
+ tpAccumScale *= scaleDelta;
56975
+ tpAccumScale = Math.max(0.05, Math.min(20, tpAccumScale));
56976
+ }
56977
+ if (obj.zimTouch.rotate) {
56978
+ tpAccumRot += rotDelta;
56729
56979
  }
56730
- var r = {
56731
- x:obj.zimTouch.boundaryStartX+p.x-b.x,
56732
- y:obj.zimTouch.boundaryStartY+p.y-b.y,
56733
- width:obj.zimTouch.boundaryStartW-b.width,
56734
- height:obj.zimTouch.boundaryStartH-b.height
56980
+
56981
+ tpApply();
56982
+ };
56983
+
56984
+ obj.zimTouch.tpGestureEndHandler = function(e) {
56985
+ if (obj.stage.zimGestureActive !== obj) return;
56986
+ e.preventDefault();
56987
+ tpGestureActive = false;
56988
+ tpEndSession();
56989
+ };
56990
+
56991
+ // Attach listeners once the object has a stage (canvas).
56992
+ // If stage exists now, attach immediately.
56993
+ // If not yet on stage, wait for the "added" event.
56994
+ obj.zimTouch.tpAttached = false;
56995
+
56996
+ function tpAttachToCanvas() {
56997
+ if (obj.zimTouch.tpAttached) return;
56998
+ if (!obj.stage) return;
56999
+ var canvas = obj.stage.canvas;
57000
+ canvas.addEventListener("wheel", obj.zimTouch.tpWheelHandler, {passive: false});
57001
+ // Safari gestureevents
57002
+ canvas.addEventListener("gesturestart", obj.zimTouch.tpGestureStartHandler, {passive: false});
57003
+ canvas.addEventListener("gesturechange", obj.zimTouch.tpGestureChangeHandler, {passive: false});
57004
+ canvas.addEventListener("gestureend", obj.zimTouch.tpGestureEndHandler, {passive: false});
57005
+ obj.zimTouch.tpCanvas = canvas;
57006
+ obj.zimTouch.tpAttached = true;
57007
+
57008
+ // Default the first gesture object attached on this stage to be selected,
57009
+ // so a single-object scene works immediately without requiring a click.
57010
+ if (zot(obj.stage.zimGestureActive)) obj.stage.zimGestureActive = obj;
57011
+ }
57012
+
57013
+ if (obj.stage) {
57014
+ tpAttachToCanvas();
57015
+ } else {
57016
+ // Defer until obj is added to the display list
57017
+ obj.on("added", function() {
57018
+ tpAttachToCanvas();
57019
+ }, null, true); // once
57020
+ }
57021
+ }
57022
+
57023
+ // END TRACKPAD SUPPORT
57024
+
57025
+ function setTouches() {
57026
+ // anytime we add or remove a pointer we reset the start positions
57027
+ // this handles cases where single touch would change the start position
57028
+ // and handles removing of one of the active pairs of pointers
57029
+ // to be replaced with another current pointer
57030
+ obj.zimTouch.pair = [];
57031
+ zim.loop(obj.zimTouch.pointers, function(id, pointer, i) {
57032
+ pointer.startX = pointer.x;
57033
+ pointer.startY = pointer.y;
57034
+ // just record the first two pointers
57035
+ // keep looping as mov uses all pointers
57036
+ if (i <= 1) obj.zimTouch.pair.push(pointer);
57037
+ });
57038
+ // record the start position, scale and rotation
57039
+ obj.zimTouch.startX = obj.x;
57040
+ obj.zimTouch.startY = obj.y;
57041
+ obj.zimTouch.startSX = obj.scaleX;
57042
+ obj.zimTouch.startSY = obj.scaleY;
57043
+ obj.zimTouch.startR = obj.rotation;
57044
+ }
57045
+
57046
+ function remakeBoundary() {
57047
+ var p = obj.localToGlobal(obj.regX, obj.regY);
57048
+ var b;
57049
+ if (circularBounds) {
57050
+ // assuming cropped if Bitmap and width==height
57051
+ var leftTop = obj.parent.localToGlobal(obj.x-obj.width/2, obj.y-obj.height/2);
57052
+ var botRight = obj.parent.localToGlobal(obj.x+obj.width/2, obj.y+obj.height/2);
57053
+ b = {
57054
+ x:leftTop.x,
57055
+ y:leftTop.y,
57056
+ width:botRight.x-leftTop.x,
57057
+ height:botRight.y-leftTop.y
56735
57058
  };
56736
- obj.gestureBoundary(r, false); // do not update the original rect
57059
+ } else {
57060
+ b = obj.boundsToGlobal();
56737
57061
  }
56738
-
56739
- return obj;
56740
- };//-34.5
57062
+ var r = {
57063
+ x:obj.zimTouch.boundaryStartX+p.x-b.x,
57064
+ y:obj.zimTouch.boundaryStartY+p.y-b.y,
57065
+ width:obj.zimTouch.boundaryStartW-b.width,
57066
+ height:obj.zimTouch.boundaryStartH-b.height
57067
+ };
57068
+ obj.gestureBoundary(r, false); // do not update the original rect
57069
+ }
57070
+
57071
+ return obj;
57072
+ };//-34.5
57073
+
56741
57074
 
56742
57075
  /*--
56743
57076
  obj.noGesture = function(move, scale, rotate)
@@ -56764,20 +57097,22 @@ rotate - (default true) - set to false not to remove rotate gesture
56764
57097
 
56765
57098
  RETURNS obj for chaining
56766
57099
  --*///+34.6
56767
- zim.noGesture = function(obj, move, scale, rotate) {
56768
- var sig = "obj, move, scale, rotate";
56769
- var duo; if (duo = zob(zim.noGesture, arguments, sig)) return duo;
56770
- z_d("34.6");
57100
+ zim.noGesture = function(obj, move, scale, rotate) {
57101
+ var sig = "obj, move, scale, rotate";
57102
+ var duo; if (duo = zob(zim.noGesture, arguments, sig)) return duo;
57103
+ z_d("34.6");
56771
57104
 
56772
- if (zot(obj) || !obj.on || !obj.zimTouch) return;
57105
+ if (zot(obj) || !obj.on || !obj.zimTouch) return;
56773
57106
 
56774
- // MONITOR
56775
- var mID = "z~noGesture";
56776
- if (obj && obj.mID && ((obj.mID[2] && obj.mID[2]=="-") || obj.mID[0]=="-")) mID = "z~-";
56777
-
56778
- if (zot(move)) move = true;
56779
- if (zot(scale)) scale = true;
56780
- if (zot(rotate)) rotate = true;
57107
+ // MONITOR
57108
+ var mID = "z~noGesture";
57109
+ if (obj && obj.mID && ((obj.mID[2] && obj.mID[2]=="-") || obj.mID[0]=="-")) mID = "z~-";
57110
+
57111
+ if (zot(move)) move = true;
57112
+ if (zot(scale)) scale = true;
57113
+ if (zot(rotate)) rotate = true;
57114
+
57115
+ if (obj.zimTouch) {
56781
57116
  obj.zimTouch.move = !move;
56782
57117
  obj.zimTouch.scale = !scale;
56783
57118
  obj.zimTouch.rotate = !rotate;
@@ -56785,13 +57120,24 @@ RETURNS obj for chaining
56785
57120
  obj.off("mousedown", obj.zimTouch.mousedown, null, mID);
56786
57121
  obj.off("pressmove", obj.zimTouch.pressmove, null, mID);
56787
57122
  obj.off("pressup", obj.zimTouch.pressup, null, mID);
57123
+
57124
+ if (obj.zimTouch.tpSelectHandler) obj.off("mousedown", obj.zimTouch.tpSelectHandler);
57125
+ var canvas = obj.canvas;
57126
+ if (canvas) {
57127
+ if (obj.zimTouch.tpWheelHandler) canvas.removeEventListener("wheel", obj.zimTouch.tpWheelHandler, {passive: false});
57128
+ if (obj.zimTouch.tpGestureStartHandler) canvas.removeEventListener("gesturestart", obj.zimTouch.tpGestureStartHandler, {passive: false});
57129
+ if (obj.zimTouch.tpGestureChangeHandler) canvas.removeEventListener("gesturechange", obj.zimTouch.tpGestureChangeHandler, {passive: false});
57130
+ if (obj.zimTouch.tpGestureEndHandler) canvas.removeEventListener("gestureend", obj.zimTouch.tpGestureEndHandler, {passive: false});
57131
+ }
56788
57132
  delete obj.zimTouch;
56789
- }
56790
- if (obj.tsmd) obj.stage.off("stagemousedown", obj.tsmd, null, mID);
56791
- if (obj.tsmu) obj.stage.off("stagemouseup", obj.tsmu, null, mID);
57133
+ }
57134
+ }
56792
57135
 
56793
- return obj;
56794
- };//-34.6
57136
+ if (obj.stage && obj.tsmd) obj.stage.off("stagemousedown", obj.tsmd, null, mID);
57137
+ if (obj.stage && obj.tsmu) obj.stage.off("stagemouseup", obj.tsmu, null, mID);
57138
+
57139
+ return obj;
57140
+ };//-34.6
56795
57141
 
56796
57142
  /*--
56797
57143
  obj.gestureBoundary = function(boundary, new)
@@ -58036,7 +58382,7 @@ RETURNS an index Number (or undefined) | col | row | an Array of [index, col, ro
58036
58382
  // SUBSECTION ANIMATE, WIGGLE, AND LOOP
58037
58383
 
58038
58384
  /*--
58039
- obj.animate = function(props, time, ease, call, params, wait, waitedCall, waitedParams, loop, loopCount, loopWait, loopCall, loopParams, loopWaitCall, loopWaitParams, loopPick, rewind, rewindWait, rewindCall, rewindParams, rewindWaitCall, rewindWaitParams, rewindTime, rewindEase, startCall, startParams, animateCall, animateParams, sequence, sequenceCall, sequenceParams, sequenceReverse, sequenceRatio, ticker, cjsProps, css, protect, override, from, set, id, events, sequenceTarget, dynamic, drag, clamp, startPaused, clean, obj, seriesWait, sequenceWait, rate, pauseOnBlur, easeAmount, easeFrequency, timeUnit, timeCheck, noAnimateCall, pathDamp, rewindPick)
58385
+ obj.animate = function(props, time, ease, call, params, wait, waitedCall, waitedParams, loop, loopCount, loopWait, loopCall, loopParams, loopWaitCall, loopWaitParams, loopPick, rewind, rewindWait, rewindCall, rewindParams, rewindWaitCall, rewindWaitParams, rewindTime, rewindEase, rewindPick, startCall, startParams, animateCall, animateParams, sequence, sequenceCall, sequenceParams, sequenceReverse, sequenceRatio, ticker, cjsProps, css, protect, override, from, set, id, events, sequenceTarget, dynamic, drag, clamp, startPaused, clean, obj, seriesWait, sequenceWait, rate, pauseOnBlur, easeAmount, easeFrequency, timeUnit, timeCheck, noAnimateCall, pathDamp, style, group)
58040
58386
 
58041
58387
  animate
58042
58388
  zim DisplayObject method
@@ -58448,6 +58794,12 @@ rewindEase - (default null) overwrite the ease for the rewind direction
58448
58794
  so setting rewindEase:"bounceOut" will bounce back at the start of the animation
58449
58795
  note - setting ease:"bounceOut" will bounce at the end of the animation
58450
58796
  this allows for a normal start with a bounce and then a normal start at rewind and a bounce
58797
+ rewindPick - (default false) set to true to pick from props as it rewinds
58798
+ this will be moved to the other rewind parameters in ZIM 019
58799
+ also see loopPick - using both loopPick and rewindPick will act like a series
58800
+ where if the property has a series it will animate one after the other
58801
+ do not use if the property is just a regular value as it will appear to stop the animation.
58802
+ Can use a series, results of a function, min max or array for random picks
58451
58803
  startCall - (default null) calls function at the start of actual animation and after any wait (and waitedCall)
58452
58804
  this is basically the same as the waitedCall but will also be called at the start of animation when there is no waitedCall
58453
58805
  startParams - (default target) parameters to send startCall function
@@ -58571,12 +58923,6 @@ timeUnit - (default TIME) override the TIME setting to "seconds" / "s" or "milli
58571
58923
  timeCheck - (default true) set to false to not have animate() warn of potentially wrong time units - see also TIMECHECK
58572
58924
  noAnimateCall - (default true) set to false to not call the callback function if ANIMATE is set to false
58573
58925
  pathDamp - (default .15) damping for drag along path
58574
- rewindPick - (default false) set to true to pick from props as it rewinds
58575
- this will be moved to the other rewind parameters in ZIM 019
58576
- also see loopPick - using both loopPick and rewindPick will act like a series
58577
- where if the property has a series it will animate one after the other
58578
- do not use if the property is just a regular value as it will appear to stop the animation.
58579
- Can use a series, results of a function, min max or array for random picks
58580
58926
  style - (default true) set to false to ignore styles set with the STYLE - will receive original parameter defaults
58581
58927
  group - (default null) set to String (or comma delimited String) so STYLE can set default styles to the group(s) (like a CSS class)
58582
58928
 
@@ -58649,8 +58995,8 @@ EVENTS - zim animate() will add an "animation" event to the target IF the events
58649
58995
 
58650
58996
  RETURNS the target for chaining (or null if no target is provided and run on zim with series)
58651
58997
  --*///+45
58652
- zim.animate = function(target, props, time, ease, call, params, wait, waitedCall, waitedParams, loop, loopCount, loopWait, loopCall, loopParams, loopWaitCall, loopWaitParams, loopPick, rewind, rewindWait, rewindCall, rewindParams, rewindWaitCall, rewindWaitParams, rewindTime, rewindEase, startCall, startParams, animateCall, animateParams, sequence, sequenceCall, sequenceParams, sequenceReverse, sequenceRatio, ticker, cjsProps, css, protect, override, from, set, id, events, sequenceTarget, dynamic, drag, clamp, startPaused, clean, obj, seriesWait, sequenceWait, rate, pauseOnBlur, easeAmount, easeFrequency, timeUnit, timeCheck, noAnimateCall, pathDamp, rewindPick, style, group) {
58653
- var sig = "target, props, time, ease, call, params, wait, waitedCall, waitedParams, loop, loopCount, loopWait, loopCall, loopParams, loopWaitCall, loopWaitParams, loopPick, rewind, rewindWait, rewindCall, rewindParams, rewindWaitCall, rewindWaitParams, rewindTime, rewindEase, startCall, startParams, animateCall, animateParams, sequence, sequenceCall, sequenceParams, sequenceReverse, sequenceRatio, ticker, cjsProps, css, protect, override, from, set, id, events, sequenceTarget, dynamic, drag, clamp, startPaused, clean, obj, seriesWait, sequenceWait, rate, pauseOnBlur, easeAmount, easeFrequency, timeUnit, timeCheck, noAnimateCall, pathDamp, rewindPick, style, group";
58998
+ zim.animate = function(target, props, time, ease, call, params, wait, waitedCall, waitedParams, loop, loopCount, loopWait, loopCall, loopParams, loopWaitCall, loopWaitParams, loopPick, rewind, rewindWait, rewindCall, rewindParams, rewindWaitCall, rewindWaitParams, rewindTime, rewindEase, rewindPick, startCall, startParams, animateCall, animateParams, sequence, sequenceCall, sequenceParams, sequenceReverse, sequenceRatio, ticker, cjsProps, css, protect, override, from, set, id, events, sequenceTarget, dynamic, drag, clamp, startPaused, clean, obj, seriesWait, sequenceWait, rate, pauseOnBlur, easeAmount, easeFrequency, timeUnit, timeCheck, noAnimateCall, pathDamp, style, group) {
58999
+ var sig = "target, props, time, ease, call, params, wait, waitedCall, waitedParams, loop, loopCount, loopWait, loopCall, loopParams, loopWaitCall, loopWaitParams, loopPick, rewind, rewindWait, rewindCall, rewindParams, rewindWaitCall, rewindWaitParams, rewindTime, rewindEase, rewindPick, startCall, startParams, animateCall, animateParams, sequence, sequenceCall, sequenceParams, sequenceReverse, sequenceRatio, ticker, cjsProps, css, protect, override, from, set, id, events, sequenceTarget, dynamic, drag, clamp, startPaused, clean, obj, seriesWait, sequenceWait, rate, pauseOnBlur, easeAmount, easeFrequency, timeUnit, timeCheck, noAnimateCall, pathDamp, style, group";
58654
59000
 
58655
59001
  if (target && (target.props || target.obj)) {
58656
59002
  var duo; if (duo = zob(zim.animate, arguments, sig)) return duo;
@@ -58676,12 +59022,12 @@ RETURNS the target for chaining (or null if no target is provided and run on zim
58676
59022
  if (zot(waitedCall)) waitedCall = DS.waitedCall!=null?DS.waitedCall:null;
58677
59023
  if (zot(waitedParams)) waitedParams = DS.waitedParams!=null?DS.waitedParams:null;
58678
59024
  if (zot(loop)) loop = DS.loop!=null?DS.loop:null;
59025
+ if (zot(loopWaitParams)) loopWaitParams = DS.loopWaitParams!=null?DS.loopWaitParams:null;
58679
59026
  if (zot(loopCount)) loopCount = DS.loopCount!=null?DS.loopCount:null;
58680
59027
  if (zot(loopWait)) loopWait = DS.loopWait!=null?DS.loopWait:null;
58681
59028
  if (zot(loopCall)) loopCall = DS.loopCall!=null?DS.loopCall:null;
58682
59029
  if (zot(loopParams)) loopParams = DS.loopParams!=null?DS.loopParams:null;
58683
59030
  if (zot(loopWaitCall)) loopWaitCall = DS.loopWaitCall!=null?DS.loopWaitCall:null;
58684
- if (zot(loopWaitParams)) loopWaitParams = DS.loopWaitParams!=null?DS.loopWaitParams:null;
58685
59031
  if (zot(loopPick)) loopPick = DS.loopPick!=null?DS.loopPick:null;
58686
59032
  if (zot(rewind)) rewind = DS.rewind!=null?DS.rewind:null;
58687
59033
  if (zot(rewindWait)) rewindWait = DS.rewindWait!=null?DS.rewindWait:null;
@@ -58691,6 +59037,7 @@ RETURNS the target for chaining (or null if no target is provided and run on zim
58691
59037
  if (zot(rewindWaitParams)) rewindWaitParams = DS.rewindWaitParams!=null?DS.rewindWaitParams:null;
58692
59038
  if (zot(rewindTime)) rewindTime = DS.rewindTime!=null?DS.rewindTime:null;
58693
59039
  if (zot(rewindEase)) rewindEase = DS.rewindEase!=null?DS.rewindEase:null;
59040
+ if (zot(rewindPick)) rewindPick = DS.rewindPick!=null?DS.rewindPick:null;
58694
59041
  if (zot(startCall)) startCall = DS.startCall!=null?DS.startCall:null;
58695
59042
  if (zot(startParams)) startParams = DS.startParams!=null?DS.startParams:null;
58696
59043
  if (zot(animateCall)) animateCall = DS.animateCall!=null?DS.animateCall:null;
@@ -58726,7 +59073,6 @@ RETURNS the target for chaining (or null if no target is provided and run on zim
58726
59073
  if (zot(timeCheck)) timeCheck = DS.timeCheck!=null?DS.timeCheck:null;
58727
59074
  if (zot(noAnimateCall)) noAnimateCall = DS.noAnimateCall!=null?DS.noAnimateCall:null;
58728
59075
  if (zot(pathDamp)) pathDamp = DS.pathDamp!=null?DS.pathDamp:null;
58729
- if (zot(rewindPick)) rewindPick = DS.rewindPick!=null?DS.rewindPick:null;
58730
59076
 
58731
59077
  if (!target) target = {}; // ZIM 018 replacing: return; from 10.9.0
58732
59078
  var AN = zim.ANIMATE;
@@ -58939,7 +59285,7 @@ RETURNS the target for chaining (or null if no target is provided and run on zim
58939
59285
  if (i==0 && sequence!=0) seqTime = timeType=="s"?.02:20; // patched in 10.7.0 and 10.7.1
58940
59286
 
58941
59287
  // zim.animate(tar, tar.zimObj, time, ease, (i==target.length-1?call:null), (i==target.length-1?params:null)
58942
- zim.animate(tar, tar.zimObj, time, ease, (i==target.length-1?sequenceDone:null), null, wait, waitedCall, waitedParams, null, null, null, null, null, null, null, loopPick, null, null, null, null, null, null, rewindTime, rewindEase, startCall, startParams, animateCall, animateParams, null, sequenceCall, sequenceParams, null, null, ticker, zim.copy(cjsProps), css, protect, override, null, set, id, events, sequenceTarget, dynamic, drag, clamp, startPaused, clean, obj, seriesWait, seqTime, rrr, pauseOnBlur, easeAmount, easeFrequency, timeUnit, timeCheck, noAnimateCall, pathDamp, rewindPick, style, group); // do not send from!
59288
+ zim.animate(tar, tar.zimObj, time, ease, (i==target.length-1?sequenceDone:null), null, wait, waitedCall, waitedParams, null, null, null, null, null, null, null, loopPick, null, null, null, null, null, null, rewindTime, rewindEase, rewindPick, startCall, startParams, animateCall, animateParams, null, sequenceCall, sequenceParams, null, null, ticker, zim.copy(cjsProps), css, protect, override, null, set, id, events, sequenceTarget, dynamic, drag, clamp, startPaused, clean, obj, seriesWait, seqTime, rrr, pauseOnBlur, easeAmount, easeFrequency, timeUnit, timeCheck, noAnimateCall, pathDamp, style, group); // do not send from!
58943
59289
 
58944
59290
  }
58945
59291
  return sequenceTarget;
@@ -59289,7 +59635,7 @@ RETURNS the target for chaining (or null if no target is provided and run on zim
59289
59635
  }
59290
59636
  }
59291
59637
 
59292
- // props, time, ease, call, params, wait, waitedCall, waitedParams, loop, loopCount, loopWait, loopCall, loopParams, loopWaitCall, loopWaitParams, loopPick, rewind, rewindWait, rewindCall, rewindParams, rewindWaitCall, rewindWaitParams, rewindTime, rewindEase, startCall, startParams, animateCall, animateParams, sequence, sequenceCall, sequenceParams, sequenceReverse, sequenceRatio, ticker, cjsProps, css, protect, override, from, set, id, events, sequenceTarget, dynamic, drag, clamp, startPaused, clean, obj, seriesWait, sequenceWait, rate, pauseOnBlur, easeAmount, easeFrequency, timeUnit, timeCheck, noAnimateCall, pathDamp, rewindPick
59638
+ // props, time, ease, call, params, wait, waitedCall, waitedParams, loop, loopCount, loopWait, loopCall, loopParams, loopWaitCall, loopWaitParams, loopPick, rewind, rewindWait, rewindCall, rewindParams, rewindWaitCall, rewindWaitParams, rewindTime, rewindEase, rewindPick, startCall, startParams, animateCall, animateParams, sequence, sequenceCall, sequenceParams, sequenceReverse, sequenceRatio, ticker, cjsProps, css, protect, override, from, set, id, events, sequenceTarget, dynamic, drag, clamp, startPaused, clean, obj, seriesWait, sequenceWait, rate, pauseOnBlur, easeAmount, easeFrequency, timeUnit, timeCheck, noAnimateCall, pathDamp
59293
59639
 
59294
59640
  // -----------------------------
59295
59641
  // NORMALIZED TWEEN COMING THROUGH
@@ -63396,7 +63742,7 @@ Style.remove("color");
63396
63742
  // add styles for a Dial - overwriting all previous Dial styles
63397
63743
  Style.addType("Dial", {useTicks:false, backgroundColor:yellow});
63398
63744
 
63399
- // remember current style using a "default" id
63745
+ // remember current style using a "default" id - also see with ID below
63400
63746
  Style.remember();
63401
63747
 
63402
63748
  // new Dials will use ticks and not be yellow
@@ -63411,7 +63757,7 @@ Style.remember("myID");
63411
63757
  // add styles for a group (existing objects are not changed - new ones will be)
63412
63758
  Style.addGroup("big", {size:100});
63413
63759
 
63414
- the STYLE at the time myID was remembered will be active from now on
63760
+ // the STYLE at the time myID was remembered will be active from now on
63415
63761
  Style.recall("myID");
63416
63762
  END EXAMPLE
63417
63763
 
@@ -66612,6 +66958,7 @@ allowToggle - (default true) set to false to not allow grid to toggle between pe
66612
66958
  cache - (default true) cache the grid
66613
66959
  numbers - (default true) show numbers on grid
66614
66960
  mouseOutside - (default true) set to false to not move grid values if mouse is outside the grid
66961
+ cross - (default true) set to false to not show cross in grid
66615
66962
  style - (default true) set to false to ignore styles set with the STYLE - will receive original parameter defaults
66616
66963
  group - (default null) set to String (or comma delimited String) so STYLE can set default styles to the group(s) (like a CSS class)
66617
66964
  inherit - (default null) used internally but can receive an {} of styles directly
@@ -69160,6 +69507,7 @@ PROPERTIES
69160
69507
  type - holds the class name as a String
69161
69508
  items - get the original items array passed to the pack (including addAt() and removeFrom() changes)
69162
69509
  currentItems - get the array of items in the current order (this may be different if dragOrder is true)
69510
+ content - the ZIM Container holding the items
69163
69511
  cols - get the current number of columns
69164
69512
  rows - get the current number of rows
69165
69513
  iterations - get the number of times the pack was made to optimize its size
@@ -70133,6 +70481,188 @@ alpha, cursor, shadow, name, mouseChildren, mouseEnabled, parent, numChildren, e
70133
70481
  zim.extend(zim.Beads, zim.Container, ["clone","dispose"], "zimContainer", false);
70134
70482
  //-66.7
70135
70483
 
70484
+
70485
+ /*--
70486
+ zim.Bullets(list, bulletType, size, color, cols, font, italic, bold, variant, shiftH, shiftV, spacing, spacingH, spacingV, colSpacing, bulletAlign, style, group, inherit)
70487
+
70488
+ Bullets
70489
+ zim class - extends a zim.Tile which extends a zim.Container
70490
+
70491
+ DESCRIPTION
70492
+ Bullets creates a list with bullet points or custom bullet types.
70493
+ Different bullet types can be specified such as circle, square, dash, or number.
70494
+ The bullets can be arranged in multiple columns with customizable spacing.
70495
+
70496
+ EXAMPLE
70497
+ new Bullets(["First item", "Second item", "Third item"]).center();
70498
+ END EXAMPLE
70499
+
70500
+ EXAMPLE
70501
+ new Bullets({
70502
+ list:["Red bullet", "Purple bullet"],
70503
+ bulletType:"square",
70504
+ size:18,
70505
+ color:series(red, purple).every(2),
70506
+ cols:2,
70507
+ spacing:10,
70508
+ colSpacing:40
70509
+ }).center();
70510
+ END EXAMPLE
70511
+
70512
+ EXAMPLE
70513
+ // Nested Bullets
70514
+ // must import ZIM pizzazz for makeIcon
70515
+ new Bullets({
70516
+ list:["Share puzzles as present", new Bullets({
70517
+ list:["Birthdays", "Babies", "Family Pics", "Grads"],
70518
+ bulletType:makeIcon("heart", red, .5)
70519
+ }), "Share Puzzles for", new Bullets({
70520
+ list:["Company Sites", "Social Media", "Marketing Games", "Forum Fame"],
70521
+ bulletType:makeIcon("pic", purple, .5)
70522
+ })],
70523
+ bulletType:makeIcon("checkmark", green.darken(.2), .8),
70524
+ size:40,
70525
+ spacing:20,
70526
+ spacingV:40
70527
+ }).center();
70528
+ END EXAMPLE
70529
+
70530
+ PARAMETERS
70531
+ ** supports DUO - parameters or single object with properties below
70532
+ ** supports VEE - parameters marked with ZIM VEE mean a zim Pick() object or Pick Literal can be passed
70533
+ Pick Literal formats: [1,3,2] - random; {min:10, max:20} - range; series(1,2,3) - order, function(){return result;} - function
70534
+ ** supports OCT - parameter defaults can be set with STYLE control (like CSS)
70535
+ list - (default ["One", "Two", "Three"]) an array of text items for the bullet list
70536
+ bulletType - |ZIM VEE| (default "circle") the style of bullet - options: "circle", "square", "dash", "number" or "numbers", or a ZIM object
70537
+ size - (default null) the font size of the text
70538
+ color - (default null) the color of the text
70539
+ cols - (default 1) the number of columns to arrange the bullets in
70540
+ font - (default null) the font family for the text
70541
+ italic - (default null) set to true for italic text
70542
+ bold - (default null) set to true for bold text
70543
+ variant - (default null) the font variant for the text
70544
+ shiftH - (default null) horizontal shift of the bullet text
70545
+ shiftV - (default 2) vertical shift of the bullet text
70546
+ spacing - (default 14) the default tile spacing - also see spacingH and spacingV
70547
+ spacingH - (default spacing) horizontal spacing between bullet and text
70548
+ spacingV - (default spacing) vertical spacing
70549
+ colSpacing - (default spacingH) spacing between columns
70550
+ bulletAlign - (default LEFT) alignment of bullets
70551
+ style - (default true) set to false to ignore styles set with the STYLE
70552
+ group - (default null) set to String (or comma delimited String) so STYLE can set default styles to the group(s)
70553
+ inherit - (default null) used internally but can receive an {} of styles directly
70554
+
70555
+ METHODS
70556
+ clone(exact) - makes a copy with properties such as x, y, etc. also copied
70557
+ hasProp(property as String) - returns true if property exists on object else returns false
70558
+ dispose() - deletes object
70559
+
70560
+ ALSO: see ZIM Tile for methods such as:
70561
+ setProps(), setSpacing(), remake(), resize(), etc.
70562
+
70563
+ ALSO: ZIM adds all the methods listed under Container, such as:
70564
+ drag(), hitTestRect(), animate(), sca(), reg(), addTo(), removeFrom(), loop(), alp(), rot(), etc.
70565
+
70566
+ ALSO: see the CreateJS Easel Docs for Container methods, such as:
70567
+ on(), off(), getBounds(), setBounds(), cache(), uncache(), dispatchEvent(),
70568
+ addChild(), removeChild(), addChildAt(), getChildAt(), contains(), etc.
70569
+
70570
+ PROPERTIES
70571
+ type - holds the class name as a String
70572
+ list - the array of text items for the bullets
70573
+ bulletType - the bullet style being used
70574
+
70575
+ ALSO: see ZIM Container for properties such as:
70576
+ width, height, widthOnly, heightOnly, draggable, level, depth, group
70577
+ blendMode, hue, saturation, brightness, contrast, etc.
70578
+
70579
+ ALSO: see the CreateJS Easel Docs for Container properties, such as:
70580
+ x, y, rotation, scaleX, scaleY, regX, regY, skewX, skewY,
70581
+ alpha, cursor, shadow, name, mouseChildren, mouseEnabled, parent, numChildren, etc.
70582
+
70583
+ --*///+67.8
70584
+
70585
+ zim.Bullets = function(list, bulletType, size, color, cols, font, italic, bold, variant, shiftH, shiftV, spacing, spacingH, spacingV, colSpacing, bulletAlign, style, group, inherit) {
70586
+ var sig = "list, bulletType, size, color, cols, font, italic, bold, variant, shiftH, shiftV, spacing, spacingH, spacingV, colSpacing, bulletAlign, style, group, inherit";
70587
+ var duo; if (duo = zob(zim.Bullets, arguments, sig, this)) return duo;
70588
+ z_d("67.8");
70589
+
70590
+ this.group = group;
70591
+ var DS = style===false?group!=null?zim.getStyle(null,null,inherit,this.group):{}:zim.getStyle("Bullets", this.group, inherit);
70592
+
70593
+ // MONITOR
70594
+ var mID = this.mID = "z~"+(DS.monitor===false?"-":"Bullets");
70595
+
70596
+ if (zot(list)) list = DS.list!=null?DS.list:["One", "Two", "Three"];
70597
+ if (zot(bulletType)) bulletType = DS.bulletType!=null?DS.bulletType:"circle";
70598
+ if (zot(size)) size = DS.size!=null?DS.size:null;
70599
+ if (zot(color)) color = DS.color!=null?DS.color:null;
70600
+ if (zot(cols)) cols = DS.cols!=null?DS.cols:1;
70601
+ if (cols < 1) cols = 1;
70602
+ if (zot(font)) font = DS.font!=null?DS.font:null;
70603
+ if (zot(shiftH)) shiftH = DS.shiftH!=null?DS.shiftH:null;
70604
+ if (zot(italic)) italic = DS.italic!=null?DS.italic:null;
70605
+ if (zot(bold)) bold = DS.bold!=null?DS.bold:null;
70606
+ if (zot(variant)) variant = DS.variant!=null?DS.variant:null;
70607
+ if (zot(shiftV)) shiftV = DS.shiftV!=null?DS.shiftV:2;
70608
+ if (zot(spacing)) spacing = DS.spacing!=null?DS.spacing:14;
70609
+ if (zot(spacingH)) spacingH = DS.spacingH!=null?DS.spacingH:spacing;
70610
+ if (zot(spacingV)) spacingV = DS.spacingV!=null?DS.spacingV:spacing;
70611
+ if (zot(colSpacing)) colSpacing = DS.colSpacing!=null?DS.colSpacing:spacingH;
70612
+ if (zot(bulletAlign)) bulletAlign = DS.bulletAlign!=null?DS.bulletAlign:LEFT;
70613
+ var tileList = [];
70614
+ var num = 1;
70615
+ this.list = list;
70616
+ var icons = [];
70617
+ zim.loop(list, function(words, i) {
70618
+ if (words.type=="Bullets") { // nested Bullets
70619
+ tileList.push(new zim.Container(1,1));
70620
+ tileList.push(words);
70621
+ return;
70622
+ }
70623
+ const bt = zik(bulletType);
70624
+ icons.push(bt);
70625
+ if (bt.type && bt.clone) tileList.push(bt.clone());
70626
+ else if (bt == "circle") tileList.push(new zim.Circle(5, color));
70627
+ else if (bt == "square") tileList.push(new zim.Rectangle(10, 10, color));
70628
+ 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}));
70629
+ 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}));
70630
+ tileList.push(new zim.Label({text:words, size:size, font:font, color:color, italic:italic, bold:bold, variant:variant, shiftH:shiftH, shiftV:shiftV}));
70631
+ })
70632
+ if (cols > 1 ) {
70633
+ // need to shift pairs
70634
+ // [b1, w1, b2, w2, b3, w3, b4, w4, b5, w5]
70635
+ // [b1, w1, b4, w4, b2, w2, b5, w5, b3, w3]
70636
+ var temp = [];
70637
+ // [[b1, w1, b2, w2, b3, w3], [b4, w4, b5,w5]]
70638
+ zim.loop(cols, function(){temp.push([])});
70639
+ zim.loop(tileList, function(item, i, t) {
70640
+ temp[Math.floor(i/Math.ceil(t/cols))].push(item);
70641
+ })
70642
+ tileList = [];
70643
+ zim.loop(temp[0].length, function(i) {
70644
+ zim.loop(temp, function(list) {
70645
+ tileList.push(list[i], list[i+1])
70646
+ })
70647
+ }, null, null, 2); // steps of 2
70648
+ }
70649
+ 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);
70650
+ this.type = "Bullets";
70651
+
70652
+ this.clone = function(exact) {
70653
+ if (exact) {
70654
+ var exactItems = [];
70655
+ for (var i=0; i<icons.length; i++) {
70656
+ var icon = icons[i];
70657
+ exactItems.push(icon.clone?icon.clone(true):icon);
70658
+ }
70659
+ }
70660
+ 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));
70661
+ };
70662
+ };
70663
+ zim.extend(zim.Bullets, zim.Tile, ["clone"], "zimTile", false);
70664
+ //-67.8
70665
+
70136
70666
  /*--
70137
70667
  zim.Layout = function(holder, regions, lastMargin, lastMarginMin, backgroundColor, vertical, showRegions, scalingObject, hideKey, style, group, inherit)
70138
70668
 
@@ -80219,7 +80749,7 @@ EXAMPLE
80219
80749
  const obj = new Container(500,500);
80220
80750
  F.makeCircles().center(obj).animate({props:{scale:2}, rewind:true, loop:true});
80221
80751
 
80222
- new zim.Perspective({
80752
+ new Perspective({
80223
80753
  obj: obj,
80224
80754
  points:[
80225
80755
  {x:-obj.width/2, y:-obj.height/2+50},
@@ -80236,7 +80766,7 @@ EXAMPLE
80236
80766
  const obj = new Container(500,500);
80237
80767
  F.makeCircles().center(obj).animate({props:{scale:2}, rewind:true, loop:true});
80238
80768
 
80239
- const perspective = new zim.Perspective(obj).center();
80769
+ const perspective = new Perspective(obj).center();
80240
80770
 
80241
80771
  perspective.selectSide(3);
80242
80772
  perspective.updateCorner(perspective.selectCorner(0).mov(0,100));
@@ -80250,7 +80780,7 @@ EXAMPLE
80250
80780
  const obj = new Container(500,500);
80251
80781
  F.makeCircles().center(obj).animate({props:{scale:2}, rewind:true, loop:true});
80252
80782
 
80253
- const perspective = new zim.Perspective(obj).center();
80783
+ const perspective = new Perspective(obj).center();
80254
80784
 
80255
80785
  perspective.selectSide(0); // comment this out to see the difference
80256
80786
  const corner = perspective.selectCorner(1).wiggle("x",null,50,100,.5,1);
@@ -80265,7 +80795,7 @@ EXAMPLE
80265
80795
  const obj = new Container(500,500);
80266
80796
  F.makeCircles().center(obj).animate({props:{scale:2}, rewind:true, loop:true});
80267
80797
 
80268
- const perspective = new zim.Perspective(obj).center();
80798
+ const perspective = new Perspective(obj).center();
80269
80799
 
80270
80800
  const point = perspective.selectCorner(2);
80271
80801
  const p = perspective.blob.globalToLocal(W,H); // the corner control is in the blob
@@ -83250,9 +83780,9 @@ EXAMPLE
83250
83780
  // With emitter on complete and re-shuffle
83251
83781
  STYLE = {Label:{backgroundColor:white}};
83252
83782
  const shuffler = new Shuffler("Will this wind be so mighty ?")
83253
- .center();
83783
+ .center();
83254
83784
  const emitter = new Emitter({startPaused:true})
83255
- .center();
83785
+ .center();
83256
83786
  shuffler.on("complete", ()=>{
83257
83787
  shuffler.shuffle(2, 2, 4);
83258
83788
  emitter.spurt(20);
@@ -90509,6 +91039,9 @@ See https://zimjs.com/frame.html for sample templates using Frame.
90509
91039
  The first frame made is called the zimDefaultFrame - or zdf.
90510
91040
  It will also have the default stage for addTo(), center(), etc.
90511
91041
  Use setDefault() on another frame to change the default frame.
91042
+ Pass a previous frame to the nextFrame parameter of a subsequent frame
91043
+ for interactivity on both frames. Any number of frames can be used.
91044
+ This is good for optimization to split interface from dynamic content.
90512
91045
 
90513
91046
  As of ZIM ZIM 01, ZIM will make F, S, W, H global variables
90514
91047
  that reference the zimDefaultFrame, its stage and the stage width and height.
@@ -92009,7 +92542,6 @@ zim.Frame = function(scaling, width, height, color, outerColor, ready, assets, p
92009
92542
  // 018 TRYING TO FIX CREATEJS ERROR IF SOUND LOADED AGAIN - BUT BREAKS LAZY LOAD
92010
92543
  // var emptyAssets = false;
92011
92544
 
92012
-
92013
92545
  for (i=0; i<assets.length; i++) {
92014
92546
  a = assets[i];
92015
92547
  // if (zim.assets[a]) {
@@ -92019,9 +92551,9 @@ zim.Frame = function(scaling, width, height, color, outerColor, ready, assets, p
92019
92551
  // // continue;
92020
92552
  // // }
92021
92553
  // }
92022
- if (a.replace) a = a.replace(/gf_/i, "https://fonts.googleapis.com/css?family=");
92554
+ if (a.replace) a = a.replace(/gf_/i, "https://fonts.googleapis.com/css?family=");
92023
92555
  // split multi into individual ZIM asset objects and make the first of these
92024
- if (a.assets) {
92556
+ if (a.assets) {
92025
92557
  var assetMulti = [];
92026
92558
  assets.splice(i, 1);
92027
92559
  if (!Array.isArray(a.assets)) a.assets = [a.assets];
@@ -97648,7 +98180,7 @@ function zimify(obj, a, b, c, d, list) {
97648
98180
  hitTestGrid:function(width, height, cols, rows, x, y, offsetX, offsetY, spacingX, spacingY, local, type) {
97649
98181
  return zim.hitTestGrid(this, width, height, cols, rows, x, y, offsetX, offsetY, spacingX, spacingY, local, type);
97650
98182
  },
97651
- animate:function(props, time, ease, call, params, wait, waitedCall, waitedParams, loop, loopCount, loopWait, loopCall, loopParams, loopWaitCall, loopWaitParams, loopPick, rewind, rewindWait, rewindCall, rewindParams, rewindWaitCall, rewindWaitParams, rewindTime, rewindEase, startCall, startParams, animateCall, animateParams, sequence, sequenceCall, sequenceParams, sequenceReverse, sequenceRatio, ticker, cjsProps, css, protect, override, from, set, id, events, sequenceTarget, dynamic, drag, clamp, startPaused, clean, obj, seriesWait, sequenceWait, rate, pauseOnBlur, easeAmount, easeFrequency, timeUnit, timeCheck, noAnimateCall, pathDamp, rewindPick) {
98183
+ animate:function(props, time, ease, call, params, wait, waitedCall, waitedParams, loop, loopCount, loopWait, loopCall, loopParams, loopWaitCall, loopWaitParams, loopPick, rewind, rewindWait, rewindCall, rewindParams, rewindWaitCall, rewindWaitParams, rewindTime, rewindEase, rewindPick, startCall, startParams, animateCall, animateParams, sequence, sequenceCall, sequenceParams, sequenceReverse, sequenceRatio, ticker, cjsProps, css, protect, override, from, set, id, events, sequenceTarget, dynamic, drag, clamp, startPaused, clean, obj, seriesWait, sequenceWait, rate, pauseOnBlur, easeAmount, easeFrequency, timeUnit, timeCheck, noAnimateCall, pathDamp) {
97652
98184
  if (props && (props.props || props.obj) && isDUO(arguments)) {
97653
98185
  // run this if duo but only if props object has a props or obj object
97654
98186
  // can you believe that sentence makes sense
@@ -97657,7 +98189,7 @@ function zimify(obj, a, b, c, d, list) {
97657
98189
  // it can only be a configuration object if there is a props or obj property
97658
98190
  arguments[0].target = this; return zim.animate(arguments[0]);
97659
98191
  }
97660
- else {return zim.animate(this, props, time, ease, call, params, wait, waitedCall, waitedParams, loop, loopCount, loopWait, loopCall, loopParams, loopWaitCall, loopWaitParams, loopPick, rewind, rewindWait, rewindCall, rewindParams, rewindWaitCall, rewindWaitParams, rewindTime, rewindEase, startCall, startParams, animateCall, animateParams, sequence, sequenceCall, sequenceParams, sequenceReverse, sequenceRatio, ticker, cjsProps, css, protect, override, from, set, id, events, sequenceTarget, dynamic, drag, clamp, startPaused, clean, obj, seriesWait, sequenceWait, rate, pauseOnBlur, easeAmount, easeFrequency, timeUnit, timeCheck, noAnimateCall, pathDamp, rewindPick);}
98192
+ else {return zim.animate(this, props, time, ease, call, params, wait, waitedCall, waitedParams, loop, loopCount, loopWait, loopCall, loopParams, loopWaitCall, loopWaitParams, loopPick, rewind, rewindWait, rewindCall, rewindParams, rewindWaitCall, rewindWaitParams, rewindTime, rewindEase, rewindPick, startCall, startParams, animateCall, animateParams, sequence, sequenceCall, sequenceParams, sequenceReverse, sequenceRatio, ticker, cjsProps, css, protect, override, from, set, id, events, sequenceTarget, dynamic, drag, clamp, startPaused, clean, obj, seriesWait, sequenceWait, rate, pauseOnBlur, easeAmount, easeFrequency, timeUnit, timeCheck, noAnimateCall, pathDamp);}
97661
98193
  },
97662
98194
  pauseAnimate:function(){return this;},
97663
98195
  stopAnimate:function(){return this;},
@@ -98232,7 +98764,6 @@ zim.setBlurDetect = function() {
98232
98764
  obj = zim.pauseOnBlur[i];
98233
98765
  obj.pauseOnBlurPaused = obj.paused;
98234
98766
  obj.pause(true);
98235
- zogr(obj.type, obj.special, obj.pauseOnBlurPaused)
98236
98767
  }
98237
98768
  }
98238
98769
  if (zim.pauseAnimateOnBlur && zim.animatedObjects) {
@@ -98776,7 +99307,7 @@ getLatestVersions(function(versions) {
98776
99307
  });
98777
99308
  END EXAMPLE
98778
99309
  --*///+82.1
98779
- zim.VERSION = "019/zim";
99310
+ zim.VERSION = "020/zim";
98780
99311
  //-82.1
98781
99312
 
98782
99313
  /*--
@@ -101793,7 +102324,7 @@ SEE: https://zimjs.com/018/handtrack.html - replacing the cursor
101793
102324
  GENERAL ML5 FUNCTIONALITY
101794
102325
  ML5 can give very accurate hand poses, face poses and body poses and results return points.
101795
102326
  These points can be used to place ZIM objects or with a ZIM Shape to make circles, etc.
101796
- There are other features too like shape recognition, blurring backgrounds, etc.
102327
+ There are other features too like shape recognition, segmentation, blurring backgrounds, etc.
101797
102328
  These can all be used in ZIM - for using ML5 for interaction see the HAND TRACKING section above.
101798
102329
  SEE: https://zimjs.com/ml5/ - general ML5 integration examples
101799
102330
 
@@ -103119,6 +103650,1187 @@ https://codepen.io/zimjs/pen/ZqNYxX
103119
103650
 
103120
103651
  //-151
103121
103652
 
103653
+
103654
+ //////////////// ZIM CHART //////////////
103655
+
103656
+ // Zim Chart adds graph and chart classes and functions
103657
+
103658
+ /*--
103659
+ zim.bestFit = function (dataH, dataV)
103660
+
103661
+ bestFit
103662
+ function
103663
+
103664
+ DESCRIPTION
103665
+ Calculates a linear least-squares fit through the provided horizontal and vertical value arrays.
103666
+ Returns the slope and intercept for the best-fit line y = slope * x + intercept.
103667
+ Used internally by PlotGraph
103668
+
103669
+ EXAMPLE
103670
+ const fit = bestFit([0,50,100], [0,40,90]);
103671
+ END EXAMPLE
103672
+
103673
+ PARAMETERS
103674
+ dataH - (required) array of horizontal x values
103675
+ dataV - (required) array of vertical y values
103676
+
103677
+ RETURNS
103678
+ Object with slope and intercept properties
103679
+
103680
+ --*///+160
103681
+
103682
+ // THE CODE FOR THE CHART MODULE IS LINKED TO AT THE TOP OF THE DOCS
103683
+
103684
+ //-160
103685
+
103686
+ /*--
103687
+ zim.Graph = function(width, height, title, labelH, labelV, dataH, dataV, footer, backgroundColor, color, font, size, dataColor, dataSize, padding, gridThickness, gridColor, axisThickness, axisColor, decimalsH, decimalsV, style, group, inherit)
103688
+
103689
+ Graph
103690
+ zim class - extends a zim.Container which extends a createjs.Container
103691
+
103692
+ DESCRIPTION
103693
+ Creates a basic chart (no data) with horizontal and vertical axes, optional title, footer, and axis labels.
103694
+ The graph can use arrays of values or a {start, end, step} object for dataH and dataV.
103695
+ Graph is used by other graphs like BarGraph, LineGraph, PlotGraph to create the axis.
103696
+ Then these other graphs draw the data.
103697
+
103698
+ EXAMPLE
103699
+ const graph = new Graph(500, 400, "Sales", "Month", "Revenue", [1,2,3,4], [100,150,200,250], "Q1")
103700
+ .center();
103701
+ END EXAMPLE
103702
+
103703
+ PARAMETERS
103704
+ ** supports DUO - parameters or single object with properties below
103705
+ ** supports OCT - parameter defaults can be set with STYLE control (like CSS)
103706
+ width - (default 500) width of the chart
103707
+ height - (default 500) height of the chart
103708
+ title - (default null) text or Label for the title
103709
+ labelH - (default null) text or Label for the horizontal axis label
103710
+ labelV - (default null) text or Label for the vertical axis label
103711
+ dataH - (default null) array of horizontal values or {start,end,step} for tick values
103712
+ dataV - (default null) array of vertical values or {start,end,step} for tick values
103713
+ footer - (default null) text or Label for the footer
103714
+ backgroundColor - (default white) background fill color
103715
+ color - (default dark) color for labels and axis lines
103716
+ font - (default null) font for labels
103717
+ size - (default 14) font size for title and labels
103718
+ dataColor - (default grey) color for axis data labels
103719
+ dataSize - (default 10) size for data labels
103720
+ padding - (default 20) padding around the chart content
103721
+ gridThickness - (default 1) thickness of the grid lines
103722
+ gridColor - (default light) color of the grid lines
103723
+ axisThickness - (default 1) thickness of the axis lines
103724
+ axisColor - (default dark) color of the axis lines
103725
+ decimalsH - (default 1) decimal precision for horizontal labels
103726
+ decimalsV - (default 1) decimal precision for vertical labels
103727
+ style - (default true) set to false to ignore STYLE defaults
103728
+ group - (default null) group name(s) for STYLE
103729
+ inherit - (default null) direct style object or inherit instruction
103730
+
103731
+ METHODS
103732
+ offsetH(offset) - update horizontal axis labels by offset
103733
+ offsetV(offset) - update vertical axis labels by offset
103734
+ clone() - copies the graph
103735
+
103736
+ ALSO: ZIM adds all the methods listed under Container, such as:
103737
+ drag(), hitTestRect(), animate(), sca(), reg(), mov(), center(), centerReg(),
103738
+ addTo(), removeFrom(), loop(), outline(), place(), pos(), alp(), rot(), setMask(), etc.
103739
+ ALSO: see the CreateJS Easel Docs for Container methods, such as:
103740
+ on(), off(), getBounds(), setBounds(), uncache(), updateCache(), dispatchEvent(),
103741
+ addChild(), removeChild(), addChildAt(), getChildAt(), contains(), removeAllChildren(), etc.
103742
+
103743
+ PROPERTIES
103744
+ type - holds the class name as a String
103745
+ axisH - the horizontal axis line
103746
+ axisV - the vertical axis line
103747
+ linesH - container for horizontal grid lines
103748
+ linesV - container for vertical grid lines
103749
+ labelsH - container for horizontal labels
103750
+ labelsV - container for vertical labels
103751
+ backgroundColor - the background fill color
103752
+ firstDataH - first horizontal data value
103753
+ lastDataH - last horizontal data value
103754
+ firstDataV - first vertical data value
103755
+ lastDataV - last vertical data value
103756
+ --*///+161
103757
+
103758
+ // THE CODE FOR THE CHART MODULE IS LINKED TO AT THE TOP OF THE DOCS
103759
+
103760
+ //-161
103761
+
103762
+ /*--
103763
+ zim.Legend = function(graph, data, colors, gradients, swatchSize, color, font, size, spacingH, spacingV, backdropColor, backdropPadding, backdropPaddingH, backdropPaddingV, style, group, inherit)
103764
+
103765
+ Legend
103766
+ zim class - extends a zim.Tile which extends a zim.Container
103767
+
103768
+ DESCRIPTION
103769
+ Creates a legend for chart series using swatches or icons and labels.
103770
+ If data is omitted and a graph is supplied, the legend uses the graph's info or data.
103771
+
103772
+ EXAMPLE
103773
+ new Legend(graph).pos(50,50,RIGHT,BOTTOM);
103774
+ END EXAMPLE
103775
+
103776
+ EXAMPLE
103777
+ const graph = new LineGraph({
103778
+ title: "Graph",
103779
+ info: {
103780
+ labelH: "Time",
103781
+ labelV: "Height",
103782
+ dataH: {start: 0, end: 70, step: 10},
103783
+ dataV: {start: 20, end: 90, step: 10}
103784
+ },
103785
+ data: [
103786
+ {item: "Elliot", icon: null, dataH: [5, 10, 15, 20], dataV: [30, 45, 65, 85]},
103787
+ {item: "Madeline", icon: null, dataH: [5, 10, 15, 20], dataV: [30, 45, 55, 60]},
103788
+ {item: "RoseAnne", icon: null, dataH: [10, 20, 30, 40, 50], dataV: [30, 40, 50, 55, 55]},
103789
+ {item: "Dan", icon: null, dataH: [10, 20, 30, 40, 50, 60], dataV: [30, 45, 75, 80, 80, 80]},
103790
+ ]
103791
+ });
103792
+ STYLE = {infoicon: {size: 12, color: white}, onTop: false, collapse: true, titleBar: "Line Graph", draggable: true};
103793
+ const panel = new Panel(graph.width, graph.height + 30, graph).center();
103794
+
103795
+ const legend = new Legend(graph);
103796
+ STYLE = {infoicon: {size: 12, color: white}, collapse: true, titleBar: "Legend", draggable: true};
103797
+ new Panel(legend.width + 20, legend.height + 30, legend).pos(60, 50, RIGHT, BOTTOM);
103798
+ END EXAMPLE
103799
+
103800
+ PARAMETERS
103801
+ ** supports DUO - parameters or single object with properties below
103802
+ ** supports OCT - parameter defaults can be set with STYLE control (like CSS)
103803
+ graph - (default null) chart instance to derive legend entries from
103804
+ data - (default null) array of labels or objects for legend entries
103805
+ colors - (default null) array of colors for legend swatches
103806
+ gradients - (default false) if true use gradient swatches
103807
+ swatchSize - (default 20) size of each legend swatch
103808
+ color - (default dark) text color for labels
103809
+ font - (default null) font for labels
103810
+ size - (default 16) font size for labels
103811
+ spacingH - (default 10) horizontal spacing between legend items
103812
+ spacingV - (default 10) vertical spacing between legend rows
103813
+ backdropColor - (default lighter) background color behind legend items
103814
+ backdropPadding - (default 20) padding inside the backdrop
103815
+ backdropPaddingH - (default 10) horizontal padding inside the backdrop
103816
+ backdropPaddingV - (default 20) vertical padding inside the backdrop
103817
+ style - (default true) set to false to ignore STYLE defaults
103818
+ group - (default null) group name(s) for STYLE
103819
+ inherit - (default null) direct style object or inherit instruction
103820
+
103821
+ METHODS
103822
+ clone() - copies the legend
103823
+
103824
+ PROPERTIES
103825
+ data - legend data array
103826
+ finalColors - computed colors used in the legend
103827
+ --*///+162
103828
+
103829
+ // THE CODE FOR THE CHART MODULE IS LINKED TO AT THE TOP OF THE DOCS
103830
+
103831
+ //-162
103832
+
103833
+ /*--
103834
+ zim.LineGraph = function(width, height, title, info, data, showDots, smooth, colors, thickness, gradients, footer, backgroundColor, color, font, size, dataColor, dataSize, padding, gridThickness, gridColor, axisThickness, axisColor, decimalsH, decimalsV, style, group, inherit)
103835
+
103836
+ LineGraph
103837
+ zim class - extends a zim.Graph which extends a zim.Container
103838
+
103839
+ DESCRIPTION
103840
+ Draws one or more series of line graphs on a shared axis system.
103841
+ Supports optional dot markers, smoothing, and fill gradients beneath the lines.
103842
+
103843
+ See: https://zimjs.com/020/linegraph.html
103844
+
103845
+ EXAMPLE
103846
+ new LineGraph(500, 400, "Performance").center();
103847
+ END EXAMPLE
103848
+
103849
+ EXAMPLE
103850
+ // must import zim_chart
103851
+ const graph = new LineGraph({
103852
+ title: "Graph",
103853
+ info: {
103854
+ labelH: "Time",
103855
+ labelV: "Height",
103856
+ dataH: {start: 0, end: 70, step: 10},
103857
+ dataV: {start: 20, end: 90, step: 10}
103858
+ },
103859
+ data: [
103860
+ {item: "Elliot", icon: null, dataH: [5, 10, 15, 20], dataV: [30, 45, 65, 85]},
103861
+ {item: "Madeline", icon: null, dataH: [5, 10, 15, 20], dataV: [30, 45, 55, 60]},
103862
+ {item: "RoseAnne", icon: null, dataH: [10, 20, 30, 40, 50], dataV: [30, 40, 50, 55, 55]},
103863
+ {item: "Dan", icon: null, dataH: [10, 20, 30, 40, 50, 60], dataV: [30, 45, 75, 80, 80, 80]},
103864
+ ],
103865
+ smooth: true,
103866
+ // showDots:true,
103867
+ // gradients:false
103868
+ });
103869
+ STYLE = {infoicon: {size: 12, color: white}, onTop: false, collapse: true, titleBar: "Line Graph", draggable: true};
103870
+ const panel = new Panel(graph.width, graph.height + 30, graph).center();
103871
+
103872
+ const legend = new Legend(graph);
103873
+ STYLE = {infoicon: {size: 12, color: white}, collapse: true, titleBar: "Legend", draggable: true};
103874
+ new Panel(legend.width + 20, legend.height + 30, legend).pos(60, 50, RIGHT, BOTTOM);
103875
+ END EXAMPLE
103876
+
103877
+ PARAMETERS
103878
+ ** supports DUO - parameters or single object with properties below
103879
+ ** supports OCT - parameter defaults can be set with STYLE control (like CSS)
103880
+ width - (default 500) width of the chart
103881
+ height - (default 500) height of the chart
103882
+ title - (default null) title text or Label
103883
+ info - (default null) object with labelH, labelV, dataH, dataV for axis definition
103884
+ data - (default null) array of objects with the following properties {item,icon,dataH,dataV}
103885
+ icon is optional
103886
+ showDots - (default !smooth) draw dots at each data point when true
103887
+ smooth - (default false) smooth the connecting lines using quadratic curves
103888
+ colors - (default series colors) array of line colors
103889
+ thickness - (default 2) line thickness
103890
+ gradients - (default true) if true draw gradient fills behind lines
103891
+ footer - (default null) footer text or Label
103892
+ backgroundColor - (default white) background fill color
103893
+ color - (default dark) color for labels and axis lines
103894
+ font - (default null) font for labels
103895
+ size - (default 14) font size for title and labels
103896
+ dataColor - (default grey) color for axis data labels
103897
+ dataSize - (default 10) size for data labels
103898
+ padding - (default 20) padding around the chart content
103899
+ gridThickness - (default 1) thickness of the grid lines
103900
+ gridColor - (default light) color of the grid lines
103901
+ axisThickness - (default 1) thickness of the axis lines
103902
+ axisColor - (default dark) color of the axis lines
103903
+ decimalsH - (default 1) decimal precision for horizontal labels
103904
+ decimalsV - (default 1) decimal precision for vertical labels
103905
+ style - (default true) set to false to ignore STYLE defaults
103906
+ group - (default null) group name(s) for STYLE
103907
+ inherit - (default null) direct style object or inherit instruction
103908
+
103909
+ METHODS
103910
+ clone() - copies the line graph
103911
+
103912
+ PROPERTIES
103913
+ info - axis definition object
103914
+ data - series data array
103915
+ finalColors - colors used for series lines
103916
+ gradients - whether gradients are enabled
103917
+ --*///+163
103918
+
103919
+ // THE CODE FOR THE CHART MODULE IS LINKED TO AT THE TOP OF THE DOCS
103920
+
103921
+ //-163
103922
+
103923
+ /*--
103924
+ zim.BarGraph = function(width, height, title, info, data, gap, spacing, colors, thickness, gradients, footer, backgroundColor, color, font, size, dataColor, dataSize, padding, gridThickness, gridColor, axisThickness, axisColor, decimalsH, decimalsV, style, group, inherit)
103925
+
103926
+ BarGraph
103927
+ zim class - extends a zim.Graph which extends a zim.Container
103928
+
103929
+ DESCRIPTION
103930
+ Draws grouped bar charts on a shared axis system.
103931
+ Supports multiple series, optional gradients, and custom spacing between groups and bars.
103932
+
103933
+ See: https://zimjs.com/020/bargraph.html
103934
+
103935
+ EXAMPLE
103936
+ // must import zim_chart
103937
+ new BarGraph(500, 400, "Sales").center();
103938
+ END EXAMPLE
103939
+
103940
+ EXAMPLE
103941
+ // must import zim_chart
103942
+ const graph = new zim.BarGraph({
103943
+ title:"Sales of Vegetables",
103944
+ width: 700,
103945
+ // comment these out to see with light background
103946
+ backgroundColor: black,
103947
+ axisColor: light,
103948
+ gridColor: grey,
103949
+ color: lighter,
103950
+ dataColor: silver,
103951
+ // end of comment for light background
103952
+ info: {
103953
+ labelH: "Days",
103954
+ labelV: "Sales",
103955
+ dataH: {start: 1, end: 7, step: 1},
103956
+ dataV: {start: 0, end: 100, step: 10}
103957
+ },
103958
+ colors: series(purple, yellow, blue),
103959
+ data: [
103960
+ {item: "Cucumber", icon: null, dataH: [2, 3, 4, 5, 6], dataV: [10, 40, 50, 60, 20]},
103961
+ {item: "Lettuce", icon: null, dataH: [2, 3, 4, 5, 6], dataV: [70, 50, 20, 20, 40]},
103962
+ {item: "Cilantro", icon: null, dataH: [2, 3, 4, 5, 6], dataV: [20, 50, 80, 90, 50]},
103963
+ ],
103964
+ // gradients:false
103965
+ });
103966
+
103967
+ // optionally put graph in Panel
103968
+ STYLE = {infoicon: {size: 12, color: white}, onTop: false, collapse: true, titleBar: "Bar Graph", draggable: true};
103969
+ new Panel(graph.width, graph.height + 30, graph).center();
103970
+
103971
+ // optionally put legend in Panel
103972
+ const legend = new zim.Legend(graph);
103973
+ STYLE = {infoicon: {size: 12, color: white}, collapse: true, titleBar: "Legend", draggable: true};
103974
+ new Panel(legend.width + 20, legend.height + 30, legend).pos(60, 50, RIGHT, BOTTOM);
103975
+ STYLE = {}
103976
+ END EXAMPLE
103977
+
103978
+ PARAMETERS
103979
+ ** supports DUO - parameters or single object with properties below
103980
+ ** supports OCT - parameter defaults can be set with STYLE control (like CSS)
103981
+ width - (default null) width of the graph
103982
+ height - (default null) height of the graph
103983
+ title - (default null) title text or Label
103984
+ info - (default null) object with labelH, labelV, dataH, dataV for axis definition
103985
+ data - (default null) array of series objects {item,dataH,dataV}
103986
+ gap - (default 25) gap between series clusters
103987
+ spacing - (default 3) spacing between bars inside each cluster
103988
+ colors - (default series colors) array of bar colors
103989
+ thickness - (default 1) stroke thickness for bar outlines
103990
+ gradients - (default true) if true draw gradient fills for bars
103991
+ footer - (default null) footer text or Label
103992
+ backgroundColor - (default white) background fill color
103993
+ color - (default dark) color for labels and axis lines
103994
+ font - (default null) font for labels
103995
+ size - (default 14) font size for title and labels
103996
+ dataColor - (default grey) color for axis data labels
103997
+ dataSize - (default 10) size for data labels
103998
+ padding - (default 20) padding around the chart content
103999
+ gridThickness - (default 1) thickness of the grid lines
104000
+ gridColor - (default light) color of the grid lines
104001
+ axisThickness - (default 1) thickness of the axis lines
104002
+ axisColor - (default dark) color of the axis lines
104003
+ decimalsH - (default 1) decimal precision for horizontal labels
104004
+ decimalsV - (default 1) decimal precision for vertical labels
104005
+ style - (default true) set to false to ignore STYLE defaults
104006
+ group - (default null) group name(s) for STYLE
104007
+ inherit - (default null) direct style object or inherit instruction
104008
+
104009
+ METHODS
104010
+ clone() - copies the bar graph
104011
+
104012
+ PROPERTIES
104013
+ info - axis definition object
104014
+ data - series data array
104015
+ finalColors - colors used for bar series
104016
+ --*///+164
104017
+
104018
+ // THE CODE FOR THE CHART MODULE IS LINKED TO AT THE TOP OF THE DOCS
104019
+
104020
+ //-164
104021
+
104022
+ /*--
104023
+ zim.PlotGraph = function(width, height, title, info, data, extrapolate, colors, thickness, footer, backgroundColor, color, font, size, dataColor, dataSize, padding, gridThickness, gridColor, axisThickness, axisColor, decimalsH, decimalsV, style, group, inherit)
104024
+
104025
+ PlotGraph
104026
+ zim class - extends a zim.Graph which extends a zim.Container
104027
+
104028
+ DESCRIPTION
104029
+ Draws best-fit lines for one or more series of plotted data points on a graph.
104030
+ Each series can provide horizontal and vertical values for regression plotting.
104031
+
104032
+ See: https://zimjs.com/020/plotgraph.html
104033
+
104034
+ EXAMPLE
104035
+ // must import zim_chart
104036
+ new PlotGraph(500, 400, "Trend").center();
104037
+ END EXAMPLE
104038
+
104039
+ EXAMPLE
104040
+ // must import zim_chart
104041
+ const graph = new PlotGraph({
104042
+ title: "Plot of Population over Time",
104043
+ info: {
104044
+ labelH: "Year",
104045
+ labelV: "People (Millions)",
104046
+ dataH: {start: 1991, end: 2031, step: 5},
104047
+ dataV: {start: 20, end: 80, step: 5}
104048
+ },
104049
+ data: [
104050
+ // {item:"Canada", icon:null, dataH:[1996, 2001, 2006, 2011, 2016, 2021, 2026], dataV:[30, 31, 33, 34, 36, 38, 40]},
104051
+ {item: "Italy", icon: null, dataH: [1996, 2001, 2006, 2011, 2016, 2021, 2026], dataV: [57, 57, 58, 59, 60, 59, 59]},
104052
+ {item: "France", icon: null, dataH: [1996, 2001, 2006, 2011, 2016, 2021, 2026], dataV: [60, 62, 64, 65, 66, 67, 67]},
104053
+ ],
104054
+ backgroundColor: clear,
104055
+ footer: "Historical data compiled from demographic records on Worldometer"
104056
+
104057
+ });
104058
+ STYLE = {infoicon: {size: 12, color: white}, onTop: false, collapse: true, titleBar: "Plot Graph", draggable: true};
104059
+ const panel = new Panel({width: graph.width, height: graph.height + 30, content: graph, corner: 10, backgroundColor: white}).center();
104060
+
104061
+ const legend = new Legend(graph);
104062
+ STYLE = {infoicon: {size: 12, color: white}, collapse: true, titleBar: "Legend", draggable: true};
104063
+ new Panel(legend.width + 20, legend.height + 30, legend).pos(60, 50, RIGHT, BOTTOM);
104064
+ STYLE = {}
104065
+ END EXAMPLE
104066
+
104067
+ PARAMETERS
104068
+ ** supports DUO - parameters or single object with properties below
104069
+ ** supports OCT - parameter defaults can be set with STYLE control (like CSS)
104070
+ width - (default null) width of the graph
104071
+ height - (default null) height of the graph
104072
+ title - (default null) title text or Label
104073
+ info - (default null) object with labelH, labelV, dataH, dataV for axis definition
104074
+ data - (default null) array of series objects {item,dataH,dataV}
104075
+ extrapolate - (default false) if true extend the best-fit lines to the graph edges
104076
+ colors - (default series colors) array of line colors
104077
+ thickness - (default 2) line thickness
104078
+ footer - (default null) footer text or Label
104079
+ backgroundColor - (default white) background fill color
104080
+ color - (default dark) color for labels and axis lines
104081
+ font - (default null) font for labels
104082
+ size - (default 14) font size for title and labels
104083
+ dataColor - (default grey) color for axis data labels
104084
+ dataSize - (default 10) size for data labels
104085
+ padding - (default 20) padding around the chart content
104086
+ gridThickness - (default 1) thickness of the grid lines
104087
+ gridColor - (default light) color of the grid lines
104088
+ axisThickness - (default 1) thickness of the axis lines
104089
+ axisColor - (default dark) color of the axis lines
104090
+ decimalsH - (default 1) decimal precision for horizontal labels
104091
+ decimalsV - (default 1) decimal precision for vertical labels
104092
+ style - (default true) set to false to ignore STYLE defaults
104093
+ group - (default null) group name(s) for STYLE
104094
+ inherit - (default null) direct style object or inherit instruction
104095
+
104096
+ METHODS
104097
+ clone() - copies the plot graph
104098
+
104099
+ PROPERTIES
104100
+ info - axis definition object
104101
+ data - series data array
104102
+ finalColors - colors used for series lines
104103
+ --*///+165
104104
+
104105
+ // THE CODE FOR THE CHART MODULE IS LINKED TO AT THE TOP OF THE DOCS
104106
+
104107
+ //-165
104108
+
104109
+ /*--
104110
+ zim.PieChart(width, height, info, data, units, title, footer, backgroundColor, color, size, dataSize, font, spacing, iconOrient, iconFlip, iconWidth, iconScale, dec, padding, showData, showInfo, exchange, shiftForWedge, style, group, inherit)
104111
+
104112
+ PieChart
104113
+ zim class - extends a zim.Container which extends a createjs.Container
104114
+
104115
+ DESCRIPTION
104116
+ Creates a pie chart visualization with optional data and title labels and icons.
104117
+ Displays data as pie wedges with interactive features including hover and click detection.
104118
+ Supports wedge lifting, customizable styling, and legend display.
104119
+
104120
+ See: https://zimjs.com/020/piechart.html
104121
+
104122
+ EXAMPLE
104123
+ // must import zim_chart
104124
+ new zim.PieChart(400, 400, [{name:"A", backgroundColor:red}, {name:"B", backgroundColor:blue}], [50, 150])
104125
+ .center();
104126
+ END EXAMPLE
104127
+
104128
+ EXAMPLE
104129
+ // must import zim_chart
104130
+ // interactive Pie Chart with icons
104131
+ STYLE = {backdrop:{corner:10, shadow:true}, chartBacking:{corner:10, shadow:true}}
104132
+
104133
+ var graph = new zim.PieChart({
104134
+ backgroundColor:dark,
104135
+ color:light,
104136
+ padding:30,
104137
+ width:500,
104138
+ info:[
104139
+ {name:"Maginifying Glass", icon:pizzazz.makeIcon("magnify", white), backgroundColor:blue.darken(.1), color:white},
104140
+ {name:"Hamburger Menu", icon:pizzazz.makeIcon("menu", white), backgroundColor:orange.darken(.1), color:white},
104141
+ {name:"Settings Gear", icon:pizzazz.makeIcon("settings", white), backgroundColor:green.darken(.1), color:white},
104142
+ {name:"Edit Pencil", icon:pizzazz.makeIcon("edit", white), backgroundColor:pink.darken(.1), color:white},
104143
+ ],
104144
+ data:[35,30,20,15],
104145
+ // units:"%",
104146
+ title:"Estimated Percentage Icon Usage",
104147
+ footer:"AI generated numbers",
104148
+ dataSize:20,
104149
+ iconOrient:false,
104150
+ iconFlip:true,
104151
+ showInfo:false,
104152
+ // showData:false,
104153
+ exchange:true,
104154
+ shiftForWedge:false
104155
+ }).center().cur();
104156
+
104157
+ new Legend({graph, color:white, backdropColor:grey}).loc(690, 554); //.place()
104158
+
104159
+ // ---------------------------
104160
+ // optional handle rollover
104161
+
104162
+ let lastIndex;
104163
+ graph.movement(function() {
104164
+ if (lastIndex != graph.rollIndex) {
104165
+ if (lastIndex!=null && !selections.isSelected(lastIndex)) graph.lowerWedge(lastIndex);
104166
+ graph.raiseWedge(graph.rollIndex,10);
104167
+ lastIndex = graph.rollIndex;
104168
+ S.update();
104169
+ }
104170
+ });
104171
+
104172
+ graph.on("mouseout", ()=>{
104173
+ if (!selections.isSelected(lastIndex)) graph.lowerWedge(lastIndex);
104174
+ lastIndex = null;
104175
+ S.update();
104176
+ });
104177
+
104178
+ // ---------------------------
104179
+ // optional handle select
104180
+
104181
+ const selections = new SelectionSet();
104182
+ graph.on("mousedown", ()=>{
104183
+ selections.toggle(graph.index, true);
104184
+ loop(graph.currentWedges, (wedge,i)=>{
104185
+ if (selections.isSelected(i)) graph.raiseWedge(i);
104186
+ else graph.lowerWedge(i);
104187
+ });
104188
+ S.update();
104189
+ });
104190
+ END EXAMPLE
104191
+
104192
+ PARAMETERS
104193
+ ** supports DUO - parameters or single object with properties below
104194
+ ** supports OCT - parameter defaults can be set with STYLE control (like CSS)
104195
+ width - (400) width in pixels
104196
+ height - (width) height in pixels (defaults to width)
104197
+ info - (null) ***** array of label objects with name and backgroundColor properties
104198
+ data - (null) ***** array of numbers representing pie slice values
104199
+ units - (null) ***** unit label appended to data values
104200
+ title - (null) title label or text displayed at top
104201
+ footer - (null) footer label or text displayed at bottom in italics
104202
+ backgroundColor - (white) background color
104203
+ color - (dark) text color
104204
+ size - (14) title/footer label font size
104205
+ dataSize - (size) font size for data labels
104206
+ font - (null) font family name
104207
+ spacing - (5) spacing between elements in pixels
104208
+ iconOrient - (true) ***** whether icon graphics are oriented to angle
104209
+ iconFlip - (true) ***** whether icons are flipped
104210
+ iconWidth - (null) ***** width of icon graphics if used
104211
+ iconScale - (null) ***** scale factor for icon graphics
104212
+ dec - (0) decimal places for displayed data values
104213
+ padding - (10) padding around chart edges
104214
+ showData - (true) whether to display data values
104215
+ showInfo - (true) whether to display info labels
104216
+ exchange - (false) ***** whether to exchange display positions of data and info
104217
+ shiftForWedge - (true) whether labels shift when wedge is raised
104218
+
104219
+ METHODS
104220
+ clone() - returns a clone of the PieChart
104221
+ getIndex(x, y) - returns the pie wedge index at the given local coordinates
104222
+ raiseWedge(index, factor) - raises a wedge by the specified factor
104223
+ lowerWedge(index) - lowers the raised wedge(s) back to flat
104224
+ setChart(obj) - ***** redraws chart with new data or configuration
104225
+
104226
+ PROPERTIES
104227
+ index - the currently selected wedge index from mouse click
104228
+ rollIndex - the wedge index currently under the mouse
104229
+ angles - array of angle values for each wedge
104230
+ info - info labels array
104231
+ data - data values array
104232
+ title - title label
104233
+ footer - footer label
104234
+ backgroundColor - background color
104235
+ radius - calculated radius of the pie
104236
+
104237
+ --*///+166
104238
+
104239
+ // THE CODE FOR THE CHART MODULE IS LINKED TO AT THE TOP OF THE DOCS
104240
+
104241
+ //-166
104242
+
104243
+ /*--
104244
+ zim.RadarGraph(data, radius, num, title, footer, backgroundColor, color, font, size, circleColor, circleAlpha, circleBorderColor, circleBorderWidth, circleBorderAlpha, circleLastBorderColor, lineThickness, lineColor, shapeColor, shapeAlpha, shapeLineThickness, shapeLineColor, gradients, dotRadius, dotColor, dotBorderColor, dotBorderWidth, showDots, blendmode, numbers, numbersAngle, numbersColor, numbersSize, numbersFactor, padding, labelMargin, style, group, inherit)
104245
+
104246
+ RadarGraph
104247
+ zim class - extends a zim.Container which extends a createjs.Container
104248
+
104249
+ DESCRIPTION
104250
+ Creates a radar chart (spider web chart) for comparing multiple data series across multiple axes.
104251
+ Displays data as colored polygons with grid circles, axis labels, and optional gradient fills.
104252
+ Supports multiple data series with customizable colors, dot markers, and numerical labels.
104253
+
104254
+ See: https://zimjs.com/020/radargraph.html
104255
+
104256
+ NOTE: as of ZIM 5.5.0 the zim namespace is no longer required (unless zns is set to true before running zim)
104257
+
104258
+ EXAMPLE
104259
+ // must import zim_chart
104260
+ let radar = new zim.RadarGraph([["Strength", "Speed", "Power"], ["Good", "Bad"], [[8,6,7], [5,9]]], 200, 10);
104261
+ radar.addTo(stage);
104262
+ END EXAMPLE
104263
+
104264
+ EXAMPLE
104265
+ // must import zim_chart
104266
+ // this data came from an export of data from ZIM Rank app https://zimjs.com/rank
104267
+ const data = JSON.parse('[["Sweet Chili Heat","Ruffles","Corn Chips","Cheetos","Fuegos","Nacho Chips","","","",""], ["Taste","Size","Aftertaste","Spiciness","Filling",""],[[8,9,9,10,9.5,0],[7,6,8,7,9,0],[10,8,9,9,10,0],[8.5,8,6,9,8.5,0],[9,7,7.5,10,8.5,0],[8,7.5,8.5,8,7.5,0],[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0]],[1,1,1,1,1,1],[1,1,1,1,1,1,1,1,1,1],true,true,3]');
104268
+ // data[0][0] = {icon:new Circle(10,red), name:"Sweet Chili Heat"};
104269
+
104270
+ const graph = new RadarGraph({
104271
+ data: data,
104272
+ circleColor: dark,
104273
+ backgroundColor: clear,
104274
+ gradients: true,
104275
+ title: "My Favourite Snacks",
104276
+ footer: "Data from ZIM Rank",
104277
+ dotRadius:10,
104278
+ dotColor:clear,
104279
+ dotBorderWidth:1,
104280
+ dotBorderColor:white,
104281
+ gradients:false
104282
+ }).center();
104283
+
104284
+ STYLE = {infoicon: {size: 12, color: white}, onTop: false, collapse: true, titleBar: "Radar Graph", draggable: true};
104285
+ const panel = new Panel({width: graph.width, height: graph.height + 30, draggable: false, backgroundColor: white, content: graph, corner: 10}).center();
104286
+
104287
+ const legend = new Legend(graph);
104288
+ STYLE = {infoicon: {size: 12, color: white}, collapse: true, titleBar: "Legend", draggable: true};
104289
+ new Panel(legend.width + 30, legend.height + 35, legend).pos(60, 50, RIGHT, BOTTOM);
104290
+ STYLE = {};
104291
+ END EXAMPLE
104292
+
104293
+ PARAMETERS
104294
+ ** supports DUO - parameters or single object with properties below
104295
+ ** supports OCT - parameter defaults can be set with STYLE control (like CSS)
104296
+ data - (default array) ***** 3D array [labels, seriesNames, dataPoints] where dataPoints[i] corresponds to seriesNames[i]
104297
+ radius - (200) radius of the radar chart in pixels
104298
+ num - (10) number of concentric circles
104299
+ title - (null) title label or text displayed at top
104300
+ footer - (null) footer label or text displayed at bottom
104301
+ backgroundColor - (white) background color
104302
+ color - (dark) text and axis color
104303
+ font - (null) font family name
104304
+ size - (20) font size for labels
104305
+ circleColor - (clear) fill color for concentric circles
104306
+ circleAlpha - (.05) transparency of circle fill
104307
+ circleBorderColor - (light) color of circle borders
104308
+ circleBorderWidth - (1) thickness of circle border lines
104309
+ circleBorderAlpha - (.2) transparency of circle borders
104310
+ circleLastBorderColor - (mist) color of outermost circle border
104311
+ lineThickness - (1) thickness of axis lines
104312
+ lineColor - (dark) color of axis lines
104313
+ shapeColor - (series) ***** array of colors for each data series polygon fill
104314
+ shapeAlpha - (.2) transparency of shape fills
104315
+ shapeLineThickness - (3) thickness of shape outline
104316
+ shapeLineColor - (series) ***** array of colors for shape outlines
104317
+ gradients - (true) whether to apply gradient fills to shapes
104318
+ dotRadius - (3) radius of dot markers at data points
104319
+ dotColor - (lineColor) color of dots
104320
+ dotBorderColor - (-1) border color of dots (-1 for no border)
104321
+ dotBorderWidth - (1) thickness of dot borders
104322
+ showDots - (true) whether to display dots at data points
104323
+ blendmode - (null) blend mode for rendering
104324
+ numbers - (true) whether to display circle numbers
104325
+ numbersAngle - (0) rotation angle for number labels
104326
+ numbersColor - (lineColor) color of circle numbers
104327
+ numbersSize - (12) font size for circle numbers
104328
+ numbersFactor - (1) ***** scaling factor for number values
104329
+ padding - (20) padding around chart
104330
+ labelMargin - (padding/4) additional margin for axis labels
104331
+
104332
+ METHODS
104333
+ clone() - returns a clone of the Radar chart
104334
+
104335
+ PROPERTIES
104336
+ type - "Radar"
104337
+
104338
+ --*///+167
104339
+
104340
+ // THE CODE FOR THE CHART MODULE IS LINKED TO AT THE TOP OF THE DOCS
104341
+
104342
+ //-167
104343
+
104344
+ /*--
104345
+ zim.LiveGraph(width, height, title, info, data, src, timeStep, thickness, smooth, footer, colors, gradients, backgroundColor, color, font, size, dataColor, dataSize, padding, gridThickness, gridColor, axisThickness, axisColor, decimalsH, decimalsV, maxData, fullGradients, animated, style, group, inherit)
104346
+
104347
+ LiveGraph
104348
+ zim class - extends zim.Graph which extends a zim.Container which extends a createjs.Container
104349
+
104350
+ DESCRIPTION
104351
+ Creates a live/animated line graph that updates data over time using a WebWorker.
104352
+ Displays multiple data series as lines with optional gradient fills and smooth curves.
104353
+ Automatically manages maxData limit, supports real-time data streaming and animation.
104354
+
104355
+ See: https://zimjs.com/020/livegraph.html
104356
+
104357
+ NOTE: as of ZIM 5.5.0 the zim namespace is no longer required (unless zns is set to true before running zim)
104358
+
104359
+ EXAMPLE
104360
+ // must import zim_chart
104361
+ let info = {labelH:["Time"], labelV:["Value"], dataH:[0,1,2,3], dataV:[0,10,20,15]};
104362
+ let liveGraph = new zim.LiveGraph(600, 400, "Live Data", info, null, null, 1);
104363
+ liveGraph.addTo(stage);
104364
+ END EXAMPLE
104365
+
104366
+ EXAMPLE
104367
+ // must import zim_chart
104368
+ const graph = new LiveGraph({
104369
+ // title:"Graph",
104370
+ width: 700,
104371
+ info: {
104372
+ labelH: "Time (s)",
104373
+ labelV: "Height",
104374
+ dataH: {start: -10, end: 0, step: 1},
104375
+ dataV: {start: 20, end: 90, step: 10}
104376
+ },
104377
+ data: [
104378
+ {item: "CPU", icon: null},
104379
+ {item: "Memory", icon: null},
104380
+ ],
104381
+ timeStep: .5,
104382
+ smooth: true,
104383
+ thickness: 2,
104384
+ gradients: true,
104385
+ // animated:false,
104386
+ // fullGradients:true
104387
+ });
104388
+ STYLE = {infoicon: {size: 12, color: white}, onTop: false, collapse: true, titleBar: "Live Graph", draggable: true};
104389
+ const panel = new Panel(graph.width, graph.height + 30, graph).center().mov(0,-30);
104390
+
104391
+ const legend = new Legend(graph);
104392
+ STYLE = {infoicon: {size: 12, color: white}, collapse: true, titleBar: "Legend", draggable: true};
104393
+ new Panel(legend.width + 20, legend.height + 30, legend).pos(60, 50, RIGHT, BOTTOM);
104394
+
104395
+ STYLE = {};
104396
+ const pauseBut = new Button({label: "PAUSE", toggle: "PLAY"}).sca(.5).pos(0, 40, CENTER, BOTTOM);
104397
+ pauseBut.on("mousedown", () => {
104398
+ // const offset = graph.offset; // use to continue from paused time rather than back to live
104399
+ graph.paused = !pauseBut.toggled;
104400
+ // graph.offset = offset;
104401
+ });
104402
+ END EXAMPLE
104403
+
104404
+ PARAMETERS
104405
+ ** supports DUO - parameters or single object with properties below
104406
+ ** supports OCT - parameter defaults can be set with STYLE control (like CSS)
104407
+ width - (default null) width of the graph
104408
+ height - (default null) height of the graph
104409
+ title - (default null) title label or text displayed at top
104410
+ info - (default null) info object with labelH, labelV, dataH, dataV arrays
104411
+ data - (default null) array of data objects with dataH and dataV properties
104412
+ src - (default null) external data source URL for updates
104413
+ timeStep - (default .5) time interval in seconds between data updates
104414
+ thickness - (default 2) line thickness in pixels
104415
+ smooth - (default true) whether to use smooth curves instead of straight lines
104416
+ footer - (default null) footer label or text displayed at bottom
104417
+ colors - (default series) array of colors for each data series
104418
+ gradients - (default true) whether to apply gradient fills under lines
104419
+ backgroundColor - (default white) background fill color
104420
+ color - (default dark) color for labels and axis lines
104421
+ font - (default null) font for labels
104422
+ size - (default 14) font size for title and labels
104423
+ dataColor - (default grey) color for axis data labels
104424
+ dataSize - (default 10) size for data labels
104425
+ padding - (default 20) padding around the chart content
104426
+ gridThickness - (default 1) thickness of the grid lines
104427
+ gridColor - (default light) color of the grid lines
104428
+ axisThickness - (default 1) thickness of the axis lines
104429
+ axisColor - (default dark) color of the axis lines
104430
+ decimalsH - (default 1) decimal precision for horizontal labels
104431
+ decimalsV - (default 1) decimal precision for vertical labels
104432
+ maxData - (1000) maximum number of data points to maintain before trimming
104433
+ fullGradients - (true) whether gradients extend full height or to min/max values
104434
+ animated - (true) whether to animate line movements
104435
+
104436
+ METHODS
104437
+ addData(data) - adds new data points and updates the graph
104438
+ pause() - pauses the live update
104439
+ resume() - resumes live update
104440
+ clone() - returns a clone of the LiveGraph
104441
+
104442
+ PROPERTIES
104443
+ type - "LiveGraph"
104444
+ info - the info object with axis configuration
104445
+ data - current data array
104446
+ gradients - gradient setting
104447
+ timeStep - current time step interval
104448
+ currentData - array of data maintained up to maxData limit
104449
+ animated - animation setting
104450
+ doDraw - whether to redraw on next update
104451
+
104452
+ --*///+168
104453
+
104454
+ // THE CODE FOR THE CHART MODULE IS LINKED TO AT THE TOP OF THE DOCS
104455
+
104456
+ //-168
104457
+
104458
+ /*--
104459
+ zim.GrowthChart = function(width, height, title, num, info, data, time, footer, backgroundColor, color, size, iconWidth, dec, spacing, padding, damp, footerAlign, favorRight, style, group, inherit)
104460
+
104461
+ GrowthChart
104462
+ zim class - extends a zim.Container which extends a createjs.Container
104463
+
104464
+ DESCRIPTION
104465
+ Creates a scrolling growth chart that cycles through data slices over time.
104466
+ Each slice is shown as a ranked bar chart with icon labels and value labels.
104467
+
104468
+ See: https://zimjs.com/020/growthchart.html
104469
+
104470
+ NOTE: as of ZIM 5.5.0 the zim namespace is no longer required (unless zns is set to true before running zim)
104471
+
104472
+ EXAMPLE
104473
+ // must import zim_chart
104474
+ const growthChart = new GrowthChart(400, 300, "Growth").center();
104475
+ new GrowthWidget(growthChart, "Growth", light, dark).loc(100,100);
104476
+ END EXAMPLE
104477
+
104478
+ PARAMETERS
104479
+ ** supports DUO - parameters or single object with properties below
104480
+ ** supports OCT - parameter defaults can be set with STYLE control (like CSS)
104481
+ width - (default 400) total width of the chart
104482
+ height - (default 300) total height of the chart
104483
+ title - (default null) title text or Label displayed at the top
104484
+ num - (default 10) number of items to show in each snapshot
104485
+ info - (default null) array of item metadata objects {icon,name,backgroundColor,color}
104486
+ data - (default null) array of arrays containing numeric values for each snapshot
104487
+ time - (default 0.5) time in seconds between automatic updates
104488
+ footer - (default null) footer text or Label displayed at the bottom
104489
+ backgroundColor - (default white) chart background fill
104490
+ color - (default dark) title and label color
104491
+ size - (default 14) base font size for item labels
104492
+ iconWidth - (default 50) width of the icon column
104493
+ dec - (default 0) decimal precision used for numeric labels
104494
+ spacing - (default 2) vertical spacing between bars
104495
+ padding - (default 10) outer padding inside the chart
104496
+ damp - (default 0.07) smoothing factor for animated bar width and position
104497
+ footerAlign - (default CENTER) alignment for the footer
104498
+ favorRight - (default false) set to true to start with data labels to right of bars
104499
+ and if they don't fit then move the data labels into the bars
104500
+ Keep set to false to start labels in bars and move to right if they don't fit
104501
+ style - (default true) set to false to ignore STYLE defaults
104502
+ group - (default null) group name(s) for STYLE
104503
+ inherit - (default null) direct style object or inherit instruction
104504
+
104505
+ METHODS
104506
+ restart() - restarts the automatic update cycle
104507
+ dispose() - clears timers and disposes the chart
104508
+ clone() - copies the chart
104509
+
104510
+ PROPERTIES
104511
+ graph - passed-in graph instance if provided
104512
+ data - current dataset array
104513
+ info - current item metadata array
104514
+ growth - array of growth values used for each snapshot
104515
+ finalColors - computed display colors for items
104516
+ --*///+169
104517
+
104518
+ // THE CODE FOR THE CHART MODULE IS LINKED TO AT THE TOP OF THE DOCS
104519
+
104520
+ //-169
104521
+
104522
+ /*--
104523
+ zim.GrowthWidget = function(graph, title, color, backgroundColor, font, size, padding, paddingInside, restart, corner, restartCorner, style, group, inherit)
104524
+
104525
+ GrowthWidget
104526
+ zim class - extends a zim.Container which extends a createjs.Container
104527
+
104528
+ DESCRIPTION
104529
+ Creates a small widget that displays the current growth amount from a GrowthChart instance.
104530
+ Includes an optional restart button to restart the GrowthChart animation.
104531
+
104532
+ See: https://zimjs.com/020/growthchart.html
104533
+
104534
+ NOTE: as of ZIM 5.5.0 the zim namespace is no longer required (unless zns is set to true before running zim)
104535
+
104536
+ EXAMPLE
104537
+ // must import zim_chart
104538
+ const growthChart = new GrowthChart(400, 300, "Growth").center();
104539
+ new GrowthWidget(growthChart, "Growth", light, dark).loc(100,100);
104540
+ END EXAMPLE
104541
+
104542
+ PARAMETERS
104543
+ ** supports DUO - parameters or single object with properties below
104544
+ ** supports OCT - parameter defaults can be set with STYLE control (like CSS)
104545
+ graph - (default null) GrowthChart instance to listen to
104546
+ title - (default "GROWTH") title text or Label shown in the widget
104547
+ color - (default light) text color for title and values
104548
+ backgroundColor - (default dark) background color for the widget tile
104549
+ font - (default null) font for text
104550
+ size - (default null) font size for text
104551
+ padding - (default 10) spacing between widget content and edge
104552
+ paddingInside - (default 10) padding inside the tile background
104553
+ restart - (default true) show a restart button when true
104554
+ corner - (default 10) corner radius for the tile background
104555
+ restartCorner - (default 0) corner radius for the restart button
104556
+ style - (default true) set to false to ignore STYLE defaults
104557
+ group - (default null) group name(s) for STYLE
104558
+ inherit - (default null) direct style object or inherit instruction
104559
+
104560
+ METHODS
104561
+ clone() - copies the widget
104562
+
104563
+ PROPERTIES
104564
+ graph - GrowthChart instance being tracked
104565
+ amount - label showing the current amount
104566
+ restart - restart button instance when enabled
104567
+ --*///+170
104568
+
104569
+ // THE CODE FOR THE CHART MODULE IS LINKED TO AT THE TOP OF THE DOCS
104570
+
104571
+ //-170
104572
+
104573
+ /*--
104574
+ zim.WordCloud = function(width, height, words, max, exclude, include, scaleFix, font, color, backgroundColor, spacing, verticalMix, uppercase, minSize, maxSize, threshold, style, group, inherit)
104575
+
104576
+ WordCloud
104577
+ zim class - extends a zim.Container which extends a createjs.Container
104578
+
104579
+ DESCRIPTION
104580
+ Creates a word cloud from text or a word-frequency array.
104581
+ Words are placed using a spiral algorithm and can be rotated vertically.
104582
+
104583
+ See: https://zimjs.com/020/wordcloud.html
104584
+
104585
+ EXAMPLE
104586
+ // must import zim_chart
104587
+ new WordCloud(800, 500, "hello world hello").center();
104588
+ END EXAMPLE
104589
+
104590
+ EXAMPLE
104591
+ // must import zim_chart
104592
+ // we can use WordCloud on raw text - but that takes extra processing
104593
+ // here are the steps to have WordCloud process and save a data list
104594
+
104595
+ // we copied the text from the ZIM Innovation page,
104596
+ // saved it as a long string `` in a const words and passed that into WordCloud
104597
+ // we ran the WordCloud and noticed words we did not want
104598
+ // so we manually created this exclude array:
104599
+ // const exclude = ["complex", "decade", "through", "last", "fully", "63", "allows", "set", "made", "friction", "other", "single", "zims", "still", "every"];
104600
+ // then we added this coding line
104601
+ // zog(JSON.stringify(cloud.prepareWordData(words, 50, 1, exclude)))
104602
+ // this we stored in this const words instead of the raw text
104603
+ // a shortened version is shown here
104604
+
104605
+ const words = [
104606
+ {"text": "Zim", "freq": 100},
104607
+ {"text": "Canvas", "freq": 44},
104608
+ // etc.,
104609
+ {"text": "Creating", "freq": 6}
104610
+ ];
104611
+
104612
+ // words, width, height, scaleFix, font, color, backgroundColor, spacing, verticalMix, uppercase, minSize, maxSize, style, group, inherit
104613
+ var cloud = new zim.WordCloud({
104614
+ width:700,
104615
+ words: words,
104616
+ // exclude:exclude,
104617
+ }).center();
104618
+
104619
+ // optionally animate the words in
104620
+ cloud.animate({
104621
+ props: {alpha: 0},
104622
+ from: true,
104623
+ time: .3,
104624
+ sequence: 0.02
104625
+ });
104626
+ END EXAMPLE
104627
+
104628
+ PARAMETERS
104629
+ ** supports DUO - parameters or single object with properties below
104630
+ ** supports OCT - parameter defaults can be set with STYLE control (like CSS)
104631
+ width - (default 800) width of the cloud area
104632
+ height - (default 500) height of the cloud area
104633
+ words - (default null) string or array of word objects to build the cloud
104634
+ max - (default 100) maximum number of words
104635
+ exclude - (default null) word or words to ignore
104636
+ include - (default null) word or words to force include
104637
+ scaleFix - (default 1 or 2 depending on width/height) internal scaling factor for smaller layouts
104638
+ font - (default null) font for word labels
104639
+ color - (default palette) color or array of colors for words
104640
+ backgroundColor - (default interstellar) background fill color
104641
+ spacing - (default 6) minimum spacing between placed words
104642
+ verticalMix - (default true) if true randomly rotate some words vertically
104643
+ uppercase - (default true) if true convert words to uppercase
104644
+ minSize - (default 10) minimum font size
104645
+ maxSize - (default 90) maximum font size
104646
+ threshold - (default 1) minimum word frequency to include
104647
+ style - (default true) set to false to ignore STYLE defaults
104648
+ group - (default null) group name(s) for STYLE
104649
+ inherit - (default null) direct style object or inherit instruction
104650
+
104651
+ METHODS
104652
+ prepareWordData(text, max, threshold, exclude, include) - prepares data from text
104653
+ max is the maximul number of words to add to the data
104654
+ threshold is the minimum occurances required to add the word to the data
104655
+ exclude is a word or an array of words to not include
104656
+ include is a word or an array of words to include
104657
+ Note - there are a number of words already excluded - see code
104658
+ clone() - copies the word cloud
104659
+
104660
+ PROPERTIES
104661
+ type - the class type as a string
104662
+ --*///+171
104663
+
104664
+ // THE CODE FOR THE CHART MODULE IS LINKED TO AT THE TOP OF THE DOCS
104665
+
104666
+ //-171
104667
+
104668
+ /*--
104669
+ zim.Championship = function(width, title, num, data, textLines, curved, shiftFactor, mirror, lastFlip, lastCenter, lastScale, footer, backgroundColor, color, font, size, align, boxColor, corner, borderColor, borderWidth, dataColor, dataSize, padding, spacingH, spacingV, gapCount, gap, paddingH, paddingV, lineColor, lineThickness, style, group, inherit)
104670
+
104671
+ Championship
104672
+ zim class - extends a zim.Container which extends a createjs.Container
104673
+
104674
+ DESCRIPTION
104675
+ Creates an elimination bracket chart for tournament-style data.
104676
+ Boxes are arranged in rounds and connected by bracket lines, with support for mirrored layouts.
104677
+
104678
+ EXAMPLE
104679
+ // must import zim_chart
104680
+ new Championship(500, "Tournament", 16).center();
104681
+ END EXAMPLE
104682
+
104683
+ EXAMPLE
104684
+ // must import zim_chart
104685
+ // This example is part way through an actual championship on facebook
104686
+ // Note how we darken colors where the matches are not active
104687
+ // We also provide a current challenge at the bottom
104688
+ // a custom pic is shown for the title area
104689
+ // and custom emojis are used for the challenge area
104690
+
104691
+ new Pic("logo_small.png").sca(.66).loc(589, 45); // .place()
104692
+
104693
+ STYLE = {champTitle:{size:20}}
104694
+ function getColor(color, active) {
104695
+ // if (active) return new GradientColor([color,color.lighten(.6),color], 60);
104696
+ // return new GradientColor([color.darken(.5),color,color.darken(.5)], 60);
104697
+ return color.darken(active?0:.2)
104698
+ }
104699
+ const colors = [];
104700
+ // loop(16, (i)=>{colors.push(getColor(yellow, i>1))}); // darkens
104701
+ // loop(8, (i)=>{colors.push(getColor(yellow, i<1))}); // lightens
104702
+
104703
+ loop(16, (i)=>{colors.push(getColor(yellow, false))}); // darkens
104704
+ loop(8, (i)=>{colors.push(getColor(yellow, i>=4))}); // lightens
104705
+ loop(4, (i)=>{colors.push(getColor(yellow, i<2))});
104706
+ loop(2, (i)=>{colors.push(getColor(yellow))});
104707
+ colors.push(colors.push(getColor(yellow)));
104708
+
104709
+ const graph = new Championship({
104710
+ width:W,
104711
+ num:16,
104712
+ dataSize:16,
104713
+ font:"RocknRoll+One",
104714
+ boxColor:series(colors),
104715
+ borderColor:"red".darken(.5),
104716
+ borderWidth:2,
104717
+ data:[[
104718
+ "CAPTCHAs",
104719
+ "MS Word",
104720
+ "FAQs",
104721
+ "2FA",
104722
+ "Setting Clocks",
104723
+ "Public Wi-Fi",
104724
+ "Adobe Acrobat",
104725
+ "Ticketmaster",
104726
+ "Voice Assistants",
104727
+ "Bluetooth Audio",
104728
+ "Mac Finder",
104729
+ "TV Remotes",
104730
+ "Instagram UI",
104731
+ "Bank Kiosks",
104732
+ "Smart Printers",
104733
+ "Meta B. Suite"
104734
+ ],
104735
+ ["MS Word", "2FA", "Setting Clocks","Ticketmaster","Voice Assistants","TV Remotes","Instagram UI", "Smart Printers"],
104736
+ ["2FA", "Ticketmaster"],
104737
+ [],
104738
+ ["Most Frustrating"]
104739
+ ],
104740
+ // borderWidth:0,
104741
+ curved:false,
104742
+ // color:red.lighten(.2),
104743
+ // corner:10,
104744
+ // backgroundColor:clear,
104745
+ lineColor:"red".darken(.5),
104746
+ lineThickness:2,
104747
+ // gap:null,
104748
+ // gapCount:4,
104749
+ lastFlip:true,
104750
+ // lastScale:2,
104751
+ align:CENTER,
104752
+ paddingV:8,
104753
+ spacingV:8,
104754
+ // boxColor:series(colors),
104755
+ title:"FRUSTRATING TECH",
104756
+
104757
+ }).addTo().mov(0,20)
104758
+
104759
+ graph.title.sca(1.6).pos(20,20,RIGHT,TOP)
104760
+
104761
+ // create the challenge - there is a default graph.challenge() but we customize...
104762
+ const round = 1;
104763
+ const index = 4;
104764
+ const footer = new Container(W,H).loc(0,-10).tap(()=>{
104765
+ zgo("https://facebook.com/danzen", "fb")
104766
+ }); // .place(); // place is used to position then check console for coords
104767
+ new Label("vote with icon", 30, "RocknRoll+One", lighter).loc(274, 847, footer); // .place();
104768
+ new Pic("icon_sad.png").sca(.4).reg(CENTER).loc(185, 865-10, footer).sha();
104769
+ new Pic("icon_angry.png").sca(.4).reg(CENTER).loc(582, 865-10, footer).sha();
104770
+ var challenge = graph.challenge(round, index, lighter, black).pos(0,30,CENTER,BOTTOM, footer);
104771
+ challenge.items[0].backing.sha(black.toAlpha(.2), 0, 8, 15); // adding shadow to all adds it to text too
104772
+ challenge.items[2].backing.sha(black.toAlpha(.2), 0, 8, 15);
104773
+ challenge.items[0].mov(-20);
104774
+ challenge.items[1].rot(0);
104775
+ challenge.items[2].mov(20);
104776
+ END EXAMPLE
104777
+
104778
+ PARAMETERS
104779
+ ** supports DUO - parameters or single object with properties below
104780
+ ** supports OCT - parameter defaults can be set with STYLE control (like CSS)
104781
+ width - (default 500) total width of the championship chart
104782
+ title - (default null) title text or Label shown at the top
104783
+ num - (default 16) number of competitors or slots (rounded to the next power of two)
104784
+ data - (default [[]]) nested array of competitor values or labels for each round
104785
+ textLines - (default 1) number of sample lines used to size label boxes when no data sample exists
104786
+ curved - (default spacingH/2) curve radius for bracket lines, or true to enable default curvature
104787
+ shiftFactor - (default 0) horizontal shift amount per round for layout variation
104788
+ mirror - (default null) if true reverse shift direction for the lower half of the bracket
104789
+ lastFlip - (default false) if true flip the last round's champion box horizontally
104790
+ lastCenter - (default true) if true center the final box between its feeders
104791
+ lastScale - (default 2) scale applied to the final champion box
104792
+ footer - (default null) footer text or Label shown at the bottom
104793
+ backgroundColor - (default lighter) chart background fill color
104794
+ color - (default dark) title and default text color
104795
+ font - (default null) font for competitor labels
104796
+ size - (default 12) font size for text labels
104797
+ align - (default left) alignment for box content
104798
+ boxColor - (default white) fill color for competitor boxes
104799
+ corner - (default 0) corner radius for competitor boxes
104800
+ borderColor - (default color) border stroke color for boxes
104801
+ borderWidth - (default 1) border stroke width for boxes
104802
+ dataColor - (default darker) color for values or sublabels inside boxes
104803
+ dataSize - (default 14) font size for box content
104804
+ padding - (default 20) outer padding around the chart
104805
+ spacingH - (default 20) horizontal spacing between rounds
104806
+ spacingV - (default 5) vertical spacing between boxes
104807
+ gapCount - (default 4) number of boxes between extra vertical gaps
104808
+ gap - (default spacingV * 2) extra vertical gap size after gapCount boxes
104809
+ paddingH - (default 3) horizontal padding inside boxes
104810
+ paddingV - (default 5) vertical padding inside boxes
104811
+ lineColor - (default dark) color of bracket connecting lines
104812
+ lineThickness - (default 1) thickness of bracket connecting lines
104813
+ style - (default true) set to false to ignore STYLE defaults
104814
+ group - (default null) group name(s) for STYLE
104815
+ inherit - (default null) direct style object or inherit instruction
104816
+
104817
+ METHODS
104818
+ updateData(data, merge) - updates competitor data values or labels
104819
+ if merge is true will keep previous data and replace with merged data (positional)
104820
+ challenge(round, index, bColor, fColor, obj1, obj2, extra1, extra2) - returns a battle tile for the specified match
104821
+ can overrid objects and add extras
104822
+ clone() - copies the championship chart
104823
+
104824
+ PROPERTIES
104825
+ data - data array
104826
+ rounds - containers for each round of boxes
104827
+ backgroundColor - chart background fill
104828
+ --*///+172
104829
+
104830
+ // THE CODE FOR THE CHART MODULE IS LINKED TO AT THE TOP OF THE DOCS
104831
+
104832
+ //-172
104833
+
103122
104834
  return zim;
103123
104835
  } (zim || {});
103124
104836
 
@@ -103490,6 +105202,7 @@ export let Wrapper = zim.Wrapper;
103490
105202
  export let Tile = zim.Tile;
103491
105203
  export let Pack = zim.Pack;
103492
105204
  export let Beads = zim.Beads;
105205
+ export let Bullets = zim.Bullets;
103493
105206
  export let Layout = zim.Layout;
103494
105207
  export let Accessibility = zim.Accessibility;
103495
105208
  export let TextureActive = zim.TextureActive;