zimjs 19.1.5 → 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
@@ -17681,6 +17681,7 @@ addPoint(percent, controlType) - add a point at a percent (100) of the total cur
17681
17681
  controlType can be as specified in main points parameter
17682
17682
  returns index of new point
17683
17683
  addPoints(num, controlType, startPoint, spread, dataOnly, points, even) - add num points between existing points
17684
+ accepts ZIM DUO normal parameters or configuration object literal with parameter names as propterties
17684
17685
  controlType can be as specified in main points parameter
17685
17686
  specify a startPoint to add points between the startPoint and the next point (one segment of points)
17686
17687
  spread (default false) set to true to spread points evenly around path rather than evenly between segments
@@ -19580,6 +19581,8 @@ Note the points property has been split into points and pointObjects (and there
19580
19581
  }
19581
19582
 
19582
19583
  this.addPoints = function(num, controlType, startPoint, spread, dataOnly, points, even) {
19584
+ var sig = "num, controlType, startPoint, spread, dataOnly, points, even";
19585
+ var duo; if (duo = zob(that.addPoints, arguments, sig)) return duo;
19583
19586
  if (zot(points)) points = zim.copy(that.points);
19584
19587
  var ratios = zim.copy(that.segmentRatios);
19585
19588
  var lastRatio = 0;
@@ -19869,6 +19872,7 @@ addPoint(percent, controlType) - add a point at a percent (100) of the total cur
19869
19872
  controlType can be as specified in main points parameter
19870
19873
  returns index of new point
19871
19874
  addPoints(num, controlType, startPoint, spread, dataOnly, points, even) - add num points between existing points
19875
+ accepts ZIM DUO normal parameters or configuration object literal with parameter names as propterties
19872
19876
  controlType can be as specified in main points parameter
19873
19877
  specify a startPoint to add points between the startPoint and the next point (one segment of points)
19874
19878
  spread (default false) set to true to spread points evenly around path rather than evenly between segments
@@ -21920,6 +21924,8 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
21920
21924
  }
21921
21925
 
21922
21926
  this.addPoints = function(num, controlType, startPoint, spread, dataOnly, points, even) {
21927
+ var sig = "num, controlType, startPoint, spread, dataOnly, points, even";
21928
+ var duo; if (duo = zob(that.addPoints, arguments, sig)) return duo;
21923
21929
  if (zot(points)) points = zim.copy(that.points);
21924
21930
  var ratios = zim.copy(that.segmentRatios);
21925
21931
  var lastRatio = 0;
@@ -23473,7 +23479,7 @@ rollColor - (default color) the rollover color of the font
23473
23479
  shadowColor - (default -1) for no shadow - set to any css color to see
23474
23480
  shadowBlur - (default 14) if shadow is present
23475
23481
  align - ((default LEFT) text registration point alignment also CENTER/MIDDLE and RIGHT
23476
- 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
23477
23483
  valign - (default TOP) vertical registration point alignment alse CENTER/MIDDLE, BOTTOM
23478
23484
  bold - (default false) set the font to bold - note: fontOptions has been removed as of ZIM Cat
23479
23485
  italic - (default false) set the font to italic - note: fontOptions has been removed as of ZIM Cat
@@ -24186,7 +24192,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
24186
24192
  fitText();
24187
24193
  }
24188
24194
 
24189
- function fitText() {
24195
+ function fitText() {
24190
24196
  that.size = maxSize?maxSize:200;
24191
24197
  var count = 0;
24192
24198
  while(lineHeight < lH / 2 && (that.height > lH || that.width > lW)) {
@@ -24619,6 +24625,7 @@ letterHeight - get the height of letters
24619
24625
  color - get or set the text color
24620
24626
  circle - access to the circle object
24621
24627
  arc - access to the arc object
24628
+ angle - the angle the letters make
24622
24629
  angles - access to the array angles for letter positioning
24623
24630
  use angles.toString() to log angle data (for kerning)
24624
24631
  this can be modified and passed in as an angles property to start
@@ -24685,7 +24692,6 @@ zim.LabelOnArc = function(label, size, font, color, radius, flip, spacing, lette
24685
24692
  var rev = label.text.split("").reverse().join("");
24686
24693
  label.text = rev;
24687
24694
  }
24688
- zog(that.width, that.height)
24689
24695
  letters = that.letters = new zim.Container(100,100).center(that);
24690
24696
 
24691
24697
  that.numLetters = label.text.length;
@@ -24739,6 +24745,7 @@ zim.LabelOnArc = function(label, size, font, color, radius, flip, spacing, lette
24739
24745
  else if (zot(arcBorderWidth) && !zot(arcBorderColor)) arcBorderWidth = 2;
24740
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);
24741
24747
  }
24748
+ that.angle = totalAngle;
24742
24749
  }
24743
24750
 
24744
24751
  function makeAngles() {
@@ -28981,8 +28988,8 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
28981
28988
 
28982
28989
  var accessibilityClicker;
28983
28990
  this.show = function(call, params) {
28984
- if (!zot(call)) that.closeCall = call;
28985
- if (!zot(params)) that.closeParams = params;
28991
+ that.closeCall = call;
28992
+ that.closeParams = params;
28986
28993
  if (center) {
28987
28994
  if (isNaN(that.resetX)) {
28988
28995
  that.x = (that.container.getBounds().width) /2;
@@ -29058,7 +29065,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
29058
29065
  //-58
29059
29066
 
29060
29067
  /*--
29061
- 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)
29062
29069
 
29063
29070
  Panel
29064
29071
  zim class - extends a zim.Container which extends a createjs.Container
@@ -29184,6 +29191,7 @@ shadowColor - (default "rgba(0,0,0,.3)" if shadowBlur) the shadow color - set to
29184
29191
  shadowBlur - (default 14 if shadowColor) the shadow blur - set to -1 for no shadow
29185
29192
  draggable - (default true if titleBar) set to false to not allow dragging titleBar to drag window
29186
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
29187
29195
  style - (default true) set to false to ignore styles set with the STYLE - will receive original parameter defaults
29188
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)
29189
29197
  inherit - (default null) used internally but can receive an {} of styles directly
@@ -29261,8 +29269,8 @@ dispatches a "expand" event if expanding after being collapsed
29261
29269
  ALSO: see the CreateJS Easel Docs for Container events such as:
29262
29270
  added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmove, pressup, removed, rollout, rollover
29263
29271
  --*///+57.7
29264
- 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) {
29265
- 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";
29266
29274
  var duo; if (duo = zob(zim.Panel, arguments, sig, this)) return duo;
29267
29275
  z_d("57.7");
29268
29276
 
@@ -29301,6 +29309,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
29301
29309
  if (zot(collapse)) collapse=DS.collapse!=null?DS.collapse:false;
29302
29310
  if (zot(collapseColor)) collapseColor = DS.collapseColor != null ? DS.collapseColor:!zot(titleBarColor)?titleBarColor:zim.grey;
29303
29311
  if (zot(collapsed)) collapsed=DS.collapsed!=null?DS.collapsed:false;
29312
+ if (zot(onTop)) onTop=DS.onTop!=null?DS.onTop:true;
29304
29313
 
29305
29314
  var that = this;
29306
29315
 
@@ -29406,7 +29415,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
29406
29415
  if (draggable) {
29407
29416
  titleBar.cur("pointer");
29408
29417
  titleBar.on("mousedown", function() {
29409
- that.drag({rect:boundary, currentTarget:true});
29418
+ that.drag({rect:boundary, currentTarget:true, onTop:onTop});
29410
29419
  var ch,i;
29411
29420
  var tar = that.content||that.contentContainer||that;
29412
29421
  if (tar.type != "Container") tar = that.contentContainer||that;
@@ -29585,7 +29594,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
29585
29594
  if (style !== false) zim.styleTransforms(this, DS);
29586
29595
 
29587
29596
  this.clone = function () {
29588
- 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));
29589
29598
  };
29590
29599
  this.doDispose = function(a,b,disposing) {
29591
29600
  // need to dispose properly for Panel
@@ -32858,7 +32867,7 @@ borderColor - |ZIM VEE| (default null) the background stroke color
32858
32867
  borderWidth - (default null) thickness of the background border
32859
32868
  maxLength - (default null) set to limit the number of characters in the field
32860
32869
  password - (default false) set to true to show **** for text to hide password
32861
- this will be replaced by inputType in upcoming versions of ZIM
32870
+ see also inputType
32862
32871
  selectionColor - (default color) the selection color of the text
32863
32872
  selectionAlpha - (default .2) the alpha of the selection color
32864
32873
  cursorColor - (default color) the blinking cursor in the text
@@ -32888,7 +32897,7 @@ scrollBarV - (default true) if scrolling in vertical is needed then show scrollB
32888
32897
  readOnly - (default false) set to true for field to be readOnly - also see readOnly property
32889
32898
  inputType - (default "text") set to "text", "number", "password", "email"
32890
32899
  number has 0-9 . + - / * % $ available
32891
- this will replace the password parameter in upcoming versions of ZIM
32900
+ see also password for password setting
32892
32901
  rtl - (default ZIM DIR) the direction of the text. Also set "rtl" in the HTML tag dir parameter for RTL
32893
32902
  uppercase - (default false) set to true to force uppercase letters
32894
32903
  placeholderInstant - (default true) set to false to not remove the placeholder as soon as the cursor is in the field
@@ -33264,7 +33273,7 @@ zim.TextInput = function(width, height, placeholder, text, size, font, color, ba
33264
33273
  blinker.oldX = blinkerX; // get previous blinker global x.
33265
33274
  // end Pettis Brandon code '23
33266
33275
 
33267
- if (that.stage) that.stage.update();
33276
+ if ((!zim.OPTIMIZE&&(zns||!WW.OPTIMIZE)) && that.stage) that.stage.update();
33268
33277
  }, null, null, null, null, mID);
33269
33278
 
33270
33279
  if (pastText != null) {
@@ -33327,11 +33336,11 @@ zim.TextInput = function(width, height, placeholder, text, size, font, color, ba
33327
33336
  function doPlaceholder() {
33328
33337
  if (label.text != "" && that.placeholderLabel.parent) {
33329
33338
  that.placeholderLabel.removeFrom();
33330
- if (that.stage) that.stage.update();
33339
+ if ((!zim.OPTIMIZE&&(zns||!WW.OPTIMIZE)) && that.stage) that.stage.update();
33331
33340
  }
33332
33341
  if (label.text == "" && !that.placeholderLabel.parent) {
33333
33342
  that.add(that.placeholderLabel);
33334
- if (that.stage) that.stage.update();
33343
+ if ((!zim.OPTIMIZE&&(zns||!WW.OPTIMIZE)) && that.stage) that.stage.update();
33335
33344
  }
33336
33345
  }
33337
33346
 
@@ -33492,7 +33501,7 @@ zim.TextInput.LabelInput = function(text, size, maxLength, password, selectionCo
33492
33501
  this.hiddenInput.autocorrect = "off";
33493
33502
  this.hiddenInput.autocomplete = "off";
33494
33503
  this.hiddenInput.spellcheck = false;
33495
- this.hiddenInput.style.position = "absolute";
33504
+ this.hiddenInput.style.position = "fixed"; // changed from "absolute" in ZIM 019 to fix iOS bug
33496
33505
  this.hiddenInput.style.overflow = "hidden";
33497
33506
  this.hiddenInput.style.touchAction = "none";
33498
33507
 
@@ -33506,6 +33515,9 @@ zim.TextInput.LabelInput = function(text, size, maxLength, password, selectionCo
33506
33515
 
33507
33516
  this.hiddenInput.style.left = "-99999px";
33508
33517
  this.hiddenInput.style.top = "-99999px";
33518
+ // this.hiddenInput.style.left = "10px";
33519
+ // this.hiddenInput.style.top = "10px";
33520
+
33509
33521
  this.hiddenInput.style.zIndex = -999;
33510
33522
  this.hiddenInput.style.opacity = 0;
33511
33523
  this.hiddenInput.style.width = "1px";
@@ -33523,6 +33535,7 @@ zim.TextInput.LabelInput = function(text, size, maxLength, password, selectionCo
33523
33535
  this.selection.alp(0.2);
33524
33536
  this.positionBlinkerAndSelection();
33525
33537
  this.dispatchEvent("focus");
33538
+ if (that.stage) that.stage.update();
33526
33539
  }
33527
33540
  this.onBlur = function() {
33528
33541
  if (this.stage) frame = this.stage.frame;
@@ -33532,6 +33545,7 @@ zim.TextInput.LabelInput = function(text, size, maxLength, password, selectionCo
33532
33545
  this.selection.alp(0.0);
33533
33546
  this.hiddenInput.type = inputType; // ZIM NFT 00 patch
33534
33547
  this.dispatchEvent("blur");
33548
+ if (that.stage) that.stage.update();
33535
33549
  }
33536
33550
  this.onInput = function(e, noEvent) {
33537
33551
  if (uppercase) this.hiddenInput.value = this.hiddenInput.value.toUpperCase();
@@ -33552,6 +33566,7 @@ zim.TextInput.LabelInput = function(text, size, maxLength, password, selectionCo
33552
33566
  if (this.focus) {
33553
33567
  this.blinker.replayTween();
33554
33568
  }
33569
+ if (that.stage) that.stage.update();
33555
33570
  }
33556
33571
  this.onKeydown = function(e) {
33557
33572
  this.deleteKey = (e.code=="Backspace"||e.code=="Delete");
@@ -33561,6 +33576,7 @@ zim.TextInput.LabelInput = function(text, size, maxLength, password, selectionCo
33561
33576
  that.positionBlinkerAndSelection.call(that);
33562
33577
  // that.dispatchEvent(keyevt);
33563
33578
  that.dispatchEvent(e);
33579
+ if (that.stage) that.stage.update();
33564
33580
  }, 10);
33565
33581
  }
33566
33582
  this.onMousedown = function(e) {
@@ -33576,7 +33592,8 @@ zim.TextInput.LabelInput = function(text, size, maxLength, password, selectionCo
33576
33592
  var selectionIdx = this.mapPointToIndex(point);
33577
33593
  if (rtl) this.hiddenInput.setSelectionRange(le-selectionIdx, le-selectionIdx);
33578
33594
  else this.hiddenInput.setSelectionRange(selectionIdx, selectionIdx);
33579
- this.positionBlinkerAndSelection();
33595
+ this.positionBlinkerAndSelection();
33596
+ if (that.stage) that.stage.update();
33580
33597
  }
33581
33598
  this.onPressmove = function(e) {
33582
33599
  // ZIM NFT 01 Patch any le or rtl
@@ -33598,18 +33615,20 @@ zim.TextInput.LabelInput = function(text, size, maxLength, password, selectionCo
33598
33615
  } else {
33599
33616
  this.hiddenInput.setSelectionRange(selectionIdx, this.hiddenInput.selectionEnd, rtl?"forward":"backward");
33600
33617
  }
33601
- }
33602
-
33618
+ }
33603
33619
  this.positionBlinkerAndSelection();
33620
+ if (that.stage) that.stage.update();
33604
33621
  }
33605
33622
  this.onDblclick = function() {
33606
33623
  this.hiddenInput.select();
33607
33624
  this.positionBlinkerAndSelection();
33625
+ if (that.stage) that.stage.update();
33608
33626
  }
33609
33627
  this.hiddenInput.addEventListener("paste", function() {
33610
33628
  setTimeout(function() {
33611
33629
  that.hiddenInput.setSelectionRange(that.hiddenInput.selectionStart, that.hiddenInput.selectionEnd, rtl?"forward":"backward");
33612
33630
  // setTimeout(function() {that.positionBlinkerAndSelection()}, 50);
33631
+ if (that.stage) that.stage.update();
33613
33632
  }, 50);
33614
33633
  });
33615
33634
  this.positionBlinkerAndSelection = function() {
@@ -33645,7 +33664,7 @@ zim.TextInput.LabelInput = function(text, size, maxLength, password, selectionCo
33645
33664
  this.blinker.pos(this.textWidthArray[xIdx] + paddingH - 1 + ((align=="right" && this.text == "")?this.width:(align=="center" && this.text == "")?this.width/2:0) + shiftH, paddingV+shiftV);
33646
33665
  this.dispatchEvent("blinker");
33647
33666
  }
33648
- if (this.stage) this.stage.update();
33667
+ // if ((!zim.OPTIMIZE&&(zns||!WW.OPTIMIZE)) && this.stage) this.stage.update();
33649
33668
  }
33650
33669
  this.eventPositionGlobalToLocal = function(e) {
33651
33670
  var point = this.globalToLocal(e.stageX / zim.scaX, e.stageY / zim.scaY);
@@ -33691,6 +33710,7 @@ zim.TextInput.LabelInput = function(text, size, maxLength, password, selectionCo
33691
33710
  if (uppercase) text = text.toUpperCase();
33692
33711
  this.hiddenInput.value = text;
33693
33712
  this.onInput(null, noEvent);
33713
+ if ((!zim.OPTIMIZE&&(zns||!WW.OPTIMIZE)) && that.stage) that.stage.update();
33694
33714
  }
33695
33715
  Object.defineProperty(this, 'focus', {
33696
33716
  get: function() {
@@ -33704,7 +33724,9 @@ zim.TextInput.LabelInput = function(text, size, maxLength, password, selectionCo
33704
33724
  this.positionBlinkerAndSelection();
33705
33725
  } else {
33706
33726
  that.hiddenInput.blur();
33707
- }
33727
+ if (that.stage) that.stage.update();
33728
+ }
33729
+ if ((!zim.OPTIMIZE&&(zns||!WW.OPTIMIZE)) && that.stage) that.stage.update();
33708
33730
  }
33709
33731
  });
33710
33732
 
@@ -36035,25 +36057,25 @@ NOTE: as of ZIM 5.5.0 the zim namespace is no longer required (unless zns is set
36035
36057
 
36036
36058
  EXAMPLE
36037
36059
  const stepper = new Stepper()
36038
- .center()
36039
- .change(()=>{
36040
- label.text = stepper.value;
36041
- S.update();
36042
- });
36060
+ .center()
36061
+ .change(()=>{
36062
+ label.text = stepper.value;
36063
+ S.update();
36064
+ });
36043
36065
  const label = new Label({
36044
- align:CENTER,
36045
- text: stepper.value
36066
+ align:CENTER,
36067
+ text: stepper.value
36046
36068
  }).reg(CENTER).pos(0,100,CENTER,BOT);
36047
36069
  // press and drag too
36048
36070
 
36049
36071
  // Steppers can be words too
36050
36072
  const stepper2 = new Stepper({
36051
- list:["Roger", "Wilma","Sandy","Paul"],
36052
- width:200,
36053
- continuous:true
36073
+ list:["Roger", "Wilma","Sandy","Paul"],
36074
+ width:200,
36075
+ continuous:true
36054
36076
  }).pos(0,130,CENTER,CENTER).change(()=>{
36055
- label.text = stepper2.value;
36056
- S.update();
36077
+ label.text = stepper2.value;
36078
+ S.update();
36057
36079
  });
36058
36080
  END EXAMPLE
36059
36081
 
@@ -36133,6 +36155,7 @@ containerPrev, containerNext - access to the zim Container that holds the arrows
36133
36155
  arrowPrev, arrowNext - access to the zim Triangle objects
36134
36156
  arrowPrev2, arrowNext2 - access to the zim Triangle objects for arrows2
36135
36157
  min, max - only for number mode at the moment - currently, do not change the max to be less than the min
36158
+ step - get or set the main step of the Stepper (double check it is working, consider experimental, ZIM 019 patch)
36136
36159
  label - access to the Label
36137
36160
  textBox - access to the text box backing shape
36138
36161
  continuous - does the stepper loop
@@ -36156,7 +36179,11 @@ and S.update() in change event to see component change its graphics
36156
36179
 
36157
36180
  EVENTS
36158
36181
  dispatches a "change" event when changed by pressing an arrow or a keyboard arrow
36159
- (but not when setting index or value properties)
36182
+ but not when setting index or value properties
36183
+ dispatches a "keychange" event when changed by pressing a key that changes the value
36184
+ note the change from keys are also dispatched under "change"
36185
+ but sometimes if updating data, a pressup and a keychange combo is better
36186
+ as change from pressing and dragging can be at the framerate
36160
36187
 
36161
36188
  ALSO: see the CreateJS Easel Docs for Container events such as:
36162
36189
  added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmove, pressup, removed, rollout, rollover
@@ -36229,44 +36256,47 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
36229
36256
  var numVal;
36230
36257
  var numDir = 1;
36231
36258
  var decimals;
36232
- if (stepperType == "number") {
36233
- min = Number(min);
36234
- max = Number(max);
36235
- if (isNaN(min)) min = 0;
36236
- if (isNaN(max)) max = 100;
36237
- if (max < min) {
36238
- numDir = -1;
36239
- var temp = max; // one day ES6
36240
- max = min;
36241
- min = temp;
36242
- numVal = max;
36259
+ function setup() {
36260
+ if (stepperType == "number") {
36261
+ min = Number(min);
36262
+ max = Number(max);
36263
+ if (isNaN(min)) min = 0;
36264
+ if (isNaN(max)) max = 100;
36265
+ if (max < min) {
36266
+ numDir = -1;
36267
+ var temp = max; // one day ES6
36268
+ max = min;
36269
+ min = temp;
36270
+ numVal = max;
36271
+ } else {
36272
+ numVal = min;
36273
+ }
36274
+ that.min = min;
36275
+ that.max = max;
36276
+ if (0 > min && 0 < max) numVal = 0;
36277
+ step = Math.abs(step);
36278
+ decimals = Math.max(getDecimals(step), getDecimals(step2));
36279
+ } else if (stepperType == "letter") {
36280
+ list = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");
36281
+ if (typeof min != "string") min = "A";
36282
+ if (typeof max != "string") max = "Z";
36283
+ min = min.substr(0,1).toUpperCase();
36284
+ max = max.substr(0,1).toUpperCase();
36285
+ var startLetter = list.indexOf(min);
36286
+ if (startLetter < 0) {min = "A"; startLetter = 0;}
36287
+ var endLetter = list.indexOf(max);
36288
+ if (endLetter < 0) {max = "Z"; endLetter = list.length;}
36289
+ if (endLetter < startLetter) {
36290
+ list.reverse();
36291
+ startLetter = list.length-1-startLetter;
36292
+ endLetter = list.length-1-endLetter;
36293
+ }
36294
+ list = list.splice(startLetter, endLetter-startLetter+1);
36243
36295
  } else {
36244
- numVal = min;
36245
- }
36246
- this.min = min;
36247
- this.max = max;
36248
- if (0 > min && 0 < max) numVal = 0;
36249
- step = Math.abs(step);
36250
- decimals = Math.max(getDecimals(step), getDecimals(step2));
36251
- } else if (stepperType == "letter") {
36252
- list = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");
36253
- if (typeof min != "string") min = "A";
36254
- if (typeof max != "string") max = "Z";
36255
- min = min.substr(0,1).toUpperCase();
36256
- max = max.substr(0,1).toUpperCase();
36257
- var startLetter = list.indexOf(min);
36258
- if (startLetter < 0) {min = "A"; startLetter = 0;}
36259
- var endLetter = list.indexOf(max);
36260
- if (endLetter < 0) {max = "Z"; endLetter = list.length;}
36261
- if (endLetter < startLetter) {
36262
- list.reverse();
36263
- startLetter = list.length-1-startLetter;
36264
- endLetter = list.length-1-endLetter;
36265
- }
36266
- list = list.splice(startLetter, endLetter-startLetter+1);
36267
- } else {
36268
- stepperType = "list";
36296
+ stepperType = "list";
36297
+ }
36269
36298
  }
36299
+ setup();
36270
36300
 
36271
36301
  function getDecimals(num) {
36272
36302
  var decimals = String(num).split(".")[1];
@@ -36279,18 +36309,18 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
36279
36309
  var rawY = 0;
36280
36310
 
36281
36311
  if (draggable) {
36282
- this.on("mousedown", function(e) {
36312
+ that.on("mousedown", function(e) {
36283
36313
  if (that.zimAccessibility && that.zimAccessibility.aria) return;
36284
- this.stage.mouseMoveOutside = true;
36314
+ that.stage.mouseMoveOutside = true;
36285
36315
  rawX = e.rawX/zim.scaX;
36286
36316
  rawY = e.rawY/zim.scaY;
36287
- rawEvent = this.stage.on("stagemousemove", function(e){
36317
+ rawEvent = that.stage.on("stagemousemove", function(e){
36288
36318
  rawX = e.rawX/zim.scaX;
36289
36319
  rawY = e.rawY/zim.scaY;
36290
36320
  }, null, null, null, null, mID);
36291
36321
  }, null, true, null, null, mID);
36292
36322
  }
36293
- this.label = label;
36323
+ that.label = label;
36294
36324
  label.mouseChildren = false;
36295
36325
  label.mouseEnabled = false;
36296
36326
 
@@ -36473,6 +36503,8 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
36473
36503
  }
36474
36504
  doStep(dragDir);
36475
36505
  doHold();
36506
+ // optimize takes away update on changing label so add it here
36507
+ if (that.stage && (zim.OPTIMIZE||WW.OPTIMIZE)) that.stage.update();
36476
36508
  }, dragInput);
36477
36509
  }
36478
36510
  doHold();
@@ -36711,6 +36743,41 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
36711
36743
  }
36712
36744
  });
36713
36745
 
36746
+ // version of value that does not update stage
36747
+ Object.defineProperty(this, 'valueLite', {
36748
+ get: function() {
36749
+ if (stepperType=="number") {
36750
+ return Number(numVal);
36751
+ } else {
36752
+ return list[index];
36753
+ }
36754
+ },
36755
+ set: function(value) {
36756
+ if(zot(value)) return;
36757
+ if (stepperType=="number") {
36758
+ value = Number(value);
36759
+ if (that.max > that.min) {
36760
+ if (value > that.max || value < that.min) return;
36761
+ } else {
36762
+ if (value < that.max || value > that.min) return;
36763
+ }
36764
+ var newIndex = that.stepperArray.indexOf(value);
36765
+ if (newIndex < 0) return;
36766
+ index = newIndex;
36767
+ numVal = Number(that.stepperArray[index]);
36768
+ setLabel(numVal, numVal, false); // false to not update stage
36769
+ } else {
36770
+ if (list.indexOf(value) > -1) {
36771
+ value = list.indexOf(value);
36772
+ } else {return;}
36773
+ if (value == that.index) return;
36774
+ index=value;
36775
+ setLabel(list[index], index, false); // false to not update stage
36776
+ }
36777
+ }
36778
+ });
36779
+
36780
+
36714
36781
  Object.defineProperty(this, 'currentValue', {
36715
36782
  get: function() {
36716
36783
  return this.value;
@@ -36746,6 +36813,18 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
36746
36813
  }
36747
36814
  });
36748
36815
 
36816
+ Object.defineProperty(this, 'step', {
36817
+ get: function() {
36818
+ return step;
36819
+ },
36820
+ set: function(value) {
36821
+ if (value == 0) value = 1;
36822
+ step = step2 = actualStep = value;
36823
+ var v = that.value;
36824
+ setup();
36825
+ that.value = zim.decimals(zim.constrain(that.min + Math.round((v - that.min) / step+.00001) * step, that.min, that.max), 5);
36826
+ }
36827
+ });
36749
36828
 
36750
36829
  this._enabled = true;
36751
36830
  Object.defineProperty(that, 'enabled', {
@@ -36825,8 +36904,9 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
36825
36904
  }
36826
36905
  }
36827
36906
 
36828
- function setLabel(text, n) {
36907
+ function setLabel(text, n, update) {
36829
36908
  index = n;
36909
+ if (zot(update)) update = true;
36830
36910
  if (display) {
36831
36911
  if (stepperType == "number") {
36832
36912
  if (text != 0 && decimals > 0) {
@@ -36839,9 +36919,9 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
36839
36919
  // label.y = box.y+(box.getBounds().height-label.getBounds().height)/2;
36840
36920
  }
36841
36921
  if (arrows) setArrows();
36842
- if (next && ((!zim.OPTIMIZE&&(zns||!WW.OPTIMIZE)) && next.stage)) {
36922
+ if (update && next && ((!zim.OPTIMIZE&&(zns||!WW.OPTIMIZE)) && next.stage)) {
36843
36923
  next.stage.update();
36844
- } else if (label && ((!zim.OPTIMIZE&&(zns||!WW.OPTIMIZE)) && label.stage)) {
36924
+ } else if (update && label && ((!zim.OPTIMIZE&&(zns||!WW.OPTIMIZE)) && label.stage)) {
36845
36925
  label.stage.update();
36846
36926
  }
36847
36927
  if (that.zimAccessibility) that.zimAccessibility.changeTitle(that, null, true);
@@ -36888,14 +36968,22 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
36888
36968
  } else {
36889
36969
  actualStep = step2;
36890
36970
  }
36971
+ var lastV = that.value;
36891
36972
  doStep(1);
36973
+ if (that.value != lastV) {
36974
+ that.dispatchEvent("keychange");
36975
+ }
36892
36976
  } else if (k == backwardVertical || k == backwardHorizontal) {
36893
36977
  if ((vertical && k == backwardVertical) || (!vertical && k == backwardHorizontal)) {
36894
36978
  actualStep = step;
36895
36979
  } else {
36896
36980
  actualStep = step2;
36897
36981
  }
36982
+ var lastV = that.value
36898
36983
  doStep(-1);
36984
+ if (that.value != lastV) {
36985
+ that.dispatchEvent("keychange");
36986
+ }
36899
36987
  }
36900
36988
  }
36901
36989
  }
@@ -36923,7 +37011,10 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
36923
37011
  other = true;
36924
37012
  } else if (k==173 || k==189) {
36925
37013
  that.value = that.value * -1;
36926
- if (that.value != lastValue) that.dispatchEvent("change");
37014
+ if (that.value != lastValue) {
37015
+ that.dispatchEvent("change");
37016
+ that.dispatchEvent("keychange");
37017
+ }
36927
37018
  lastValue = that.value;
36928
37019
  negativeCheck = !negativeCheck;
36929
37020
  } else if (k == 46) { // delete
@@ -36947,14 +37038,20 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
36947
37038
  if (num < min || num > max) return;
36948
37039
 
36949
37040
  that.value = num;
36950
- if (that.value != lastValue) that.dispatchEvent("change");
37041
+ if (that.value != lastValue) {
37042
+ that.dispatchEvent("change");
37043
+ that.dispatchEvent("keychange");
37044
+ }
36951
37045
  lastValue = that.value;
36952
37046
 
36953
37047
  } else {
36954
37048
  keyRestartCheck = true;
36955
37049
  lastKeyNum = "";
36956
37050
  that.value = String.fromCharCode(e.keyCode);
36957
- if (that.value != lastValue) that.dispatchEvent("change");
37051
+ if (that.value != lastValue) {
37052
+ that.dispatchEvent("change");
37053
+ that.dispatchEvent("keychange");
37054
+ }
36958
37055
  lastValue = that.value;
36959
37056
  }
36960
37057
  }
@@ -41268,7 +41365,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
41268
41365
  //-66
41269
41366
 
41270
41367
  /*--
41271
- 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)
41272
41369
 
41273
41370
  NumPad
41274
41371
  zim class - extends a zim.Panel which extends a zim.Container which extends a createjs.Container
@@ -41326,6 +41423,7 @@ shadowColor - (default "rgba(0,0,0,.3)" if shadowBlur) the shadow color - set to
41326
41423
  shadowBlur - (default 14 if shadowColor) the shadow blur - set to -1 for no shadow
41327
41424
  draggable - (default true if titleBar) set to false to not allow dragging titleBar to drag window
41328
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
41329
41427
  style - (default true) set to false to ignore styles set with the STYLE - will receive original parameter defaults
41330
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)
41331
41429
  inherit - (default null) used internally but can receive an {} of styles directly
@@ -41365,8 +41463,8 @@ dispatches a "expand" event if expanding after being collapsed
41365
41463
  ALSO: see the CreateJS Easel Docs for Container events such as:
41366
41464
  added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmove, pressup, removed, rollout, rollover
41367
41465
  --*///+57.7
41368
- 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) {
41369
- 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";
41370
41468
  var duo; if (duo = zob(zim.NumPad, arguments, sig, this)) return duo;
41371
41469
  z_d("57.7");
41372
41470
 
@@ -41397,8 +41495,10 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
41397
41495
  if (zot(collapse)) collapse=DS.collapse!=null?DS.collapse:true;
41398
41496
  if (zot(collapseColor)) collapseColor = DS.collapseColor!=null?DS.collapseColor:!zot(titleBarColor)?titleBarColor:zim.grey;
41399
41497
  if (zot(collapsed)) collapsed=DS.collapsed!=null?DS.collapsed:false;
41498
+ if (zot(onTop)) onTop=DS.onTop!=null?DS.onTop:true;
41499
+
41400
41500
 
41401
- 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);
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);
41402
41502
  this.type = "NumPad";
41403
41503
 
41404
41504
  // MONITOR
@@ -41460,7 +41560,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
41460
41560
 
41461
41561
  if (style!==false) zim.styleTransforms(this, DS);
41462
41562
  this.clone = function () {
41463
- 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));
41464
41564
  };
41465
41565
  };
41466
41566
  zim.extend(zim.NumPad, zim.Panel, ["clone"], "zimPanel", false);
@@ -44065,7 +44165,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
44065
44165
  }
44066
44166
  }
44067
44167
 
44068
- 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);
44069
44169
 
44070
44170
  this.type = "TextEditor";
44071
44171
 
@@ -56188,9 +56288,14 @@ DESCRIPTION
56188
56288
  Sets multi-touch pan, pinch and rotate for position, scale and rotation
56189
56289
  Handles scaled and rotated containers
56190
56290
  Scale and rotation occur from the pinch point (with optional regControl for about the registration point)
56191
- Note - gesture() only works on the currentTarget - not a container's children (like drag() can)
56192
- 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
+
56193
56297
  ALSO: see the noGesture() method to remove some or all gestures
56298
+
56194
56299
  ALSO: see the gestureBoundary() method to set or reset the boundary rectangle dynamically
56195
56300
 
56196
56301
  EXAMPLE
@@ -56226,6 +56331,9 @@ surround - (default false) is for dragging a big object that always surrounds th
56226
56331
  circularBounds - (default false) set to true if object is circular with center registration
56227
56332
  set to true to use radius to calculate rotated object in boundary if boundary is set
56228
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
56229
56337
 
56230
56338
  EVENTS
56231
56339
  Adds move, scale and rotate events to obj (when associated gesture parameters are set to true)
@@ -56233,417 +56341,736 @@ If slide is true, obj dispatches a "slidestop" event when sliding stops
56233
56341
 
56234
56342
  RETURNS obj for chaining
56235
56343
  --*///+34.5
56236
- zim.gesture = function(obj, move, scale, rotate, boundary, minScale, maxScale, snapRotate, localBoundary, slide, slideFactor, regControl, onTop, surround, circularBounds, rect) {
56237
- var sig = "obj, move, scale, rotate, boundary, minScale, maxScale, snapRotate, localBoundary, slide, slideFactor, regControl, onTop, surround, circularBounds, rect";
56238
- var duo; if (duo = zob(zim.gesture, arguments, sig)) return duo;
56239
- if (obj.type=="AC"&&WW.zdf) {WW.zdf.ac("gesture", arguments); return obj;}
56240
- z_d("34.5");
56241
-
56242
- // MONITOR
56243
- var mID = "z~gesture";
56244
- if (obj && obj.mID && ((obj.mID[2] && obj.mID[2]=="-") || obj.mID[0]=="-")) mID = "z~-";
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");
56245
56349
 
56246
- if (zot(obj) || !obj.on) return;
56247
- if (zot(move)) move = true;
56248
- if (zot(scale)) scale = true;
56249
- if (zot(rotate)) rotate = true;
56250
- if (zot(localBoundary)) localBoundary = false;
56251
- if (zot(snapRotate)) snapRotate = 1;
56252
- if (zot(slide)) slide = false;
56253
- if (zot(slideFactor)) slideFactor = 5;
56254
- if (zot(regControl)) regControl = false;
56255
- if (zot(onTop)) onTop = true;
56256
- if (zot(surround)) surround = false;
56257
- if (surround && rotate) {
56258
- surround = rect = null;
56259
- if (zon) zogy("gesture() - does not support surround when rotate is true");
56260
- }
56261
- if (zot(circularBounds)) circularBounds = false;
56262
- if (zot(boundary) && !zot(rect)) boundary = rect;
56263
-
56264
- var slideData;
56265
- var slideCount;
56266
- var slideSlice;
56267
- 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~-";
56268
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;
56269
56372
 
56270
- var timeType = getTIME();
56373
+ var slideData;
56374
+ var slideCount;
56375
+ var slideSlice;
56376
+ var slideTotal;
56271
56377
 
56272
- // HANDLE MASK if there is one
56273
- if (!zot(obj.zimMaskDynamic)) obj.zimMaskApply(); // set mask set by zimMask to dynamic
56274
56378
 
56275
- if (!obj.zimTouch) {
56379
+ var timeType = getTIME();
56276
56380
 
56277
- var dampScaleX = new zim.Damp(obj.scaleX, .05);
56278
- var dampScaleY = new zim.Damp(obj.scaleY, .05);
56279
- 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
56280
56383
 
56281
- obj.zimTouch = {
56282
- move:move, // store settings on object to control with noGesture()
56283
- scale:scale,
56284
- rotate:rotate,
56285
- pointers:{}, // holds the current pointer data
56286
- checkBounds:function(x, y) { // used locally and by zim.gestureBoundary
56287
- if (obj.zimTouch.boundary) {
56288
- var boundary = obj.zimTouch.boundary;
56289
- // convert the desired drag position to a global point
56290
- // note that we want the position of the object in its parent
56291
- // so we use the parent as the local frame
56292
- var point = obj.parent.localToLocal(x,y,obj.parent);
56293
- // boundary is the boundary rectangle on the global stage
56294
- // boundary is set during mousedown to allow for global scaling when in localBoundary mode
56295
- // if you scale in localBoundary==false mode, you will need to reset bounds with dragBoundary()
56296
- if (surround) {
56297
- x = Math.min(boundary.x, Math.max(boundary.x+boundary.width, point.x));
56298
- y = Math.min(boundary.y, Math.max(boundary.y+boundary.height, point.y));
56299
- } else {
56300
- x = Math.max(boundary.x, Math.min(boundary.x+boundary.width, point.x));
56301
- y = Math.max(boundary.y, Math.min(boundary.y+boundary.height, point.y));
56302
- }
56303
- // now that the point has been checked on the global scale
56304
- // convert the point back to the obj parent frame of reference
56305
- point = obj.parent.globalToLocal(x, y);
56306
- x = point.x;
56307
- 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));
56308
56411
  }
56309
- 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;
56310
56417
  }
56311
- };
56312
-
56313
- if (boundary) {
56314
- obj.zimTouch.boundary = boundary;
56315
- if (localBoundary) obj.zimTouch.boundary = zim.boundsToGlobal(obj.parent, boundary);
56316
- obj.zimTouch.boundaryStartX = obj.zimTouch.boundary.x;
56317
- obj.zimTouch.boundaryStartY = obj.zimTouch.boundary.y;
56318
- obj.zimTouch.boundaryStartW = obj.zimTouch.boundary.width;
56319
- obj.zimTouch.boundaryStartH = obj.zimTouch.boundary.height;
56320
- var result = obj.zimTouch.checkBounds(obj.x, obj.y); // set in bounds to start
56321
- obj.x = result.x;
56322
- obj.y = result.y;
56418
+ return {x:x,y:y};
56323
56419
  }
56420
+ };
56324
56421
 
56325
- if (slide) {
56326
- slideSlice = 10;
56327
- slideTotal = 5;
56328
- slideCount = 0;
56329
- slideData = [];
56330
-
56331
- obj.zimTouch.slideInterval = zim.interval(slideSlice/(timeType=="s"?1000:1),function() {
56332
- slideData[slideCount++%slideTotal] = [obj.x, obj.y];
56333
- }, null, null, null, null, null, null, null, mID, obj);
56334
- obj.zimTouch.slideInterval.pause();
56335
- obj.animate({x:obj.x, y:obj.y}, 10/(timeType=="s"?1000:1), "quadOut"); // for some reason, first throw is smoother if already animated
56336
- }
56337
-
56338
- var matrixStart;
56339
- var startScaleX;
56340
- var startScaleY;
56341
- var startRotation;
56342
- var startRegX;
56343
- var startRegY;
56344
- var lastPoint;
56345
- var maxTouches;
56346
-
56347
- obj.zimTouch.mousedown = obj.on("mousedown", function(e) {
56348
- if (zot(maxTouches)) maxTouches = 1;
56349
- else maxTouches++;
56350
-
56351
- if (onTop) {
56352
- var nc = obj.parent.numChildren-1;
56353
- if (obj.parent.getChildAt(nc).type=="Keyboard") nc--;
56354
- obj.parent.setChildIndex(obj,nc);
56355
- if (obj.ZIMoutlineShape) obj.outline();
56356
- }
56357
- if (!regControl) {
56358
- lastPoint = null;
56359
- startScaleX = obj.scaleX;
56360
- startScaleY = obj.scaleY;
56361
- startRotation = obj.rotation;
56362
- startRegX = obj.regX;
56363
- startRegY = obj.regY;
56364
- obj.reg(0,0);
56365
- matrixStart = obj.getMatrix();
56366
- obj.regX = startRegX;
56367
- obj.regY = startRegY;
56368
- }
56369
-
56370
- var id = "id"+Math.abs(e.pointerID+1); // some pointers have negative ids
56371
- // convert all pointer x and y to the parent container of the obj
56372
- var local = obj.parent.globalToLocal(e.stageX/zim.scaX, e.stageY/zim.scaY);
56373
- // we compare current pointer to start pointer (rather than increment as we go)
56374
- obj.zimTouch.pointers[id] = {
56375
- startX:local.x, startY:local.y,
56376
- x:local.x, y:local.y
56377
- };
56378
- if (obj.zimTouch.move || obj.zimTouch.rotate) {
56379
- obj.zimTouch.total = 0;
56380
- zim.loop(obj.zimTouch.pointers, function() {
56381
- obj.zimTouch.total++;
56382
- });
56383
- }
56384
- if (slide && obj.zimTouch.total == 1) obj.zimTouch.slideInterval.pause(false);
56385
- setTouches();
56386
- }, 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
+ }
56387
56433
 
56388
- 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++;
56389
56459
 
56390
- var id = "id"+Math.abs(e.pointerID+1);
56391
- var local = obj.parent.globalToLocal(e.stageX/zim.scaX, e.stageY/zim.scaY);
56392
- // update our pointer data with new x and y
56393
- if (obj.zimTouch.pointers[id]) {
56394
- obj.zimTouch.pointers[id].x = local.x;
56395
- obj.zimTouch.pointers[id].y = local.y;
56396
- }
56397
-
56398
- // average the pointers' movement
56399
- var newX = 0;
56400
- var newY = 0;
56401
- var aveX = 0; // point about which to scale and rotate
56402
- var aveY = 0;
56403
- var deltaX = 0;
56404
- var deltaY = 0;
56405
- zim.loop(obj.zimTouch.pointers, function(id, pointer) {
56406
- newX += pointer.x - pointer.startX;
56407
- newY += pointer.y - pointer.startY;
56408
- aveX += pointer.x;
56409
- 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++;
56410
56491
  });
56411
- if (obj.zimTouch.total == 0) return;
56412
- deltaX = newX / obj.zimTouch.total;
56413
- deltaY = newY / obj.zimTouch.total;
56414
- newX = obj.zimTouch.startX + deltaX;
56415
- newY = obj.zimTouch.startY + deltaY;
56416
- aveX = aveX / obj.zimTouch.total;
56417
- aveY = aveY / obj.zimTouch.total;
56418
-
56419
- var proxy = {
56420
- x: obj.x,
56421
- y: obj.y,
56422
- scaleX:obj.scaleX,
56423
- scaleY:obj.scaleY,
56424
- rotation:obj.rotation
56425
- }; // will store desired scale and rotation on this object then apply matrix calculations
56426
-
56427
- if (obj.zimTouch.move) {
56428
- var result = obj.zimTouch.checkBounds(newX, newY); // es6 opportunity
56429
- proxy.x = result.x;
56430
- proxy.y = result.y;
56431
- }
56432
-
56433
- // if we have multitouch as determined by setTouches()
56434
- if (obj.zimTouch.pair.length == 2) {
56435
- var point1 = obj.zimTouch.pair[0];
56436
- var point2 = obj.zimTouch.pair[1];
56437
- if (obj.zimTouch.scale) {
56438
- // use ratio of distance between fingers to start and then current distance between fingers
56439
- var startDistance = Math.sqrt(Math.pow((point2.startX-point1.startX),2) + Math.pow((point2.startY-point1.startY),2));
56440
- var currentDistance = Math.sqrt(Math.pow((point2.x-point1.x),2) + Math.pow((point2.y-point1.y),2));
56441
- var newScaleX = obj.zimTouch.startSX + (currentDistance / startDistance - 1);
56442
- var newScaleY = obj.zimTouch.startSY + (currentDistance / startDistance - 1);
56443
- proxy.scaleX = newScaleX;
56444
- proxy.scaleY = newScaleY;
56445
-
56446
- proxy.scaleX = dampScaleX.convert(newScaleX);
56447
- proxy.scaleY = dampScaleY.convert(newScaleY);
56448
-
56449
- // set to scale min or max if scale would be outside range
56450
- var minBad = (!zot(minScale) && Math.min(newScaleX, newScaleY) < minScale);
56451
- var maxBad = (!zot(maxScale) && Math.max(newScaleX, newScaleY) > maxScale);
56452
- if (minBad || maxBad) {
56453
- if (minBad) {
56454
- if (scaleRatio > 1) {
56455
- proxy.scaleY = minScale;
56456
- proxy.scaleX = minScale*scaleRatio;
56457
- } else {
56458
- proxy.scaleX = minScale;
56459
- proxy.scaleY = minScale/scaleRatio;
56460
- }
56461
- } else if (maxBad) {
56462
- if (scaleRatio > 1) {
56463
- proxy.scaleX = maxScale;
56464
- proxy.scaleY = maxScale/scaleRatio;
56465
- } else {
56466
- proxy.scaleY = maxScale;
56467
- proxy.scaleX = maxScale*scaleRatio;
56468
- }
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;
56469
56577
  }
56470
- dampScaleX.immediate(proxy.scaleX);
56471
- dampScaleY.immediate(proxy.scaleY);
56472
56578
  }
56473
-
56474
- }
56475
- if (obj.zimTouch.rotate) {
56476
- // rotate based on the difference of angle between the fingers at start and at current
56477
- var startAngle = Math.atan2((point1.startY - point2.startY), (point1.startX - point2.startX)) * (180 / Math.PI);
56478
- var currentAngle = Math.atan2((point1.y - point2.y), (point1.x - point2.x)) * (180 / Math.PI);
56479
- var deltaR = currentAngle - startAngle;
56480
- proxy.rotation = obj.zimTouch.startR + deltaR;
56579
+ dampScaleX.immediate(proxy.scaleX);
56580
+ dampScaleY.immediate(proxy.scaleY);
56481
56581
  }
56482
56582
 
56483
- if (regControl) {
56484
- obj.scaleX = proxy.scaleX;
56485
- obj.scaleY = proxy.scaleY;
56486
- obj.rotation = proxy.rotation;
56487
- if (obj.zimTouch.move) {
56488
- obj.x = proxy.x;
56489
- obj.y = proxy.y;
56490
- }
56491
- } else {
56492
- // transformations seem to ignore registration so need to set to 0 then reset after transformations
56493
- obj.reg(0,0);
56494
-
56495
- // need global data - the transformation about the pinch point is an adjustment of the system
56496
- // originally we wanted calculations in the container of the object
56497
- // these calculations were probably used for min and max of things, etc. so just leaving them
56498
- // and instead, bringing the calculations back into the global - and then eventually into the local for the transformations
56499
- var adjust = obj.parent.localToGlobal(aveX, aveY);
56500
- aveX = adjust.x;
56501
- aveY = adjust.y;
56502
-
56503
- // unfortunately, system goes haywire after a while without adjusting for minor shifts
56504
- // saving the location of the center back to global after the transformation seems to correct this
56505
- // we set lastPoint down below after the transformation
56506
- var point = zot(lastPoint) ? obj.globalToLocal(aveX, aveY) : obj.globalToLocal(lastPoint.x, lastPoint.y);
56507
-
56508
- // the classic Matrix transformation - translate to the pinch point, scale and rotate, and then translate back
56509
- // var matrix = new createjs.Matrix2D()
56510
- var matrix = matrixStart.clone()
56511
- .translate(point.x, point.y)
56512
- .rotate(proxy.rotation-startRotation)
56513
- .scale(proxy.scaleX/startScaleX,proxy.scaleY/startScaleY)
56514
- .translate(-(point.x), -(point.y));
56515
- // .prependMatrix(matrixStart) // would use if started new Matrix each time
56516
-
56517
- matrix.decompose(obj);
56518
-
56519
- if (obj.zimTouch.move) {
56520
- obj.x += deltaX;
56521
- obj.y += deltaY;
56522
- }
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
+ }
56523
56591
 
56524
- // correcting for minor shifts which can magnify and set the system haywire
56525
- 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);
56526
56603
 
56527
- 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;
56528
56631
  }
56529
56632
 
56530
- if (obj.zimTouch.scale) obj.dispatchEvent("scale");
56531
- if (obj.zimTouch.rotate) obj.dispatchEvent("rotate");
56532
- 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);
56533
56635
 
56534
- } else {
56535
- obj.x = proxy.x;
56536
- obj.y = proxy.y;
56537
- if (obj.zimTouch.move) obj.dispatchEvent("move");
56636
+ obj.reg(startRegX, startRegY);
56538
56637
  }
56539
- if (obj.type == "Tag" || obj.type == "TextArea" || obj.type == "Loader") obj.resize();
56540
56638
 
56541
- if (obj.ZIMoutlineShape) obj.outline();
56542
- 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++;
56543
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
56544
56672
 
56545
- obj.on("mousedown", function() {
56546
- // if an object is removed that is touched, the touch will still be registered
56547
- // this code makes sure that no ghost touches are left by counting stagemousedown and stagemouseup events
56548
- var mouseCount = 1;
56549
- obj.tsmd = obj.stage.on("stagemousedown", function() {
56550
- mouseCount++;
56551
- }, null, null, null, null, mID);
56552
- obj.tsmu = obj.stage.on("stagemouseup", function() {
56553
- mouseCount--;
56554
- if (mouseCount == 0) {
56555
- setTimeout(function() {
56556
- if (obj.zimTouch) obj.zimTouch.total = 0;
56557
- if (obj.zimTouch) obj.zimTouch.pointers = {};
56558
- maxTouches = null;
56559
- }, 50);
56560
- }
56561
- }, null, null, null, null, mID);
56562
- }, 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
+ }
56563
56707
 
56564
- obj.zimTouch.pressup = obj.on("pressup", function(e) {
56565
- var id = "id"+Math.abs(e.pointerID+1);
56566
- // remove touch data for pointer
56567
- delete obj.zimTouch.pointers[id];
56568
- if (obj.zimTouch.move || obj.zimTouch.rotate) obj.zimTouch.total--;
56569
- if (rotate && !zot(snapRotate) && obj.zimTouch.total == 0) {
56570
- if (snapRotate > 0) {
56571
- obj.rotation = Math.round(obj.rotation/snapRotate)*snapRotate;
56572
- } else if (snapRotate == 0) {
56573
- obj.rotation = Math.round(obj.rotation);
56574
- }
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);
56575
56833
  }
56576
- // spinning was throwing slide off so just slide with single touch for now...
56577
- if (slide && obj.zimTouch.total == 0 && maxTouches == 1) {
56578
- obj.zimTouch.slideInterval.pause();
56579
- var startSlide = slideData[(slideCount+1)%slideData.length];
56580
- var currentSlide = slideData[(slideCount)%slideData.length];
56581
- var newX = obj.x + (startSlide[0]-currentSlide[0]) * slideFactor;
56582
- var newY = obj.y + (startSlide[1]-currentSlide[1]) * slideFactor;
56583
- var result = obj.zimTouch.checkBounds(newX, newY); // es6 opportunity
56584
- // if it is being thrown past the bounds, need to reduce time by percentage of blocked movement
56585
- var newT = slideTotal*slideSlice*slideFactor * Math.min((obj.x-result.x)/(obj.x-newX)||1, (obj.y-result.y)/(obj.y-newY)||1);
56586
- obj.animate({x:result.x, y:result.y}, newT/(timeType=="s"?1000:1), "quadOut", function(){obj.dispatchEvent("slidestop");});
56587
- }
56588
- if (obj.zimTouch.total == 0) maxTouches = null;
56589
56834
  if (obj.getStage && obj.stage) obj.stage.update();
56590
- setTouches();
56591
- }, null, null, null, null, mID);
56592
-
56593
- if (boundary) {
56594
- remakeBoundary();
56595
- obj.on("move", remakeBoundary, null, null, null, null, mID);
56596
- }
56597
- }
56598
-
56599
- function setTouches() {
56600
- // anytime we add or remove a pointer we reset the start positions
56601
- // this handles cases where single touch would change the start position
56602
- // and handles removing of one of the active pairs of pointers
56603
- // to be replaced with another current pointer
56604
- obj.zimTouch.pair = [];
56605
- zim.loop(obj.zimTouch.pointers, function(id, pointer, i) {
56606
- pointer.startX = pointer.x;
56607
- pointer.startY = pointer.y;
56608
- // just record the first two pointers
56609
- // keep looping as mov uses all pointers
56610
- if (i <= 1) obj.zimTouch.pair.push(pointer);
56611
- });
56612
- // record the start position, scale and rotation
56613
- obj.zimTouch.startX = obj.x;
56614
- obj.zimTouch.startY = obj.y;
56615
- obj.zimTouch.startSX = obj.scaleX;
56616
- obj.zimTouch.startSY = obj.scaleY;
56617
- obj.zimTouch.startR = obj.rotation;
56618
- }
56619
-
56620
- function remakeBoundary() {
56621
- var p = obj.localToGlobal(obj.regX, obj.regY);
56622
- var b;
56623
- if (circularBounds) {
56624
- // assuming cropped if Bitmap and width==height
56625
- var leftTop = obj.parent.localToGlobal(obj.x-obj.width/2, obj.y-obj.height/2);
56626
- var botRight = obj.parent.localToGlobal(obj.x+obj.width/2, obj.y+obj.height/2);
56627
- b = {
56628
- x:leftTop.x,
56629
- y:leftTop.y,
56630
- width:botRight.x-leftTop.x,
56631
- height:botRight.y-leftTop.y
56632
- };
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
+
56633
56895
  } else {
56634
- 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
+ }
56635
56941
  }
56636
- var r = {
56637
- x:obj.zimTouch.boundaryStartX+p.x-b.x,
56638
- y:obj.zimTouch.boundaryStartY+p.y-b.y,
56639
- width:obj.zimTouch.boundaryStartW-b.width,
56640
- height:obj.zimTouch.boundaryStartH-b.height
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;
56979
+ }
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
56641
57058
  };
56642
- obj.gestureBoundary(r, false); // do not update the original rect
57059
+ } else {
57060
+ b = obj.boundsToGlobal();
56643
57061
  }
56644
-
56645
- return obj;
56646
- };//-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
+
56647
57074
 
56648
57075
  /*--
56649
57076
  obj.noGesture = function(move, scale, rotate)
@@ -56670,20 +57097,22 @@ rotate - (default true) - set to false not to remove rotate gesture
56670
57097
 
56671
57098
  RETURNS obj for chaining
56672
57099
  --*///+34.6
56673
- zim.noGesture = function(obj, move, scale, rotate) {
56674
- var sig = "obj, move, scale, rotate";
56675
- var duo; if (duo = zob(zim.noGesture, arguments, sig)) return duo;
56676
- 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");
56677
57104
 
56678
- if (zot(obj) || !obj.on || !obj.zimTouch) return;
57105
+ if (zot(obj) || !obj.on || !obj.zimTouch) return;
56679
57106
 
56680
- // MONITOR
56681
- var mID = "z~noGesture";
56682
- if (obj && obj.mID && ((obj.mID[2] && obj.mID[2]=="-") || obj.mID[0]=="-")) mID = "z~-";
56683
-
56684
- if (zot(move)) move = true;
56685
- if (zot(scale)) scale = true;
56686
- 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) {
56687
57116
  obj.zimTouch.move = !move;
56688
57117
  obj.zimTouch.scale = !scale;
56689
57118
  obj.zimTouch.rotate = !rotate;
@@ -56691,13 +57120,24 @@ RETURNS obj for chaining
56691
57120
  obj.off("mousedown", obj.zimTouch.mousedown, null, mID);
56692
57121
  obj.off("pressmove", obj.zimTouch.pressmove, null, mID);
56693
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
+ }
56694
57132
  delete obj.zimTouch;
56695
- }
56696
- if (obj.tsmd) obj.stage.off("stagemousedown", obj.tsmd, null, mID);
56697
- if (obj.tsmu) obj.stage.off("stagemouseup", obj.tsmu, null, mID);
57133
+ }
57134
+ }
56698
57135
 
56699
- return obj;
56700
- };//-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
56701
57141
 
56702
57142
  /*--
56703
57143
  obj.gestureBoundary = function(boundary, new)
@@ -57942,7 +58382,7 @@ RETURNS an index Number (or undefined) | col | row | an Array of [index, col, ro
57942
58382
  // SUBSECTION ANIMATE, WIGGLE, AND LOOP
57943
58383
 
57944
58384
  /*--
57945
- 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)
57946
58386
 
57947
58387
  animate
57948
58388
  zim DisplayObject method
@@ -58354,6 +58794,12 @@ rewindEase - (default null) overwrite the ease for the rewind direction
58354
58794
  so setting rewindEase:"bounceOut" will bounce back at the start of the animation
58355
58795
  note - setting ease:"bounceOut" will bounce at the end of the animation
58356
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
58357
58803
  startCall - (default null) calls function at the start of actual animation and after any wait (and waitedCall)
58358
58804
  this is basically the same as the waitedCall but will also be called at the start of animation when there is no waitedCall
58359
58805
  startParams - (default target) parameters to send startCall function
@@ -58477,12 +58923,6 @@ timeUnit - (default TIME) override the TIME setting to "seconds" / "s" or "milli
58477
58923
  timeCheck - (default true) set to false to not have animate() warn of potentially wrong time units - see also TIMECHECK
58478
58924
  noAnimateCall - (default true) set to false to not call the callback function if ANIMATE is set to false
58479
58925
  pathDamp - (default .15) damping for drag along path
58480
- rewindPick - (default false) set to true to pick from props as it rewinds
58481
- this will be moved to the other rewind parameters in ZIM 019
58482
- also see loopPick - using both loopPick and rewindPick will act like a series
58483
- where if the property has a series it will animate one after the other
58484
- do not use if the property is just a regular value as it will appear to stop the animation.
58485
- Can use a series, results of a function, min max or array for random picks
58486
58926
  style - (default true) set to false to ignore styles set with the STYLE - will receive original parameter defaults
58487
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)
58488
58928
 
@@ -58555,8 +58995,8 @@ EVENTS - zim animate() will add an "animation" event to the target IF the events
58555
58995
 
58556
58996
  RETURNS the target for chaining (or null if no target is provided and run on zim with series)
58557
58997
  --*///+45
58558
- 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) {
58559
- 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";
58560
59000
 
58561
59001
  if (target && (target.props || target.obj)) {
58562
59002
  var duo; if (duo = zob(zim.animate, arguments, sig)) return duo;
@@ -58582,12 +59022,12 @@ RETURNS the target for chaining (or null if no target is provided and run on zim
58582
59022
  if (zot(waitedCall)) waitedCall = DS.waitedCall!=null?DS.waitedCall:null;
58583
59023
  if (zot(waitedParams)) waitedParams = DS.waitedParams!=null?DS.waitedParams:null;
58584
59024
  if (zot(loop)) loop = DS.loop!=null?DS.loop:null;
59025
+ if (zot(loopWaitParams)) loopWaitParams = DS.loopWaitParams!=null?DS.loopWaitParams:null;
58585
59026
  if (zot(loopCount)) loopCount = DS.loopCount!=null?DS.loopCount:null;
58586
59027
  if (zot(loopWait)) loopWait = DS.loopWait!=null?DS.loopWait:null;
58587
59028
  if (zot(loopCall)) loopCall = DS.loopCall!=null?DS.loopCall:null;
58588
59029
  if (zot(loopParams)) loopParams = DS.loopParams!=null?DS.loopParams:null;
58589
59030
  if (zot(loopWaitCall)) loopWaitCall = DS.loopWaitCall!=null?DS.loopWaitCall:null;
58590
- if (zot(loopWaitParams)) loopWaitParams = DS.loopWaitParams!=null?DS.loopWaitParams:null;
58591
59031
  if (zot(loopPick)) loopPick = DS.loopPick!=null?DS.loopPick:null;
58592
59032
  if (zot(rewind)) rewind = DS.rewind!=null?DS.rewind:null;
58593
59033
  if (zot(rewindWait)) rewindWait = DS.rewindWait!=null?DS.rewindWait:null;
@@ -58597,6 +59037,7 @@ RETURNS the target for chaining (or null if no target is provided and run on zim
58597
59037
  if (zot(rewindWaitParams)) rewindWaitParams = DS.rewindWaitParams!=null?DS.rewindWaitParams:null;
58598
59038
  if (zot(rewindTime)) rewindTime = DS.rewindTime!=null?DS.rewindTime:null;
58599
59039
  if (zot(rewindEase)) rewindEase = DS.rewindEase!=null?DS.rewindEase:null;
59040
+ if (zot(rewindPick)) rewindPick = DS.rewindPick!=null?DS.rewindPick:null;
58600
59041
  if (zot(startCall)) startCall = DS.startCall!=null?DS.startCall:null;
58601
59042
  if (zot(startParams)) startParams = DS.startParams!=null?DS.startParams:null;
58602
59043
  if (zot(animateCall)) animateCall = DS.animateCall!=null?DS.animateCall:null;
@@ -58632,7 +59073,6 @@ RETURNS the target for chaining (or null if no target is provided and run on zim
58632
59073
  if (zot(timeCheck)) timeCheck = DS.timeCheck!=null?DS.timeCheck:null;
58633
59074
  if (zot(noAnimateCall)) noAnimateCall = DS.noAnimateCall!=null?DS.noAnimateCall:null;
58634
59075
  if (zot(pathDamp)) pathDamp = DS.pathDamp!=null?DS.pathDamp:null;
58635
- if (zot(rewindPick)) rewindPick = DS.rewindPick!=null?DS.rewindPick:null;
58636
59076
 
58637
59077
  if (!target) target = {}; // ZIM 018 replacing: return; from 10.9.0
58638
59078
  var AN = zim.ANIMATE;
@@ -58845,7 +59285,7 @@ RETURNS the target for chaining (or null if no target is provided and run on zim
58845
59285
  if (i==0 && sequence!=0) seqTime = timeType=="s"?.02:20; // patched in 10.7.0 and 10.7.1
58846
59286
 
58847
59287
  // zim.animate(tar, tar.zimObj, time, ease, (i==target.length-1?call:null), (i==target.length-1?params:null)
58848
- 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!
58849
59289
 
58850
59290
  }
58851
59291
  return sequenceTarget;
@@ -59195,7 +59635,7 @@ RETURNS the target for chaining (or null if no target is provided and run on zim
59195
59635
  }
59196
59636
  }
59197
59637
 
59198
- // 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
59199
59639
 
59200
59640
  // -----------------------------
59201
59641
  // NORMALIZED TWEEN COMING THROUGH
@@ -63302,7 +63742,7 @@ Style.remove("color");
63302
63742
  // add styles for a Dial - overwriting all previous Dial styles
63303
63743
  Style.addType("Dial", {useTicks:false, backgroundColor:yellow});
63304
63744
 
63305
- // remember current style using a "default" id
63745
+ // remember current style using a "default" id - also see with ID below
63306
63746
  Style.remember();
63307
63747
 
63308
63748
  // new Dials will use ticks and not be yellow
@@ -63317,7 +63757,7 @@ Style.remember("myID");
63317
63757
  // add styles for a group (existing objects are not changed - new ones will be)
63318
63758
  Style.addGroup("big", {size:100});
63319
63759
 
63320
- 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
63321
63761
  Style.recall("myID");
63322
63762
  END EXAMPLE
63323
63763
 
@@ -66518,6 +66958,7 @@ allowToggle - (default true) set to false to not allow grid to toggle between pe
66518
66958
  cache - (default true) cache the grid
66519
66959
  numbers - (default true) show numbers on grid
66520
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
66521
66962
  style - (default true) set to false to ignore styles set with the STYLE - will receive original parameter defaults
66522
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)
66523
66964
  inherit - (default null) used internally but can receive an {} of styles directly
@@ -69066,6 +69507,7 @@ PROPERTIES
69066
69507
  type - holds the class name as a String
69067
69508
  items - get the original items array passed to the pack (including addAt() and removeFrom() changes)
69068
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
69069
69511
  cols - get the current number of columns
69070
69512
  rows - get the current number of rows
69071
69513
  iterations - get the number of times the pack was made to optimize its size
@@ -70039,6 +70481,188 @@ alpha, cursor, shadow, name, mouseChildren, mouseEnabled, parent, numChildren, e
70039
70481
  zim.extend(zim.Beads, zim.Container, ["clone","dispose"], "zimContainer", false);
70040
70482
  //-66.7
70041
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
+
70042
70666
  /*--
70043
70667
  zim.Layout = function(holder, regions, lastMargin, lastMarginMin, backgroundColor, vertical, showRegions, scalingObject, hideKey, style, group, inherit)
70044
70668
 
@@ -72833,7 +73457,33 @@ It tiles all TextureActive objects across the ZIM stage (and beyond to the right
72833
73457
  It adds a slider and swiper to view the objects.
72834
73458
  It adds a key (default t) and toggle() method to toggle between the three.js canvas and the ZIM canvas.
72835
73459
 
72836
- SEE the TextureActive and TextureActives examples
73460
+ EXAMPLE
73461
+ // Do not use TextureActiveManager directly
73462
+ // Make sure to import the three module
73463
+
73464
+ const panel = new TextureActive(W,H);
73465
+ const circle = new Circle(100,red).center(panel).drag();
73466
+
73467
+ const three = new Three({
73468
+ width:window.innerWidth,
73469
+ height:window.innerHeight,
73470
+ cameraPosition:new THREE.Vector3(0,0,500),
73471
+ textureActive:true
73472
+ });
73473
+
73474
+ const renderer = three.renderer;
73475
+ const scene = three.scene;
73476
+ const camera = three.camera;
73477
+
73478
+ const controls = new OrbitControls(camera, three.canvas);
73479
+
73480
+ const textureActives = new TextureActives(panel, THREE, three, renderer, scene, camera, controls);
73481
+ // turn off T key to toggle between ZIM and three.js
73482
+ textureActives.manager.toggleKey = -1;
73483
+
73484
+ const canvasWindow = three.makePanel(panel, textureActives);
73485
+ scene.add(canvasWindow);
73486
+ END EXAMPLE
72837
73487
 
72838
73488
  PARAMETERS
72839
73489
  stage (default the ZIMDefaultFrame's stage) the stage to operate on - provided internally
@@ -77395,6 +78045,15 @@ circle.contact(obj=>{
77395
78045
  });
77396
78046
  END EXAMPLE
77397
78047
 
78048
+ EXAMPLE
78049
+ // Can join objects together with different types of joins (distance, weld, revolute)
78050
+ STYLE = {corner:10};
78051
+ const bar1 = new Rectangle(100,20).reg(CENTER).loc(100,600).addPhysics();
78052
+ const bar2 = new Rectangle(100,20).reg(CENTER).loc(200,600).addPhysics();
78053
+ // revolute only needs one point - choose end middle of bar1 (remember reg is in center)
78054
+ physics.join(bar1, bar2, new Point(bar1.x+bar1.width/2, bar1.y), null, -90, 90, "revolute");
78055
+ END EXAMPLE
78056
+
77398
78057
  EXAMPLE
77399
78058
  // control a ball with a DPad - better than keys for mobile
77400
78059
  const physics = new Physics(0);
@@ -77576,6 +78235,7 @@ addPhysics(dynamic, contract, shape, friction, linear, angular, density, bouncin
77576
78235
  friction - (default .8) - how sticky will the body act - set to 0 to slide.
77577
78236
  linear - (default .5) - linear damping which slows the movement - set to 0 for no damping
77578
78237
  angular - (default .5) - angular damping which slows the rotation - set to 0 for no damping
78238
+ also can use obj.body.SetFixedRotation(true) to stop the physics body from rotating
77579
78239
  density - (default 1) - the density that can affect what happens with collisions
77580
78240
  bounciness - (default 0) - how bouncy the object is - 0 is not bouncy 4 is crazy bouncy
77581
78241
  maskBits - (default null) - used with categoryBits to determine which bodies will collide with which other bodies
@@ -77614,8 +78274,9 @@ torque(amount) - add a turning force over time on the object
77614
78274
  just applying the torque once will hardly do anything - use an spin() for that
77615
78275
  setLinearVelocity(x, y) - set the linear velocity - this overrides current forces
77616
78276
  so might look unnatural as setLinearVelocity(0,0) will stop the object moving
77617
- setAngularVelocity(amount) - set the angular velocity - this overrids current forces
78277
+ setAngularVelocity(amount) - set the angular velocity - this overrides current forces
77618
78278
  so might look unnatural as setAngularVelocity(0) will stop the object spinning
78279
+ Also can use obj.body.SetFixedRotation(true) to stop the physics body from rotating
77619
78280
  sleep() - puts object to sleep so no physics calculations are done
77620
78281
  wake() - wakes up object from sleep so physics calculations are done
77621
78282
  follow(damp, dampY, leftOffset, rightOffset, upOffset, downOffset, offsetDamp, offsetDampY, horizontal, vertical, borderLock, borderOriginal)
@@ -77718,7 +78379,7 @@ zimObj - the ZIM Object that the body is mapped to
77718
78379
  x - deprecated - please use the BODY's loc(x, y) method - note: zimObj.body.loc() is not the same as the zimObj.loc() method
77719
78380
  y - deprecated - please use the BODY's loc(x, y) method - note: zimObj.body.loc() is not the same as the zimObj.loc() method
77720
78381
  rotation - the rotation of the body (degrees) - setting this will also rotate the ZIM DisplayObject
77721
- Also see obj.body.SetFixedRotation() to stop the physics body from rotating https://zimjs.com/zapp/print/Z_C6SBW
78382
+ Also can use obj.body.SetFixedRotation(true) to stop the physics body from rotating https://zimjs.com/zapp/print/Z_C6SBW
77722
78383
  And the counter rotation technique here: https://zimjs.com/data/
77723
78384
 
77724
78385
  GLOBAL VARIABLES
@@ -80088,7 +80749,7 @@ EXAMPLE
80088
80749
  const obj = new Container(500,500);
80089
80750
  F.makeCircles().center(obj).animate({props:{scale:2}, rewind:true, loop:true});
80090
80751
 
80091
- new zim.Perspective({
80752
+ new Perspective({
80092
80753
  obj: obj,
80093
80754
  points:[
80094
80755
  {x:-obj.width/2, y:-obj.height/2+50},
@@ -80105,7 +80766,7 @@ EXAMPLE
80105
80766
  const obj = new Container(500,500);
80106
80767
  F.makeCircles().center(obj).animate({props:{scale:2}, rewind:true, loop:true});
80107
80768
 
80108
- const perspective = new zim.Perspective(obj).center();
80769
+ const perspective = new Perspective(obj).center();
80109
80770
 
80110
80771
  perspective.selectSide(3);
80111
80772
  perspective.updateCorner(perspective.selectCorner(0).mov(0,100));
@@ -80119,7 +80780,7 @@ EXAMPLE
80119
80780
  const obj = new Container(500,500);
80120
80781
  F.makeCircles().center(obj).animate({props:{scale:2}, rewind:true, loop:true});
80121
80782
 
80122
- const perspective = new zim.Perspective(obj).center();
80783
+ const perspective = new Perspective(obj).center();
80123
80784
 
80124
80785
  perspective.selectSide(0); // comment this out to see the difference
80125
80786
  const corner = perspective.selectCorner(1).wiggle("x",null,50,100,.5,1);
@@ -80134,7 +80795,7 @@ EXAMPLE
80134
80795
  const obj = new Container(500,500);
80135
80796
  F.makeCircles().center(obj).animate({props:{scale:2}, rewind:true, loop:true});
80136
80797
 
80137
- const perspective = new zim.Perspective(obj).center();
80798
+ const perspective = new Perspective(obj).center();
80138
80799
 
80139
80800
  const point = perspective.selectCorner(2);
80140
80801
  const p = perspective.blob.globalToLocal(W,H); // the corner control is in the blob
@@ -83119,9 +83780,9 @@ EXAMPLE
83119
83780
  // With emitter on complete and re-shuffle
83120
83781
  STYLE = {Label:{backgroundColor:white}};
83121
83782
  const shuffler = new Shuffler("Will this wind be so mighty ?")
83122
- .center();
83783
+ .center();
83123
83784
  const emitter = new Emitter({startPaused:true})
83124
- .center();
83785
+ .center();
83125
83786
  shuffler.on("complete", ()=>{
83126
83787
  shuffler.shuffle(2, 2, 4);
83127
83788
  emitter.spurt(20);
@@ -90378,6 +91039,9 @@ See https://zimjs.com/frame.html for sample templates using Frame.
90378
91039
  The first frame made is called the zimDefaultFrame - or zdf.
90379
91040
  It will also have the default stage for addTo(), center(), etc.
90380
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.
90381
91045
 
90382
91046
  As of ZIM ZIM 01, ZIM will make F, S, W, H global variables
90383
91047
  that reference the zimDefaultFrame, its stage and the stage width and height.
@@ -90626,7 +91290,6 @@ loadFailObj - (default result of F.makeCircles) object that shows if asset() doe
90626
91290
  This will be given a type property of "EmptyAsset"
90627
91291
  Set the loadFailObj property below to null to set no object - but this will yield errors unless each resulting asset() is tested
90628
91292
  Set to new Container() to show nothing (but avoid errors) - or new Rectangle(10, 10) to show little black square, etc.
90629
- sensors - (default false) set to true to capture Frame devicemotion and deviceorientation events - see Events
90630
91293
  retina - (default true) scales stage to use pixelDensity (sharper when scaling up) and supports Adobe Animate export
90631
91294
  may need to set mouse event targets to e.stageX/zim.scaX and e.stageY.zim.scaY
90632
91295
  except for using S.getObjectUnderPoint()
@@ -91026,7 +91689,7 @@ EVENTS
91026
91689
  note - when changing scale, it is better to multiply by a factor rather than add to the scale
91027
91690
  eg. circle.scale = constrain(circle.scale*(sign(e.deltaY)>0?.75:1.25), .5, 5);
91028
91691
  "deviceorientation" - turned on when using ZIM PermissionAsk()
91029
- fired as device orientation changes:
91692
+ fired as device orientation changes - use for tilt or compass
91030
91693
  eventObject.rotation.x (beta in HTML specs) holds rotation about the x axis between -180 and 180 (tipped forward or backward)
91031
91694
  eventObject.rotation.y (gamma in HTML specs) holds rotation about the y axis between -90 and 90 (tipped left or right)
91032
91695
  eventObject.rotation.z (alpha in HTML specs) holds rotation about the z axis 0-360 clockwise (relative to orientation when app loads)
@@ -91040,7 +91703,8 @@ EVENTS
91040
91703
  S.update();
91041
91704
  });
91042
91705
  "devicemotion" - turned on when using ZIM PermissionAsk()
91043
- fired on moving mobile device - like a tilt or shake - eventObject.acceleration holds x, y and z properties of motion
91706
+ tracks device accelerometer to capture shake
91707
+ eventObject.acceleration holds x, y and z properties of motion
91044
91708
  eg.
91045
91709
  var label = new Label().center();
91046
91710
  // Note: MUST USE PermissionAsk()
@@ -91878,7 +92542,6 @@ zim.Frame = function(scaling, width, height, color, outerColor, ready, assets, p
91878
92542
  // 018 TRYING TO FIX CREATEJS ERROR IF SOUND LOADED AGAIN - BUT BREAKS LAZY LOAD
91879
92543
  // var emptyAssets = false;
91880
92544
 
91881
-
91882
92545
  for (i=0; i<assets.length; i++) {
91883
92546
  a = assets[i];
91884
92547
  // if (zim.assets[a]) {
@@ -91888,9 +92551,9 @@ zim.Frame = function(scaling, width, height, color, outerColor, ready, assets, p
91888
92551
  // // continue;
91889
92552
  // // }
91890
92553
  // }
91891
- 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=");
91892
92555
  // split multi into individual ZIM asset objects and make the first of these
91893
- if (a.assets) {
92556
+ if (a.assets) {
91894
92557
  var assetMulti = [];
91895
92558
  assets.splice(i, 1);
91896
92559
  if (!Array.isArray(a.assets)) a.assets = [a.assets];
@@ -95255,53 +95918,91 @@ END EXAMPLE
95255
95918
  //-83.867
95256
95919
 
95257
95920
  /*--
95258
- Tilt - device motion and orientation events
95921
+ Tilt - device orientation event
95259
95922
 
95260
95923
  Tilt
95261
- "devicemotion" and "deviceorientation" Frame events
95924
+ "deviceorientation" Frame event
95262
95925
 
95263
95926
  DESCRIPTION
95264
- The Frame has a "devicemotion" event to capture device tilt
95265
- and a "deviceorientation" to capture device rotation (like a compass)
95927
+ The Frame has a "deviceorientation" event to capture tilt or device rotation (like a compass)
95928
+ and a "devicemotion" event to capture shaking the device with the accelerometer.
95929
+
95930
+ SEE: Shake - for the "devicemotion" event for accelerometer motion
95266
95931
 
95267
95932
  SEE: the PermissionAsk() class which will handle asking for permissions on devices.
95268
95933
 
95269
95934
  EXAMPLE
95270
- // TILT
95935
+ // TILT OR COMPASS - https://zimjs.com/zapp/Z_Q5UYS
95271
95936
  // for capturing tilt on device (rotation about an axis)
95272
- // be on a mobile device
95937
+ // be on a mobile device or a device with sensors
95273
95938
  new PermissionAsk(yes=>{
95274
- if (yes) {
95939
+ if (yes) { // the user answered yes to PermissionAsk
95275
95940
  // all code goes in here
95276
- const label = new Label().loc(20,20);
95941
+ new Label("Tilt the device to move circle").alp(.3).pos(0,30,CENTER);
95942
+ const circle = new Circle().center();
95943
+ const amount = .5;
95944
+ const compass = new Line(60, 4, light, "arrow").rot(90).centerReg(circle); // point up
95277
95945
  F.on("deviceorientation", e=>{
95278
- label.text = "x: " + Math.round(e.rotation.x)
95279
- +"\ny: " + Math.round(e.rotation.y)
95280
- +"\nz: " + Math.round(e.rotation.z);
95946
+ // for tilt
95947
+ circle.mov(e.rotation.y*amount, e.rotation.x*amount);
95948
+ circle.x = constrain(circle.x, 0, W);
95949
+ circle.y = constrain(circle.y, 0, H);
95950
+ // for compass use e.rotation.z
95951
+ // which has 0 angle at device start rotation (not necessarily North)
95952
+ compass.rot(90-e.rotation.z); // rotate opposite device rotation
95281
95953
  S.update();
95282
95954
  });
95283
- } else {
95955
+ } else { // the user answered no to PermissionAsk
95284
95956
  new Pane("SENSOR not available",yellow).show();
95285
95957
  }
95286
95958
  });
95287
95959
  END EXAMPLE
95288
95960
 
95961
+ EVENTS
95962
+ "deviceorientation" - for tilt
95963
+ fired as device orientation changes:
95964
+ eventObject.rotation.x (beta in HTML specs) holds rotation about the x axis between -180 and 180 (tipped forward or backward)
95965
+ eventObject.rotation.y (gamma in HTML specs) holds rotation about the y axis between -90 and 90 (tipped left or right)
95966
+ eventObject.rotation.z (alpha in HTML specs) holds rotation about the z axis 0-360 clockwise (relative to orientation when app loads)
95967
+ note rotation.z is 360-alpha compared to the HTML 5 specs
95968
+ note also that beta, gamma and alpha from the HTML 5 specs are also provided
95969
+ --*///+83.86
95970
+ // Device motion and orientation events are available as Frame events
95971
+ //-83.86
95972
+
95973
+ /*--
95974
+ Shake - device motion event
95975
+
95976
+ Shake
95977
+ "devicemotion" Frame event
95978
+
95979
+ DESCRIPTION
95980
+ The Frame has a "devicemotion" event to capture shaking the device with the accelerometer.
95981
+
95982
+ SEE: Tilt - for the "deviceorientation" event for tilt or compass
95983
+
95984
+ SEE: the PermissionAsk() class which will handle asking for permissions on devices.
95985
+
95289
95986
  EXAMPLE
95290
- // SHAKE
95291
- // for capturing shaking motion on device (acceleration about an access)
95292
- // be on a mobile device
95987
+ // SHAKE - https://zimjs.com/zapp/Z_XF8JM
95988
+ // for capturing shaking motion on device (acceleration about an axis)
95989
+ // be on a mobile device or a device with sensors
95293
95990
  new PermissionAsk(init, "devicemotion");
95294
95991
  function init(yes) {
95295
- if (yes) { // the user answers yes to the PermissionAsk
95992
+ if (yes) { // the user answered yes to PermissionAsk
95993
+ // all code goes in here
95994
+ new Label("Shake the device").center();
95995
+ S.update();
95296
95996
  let id;
95297
95997
  F.on("devicemotion", e=>{
95998
+ // for shake
95298
95999
  if (
95299
96000
  Math.abs(e.acceleration.x) > 5 ||
95300
96001
  Math.abs(e.acceleration.y) > 5 ||
95301
96002
  Math.abs(e.acceleration.z) > 5
95302
96003
  ) {
95303
- if (F.color != red) {
95304
- F.color = red;
96004
+ if (F.color != green) {
96005
+ F.color = green;
95305
96006
  S.update();
95306
96007
  }
95307
96008
  if (id) id.clear();
@@ -95311,25 +96012,18 @@ function init(yes) {
95311
96012
  });
95312
96013
  }
95313
96014
  });
95314
- } else { // the user answered no to PermissionAsk dialog
95315
- new Pane("SENSOR not available",yellow).show()
96015
+ } else { // the user answered no to PermissionAsk
96016
+ new Pane("SENSOR not available",yellow).show();
95316
96017
  }
95317
96018
  }
95318
96019
  END EXAMPLE
95319
96020
 
95320
96021
  EVENTS
95321
- "deviceorientation" - for tilt
95322
- fired as device orientation changes:
95323
- eventObject.rotation.x (beta in HTML specs) holds rotation about the x axis between -180 and 180 (tipped forward or backward)
95324
- eventObject.rotation.y (gamma in HTML specs) holds rotation about the y axis between -90 and 90 (tipped left or right)
95325
- eventObject.rotation.z (alpha in HTML specs) holds rotation about the z axis 0-360 clockwise (relative to orientation when app loads)
95326
- note rotation.z is 360-alpha compared to the HTML 5 specs
95327
- note also that beta, gamma and alpha from the HTML 5 specs are also provided
95328
96022
  "devicemotion" - for shake
95329
96023
  fired on moving mobile device - like a shake - eventObject.acceleration holds x, y and z properties of motion
95330
- --*///+83.86
96024
+ --*///+83.87
95331
96025
  // Device motion and orientation events are available as Frame events
95332
- //-83.86
96026
+ //-83.87
95333
96027
 
95334
96028
  /*--
95335
96029
  zim.PermissionAsk = function(callback, permissionType, color, backgroundColor, style, group, inherit)
@@ -95338,7 +96032,7 @@ PermissionAsk
95338
96032
  zim class - extends a zim.Pane which extends a zim.Container
95339
96033
 
95340
96034
  DESCRIPTION
95341
- A circular confirmation widget to ask the user if they want a permission on mobile.
96035
+ A circular confirmation widget to ask the user if they want a permission on devices.
95342
96036
  For some iOS permissions, the app needs to be interactive with first before permission can be asked!
95343
96037
 
95344
96038
  Also adds Frame deviceorientation and devicemotion events for a matching permissionType.
@@ -95351,19 +96045,26 @@ NOTE: as of ZIM 5.5.0 the zim namespace is no longer required (unless zns is set
95351
96045
 
95352
96046
  EXAMPLE
95353
96047
  // DEVICE ORIENTATION - gives angle of device in all 3 dimensions
96048
+ // See https://zimjs.com/zapp/Z_Q5UYS
95354
96049
  // Note: this is NOT an orientation event to see if phone is portrait or landscape (see Frame orientation event)
95355
-
95356
96050
  new PermissionAsk(yes=>{
95357
- if (yes) {
96051
+ if (yes) { // the user answered yes to PermissionAsk
95358
96052
  // all code goes in here
95359
- const label = new Label().loc(20,20);
96053
+ new Label("Tilt the device to move circle").alp(.3).pos(0,30,CENTER);
96054
+ const circle = new Circle().center();
96055
+ const amount = .5;
96056
+ const compass = new Line(60, 4, light, "arrow").rot(90).centerReg(circle); // point up
95360
96057
  F.on("deviceorientation", e=>{
95361
- label.text = "x: " + Math.round(e.rotation.x)
95362
- +"\ny: " + Math.round(e.rotation.y)
95363
- +"\nz: " + Math.round(e.rotation.z);
96058
+ // for tilt
96059
+ circle.mov(e.rotation.y*amount, e.rotation.x*amount);
96060
+ circle.x = constrain(circle.x, 0, W);
96061
+ circle.y = constrain(circle.y, 0, H);
96062
+ // for compass use e.rotation.z
96063
+ // which has 0 angle at device start rotation (not necessarily North)
96064
+ compass.rot(90-e.rotation.z); // rotate opposite device rotation
95364
96065
  S.update();
95365
96066
  });
95366
- } else {
96067
+ } else { // the user answered no to PermissionAsk
95367
96068
  new Pane("SENSOR not available",yellow).show();
95368
96069
  }
95369
96070
  });
@@ -95371,19 +96072,23 @@ END EXAMPLE
95371
96072
 
95372
96073
  EXAMPLE
95373
96074
  // DEVICE MOTION - gives accelerometer values in all 3 dimensions
95374
-
96075
+ // See https://zimjs.com/zapp/Z_XF8JM
95375
96076
  new PermissionAsk(init, "devicemotion");
95376
96077
  function init(yes) {
95377
- if (yes) { // the user answers yes to the PermissionAsk
96078
+ if (yes) { // the user answered yes to PermissionAsk
96079
+ // all code goes in here
96080
+ new Label("Shake the device").center();
96081
+ S.update();
95378
96082
  let id;
95379
- F.on("devicemotion", e=>{
96083
+ F.on("devicemotion", e=>{
96084
+ // for shake
95380
96085
  if (
95381
96086
  Math.abs(e.acceleration.x) > 5 ||
95382
96087
  Math.abs(e.acceleration.y) > 5 ||
95383
96088
  Math.abs(e.acceleration.z) > 5
95384
96089
  ) {
95385
- if (F.color != red) {
95386
- F.color = red;
96090
+ if (F.color != green) {
96091
+ F.color = green;
95387
96092
  S.update();
95388
96093
  }
95389
96094
  if (id) id.clear();
@@ -95393,13 +96098,14 @@ function init(yes) {
95393
96098
  });
95394
96099
  }
95395
96100
  });
95396
- } else { // the user answered no to PermissionAsk dialog
95397
- new Pane("SENSOR not available",yellow).show()
96101
+ } else { // the user answered no to PermissionAsk
96102
+ new Pane("SENSOR not available",yellow).show();
95398
96103
  }
95399
96104
  }
95400
96105
  END EXAMPLE
95401
96106
 
95402
96107
  EXAMPLE
96108
+ // CAM
95403
96109
  // on iOS, the app must be interacted with before using mic or cam
95404
96110
  // goes right to permissions on computer and android
95405
96111
  // pops up a PermissionAsk Pane on iOS then if yes, goes to permissions on iOS
@@ -95411,6 +96117,7 @@ function init(val) {
95411
96117
  END EXAMPLE
95412
96118
 
95413
96119
  EXAMPLE
96120
+ // MIC
95414
96121
  // on iOS, the app must be interacted with before using mic or cam
95415
96122
  // this goes right to permissions on computer and android
95416
96123
  // but pops up a PermissionAsk Pane on iOS then if yes, goes to permissions on iOS
@@ -95429,6 +96136,17 @@ callback - the function to callback when permission is accepted
95429
96136
  for iOS the PermissionAsk Pane will be shown and the system permissions
95430
96137
  in all cases, the callback will be called on result
95431
96138
  the parameter given to the callback will be true (sensors) or a media stream (mic / cam) or false if not accepted
96139
+ the callback will receive an error number as its second parameter
96140
+ 1 - device orientation fail
96141
+ 2 - device motion fail
96142
+ 3 - test timeout fail
96143
+ 4 - mic or miccam fail
96144
+ 5 - mediaDevices or getUserMedia fail
96145
+ 6 - native request permission denied by user
96146
+ 7 - request permission fail
96147
+ 8 - ZIM interface request permission denied by user (NO chosen)
96148
+ 9 - mic or miccam fail (no ZIM interface)
96149
+ 10 - mediaDevices or getUserMedia fail (no ZIM interface)
95432
96150
  permissionType - (default "deviceorientation") the string deviceorientation, devicemotion, mic, cam, or miccam
95433
96151
  color - (default zim.dark) the font and border color of the widget
95434
96152
  backgroundColor - (default zim.lighter) the backgroundColor of the widget
@@ -95487,8 +96205,7 @@ alpha, cursor, shadow, name, mouseChildren, mouseEnabled, parent, numChildren, e
95487
96205
 
95488
96206
  var that = this;
95489
96207
 
95490
- Style.addGroup("PermissionAsk", {
95491
- width:100,
96208
+ Style.addGroup("PermissionAsk", {
95492
96209
  color:color,
95493
96210
  rollColor:backgroundColor,
95494
96211
  corner:10,
@@ -95500,10 +96217,10 @@ alpha, cursor, shadow, name, mouseChildren, mouseEnabled, parent, numChildren, e
95500
96217
  });
95501
96218
  var pt = permissionType;
95502
96219
  var okay = false;
95503
- that.yes = new zim.Button({label:"YES", group:"PermissionAsk"}).sca(.65).pos(0,30,CENTER,TOP,this);
96220
+ that.yes = new zim.Button({label:"YES", width:100, group:"PermissionAsk"}).sca(.65).pos(0,30,CENTER,TOP,this);
95504
96221
  var words = {deviceorientation:"sensors", devicemotion:"sensors", mic:"mic", cam:"cam", miccam:"mic/cam"};
95505
96222
  that.label = new zim.Label("Use " + (words[pt]?words[pt]:"feature") + "?", 30, null, color, null, null, null, "center").sca(.9).centerReg(this);
95506
- that.no = new zim.Button({label:"NO", group:"PermissionAsk"}).sca(.65).pos(0,30,CENTER,BOTTOM,this);
96223
+ that.no = new zim.Button({label:"NO", width:100, group:"PermissionAsk"}).sca(.65).pos(0,30,CENTER,BOTTOM,this);
95507
96224
 
95508
96225
  new zim.Circle(110, zim.clear, color, 1).center(this).alp(.8);
95509
96226
  new zim.Circle(120, zim.clear, color, 1).center(this).alp(.5);
@@ -95522,9 +96239,9 @@ alpha, cursor, shadow, name, mouseChildren, mouseEnabled, parent, numChildren, e
95522
96239
  callback(stream);
95523
96240
  })
95524
96241
  .catch(function(err) {
95525
- callback(false);
96242
+ callback(false, 9);
95526
96243
  });
95527
- } else callback(false);
96244
+ } else callback(false, 10);
95528
96245
  return;
95529
96246
  }
95530
96247
 
@@ -95538,19 +96255,19 @@ alpha, cursor, shadow, name, mouseChildren, mouseEnabled, parent, numChildren, e
95538
96255
  function testMe(e) {
95539
96256
  if (okay) return;
95540
96257
  if (permissionType=="deviceorientation") {
95541
- if (e.alpha==null || (e.alpha==0&&e.beta==0&&e.gamma==0)) callback(false);
96258
+ if (e.alpha==null || (e.alpha==0&&e.beta==0&&e.gamma==0)) callback(false, 1);
95542
96259
  else setEvents();
95543
96260
  } else {
95544
96261
  // if (!e.acceleration || e.acceleration.x==null || (e.acceleration.x==0&&e.acceleration.y==0&&e.acceleration.z==0)) callback(false);
95545
- if (!e.acceleration || e.acceleration.x==null) callback(false);
96262
+ if (!e.acceleration || e.acceleration.x==null) callback(false, 2);
95546
96263
  else setEvents();
95547
96264
  }
95548
96265
  called = true;
95549
96266
  WW.removeEventListener(permissionType, testMe);
95550
96267
  }
95551
96268
  setTimeout(function(){
95552
- if (!called) callback(false);
95553
- }, 100);
96269
+ if (!called) callback(false, 3);
96270
+ }, 5000);
95554
96271
  }
95555
96272
 
95556
96273
  var lastZ = 0;
@@ -95599,9 +96316,9 @@ alpha, cursor, shadow, name, mouseChildren, mouseEnabled, parent, numChildren, e
95599
96316
  callback(stream);
95600
96317
  })
95601
96318
  .catch(function(err) {
95602
- callback(false);
96319
+ callback(false, 4);
95603
96320
  });
95604
- } else callback(false);
96321
+ } else callback(false, 5);
95605
96322
  } else {
95606
96323
  var s = DeviceMotionEvent;
95607
96324
  if (pt != "devicemotion") s = DeviceOrientationEvent;
@@ -95610,13 +96327,13 @@ alpha, cursor, shadow, name, mouseChildren, mouseEnabled, parent, numChildren, e
95610
96327
  setEvents();
95611
96328
  okay = true;
95612
96329
  }
95613
- else callback(false);
96330
+ else callback(false, 6);
95614
96331
  }).catch(function(e){
95615
- callback(false);
96332
+ callback(false, 7);
95616
96333
  });
95617
96334
  }
95618
96335
  } else {
95619
- callback(false);
96336
+ callback(false, 8);
95620
96337
  }
95621
96338
  }
95622
96339
 
@@ -96303,13 +97020,13 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
96303
97020
  var controls = new zim.Container(w*.6,w*.25);
96304
97021
  var conLev = new zim.Label({text:"LEVEL", shiftV:4}).alp(.8).sca(objTitle.scale);
96305
97022
  var conLevI = new zim.Label({text:"Depth", shiftV:4, italic:true}).alp(.5).sca(objTitle.scale);
96306
- var conLevS = new zim.Stepper({shadowColor:-1, bgColor:grey, color:lighter, value:settings.level, arrowScale:.6, group:"noMonitor"}).scaleTo(controls,40).change(function() {
97023
+ var conLevS = new zim.Stepper({arrows:true, shadowColor:-1, bgColor:grey, color:lighter, value:settings.level, arrowScale:.6, group:"noMonitor"}).scaleTo(controls,40).change(function() {
96307
97024
  settings.level = conLevS.value;
96308
97025
  updateSettings();
96309
97026
  });
96310
97027
  var conSpe = new zim.Label({text:"BATCH", shiftV:4}).alp(.8).sca(objTitle.scale);
96311
97028
  var conSpeI = new zim.Label({text:"Seconds", shiftV:4, italic:true}).alp(.5).sca(objTitle.scale);
96312
- var conBatS = new zim.Stepper({min:.1, max:3, step:.1, value:settings.time, shadowColor:-1, bgColor:grey, color:lighter, arrowScale:.6, group:"noMonitor"}).sca(conLevS.scale).change(function() {
97029
+ var conBatS = new zim.Stepper({arrows:true, min:.1, max:3, step:.1, value:settings.time, shadowColor:-1, bgColor:grey, color:lighter, arrowScale:.6, group:"noMonitor"}).sca(conLevS.scale).change(function() {
96313
97030
  settings.time = conBatS.value;
96314
97031
  updateSettings();
96315
97032
  });;
@@ -97132,6 +97849,8 @@ const content = makeContent({
97132
97849
  END EXAMPLE
97133
97850
 
97134
97851
  PARAMETERS
97852
+ ** supports VEE - parameters marked with ZIM VEE mean a zim Pick() object or Pick Literal can be passed
97853
+ Pick Literal formats: [1,3,2] - random; {min:10, max:20} - range; series(1,2,3) - order, function(){return result;} - function
97135
97854
  content - the content to make - using one of three formats:
97136
97855
  a string or number to add a ZIM Label (also see color parameter and property)
97137
97856
  a ZIM DisplayObject such as a Circle or a Container with more objects, etc.
@@ -97142,10 +97861,10 @@ content - the content to make - using one of three formats:
97142
97861
  buttons - an array of ZIM Button objects or configuration objects {} as follows:
97143
97862
  {label, color, rollColor, backgroundColor, rollBackgroundColor, call}
97144
97863
  with call being a callback function for when the button is pressed
97145
- buttonScale - the scale for the buttons
97864
+ buttonScale - |ZIM VEE| the scale for the buttons
97146
97865
  color - the color of the message
97147
- spacingH - horizontal space between the buttons (default 20xbuttonScale)
97148
- spacingV - vertical space between the content areas (default 20)
97866
+ spacingH - |ZIM VEE| horizontal space between the buttons (default 20xbuttonScale) starts with expected spaces, last space is set at left and right
97867
+ spacingV - |ZIM VEE| vertical space between the content areas (default 20) starts with space from top ends with space from bottom
97149
97868
  scrollBar - set to true if a default scrollBar is present in Window or a number if custom
97150
97869
  align - default CENTER, or use LEFT or RIGHT
97151
97870
  maxWidth - (default null) pass in a maximum width to keep scale the content to
@@ -97180,14 +97899,15 @@ RETURNS - a Label if a string or number is passed as content, a Container if a c
97180
97899
 
97181
97900
  if (!data.align) data.align = "center";
97182
97901
  obj = new zim.Container();
97183
- var spacer = new Container(10,spacingV).addTo(obj);
97184
- if (data.header) data.header.pos(0,spacingV,"left","top",obj);
97185
- if (data.message) var label = new zim.Label({text:data.message, color:zot(data.color)?color:data.color, align:data.align}).reg(LEFT,TOP).loc(0,obj.height+(data.header?spacingV:0),obj);
97186
- if (data.display) data.display.pos(0,-data.display.height-(data.header||data.message?spacingV:0),"left","bottom",obj);
97902
+ var s1 = zik(spacingV);
97903
+ var spacer = new Container(10,s1).addTo(obj);
97904
+ if (data.header) data.header.pos(0,s1,"left","top",obj);
97905
+ if (data.message) var label = new zim.Label({text:data.message, color:zot(data.color)?color:data.color, align:data.align}).reg(LEFT,TOP).loc(0,obj.height+(data.header?zik(spacingV):0),obj);
97906
+ if (data.display) data.display.pos(0,-data.display.height-(data.header||data.message?zik(spacingV):0),"left","bottom",obj);
97187
97907
  if (data.buttons) {
97188
97908
  if (!Array.isArray(data.buttons)) data.buttons = [data.buttons];
97189
97909
  var ideal = data.length*100;
97190
- var buts = new zim.Container().loc(0,obj.height+(data.header||data.message||data.display?spacingV:0),obj);
97910
+ var buts = new zim.Container().loc(0,obj.height+(data.header||data.message||data.display?zik(spacingV):0),obj);
97191
97911
  for (var bb=0; bb<data.buttons.length; bb++) {
97192
97912
  var bd = data.buttons[bb];
97193
97913
  var call = bd.call||function(){};
@@ -97204,8 +97924,12 @@ RETURNS - a Label if a string or number is passed as content, a Container if a c
97204
97924
  bd.button = bd;
97205
97925
  }
97206
97926
  bd.button.call = call;
97207
- bd.button.sca(data.buttonScale).loc((bb==0?0:buts.width+spacingH),0,buts).tap(function(e){e.target.call(e.target)});
97208
- }
97927
+ bd.button.sca(zik(data.buttonScale)).loc((bb==0?0:buts.width+zik(spacingH)),0,buts).tap(function(e){e.target.call(e.target)});
97928
+ }
97929
+ for (var bb=0; bb<data.buttons.length; bb++) {
97930
+ var bd = data.buttons[bb];
97931
+ bd.button.y = (buts.height - bd.button.height) / 2;
97932
+ }
97209
97933
  }
97210
97934
  var bb = obj.getBounds();
97211
97935
  obj.setBounds(bb.x, bb.y, bb.width, bb.height);
@@ -97218,8 +97942,9 @@ RETURNS - a Label if a string or number is passed as content, a Container if a c
97218
97942
  o.pos(0,null,"right");
97219
97943
  }
97220
97944
  }
97221
- if (maxWidth && typeof maxWidth == "number") obj.width = Math.min(obj.width, maxWidth-spacingH*2-(data.scrollBar===true?12:data.scrollBar>0?data.scrollBar:0));
97222
- new zim.Container(10,spacingV).pos(0,-spacer.height,"center","bottom",obj).bot();
97945
+ if (maxWidth && typeof maxWidth == "number") obj.width = Math.min(obj.width, maxWidth-zik(spacingH)*2-(data.scrollBar===true?12:data.scrollBar>0?data.scrollBar:0));
97946
+ var s2 = zik(spacingV);
97947
+ new zim.Container(10,s2).pos(0,-s2,"center","bottom",obj).bot();
97223
97948
 
97224
97949
  obj.setBounds(null); // make spacer in bottom adjust bounds
97225
97950
 
@@ -97455,7 +98180,7 @@ function zimify(obj, a, b, c, d, list) {
97455
98180
  hitTestGrid:function(width, height, cols, rows, x, y, offsetX, offsetY, spacingX, spacingY, local, type) {
97456
98181
  return zim.hitTestGrid(this, width, height, cols, rows, x, y, offsetX, offsetY, spacingX, spacingY, local, type);
97457
98182
  },
97458
- 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) {
97459
98184
  if (props && (props.props || props.obj) && isDUO(arguments)) {
97460
98185
  // run this if duo but only if props object has a props or obj object
97461
98186
  // can you believe that sentence makes sense
@@ -97464,7 +98189,7 @@ function zimify(obj, a, b, c, d, list) {
97464
98189
  // it can only be a configuration object if there is a props or obj property
97465
98190
  arguments[0].target = this; return zim.animate(arguments[0]);
97466
98191
  }
97467
- 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);}
97468
98193
  },
97469
98194
  pauseAnimate:function(){return this;},
97470
98195
  stopAnimate:function(){return this;},
@@ -98039,7 +98764,6 @@ zim.setBlurDetect = function() {
98039
98764
  obj = zim.pauseOnBlur[i];
98040
98765
  obj.pauseOnBlurPaused = obj.paused;
98041
98766
  obj.pause(true);
98042
- zogr(obj.type, obj.special, obj.pauseOnBlurPaused)
98043
98767
  }
98044
98768
  }
98045
98769
  if (zim.pauseAnimateOnBlur && zim.animatedObjects) {
@@ -98583,7 +99307,7 @@ getLatestVersions(function(versions) {
98583
99307
  });
98584
99308
  END EXAMPLE
98585
99309
  --*///+82.1
98586
- zim.VERSION = "019/zim";
99310
+ zim.VERSION = "020/zim";
98587
99311
  //-82.1
98588
99312
 
98589
99313
  /*--
@@ -101600,7 +102324,7 @@ SEE: https://zimjs.com/018/handtrack.html - replacing the cursor
101600
102324
  GENERAL ML5 FUNCTIONALITY
101601
102325
  ML5 can give very accurate hand poses, face poses and body poses and results return points.
101602
102326
  These points can be used to place ZIM objects or with a ZIM Shape to make circles, etc.
101603
- There are other features too like shape recognition, blurring backgrounds, etc.
102327
+ There are other features too like shape recognition, segmentation, blurring backgrounds, etc.
101604
102328
  These can all be used in ZIM - for using ML5 for interaction see the HAND TRACKING section above.
101605
102329
  SEE: https://zimjs.com/ml5/ - general ML5 integration examples
101606
102330
 
@@ -102926,6 +103650,1187 @@ https://codepen.io/zimjs/pen/ZqNYxX
102926
103650
 
102927
103651
  //-151
102928
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
+
102929
104834
  return zim;
102930
104835
  } (zim || {});
102931
104836
 
@@ -103297,6 +105202,7 @@ export let Wrapper = zim.Wrapper;
103297
105202
  export let Tile = zim.Tile;
103298
105203
  export let Pack = zim.Pack;
103299
105204
  export let Beads = zim.Beads;
105205
+ export let Bullets = zim.Bullets;
103300
105206
  export let Layout = zim.Layout;
103301
105207
  export let Accessibility = zim.Accessibility;
103302
105208
  export let TextureActive = zim.TextureActive;
@@ -103373,4 +105279,3 @@ export let Style = zim.Style;
103373
105279
  export let assets = zim.assets;
103374
105280
  export let assetIDs = zim.assetIDs;
103375
105281
  export let ZIMON = zim.ZIMON;
103376
-