zimjs 19.1.6 → 20.0.2

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
@@ -13329,9 +13329,9 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
13329
13329
  if (prop=="stroke-opacity") aa = val;
13330
13330
  });
13331
13331
  return [f,s,ss,a,aa];
13332
- }
13332
+ }
13333
13333
 
13334
- function processShape(type, tag) {
13334
+ function processShape(type, tag) {
13335
13335
  var shape;
13336
13336
  var g = processGeneral(tag); // want ES6
13337
13337
  var f = g[0], s = g[1], ss = g[2], x = g[5], y = g[6];
@@ -13370,6 +13370,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
13370
13370
  if (p.indexOf(",") != -1) {
13371
13371
  zim.loop(p.split(" "), function (point) {
13372
13372
  var pp = point.split(",");
13373
+ if (!pp || pp.length<2) return;
13373
13374
  points.push([Number(pp[0].trim()), Number(pp[1].trim()),0,0,0,0,0,0,"none"]);
13374
13375
  });
13375
13376
  } else {
@@ -13518,9 +13519,10 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
13518
13519
  // kv comments: need to apply string cleansing, application bugs when there is a semi colon character used in tags.
13519
13520
  // get rid of semi colon,
13520
13521
  // any attributes on the tag overwrites styles or general
13521
- f = tag.getAttribute("fill")?tag.getAttribute("fill"):!zot(f)?f:generalFill;
13522
- s = tag.getAttribute("stroke")?tag.getAttribute("stroke"):!zot(s)?s:generalStroke;
13523
- ss = tag.getAttribute("stroke-width")?tag.getAttribute("stroke-width"):!zot(ss)?ss:generalStrokeSize;
13522
+ // was defaulting to generalFill, generalStroke, generalStrokeSize - made null in 020 patch
13523
+ f = tag.getAttribute("fill")?tag.getAttribute("fill"):!zot(f)?f:null;
13524
+ s = tag.getAttribute("stroke")?tag.getAttribute("stroke"):!zot(s)?s:null;
13525
+ ss = tag.getAttribute("stroke-width")?tag.getAttribute("stroke-width"):!zot(ss)?ss:null;
13524
13526
  a = tag.getAttribute("fill-opacity")?tag.getAttribute("fill-opacity"):!zot(a)?a:generalAlpha;
13525
13527
  aa = tag.getAttribute("stroke-opacity")?tag.getAttribute("stroke-opacity"):!zot(aa)?aa:generalStrokeAlpha;
13526
13528
 
@@ -23479,7 +23481,7 @@ rollColor - (default color) the rollover color of the font
23479
23481
  shadowColor - (default -1) for no shadow - set to any css color to see
23480
23482
  shadowBlur - (default 14) if shadow is present
23481
23483
  align - ((default LEFT) text registration point alignment also CENTER/MIDDLE and RIGHT
23482
- set to START to align LEFT for ZIM DIR constant is "ltr" or RIGHT when DIR="rtl" - END is the opposite
23484
+ set to START to align LEFT when ZIM DIR constant is "ltr" or RIGHT when DIR="rtl" - END is the opposite
23483
23485
  valign - (default TOP) vertical registration point alignment alse CENTER/MIDDLE, BOTTOM
23484
23486
  bold - (default false) set the font to bold - note: fontOptions has been removed as of ZIM Cat
23485
23487
  italic - (default false) set the font to italic - note: fontOptions has been removed as of ZIM Cat
@@ -24625,6 +24627,7 @@ letterHeight - get the height of letters
24625
24627
  color - get or set the text color
24626
24628
  circle - access to the circle object
24627
24629
  arc - access to the arc object
24630
+ angle - the angle the letters make
24628
24631
  angles - access to the array angles for letter positioning
24629
24632
  use angles.toString() to log angle data (for kerning)
24630
24633
  this can be modified and passed in as an angles property to start
@@ -24691,7 +24694,6 @@ zim.LabelOnArc = function(label, size, font, color, radius, flip, spacing, lette
24691
24694
  var rev = label.text.split("").reverse().join("");
24692
24695
  label.text = rev;
24693
24696
  }
24694
- zog(that.width, that.height)
24695
24697
  letters = that.letters = new zim.Container(100,100).center(that);
24696
24698
 
24697
24699
  that.numLetters = label.text.length;
@@ -24745,6 +24747,7 @@ zim.LabelOnArc = function(label, size, font, color, radius, flip, spacing, lette
24745
24747
  else if (zot(arcBorderWidth) && !zot(arcBorderColor)) arcBorderWidth = 2;
24746
24748
  arc.graphics.c().f(null).s(arcBorderColor).ss(arcBorderWidth).arc(0,0,radius, (that.startAngle-90)*Math.PI/180, (that.startAngle-90+totalAngle)*Math.PI/180);
24747
24749
  }
24750
+ that.angle = totalAngle;
24748
24751
  }
24749
24752
 
24750
24753
  function makeAngles() {
@@ -25907,18 +25910,21 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
25907
25910
 
25908
25911
 
25909
25912
  /*--
25910
- zim.Emoji = function(code, size, monochrome, italic, backgroundColor, backgroundBorderColor, backgroundBorderWidth, corner, backing, padding, paddingH, paddingV, shiftH, shiftV, style, group, inherit)
25913
+ zim.Emoji = function(code, size, monochrome, italic, backgroundColor, backgroundBorderColor, backgroundBorderWidth, corner, backing, padding, paddingH, paddingV, shiftH, shiftV, color, borderColor, style, group, inherit)
25911
25914
 
25912
25915
  Emoji
25913
- zim class - extends a zim.Label which extends a zim.Container
25916
+ zim class - extends a zim.Container
25914
25917
 
25915
25918
  DESCRIPTION
25916
- Shows an emoji in a Label - an emoji is just text.
25917
- This helps treat the emoji as an image and works in conjunction with ZIM EmojiPicker
25919
+ Shows an emoji. Emojis are usually just text so it will be a Label in the Container.
25920
+ Support has been added in ZIM 020 for Noto Color Emojis - which are then added to the Container as SVG
25921
+ If color or borderColor is provided, the SVG will be an SVGContainer so independent parts can be colored, dragged or animated
25918
25922
 
25919
25923
  SEE: ZIM EmojiPicker() in COMPONENTS below ColorPicker().
25920
25924
 
25925
+ SEE: https://zimjs.com/emoji/ - Emoji Picker Tool
25921
25926
  SEE: https://zimjs.com/nft/bubbling/emoji.html
25927
+ SEE: https://zimjs.com/020/noto.html
25922
25928
 
25923
25929
  NOTE: as of ZIM 5.5.0 the zim namespace is no longer required (unless zns is set to true before running zim)
25924
25930
 
@@ -25937,19 +25943,50 @@ new Emoji("\ud83c\udf47", 100) // grapes using UTF codes
25937
25943
  .drag();
25938
25944
  END EXAMPLE
25939
25945
 
25946
+ EXAMPLE
25947
+ // Go to https://emojipedia.org/ and find an emoji page
25948
+ // copy the emoji or use the copy link and paste into the string below
25949
+ // leave the noto_ at the start and paste the emoji icon right after the _
25950
+ // where icon is the actual emoji icon (or a unicode number, or a noto code)
25951
+ // this will create and SVG that is the same across platforms (Windows, Linux, Android, iOS)
25952
+ new Emoji("noto_icon")
25953
+ .center()
25954
+ .drag();
25955
+ // Note - if using with Tile() then preload the emoji in Frame assets of zapp_assets as "noto_icon"
25956
+ // where icon is the actual emoji icon (or a unicode number, or a noto code)
25957
+ END EXAMPLE
25958
+
25959
+ EXAMPLE
25960
+ // Go to https://zimjs.com/emoji/ and find press on an emoji
25961
+ // copy the emoji code and leave the noto_ at the start and paste the emoji code right after the _
25962
+ // setting color, will create an SVGContainer in the Emoji so individual parts can be colored
25963
+ new Emoji({code:"noto_\ud83e\udd51", color:series(red, blue, orange, purple, yellow)})
25964
+ .center()
25965
+ .expand(0) // blobs with interactive false do not get mouse, expand will give it a mouse for the drag
25966
+ .drag({all:true}); // without all:true would drag individual parts of the SVG
25967
+ END EXAMPLE
25968
+
25940
25969
  PARAMETERS
25941
25970
  ** supports DUO - parameters or single object with properties below
25942
25971
  ** supports OCT - parameter defaults can be set with STYLE control (like CSS)
25943
25972
  ** supports VEE - parameters marked with ZIM VEE mean a zim Pick() object or Pick Literal can be passed
25944
25973
  Pick Literal formats: [1,3,2] - random; {min:10, max:20} - range; series(1,2,3) - order, function(){return result;} - function
25945
25974
  code - |ZIM VEE| (default \ud83d\ude42") the Unicode Character or the Emoji from https://emojipedia.org/
25946
- or pass in UTF codes such as "\ud83d\ude42".
25947
- To convert from Unicode to UTF use https://zimjs.com/emoji/ (also see MORE link at bottom of page)
25975
+ or pass in UTF codes such as "\ud83d\ude42".
25976
+ To convert from Unicode to UTF use https://zimjs.com/emoji/
25977
+ This will add a ZIM Label with the character to the Emoji Container
25978
+ As of ZIM 020, this supports Noto (by Google) Color Emojis which stay consistent across platforms (Windows, Linux, Android, iOS)
25979
+ To turn the emoji into Noto emojis, use "noto_code" where code is the emoji character or a code described above
25980
+ This will add a ZIM SVG of the character to the Emoji Container
25981
+ If color or borderColor paramters are used, the SVG will be in the form of an SVGContainer holding ZIM Blob and Squiggle objects
25982
+ then each part can be colored, dragged, wiggled, or animated
25983
+ If using the Emoji in a Tile() or Wrapper() then preload the emoji in the Frame assets or zapp_assets using "noto_code"
25984
+ This will preload the SVG from the Google GitHub repository - the location is set in ZIM (similar to using "gf_" for Google fonts)
25985
+ NOTE: many of the parameters below will not work on the SVG as they were made for text based emojis (but color and borderColor will)
25986
+ see https://symbl.cc/en/platforms/google/ to see all - not easily searched though
25948
25987
  size - |ZIM VEE| (default 36) the size of the font in pixels
25949
25988
  monochrome - (default false) set to true to make black outline - this is actually the bold version of the icon
25950
25989
  italic - (default false) set the font to italic
25951
- ** SEE Label for the rest of the definitions
25952
- backgroundColor, corner, backing, padding, paddingH, paddingV, shiftH, shiftV, style, group, inherit
25953
25990
  backgroundColor - (default null) set to CSS color to add a rectangular color around the label
25954
25991
  The background color will change size to match the text of the label
25955
25992
  Note: the backgroundColor is different than a backing which can be any Display Object
@@ -25967,6 +26004,10 @@ paddingH - (default padding) places border out at top bottom
25967
26004
  paddingV - (default padding) places border out at left and right
25968
26005
  shiftH - (default 0) move the emoji inside the container horizontally
25969
26006
  shiftV - (default 0) move the emoji inside the container vertically
26007
+ color - |ZIM VEE| (default null) for when color is set, set to a color or an array of colors to apply to fill of children - in order of the children
26008
+ usually a series() would be used here for colors in order, or an array for random colors
26009
+ setting this will make an SVG with bitmap:false - so blobs and squiggles so parts of SVG can be colored
26010
+ borderColor - |ZIM VEE| (default null) for when borderColor is set to a color or an array of colors to apply to border of children - in order of the children
25970
26011
  style - (default true) set to false to ignore styles set with the STYLE - will receive original parameter defaults
25971
26012
  group - (default null) set to String (or comma delimited String) so STYLE can set default styles to the group(s) (like a CSS class)
25972
26013
  inherit - (default null) used internally but can receive an {} of styles directly
@@ -26000,8 +26041,8 @@ See the CreateJS Easel Docs for Container events such as:
26000
26041
  added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmove, pressup, removed, rollout, rollover
26001
26042
  --*///+54.58
26002
26043
 
26003
- zim.Emoji = function(code, size, monochrome, italic, backgroundColor, backgroundBorderColor, backgroundBorderWidth, corner, backing, padding, paddingH, paddingV, shiftH, shiftV, style, group, inherit) {
26004
- var sig = "code, size, monochrome, italic, backgroundColor, backgroundBorderColor, backgroundBorderWidth, corner, backing, padding, paddingH, paddingV, shiftH, shiftV, style, group, inherit";
26044
+ zim.Emoji = function(code, size, monochrome, italic, backgroundColor, backgroundBorderColor, backgroundBorderWidth, corner, backing, padding, paddingH, paddingV, shiftH, shiftV, color, borderColor, style, group, inherit) {
26045
+ var sig = "code, size, monochrome, italic, backgroundColor, backgroundBorderColor, backgroundBorderWidth, corner, backing, padding, paddingH, paddingV, shiftH, shiftV, color, borderColor, style, group, inherit";
26005
26046
  var duo; if (duo = zob(zim.Emoji, arguments, sig, this)) return duo;
26006
26047
  z_d("54.58");
26007
26048
 
@@ -26020,17 +26061,33 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
26020
26061
  if (zot(paddingV)) paddingV = DS.paddingV!=null?DS.paddingV:padding;
26021
26062
  if (zot(shiftH)) shiftH = DS.shiftH!=null?DS.shiftH:0;
26022
26063
  if (zot(shiftV)) shiftV = DS.shiftV!=null?DS.shiftV:0;
26064
+ if (zot(color)) color = DS.color!=null?DS.color:null;
26065
+ if (zot(borderColor)) borderColor = DS.borderColor!=null?DS.borderColor:null;
26023
26066
 
26024
26067
  // PICK
26025
26068
  var oa = remember(code, size);
26026
26069
  this.veeObj = {code:oa[0], size:oa[1]};
26027
26070
  function remember() {return arguments;} // for cloning PICK
26028
26071
  code = zim.Pick.choose(code);
26029
- size = zim.Pick.choose(size);
26072
+ size = zim.Pick.choose(size);
26030
26073
 
26031
- if (code.substring(0,2) == "U+") code = zim.unicodeToUTF(code);
26074
+ if (code.substring && code.substring(0,2) == "U+") code = zim.unicodeToUTF(code);
26075
+ this.zimContainer_constructor();
26076
+ // this.zimLabel_constructor(code, size, null, null, null, null, null, null, null, null, italic, null, null, null, backing, null, null, backgroundColor, null, null, corner, null, padding, paddingH, paddingV, shiftH, shiftV);
26077
+
26078
+ var that = this;
26079
+
26080
+ // SVG TEST
26081
+ var match;
26082
+ if (code.match) match = code.match(/^noto_(.*)/);
26083
+ if (match) {
26084
+ var svg = that.svg = new zim.SVG({svg:code, interactive:!(color||borderColor), bitmap:!(color||borderColor), color:color, borderColor:borderColor});
26085
+ svg.addTo(this);
26086
+ } else {
26087
+ var label = this.label = new zim.Label(code, size, null, null, null, null, null, null, null, null, italic, null, null, null, backing, null, null, backgroundColor, null, null, corner, null, padding, paddingH, paddingV, shiftH, shiftV);
26088
+ label.addTo(this);
26089
+ }
26032
26090
 
26033
- this.zimLabel_constructor(code, size, null, null, null, null, null, null, null, null, italic, null, null, null, backing, null, null, backgroundColor, null, null, corner, null, padding, paddingH, paddingV, shiftH, shiftV);
26034
26091
  this.type = "Emoji";
26035
26092
 
26036
26093
  // MONITOR
@@ -26038,12 +26095,12 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
26038
26095
 
26039
26096
  this.code = code;
26040
26097
  this.size = size;
26041
- var that = this;
26098
+
26042
26099
 
26043
26100
  var b = this.getBounds();
26044
26101
  var h = 5;
26045
26102
  var w = 3
26046
- this.bounds = this.setBounds(b.x+w,b.y-h+1,b.width-w*2,b.height+h);
26103
+ if (b) this.bounds = this.setBounds(b.x+w,b.y-h+1,b.width-w*2,b.height+h);
26047
26104
 
26048
26105
  if (monochrome) {
26049
26106
  this.saturation = -100;
@@ -26077,11 +26134,11 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
26077
26134
 
26078
26135
  if (style!==false) zim.styleTransforms(this, DS);
26079
26136
  this.clone = function (exact) {
26080
- return that.cloneProps(new zim.Emoji((exact||!zim.isPick(oa[0]))?code:oa[0], (exact||!zim.isPick(oa[1]))?that.size:oa[1], monochrome, italic, backgroundColor, backgroundBorderColor, backgroundBorderWidth, corner, backing, padding, paddingH, paddingV, shiftH, shiftV, style, that.group, inherit));
26137
+ return that.cloneProps(new zim.Emoji((exact||!zim.isPick(oa[0]))?code:oa[0], (exact||!zim.isPick(oa[1]))?that.size:oa[1], monochrome, italic, backgroundColor, backgroundBorderColor, backgroundBorderWidth, corner, backing, padding, paddingH, paddingV, shiftH, shiftV, color, borderColor, style, that.group, inherit));
26081
26138
  };
26082
26139
 
26083
26140
  };
26084
- zim.extend(zim.Emoji, zim.Label, ["clone","cache"], "zimLabel", false);
26141
+ zim.extend(zim.Emoji, zim.Container, ["clone","cache"], "zimContainer", false);
26085
26142
  //-54.58
26086
26143
 
26087
26144
  /*--
@@ -28987,8 +29044,8 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
28987
29044
 
28988
29045
  var accessibilityClicker;
28989
29046
  this.show = function(call, params) {
28990
- if (!zot(call)) that.closeCall = call;
28991
- if (!zot(params)) that.closeParams = params;
29047
+ that.closeCall = call;
29048
+ that.closeParams = params;
28992
29049
  if (center) {
28993
29050
  if (isNaN(that.resetX)) {
28994
29051
  that.x = (that.container.getBounds().width) /2;
@@ -29064,7 +29121,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
29064
29121
  //-58
29065
29122
 
29066
29123
  /*--
29067
- zim.Panel = function(width, height, content, titleBar, titleBarColor, titleBarBackgroundColor, titleBarHeight, backgroundColor, borderColor, borderWidth, corner, close, closeColor, next, nextColor, extraButton, collapse, collapseColor, collapsed, align, shadowColor, shadowBlur, draggable, boundary, style, group, inherit)
29124
+ zim.Panel = function(width, height, content, titleBar, titleBarColor, titleBarBackgroundColor, titleBarHeight, backgroundColor, borderColor, borderWidth, corner, close, closeColor, next, nextColor, extraButton, collapse, collapseColor, collapsed, align, shadowColor, shadowBlur, draggable, boundary, onTop, style, group, inherit)
29068
29125
 
29069
29126
  Panel
29070
29127
  zim class - extends a zim.Container which extends a createjs.Container
@@ -29190,6 +29247,7 @@ shadowColor - (default "rgba(0,0,0,.3)" if shadowBlur) the shadow color - set to
29190
29247
  shadowBlur - (default 14 if shadowColor) the shadow blur - set to -1 for no shadow
29191
29248
  draggable - (default true if titleBar) set to false to not allow dragging titleBar to drag window
29192
29249
  boundary - (default null) set to ZIM Boundary() object - or CreateJS.rectangle()
29250
+ onTop - (default true) set to false to not bring to top if dragging
29193
29251
  style - (default true) set to false to ignore styles set with the STYLE - will receive original parameter defaults
29194
29252
  group - (default null) set to String (or comma delimited String) so STYLE can set default styles to the group(s) (like a CSS class)
29195
29253
  inherit - (default null) used internally but can receive an {} of styles directly
@@ -29267,8 +29325,8 @@ dispatches a "expand" event if expanding after being collapsed
29267
29325
  ALSO: see the CreateJS Easel Docs for Container events such as:
29268
29326
  added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmove, pressup, removed, rollout, rollover
29269
29327
  --*///+57.7
29270
- zim.Panel = function(width, height, content, titleBar, titleBarColor, titleBarBackgroundColor, titleBarHeight, backgroundColor, borderColor, borderWidth, corner, close, closeColor, next, nextColor, extraButton, collapse, collapseColor, collapsed, align, shadowColor, shadowBlur, draggable, boundary, style, group, inherit) {
29271
- var sig = "width, height, content, titleBar, titleBarColor, titleBarBackgroundColor, titleBarHeight, backgroundColor, borderColor, borderWidth, corner, close, closeColor, next, nextColor, extraButton, collapse, collapseColor, collapsed, align, shadowColor, shadowBlur, draggable, boundary, style, group, inherit";
29328
+ 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) {
29329
+ var sig = "width, height, content, titleBar, titleBarColor, titleBarBackgroundColor, titleBarHeight, backgroundColor, borderColor, borderWidth, corner, close, closeColor, next, nextColor, extraButton, collapse, collapseColor, collapsed, align, shadowColor, shadowBlur, draggable, boundary, onTop, style, group, inherit";
29272
29330
  var duo; if (duo = zob(zim.Panel, arguments, sig, this)) return duo;
29273
29331
  z_d("57.7");
29274
29332
 
@@ -29307,6 +29365,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
29307
29365
  if (zot(collapse)) collapse=DS.collapse!=null?DS.collapse:false;
29308
29366
  if (zot(collapseColor)) collapseColor = DS.collapseColor != null ? DS.collapseColor:!zot(titleBarColor)?titleBarColor:zim.grey;
29309
29367
  if (zot(collapsed)) collapsed=DS.collapsed!=null?DS.collapsed:false;
29368
+ if (zot(onTop)) onTop=DS.onTop!=null?DS.onTop:true;
29310
29369
 
29311
29370
  var that = this;
29312
29371
 
@@ -29412,7 +29471,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
29412
29471
  if (draggable) {
29413
29472
  titleBar.cur("pointer");
29414
29473
  titleBar.on("mousedown", function() {
29415
- that.drag({rect:boundary, currentTarget:true});
29474
+ that.drag({rect:boundary, currentTarget:true, onTop:onTop});
29416
29475
  var ch,i;
29417
29476
  var tar = that.content||that.contentContainer||that;
29418
29477
  if (tar.type != "Container") tar = that.contentContainer||that;
@@ -29591,7 +29650,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
29591
29650
  if (style !== false) zim.styleTransforms(this, DS);
29592
29651
 
29593
29652
  this.clone = function () {
29594
- return that.cloneProps(new zim.Panel(width, height, content, titleBar ? titleBar.text : null, titleBarColor, titleBarBackgroundColor, titleBarHeight, backgroundColor, borderColor, borderWidth, corner, close, closeColor, next, nextColor, extraButton, collapse, collapseColor, that.collapsed, align, shadowColor, shadowBlur, draggable, boundary, style, this.group, inherit));
29653
+ return that.cloneProps(new zim.Panel(width, height, content, titleBar ? titleBar.text : null, titleBarColor, titleBarBackgroundColor, titleBarHeight, backgroundColor, borderColor, borderWidth, corner, close, closeColor, next, nextColor, extraButton, collapse, collapseColor, that.collapsed, align, shadowColor, shadowBlur, draggable, boundary, onTop, style, this.group, inherit));
29595
29654
  };
29596
29655
  this.doDispose = function(a,b,disposing) {
29597
29656
  // need to dispose properly for Panel
@@ -41362,7 +41421,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
41362
41421
  //-66
41363
41422
 
41364
41423
  /*--
41365
- zim.NumPad = function(advanced, titleBar, titleBarColor, titleBarBackgroundColor, titleBarHeight, backgroundColor, borderColor, borderWidth, corner, numberCorner, close, closeColor, collapse, collapseColor, collapsed, align, shadowColor, shadowBlur, draggable, boundary, style, group, inherit)
41424
+ zim.NumPad = function(advanced, titleBar, titleBarColor, titleBarBackgroundColor, titleBarHeight, backgroundColor, borderColor, borderWidth, corner, numberCorner, close, closeColor, collapse, collapseColor, collapsed, align, shadowColor, shadowBlur, draggable, boundary, onTop, style, group, inherit)
41366
41425
 
41367
41426
  NumPad
41368
41427
  zim class - extends a zim.Panel which extends a zim.Container which extends a createjs.Container
@@ -41420,6 +41479,7 @@ shadowColor - (default "rgba(0,0,0,.3)" if shadowBlur) the shadow color - set to
41420
41479
  shadowBlur - (default 14 if shadowColor) the shadow blur - set to -1 for no shadow
41421
41480
  draggable - (default true if titleBar) set to false to not allow dragging titleBar to drag window
41422
41481
  boundary - (default null) set to ZIM Boundary() object - or CreateJS.rectangle()
41482
+ onTop - (default true) set to false to not bring to top if dragging
41423
41483
  style - (default true) set to false to ignore styles set with the STYLE - will receive original parameter defaults
41424
41484
  group - (default null) set to String (or comma delimited String) so STYLE can set default styles to the group(s) (like a CSS class)
41425
41485
  inherit - (default null) used internally but can receive an {} of styles directly
@@ -41459,8 +41519,8 @@ dispatches a "expand" event if expanding after being collapsed
41459
41519
  ALSO: see the CreateJS Easel Docs for Container events such as:
41460
41520
  added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmove, pressup, removed, rollout, rollover
41461
41521
  --*///+57.7
41462
- zim.NumPad = function(advanced, titleBar, titleBarColor, titleBarBackgroundColor, titleBarHeight, backgroundColor, borderColor, borderWidth, corner, numberCorner, close, closeColor, collapse, collapseColor, collapsed, align, shadowColor, shadowBlur, draggable, boundary, style, group, inherit) {
41463
- var sig = "advanced, titleBar, titleBarColor, titleBarBackgroundColor, titleBarHeight, backgroundColor, borderColor, borderWidth, corner, numberCorner, close, closeColor, collapse, collapseColor, collapsed, align, shadowColor, shadowBlur, draggable, boundary, style, group, inherit";
41522
+ 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) {
41523
+ var sig = "advanced, titleBar, titleBarColor, titleBarBackgroundColor, titleBarHeight, backgroundColor, borderColor, borderWidth, corner, numberCorner, close, closeColor, collapse, collapseColor, collapsed, align, shadowColor, shadowBlur, draggable, boundary, onTop, style, group, inherit";
41464
41524
  var duo; if (duo = zob(zim.NumPad, arguments, sig, this)) return duo;
41465
41525
  z_d("57.7");
41466
41526
 
@@ -41491,8 +41551,10 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
41491
41551
  if (zot(collapse)) collapse=DS.collapse!=null?DS.collapse:true;
41492
41552
  if (zot(collapseColor)) collapseColor = DS.collapseColor!=null?DS.collapseColor:!zot(titleBarColor)?titleBarColor:zim.grey;
41493
41553
  if (zot(collapsed)) collapsed=DS.collapsed!=null?DS.collapsed:false;
41554
+ if (zot(onTop)) onTop=DS.onTop!=null?DS.onTop:true;
41494
41555
 
41495
- this.zimPanel_constructor(width, height, null, titleBar, titleBarColor, titleBarBackgroundColor, titleBarHeight, backgroundColor, borderColor, borderWidth, corner, close, closeColor, null, null, null, collapse, collapseColor, collapsed, align, shadowColor, shadowBlur, draggable, boundary, style, group, inherit);
41556
+
41557
+ this.zimPanel_constructor(width, height, null, titleBar, titleBarColor, titleBarBackgroundColor, titleBarHeight, backgroundColor, borderColor, borderWidth, corner, close, closeColor, null, null, null, collapse, collapseColor, collapsed, align, shadowColor, shadowBlur, draggable, boundary, onTop, style, group, inherit);
41496
41558
  this.type = "NumPad";
41497
41559
 
41498
41560
  // MONITOR
@@ -41554,14 +41616,14 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
41554
41616
 
41555
41617
  if (style!==false) zim.styleTransforms(this, DS);
41556
41618
  this.clone = function () {
41557
- return that.cloneProps(new zim.NumPad(advanced, that.titleBar ? titleBar.text : null, titleBarColor, titleBarBackgroundColor, titleBarHeight, backgroundColor, borderColor, borderWidth, corner, numberCorner, close, closeColor, collapse, collapseColor, that.collapsed, align, shadowColor, shadowBlur, draggable, boundary, style, this.group, inherit));
41619
+ return that.cloneProps(new zim.NumPad(advanced, that.titleBar ? titleBar.text : null, titleBarColor, titleBarBackgroundColor, titleBarHeight, backgroundColor, borderColor, borderWidth, corner, numberCorner, close, closeColor, collapse, collapseColor, that.collapsed, align, shadowColor, shadowBlur, draggable, boundary, onTop, style, this.group, inherit));
41558
41620
  };
41559
41621
  };
41560
41622
  zim.extend(zim.NumPad, zim.Panel, ["clone"], "zimPanel", false);
41561
41623
  //-66.1
41562
41624
 
41563
41625
  /*--
41564
- zim.DPad = function(axis, width, backgroundColor, borderWidth, borderColor, indicatorColor, indicatorPressColor, indicatorScale, indicatorRadius, innerCircle, innerScale, activeRadius, clamp, logo, style, group, inherit)
41626
+ zim.DPad = function(axis, width, backgroundColor, borderWidth, borderColor, indicatorColor, indicatorPressColor, indicatorScale, indicatorRadius, innerCircle, innerScale, activeRadius, clamp, logo, useBubble, style, group, inherit)
41565
41627
 
41566
41628
  DPad
41567
41629
  zim class - extends a zim.Container which extends a createjs.Container
@@ -41571,8 +41633,10 @@ A DPad (Directional Pad) can be used to control x and y values
41571
41633
  This is primarily handy on mobile where a substitute for keypresses is needed
41572
41634
  The DPad can be set up for all directions, horizontal or vertical
41573
41635
  The DPad can be passed in to a ZIM MotionController to control an object
41636
+ There are default arrows but in ZIM 020 we added useBubble for a joystick like effect
41574
41637
 
41575
41638
  See: https://zimjs.com/ten/dpad.html
41639
+ See: https://zimjs.com/020/dpad.html
41576
41640
 
41577
41641
  NOTE: as of ZIM 5.5.0 the zim namespace is no longer required (unless zns is set to true before running zim)
41578
41642
 
@@ -41609,6 +41673,7 @@ innerScale - (default .5) the scale relative to the indicator
41609
41673
  activeRadius - (default width*2) radius at which the DPad works
41610
41674
  clamp - (default true) set to false to not limit the value between -1 and 1
41611
41675
  logo - (default false) set to true to show the letter D in the DPad - or add your own
41676
+ useBubble - (default false) set to true to use a joystick like effect (removes arrows)
41612
41677
  style - (default true) set to false to ignore styles set with the STYLE - will receive original parameter defaults
41613
41678
  group - (default null) set to String (or comma delimited String) so STYLE can set default styles to the group(s) (like a CSS class)
41614
41679
  inherit - (default null) used internally but can receive an {} of styles directly
@@ -41630,6 +41695,7 @@ type - holds the class name as a String
41630
41695
  dirX, dirY - the x and y values for the DPad - between -1 and 1 if clamp is set
41631
41696
  these can be multiplied by a factor to adjust speed - or use speed parameter of associated MotionController
41632
41697
  blendMode - how the object blends with what is underneath - such as "difference", "multiply", etc. same as CreateJS compositeOperation
41698
+ bubble - reference to the ZIM Circle if useBubble is set to true
41633
41699
  enabled - default is true - set to false to disable
41634
41700
 
41635
41701
  ALSO: see ZIM Container for properties such as:
@@ -41646,8 +41712,8 @@ dispatches a "change" event with dirX and dirY provided as well on the event obj
41646
41712
  ALSO: see the CreateJS Easel Docs for Container events such as:
41647
41713
  added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmove, pressup, removed, rollout, rollover
41648
41714
  --*///+66.2
41649
- zim.DPad = function(axis, width, backgroundColor, borderWidth, borderColor, indicatorColor, indicatorPressColor, indicatorScale, indicatorRadius, innerCircle, innerScale, activeRadius, clamp, logo, style, group, inherit) {
41650
- var sig = "axis, width, backgroundColor, borderWidth, borderColor, indicatorColor, indicatorPressColor, indicatorScale, indicatorRadius, innerCircle, innerScale, activeRadius, clamp, logo, style, group, inherit";
41715
+ zim.DPad = function(axis, width, backgroundColor, borderWidth, borderColor, indicatorColor, indicatorPressColor, indicatorScale, indicatorRadius, innerCircle, innerScale, activeRadius, clamp, logo, useBubble, style, group, inherit) {
41716
+ var sig = "axis, width, backgroundColor, borderWidth, borderColor, indicatorColor, indicatorPressColor, indicatorScale, indicatorRadius, innerCircle, innerScale, activeRadius, clamp, logo, useBubble, style, group, inherit";
41651
41717
  var duo; if (duo = zob(zim.DPad, arguments, sig, this)) return duo;
41652
41718
  z_d("66.2");
41653
41719
 
@@ -41676,11 +41742,12 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
41676
41742
  if (zot(activeRadius)) activeRadius = DS.activeRadius!=null?DS.activeRadius:width; // note, twice diameter
41677
41743
  if (zot(clamp)) clamp = DS.clamp!=null?DS.clamp:true;
41678
41744
  if (zot(logo)) logo = DS.logo!=null?DS.logo:false;
41745
+ if (zot(useBubble)) useBubble = DS.useBubble!=null?DS.useBubble:false;
41679
41746
 
41680
41747
  var that = this;
41681
41748
 
41682
41749
  this.axis = axis;
41683
- this.outer = new zim.Circle(width/2, backgroundColor, borderColor, borderWidth).addTo(this);
41750
+ var outer = this.outer = new zim.Circle(width/2, backgroundColor, borderColor, borderWidth).addTo(this);
41684
41751
  var inner = this.inner = new zim.Circle(width*innerScale/2, "rgba(0,0,0,.2)").center(this);
41685
41752
  if (logo) this.logo = new zim.Label({text:"D", bold:true}).center(inner).mov(1,2).alp(.3);
41686
41753
  var arrows = new zim.Container().addTo(this);
@@ -41694,6 +41761,41 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
41694
41761
  } else if (axis == "both") {
41695
41762
  numArrows = 4;
41696
41763
  }
41764
+ if (useBubble) {
41765
+ numArrows = 0;
41766
+ var bubble = that.bubble = new zim.Circle((outer.radius-inner.radius)/2-4, indicatorColor.toAlpha(.2), indicatorColor, 2).center(that);
41767
+ that.bubbleDampX = new zim.Damp();
41768
+ that.bubbleDampY = new zim.Damp();
41769
+ var r = outer.radius - bubble.radius - 4;
41770
+ that.down = false;
41771
+ that.bubbleDown = that.on("mousedown", function() {
41772
+ that.down = true;
41773
+ });
41774
+ that.bubbleUp = that.on("pressup", function() {
41775
+ that.down = false;
41776
+ });
41777
+
41778
+ // TODO - handle axis
41779
+
41780
+ that.bubbleTicker = zim.Ticker.add(function() {
41781
+ if (that.down) {
41782
+ var point = that.globalToLocal(that.stage.frame.mouseX, that.stage.frame.mouseY);
41783
+ bubble.loc(that.bubbleDampX.convert(point.x), that.bubbleDampY.convert(point.y));
41784
+ if (dist(0,0,bubble.x,bubble.y) > r) {
41785
+ var a = angle(bubble.x,bubble.y)*RAD
41786
+ var x = r*Math.cos(a);
41787
+ var y = r*Math.sin(a);
41788
+ that.bubbleDampX.immediate(x);
41789
+ that.bubbleDampY.immediate(y);
41790
+ bubble.loc(x,y)
41791
+ }
41792
+ } else {
41793
+ bubble.loc(that.bubbleDampX.convert(0), that.bubbleDampY.convert(0));
41794
+ }
41795
+ if (axis==HORIZONTAL) bubble.y = 0;
41796
+ else if (axis==VERTICAL) bubble.x = 0;
41797
+ });
41798
+ }
41697
41799
  zim.loop(numArrows, function (i, total) {
41698
41800
  new zim.Triangle(arrowSize, arrowSize, arrowSize, indicatorColor).addTo(arrows).reg(null, zot(indicatorRadius)?(width-borderWidth)*.475:indicatorRadius).rot(i*360/total);
41699
41801
  });
@@ -41760,7 +41862,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
41760
41862
 
41761
41863
  if (style!==false) zim.styleTransforms(this, DS);
41762
41864
  this.clone = function() {
41763
- return that.cloneProps(new zim.DPad(axis, width, backgroundColor, borderWidth, borderColor, indicatorColor, indicatorPressColor, indicatorScale, indicatorRadius, innerCircle, innerScale, activeRadius, clamp, logo, style, this.group, inherit));
41865
+ return that.cloneProps(new zim.DPad(axis, width, backgroundColor, borderWidth, borderColor, indicatorColor, indicatorPressColor, indicatorScale, indicatorRadius, innerCircle, innerScale, activeRadius, clamp, logo, useBubble, style, this.group, inherit));
41764
41866
  };
41765
41867
 
41766
41868
  this.dispose = function(a,b,disposing) {
@@ -44159,7 +44261,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
44159
44261
  }
44160
44262
  }
44161
44263
 
44162
- this.zimPanel_constructor(width, 300, null, titleBar, titleBarColor, titleBarBackgroundColor, titleBarHeight, backgroundColor, borderColor, borderWidth, corner, true, null, null, null, null, null, null, null, null, shadowColor, shadowBlur, draggable, boundary, style, group, inherit);
44264
+ this.zimPanel_constructor(width, 300, null, titleBar, titleBarColor, titleBarBackgroundColor, titleBarHeight, backgroundColor, borderColor, borderWidth, corner, true, null, null, null, null, null, null, null, null, shadowColor, shadowBlur, draggable, boundary, true, style, group, inherit);
44163
44265
 
44164
44266
  this.type = "TextEditor";
44165
44267
 
@@ -56282,9 +56384,16 @@ DESCRIPTION
56282
56384
  Sets multi-touch pan, pinch and rotate for position, scale and rotation
56283
56385
  Handles scaled and rotated containers
56284
56386
  Scale and rotation occur from the pinch point (with optional regControl for about the registration point)
56285
- Note - gesture() only works on the currentTarget - not a container's children (like drag() can)
56286
- ZIM Frame should have touch set to true (which is the default for mobile)
56387
+
56388
+ NOTE: gesture() only works on the currentTarget - not a container's children (like drag() can)
56389
+ ZIM Frame should have touch set to true (which is the default for mobile)
56390
+
56391
+ NOTE: as of ZIM 020 - trackpad support has been added - pinch to zoom, swipe both fingers horizontally for rotate
56392
+ ignores pinch point and operates from registration point no matter what the regControl is set at
56393
+ regControl is still used for touch screen
56394
+
56287
56395
  ALSO: see the noGesture() method to remove some or all gestures
56396
+
56288
56397
  ALSO: see the gestureBoundary() method to set or reset the boundary rectangle dynamically
56289
56398
 
56290
56399
  EXAMPLE
@@ -56320,6 +56429,10 @@ surround - (default false) is for dragging a big object that always surrounds th
56320
56429
  circularBounds - (default false) set to true if object is circular with center registration
56321
56430
  set to true to use radius to calculate rotated object in boundary if boundary is set
56322
56431
  rect - (depreciated) same as boundary - kept for backwards compatibility
56432
+ trackPad - (default true) set to false to not handle trackpad on laptop
56433
+ trackpad supports pinch for zoom
56434
+ trackpad supports swipe horizontally with both fingers (the same way) for rotate
56435
+ Ignores regControl and operates from registration point
56323
56436
 
56324
56437
  EVENTS
56325
56438
  Adds move, scale and rotate events to obj (when associated gesture parameters are set to true)
@@ -56327,417 +56440,698 @@ If slide is true, obj dispatches a "slidestop" event when sliding stops
56327
56440
 
56328
56441
  RETURNS obj for chaining
56329
56442
  --*///+34.5
56330
- zim.gesture = function(obj, move, scale, rotate, boundary, minScale, maxScale, snapRotate, localBoundary, slide, slideFactor, regControl, onTop, surround, circularBounds, rect) {
56331
- var sig = "obj, move, scale, rotate, boundary, minScale, maxScale, snapRotate, localBoundary, slide, slideFactor, regControl, onTop, surround, circularBounds, rect";
56332
- var duo; if (duo = zob(zim.gesture, arguments, sig)) return duo;
56333
- if (obj.type=="AC"&&WW.zdf) {WW.zdf.ac("gesture", arguments); return obj;}
56334
- z_d("34.5");
56335
-
56336
- // MONITOR
56337
- var mID = "z~gesture";
56338
- if (obj && obj.mID && ((obj.mID[2] && obj.mID[2]=="-") || obj.mID[0]=="-")) mID = "z~-";
56339
-
56340
- if (zot(obj) || !obj.on) return;
56341
- if (zot(move)) move = true;
56342
- if (zot(scale)) scale = true;
56343
- if (zot(rotate)) rotate = true;
56344
- if (zot(localBoundary)) localBoundary = false;
56345
- if (zot(snapRotate)) snapRotate = 1;
56346
- if (zot(slide)) slide = false;
56347
- if (zot(slideFactor)) slideFactor = 5;
56348
- if (zot(regControl)) regControl = false;
56349
- if (zot(onTop)) onTop = true;
56350
- if (zot(surround)) surround = false;
56351
- if (surround && rotate) {
56352
- surround = rect = null;
56353
- if (zon) zogy("gesture() - does not support surround when rotate is true");
56354
- }
56355
- if (zot(circularBounds)) circularBounds = false;
56356
- if (zot(boundary) && !zot(rect)) boundary = rect;
56443
+ zim.gesture = function(obj, move, scale, rotate, boundary, minScale, maxScale, snapRotate, localBoundary, slide, slideFactor, regControl, onTop, surround, circularBounds, rect, trackpad) {
56444
+ var sig = "obj, move, scale, rotate, boundary, minScale, maxScale, snapRotate, localBoundary, slide, slideFactor, regControl, onTop, surround, circularBounds, rect, trackpad";
56445
+ var duo; if (duo = zob(zim.gesture, arguments, sig)) return duo;
56446
+ if (obj.type=="AC"&&WW.zdf) {WW.zdf.ac("gesture", arguments); return obj;}
56447
+ z_d("34.5");
56357
56448
 
56358
- var slideData;
56359
- var slideCount;
56360
- var slideSlice;
56361
- var slideTotal;
56449
+ // MONITOR
56450
+ var mID = "z~gesture";
56451
+ if (obj && obj.mID && ((obj.mID[2] && obj.mID[2]=="-") || obj.mID[0]=="-")) mID = "z~-";
56362
56452
 
56453
+ if (zot(obj) || !obj.on) return;
56454
+ if (zot(move)) move = true;
56455
+ if (zot(scale)) scale = true;
56456
+ if (zot(rotate)) rotate = true;
56457
+ if (zot(localBoundary)) localBoundary = false;
56458
+ if (zot(snapRotate)) snapRotate = 1;
56459
+ if (zot(slide)) slide = false;
56460
+ if (zot(slideFactor)) slideFactor = 5;
56461
+ if (zot(regControl)) regControl = false;
56462
+ if (zot(onTop)) onTop = true;
56463
+ if (zot(surround)) surround = false;
56464
+ if (surround && rotate) {
56465
+ surround = rect = null;
56466
+ if (zon) zogy("gesture() - does not support surround when rotate is true");
56467
+ }
56468
+ if (zot(circularBounds)) circularBounds = false;
56469
+ if (zot(boundary) && !zot(rect)) boundary = rect;
56470
+ if (zot(trackpad)) trackpad = true;
56363
56471
 
56364
- var timeType = getTIME();
56472
+ var slideData;
56473
+ var slideCount;
56474
+ var slideSlice;
56475
+ var slideTotal;
56365
56476
 
56366
- // HANDLE MASK if there is one
56367
- if (!zot(obj.zimMaskDynamic)) obj.zimMaskApply(); // set mask set by zimMask to dynamic
56368
56477
 
56369
- if (!obj.zimTouch) {
56478
+ var timeType = getTIME();
56370
56479
 
56371
- var dampScaleX = new zim.Damp(obj.scaleX, .05);
56372
- var dampScaleY = new zim.Damp(obj.scaleY, .05);
56373
- var scaleRatio = obj.scaleX/obj.scaleY;
56480
+ // HANDLE MASK if there is one
56481
+ if (!zot(obj.zimMaskDynamic)) obj.zimMaskApply(); // set mask set by zimMask to dynamic
56374
56482
 
56375
- obj.zimTouch = {
56376
- move:move, // store settings on object to control with noGesture()
56377
- scale:scale,
56378
- rotate:rotate,
56379
- pointers:{}, // holds the current pointer data
56380
- checkBounds:function(x, y) { // used locally and by zim.gestureBoundary
56381
- if (obj.zimTouch.boundary) {
56382
- var boundary = obj.zimTouch.boundary;
56383
- // convert the desired drag position to a global point
56384
- // note that we want the position of the object in its parent
56385
- // so we use the parent as the local frame
56386
- var point = obj.parent.localToLocal(x,y,obj.parent);
56387
- // boundary is the boundary rectangle on the global stage
56388
- // boundary is set during mousedown to allow for global scaling when in localBoundary mode
56389
- // if you scale in localBoundary==false mode, you will need to reset bounds with dragBoundary()
56390
- if (surround) {
56391
- x = Math.min(boundary.x, Math.max(boundary.x+boundary.width, point.x));
56392
- y = Math.min(boundary.y, Math.max(boundary.y+boundary.height, point.y));
56393
- } else {
56394
- x = Math.max(boundary.x, Math.min(boundary.x+boundary.width, point.x));
56395
- y = Math.max(boundary.y, Math.min(boundary.y+boundary.height, point.y));
56396
- }
56397
- // now that the point has been checked on the global scale
56398
- // convert the point back to the obj parent frame of reference
56399
- point = obj.parent.globalToLocal(x, y);
56400
- x = point.x;
56401
- y = point.y;
56483
+ if (!obj.zimTouch) {
56484
+
56485
+ var dampScaleX = new zim.Damp(obj.scaleX, .05);
56486
+ var dampScaleY = new zim.Damp(obj.scaleY, .05);
56487
+ var scaleRatio = obj.scaleX/obj.scaleY;
56488
+
56489
+ obj.zimTouch = {
56490
+ move:move, // store settings on object to control with noGesture()
56491
+ scale:scale,
56492
+ rotate:rotate,
56493
+ pointers:{}, // holds the current pointer data
56494
+ checkBounds:function(x, y) { // used locally and by zim.gestureBoundary
56495
+ if (obj.zimTouch.boundary) {
56496
+ var boundary = obj.zimTouch.boundary;
56497
+ // convert the desired drag position to a global point
56498
+ // note that we want the position of the object in its parent
56499
+ // so we use the parent as the local frame
56500
+ var point = obj.parent.localToLocal(x,y,obj.parent);
56501
+ // boundary is the boundary rectangle on the global stage
56502
+ // boundary is set during mousedown to allow for global scaling when in localBoundary mode
56503
+ // if you scale in localBoundary==false mode, you will need to reset bounds with dragBoundary()
56504
+ if (surround) {
56505
+ x = Math.min(boundary.x, Math.max(boundary.x+boundary.width, point.x));
56506
+ y = Math.min(boundary.y, Math.max(boundary.y+boundary.height, point.y));
56507
+ } else {
56508
+ x = Math.max(boundary.x, Math.min(boundary.x+boundary.width, point.x));
56509
+ y = Math.max(boundary.y, Math.min(boundary.y+boundary.height, point.y));
56402
56510
  }
56403
- return {x:x,y:y};
56511
+ // now that the point has been checked on the global scale
56512
+ // convert the point back to the obj parent frame of reference
56513
+ point = obj.parent.globalToLocal(x, y);
56514
+ x = point.x;
56515
+ y = point.y;
56404
56516
  }
56405
- };
56406
-
56407
- if (boundary) {
56408
- obj.zimTouch.boundary = boundary;
56409
- if (localBoundary) obj.zimTouch.boundary = zim.boundsToGlobal(obj.parent, boundary);
56410
- obj.zimTouch.boundaryStartX = obj.zimTouch.boundary.x;
56411
- obj.zimTouch.boundaryStartY = obj.zimTouch.boundary.y;
56412
- obj.zimTouch.boundaryStartW = obj.zimTouch.boundary.width;
56413
- obj.zimTouch.boundaryStartH = obj.zimTouch.boundary.height;
56414
- var result = obj.zimTouch.checkBounds(obj.x, obj.y); // set in bounds to start
56415
- obj.x = result.x;
56416
- obj.y = result.y;
56517
+ return {x:x,y:y};
56417
56518
  }
56519
+ };
56418
56520
 
56419
- if (slide) {
56420
- slideSlice = 10;
56421
- slideTotal = 5;
56422
- slideCount = 0;
56423
- slideData = [];
56424
-
56425
- obj.zimTouch.slideInterval = zim.interval(slideSlice/(timeType=="s"?1000:1),function() {
56426
- slideData[slideCount++%slideTotal] = [obj.x, obj.y];
56427
- }, null, null, null, null, null, null, null, mID, obj);
56428
- obj.zimTouch.slideInterval.pause();
56429
- obj.animate({x:obj.x, y:obj.y}, 10/(timeType=="s"?1000:1), "quadOut"); // for some reason, first throw is smoother if already animated
56430
- }
56431
-
56432
- var matrixStart;
56433
- var startScaleX;
56434
- var startScaleY;
56435
- var startRotation;
56436
- var startRegX;
56437
- var startRegY;
56438
- var lastPoint;
56439
- var maxTouches;
56440
-
56441
- obj.zimTouch.mousedown = obj.on("mousedown", function(e) {
56442
- if (zot(maxTouches)) maxTouches = 1;
56443
- else maxTouches++;
56444
-
56445
- if (onTop) {
56446
- var nc = obj.parent.numChildren-1;
56447
- if (obj.parent.getChildAt(nc).type=="Keyboard") nc--;
56448
- obj.parent.setChildIndex(obj,nc);
56449
- if (obj.ZIMoutlineShape) obj.outline();
56450
- }
56451
- if (!regControl) {
56452
- lastPoint = null;
56453
- startScaleX = obj.scaleX;
56454
- startScaleY = obj.scaleY;
56455
- startRotation = obj.rotation;
56456
- startRegX = obj.regX;
56457
- startRegY = obj.regY;
56458
- obj.reg(0,0);
56459
- matrixStart = obj.getMatrix();
56460
- obj.regX = startRegX;
56461
- obj.regY = startRegY;
56462
- }
56463
-
56464
- var id = "id"+Math.abs(e.pointerID+1); // some pointers have negative ids
56465
- // convert all pointer x and y to the parent container of the obj
56466
- var local = obj.parent.globalToLocal(e.stageX/zim.scaX, e.stageY/zim.scaY);
56467
- // we compare current pointer to start pointer (rather than increment as we go)
56468
- obj.zimTouch.pointers[id] = {
56469
- startX:local.x, startY:local.y,
56470
- x:local.x, y:local.y
56471
- };
56472
- if (obj.zimTouch.move || obj.zimTouch.rotate) {
56473
- obj.zimTouch.total = 0;
56474
- zim.loop(obj.zimTouch.pointers, function() {
56475
- obj.zimTouch.total++;
56476
- });
56477
- }
56478
- if (slide && obj.zimTouch.total == 1) obj.zimTouch.slideInterval.pause(false);
56479
- setTouches();
56480
- }, null, null, null, null, mID);
56521
+ if (boundary) {
56522
+ obj.zimTouch.boundary = boundary;
56523
+ if (localBoundary) obj.zimTouch.boundary = zim.boundsToGlobal(obj.parent, boundary);
56524
+ obj.zimTouch.boundaryStartX = obj.zimTouch.boundary.x;
56525
+ obj.zimTouch.boundaryStartY = obj.zimTouch.boundary.y;
56526
+ obj.zimTouch.boundaryStartW = obj.zimTouch.boundary.width;
56527
+ obj.zimTouch.boundaryStartH = obj.zimTouch.boundary.height;
56528
+ var result = obj.zimTouch.checkBounds(obj.x, obj.y); // set in bounds to start
56529
+ obj.x = result.x;
56530
+ obj.y = result.y;
56531
+ }
56481
56532
 
56482
- obj.zimTouch.pressmove = obj.on("pressmove", function(e) {
56533
+ if (slide) {
56534
+ slideSlice = 10;
56535
+ slideTotal = 5;
56536
+ slideCount = 0;
56537
+ slideData = [];
56538
+
56539
+ obj.zimTouch.slideInterval = zim.interval(slideSlice/(timeType=="s"?1000:1),function() {
56540
+ slideData[slideCount++%slideTotal] = [obj.x, obj.y];
56541
+ }, null, null, null, null, null, null, null, mID, obj);
56542
+ obj.zimTouch.slideInterval.pause();
56543
+ obj.animate({x:obj.x, y:obj.y}, 10/(timeType=="s"?1000:1), "quadOut"); // for some reason, first throw is smoother if already animated
56544
+ }
56545
+
56546
+ var matrixStart;
56547
+ var startScaleX;
56548
+ var startScaleY;
56549
+ var startRotation;
56550
+ var startRegX;
56551
+ var startRegY;
56552
+ var lastPoint;
56553
+ var maxTouches;
56554
+
56555
+ obj.zimTouch.mousedown = obj.on("mousedown", function(e) {
56556
+ if (zot(maxTouches)) maxTouches = 1;
56557
+ else maxTouches++;
56483
56558
 
56484
- var id = "id"+Math.abs(e.pointerID+1);
56485
- var local = obj.parent.globalToLocal(e.stageX/zim.scaX, e.stageY/zim.scaY);
56486
- // update our pointer data with new x and y
56487
- if (obj.zimTouch.pointers[id]) {
56488
- obj.zimTouch.pointers[id].x = local.x;
56489
- obj.zimTouch.pointers[id].y = local.y;
56490
- }
56491
-
56492
- // average the pointers' movement
56493
- var newX = 0;
56494
- var newY = 0;
56495
- var aveX = 0; // point about which to scale and rotate
56496
- var aveY = 0;
56497
- var deltaX = 0;
56498
- var deltaY = 0;
56499
- zim.loop(obj.zimTouch.pointers, function(id, pointer) {
56500
- newX += pointer.x - pointer.startX;
56501
- newY += pointer.y - pointer.startY;
56502
- aveX += pointer.x;
56503
- aveY += pointer.y;
56559
+ if (onTop) {
56560
+ var nc = obj.parent.numChildren-1;
56561
+ if (obj.parent.getChildAt(nc).type=="Keyboard") nc--;
56562
+ obj.parent.setChildIndex(obj,nc);
56563
+ if (obj.ZIMoutlineShape) obj.outline();
56564
+ }
56565
+ if (!regControl) {
56566
+ lastPoint = null;
56567
+ startScaleX = obj.scaleX;
56568
+ startScaleY = obj.scaleY;
56569
+ startRotation = obj.rotation;
56570
+ startRegX = obj.regX;
56571
+ startRegY = obj.regY;
56572
+ obj.reg(0,0);
56573
+ matrixStart = obj.getMatrix();
56574
+ obj.regX = startRegX;
56575
+ obj.regY = startRegY;
56576
+ }
56577
+
56578
+ var id = "id"+Math.abs(e.pointerID+1); // some pointers have negative ids
56579
+ // convert all pointer x and y to the parent container of the obj
56580
+ var local = obj.parent.globalToLocal(e.stageX/zim.scaX, e.stageY/zim.scaY);
56581
+ // we compare current pointer to start pointer (rather than increment as we go)
56582
+ obj.zimTouch.pointers[id] = {
56583
+ startX:local.x, startY:local.y,
56584
+ x:local.x, y:local.y
56585
+ };
56586
+ if (obj.zimTouch.move || obj.zimTouch.rotate) {
56587
+ obj.zimTouch.total = 0;
56588
+ zim.loop(obj.zimTouch.pointers, function() {
56589
+ obj.zimTouch.total++;
56504
56590
  });
56505
- if (obj.zimTouch.total == 0) return;
56506
- deltaX = newX / obj.zimTouch.total;
56507
- deltaY = newY / obj.zimTouch.total;
56508
- newX = obj.zimTouch.startX + deltaX;
56509
- newY = obj.zimTouch.startY + deltaY;
56510
- aveX = aveX / obj.zimTouch.total;
56511
- aveY = aveY / obj.zimTouch.total;
56512
-
56513
- var proxy = {
56514
- x: obj.x,
56515
- y: obj.y,
56516
- scaleX:obj.scaleX,
56517
- scaleY:obj.scaleY,
56518
- rotation:obj.rotation
56519
- }; // will store desired scale and rotation on this object then apply matrix calculations
56520
-
56521
- if (obj.zimTouch.move) {
56522
- var result = obj.zimTouch.checkBounds(newX, newY); // es6 opportunity
56523
- proxy.x = result.x;
56524
- proxy.y = result.y;
56525
- }
56526
-
56527
- // if we have multitouch as determined by setTouches()
56528
- if (obj.zimTouch.pair.length == 2) {
56529
- var point1 = obj.zimTouch.pair[0];
56530
- var point2 = obj.zimTouch.pair[1];
56531
- if (obj.zimTouch.scale) {
56532
- // use ratio of distance between fingers to start and then current distance between fingers
56533
- var startDistance = Math.sqrt(Math.pow((point2.startX-point1.startX),2) + Math.pow((point2.startY-point1.startY),2));
56534
- var currentDistance = Math.sqrt(Math.pow((point2.x-point1.x),2) + Math.pow((point2.y-point1.y),2));
56535
- var newScaleX = obj.zimTouch.startSX + (currentDistance / startDistance - 1);
56536
- var newScaleY = obj.zimTouch.startSY + (currentDistance / startDistance - 1);
56537
- proxy.scaleX = newScaleX;
56538
- proxy.scaleY = newScaleY;
56539
-
56540
- proxy.scaleX = dampScaleX.convert(newScaleX);
56541
- proxy.scaleY = dampScaleY.convert(newScaleY);
56542
-
56543
- // set to scale min or max if scale would be outside range
56544
- var minBad = (!zot(minScale) && Math.min(newScaleX, newScaleY) < minScale);
56545
- var maxBad = (!zot(maxScale) && Math.max(newScaleX, newScaleY) > maxScale);
56546
- if (minBad || maxBad) {
56547
- if (minBad) {
56548
- if (scaleRatio > 1) {
56549
- proxy.scaleY = minScale;
56550
- proxy.scaleX = minScale*scaleRatio;
56551
- } else {
56552
- proxy.scaleX = minScale;
56553
- proxy.scaleY = minScale/scaleRatio;
56554
- }
56555
- } else if (maxBad) {
56556
- if (scaleRatio > 1) {
56557
- proxy.scaleX = maxScale;
56558
- proxy.scaleY = maxScale/scaleRatio;
56559
- } else {
56560
- proxy.scaleY = maxScale;
56561
- proxy.scaleX = maxScale*scaleRatio;
56562
- }
56591
+ }
56592
+ if (slide && obj.zimTouch.total == 1) obj.zimTouch.slideInterval.pause(false);
56593
+ setTouches();
56594
+ }, null, null, null, null, mID);
56595
+
56596
+ obj.zimTouch.pressmove = obj.on("pressmove", function(e) {
56597
+
56598
+ var id = "id"+Math.abs(e.pointerID+1);
56599
+ var local = obj.parent.globalToLocal(e.stageX/zim.scaX, e.stageY/zim.scaY);
56600
+ // update our pointer data with new x and y
56601
+ if (obj.zimTouch.pointers[id]) {
56602
+ obj.zimTouch.pointers[id].x = local.x;
56603
+ obj.zimTouch.pointers[id].y = local.y;
56604
+ }
56605
+
56606
+ // average the pointers' movement
56607
+ var newX = 0;
56608
+ var newY = 0;
56609
+ var aveX = 0; // point about which to scale and rotate
56610
+ var aveY = 0;
56611
+ var deltaX = 0;
56612
+ var deltaY = 0;
56613
+ zim.loop(obj.zimTouch.pointers, function(id, pointer) {
56614
+ newX += pointer.x - pointer.startX;
56615
+ newY += pointer.y - pointer.startY;
56616
+ aveX += pointer.x;
56617
+ aveY += pointer.y;
56618
+ });
56619
+ if (obj.zimTouch.total == 0) return;
56620
+ deltaX = newX / obj.zimTouch.total;
56621
+ deltaY = newY / obj.zimTouch.total;
56622
+ newX = obj.zimTouch.startX + deltaX;
56623
+ newY = obj.zimTouch.startY + deltaY;
56624
+ aveX = aveX / obj.zimTouch.total;
56625
+ aveY = aveY / obj.zimTouch.total;
56626
+
56627
+ var proxy = {
56628
+ x: obj.x,
56629
+ y: obj.y,
56630
+ scaleX:obj.scaleX,
56631
+ scaleY:obj.scaleY,
56632
+ rotation:obj.rotation
56633
+ }; // will store desired scale and rotation on this object then apply matrix calculations
56634
+
56635
+ if (obj.zimTouch.move) {
56636
+ var result = obj.zimTouch.checkBounds(newX, newY); // es6 opportunity
56637
+ proxy.x = result.x;
56638
+ proxy.y = result.y;
56639
+ }
56640
+
56641
+ // if we have multitouch as determined by setTouches()
56642
+ if (obj.zimTouch.pair.length == 2) {
56643
+ var point1 = obj.zimTouch.pair[0];
56644
+ var point2 = obj.zimTouch.pair[1];
56645
+ if (obj.zimTouch.scale) {
56646
+ // use ratio of distance between fingers to start and then current distance between fingers
56647
+ var startDistance = Math.sqrt(Math.pow((point2.startX-point1.startX),2) + Math.pow((point2.startY-point1.startY),2));
56648
+ var currentDistance = Math.sqrt(Math.pow((point2.x-point1.x),2) + Math.pow((point2.y-point1.y),2));
56649
+ var newScaleX = obj.zimTouch.startSX + (currentDistance / startDistance - 1);
56650
+ var newScaleY = obj.zimTouch.startSY + (currentDistance / startDistance - 1);
56651
+ proxy.scaleX = newScaleX;
56652
+ proxy.scaleY = newScaleY;
56653
+
56654
+ proxy.scaleX = dampScaleX.convert(newScaleX);
56655
+ proxy.scaleY = dampScaleY.convert(newScaleY);
56656
+
56657
+ // set to scale min or max if scale would be outside range
56658
+ var minBad = (!zot(minScale) && Math.min(newScaleX, newScaleY) < minScale);
56659
+ var maxBad = (!zot(maxScale) && Math.max(newScaleX, newScaleY) > maxScale);
56660
+ if (minBad || maxBad) {
56661
+ if (minBad) {
56662
+ if (scaleRatio > 1) {
56663
+ proxy.scaleY = minScale;
56664
+ proxy.scaleX = minScale*scaleRatio;
56665
+ } else {
56666
+ proxy.scaleX = minScale;
56667
+ proxy.scaleY = minScale/scaleRatio;
56668
+ }
56669
+ } else if (maxBad) {
56670
+ if (scaleRatio > 1) {
56671
+ proxy.scaleX = maxScale;
56672
+ proxy.scaleY = maxScale/scaleRatio;
56673
+ } else {
56674
+ proxy.scaleY = maxScale;
56675
+ proxy.scaleX = maxScale*scaleRatio;
56563
56676
  }
56564
- dampScaleX.immediate(proxy.scaleX);
56565
- dampScaleY.immediate(proxy.scaleY);
56566
56677
  }
56567
-
56568
- }
56569
- if (obj.zimTouch.rotate) {
56570
- // rotate based on the difference of angle between the fingers at start and at current
56571
- var startAngle = Math.atan2((point1.startY - point2.startY), (point1.startX - point2.startX)) * (180 / Math.PI);
56572
- var currentAngle = Math.atan2((point1.y - point2.y), (point1.x - point2.x)) * (180 / Math.PI);
56573
- var deltaR = currentAngle - startAngle;
56574
- proxy.rotation = obj.zimTouch.startR + deltaR;
56678
+ dampScaleX.immediate(proxy.scaleX);
56679
+ dampScaleY.immediate(proxy.scaleY);
56575
56680
  }
56576
56681
 
56577
- if (regControl) {
56578
- obj.scaleX = proxy.scaleX;
56579
- obj.scaleY = proxy.scaleY;
56580
- obj.rotation = proxy.rotation;
56581
- if (obj.zimTouch.move) {
56582
- obj.x = proxy.x;
56583
- obj.y = proxy.y;
56584
- }
56585
- } else {
56586
- // transformations seem to ignore registration so need to set to 0 then reset after transformations
56587
- obj.reg(0,0);
56588
-
56589
- // need global data - the transformation about the pinch point is an adjustment of the system
56590
- // originally we wanted calculations in the container of the object
56591
- // these calculations were probably used for min and max of things, etc. so just leaving them
56592
- // and instead, bringing the calculations back into the global - and then eventually into the local for the transformations
56593
- var adjust = obj.parent.localToGlobal(aveX, aveY);
56594
- aveX = adjust.x;
56595
- aveY = adjust.y;
56596
-
56597
- // unfortunately, system goes haywire after a while without adjusting for minor shifts
56598
- // saving the location of the center back to global after the transformation seems to correct this
56599
- // we set lastPoint down below after the transformation
56600
- var point = zot(lastPoint) ? obj.globalToLocal(aveX, aveY) : obj.globalToLocal(lastPoint.x, lastPoint.y);
56601
-
56602
- // the classic Matrix transformation - translate to the pinch point, scale and rotate, and then translate back
56603
- // var matrix = new createjs.Matrix2D()
56604
- var matrix = matrixStart.clone()
56605
- .translate(point.x, point.y)
56606
- .rotate(proxy.rotation-startRotation)
56607
- .scale(proxy.scaleX/startScaleX,proxy.scaleY/startScaleY)
56608
- .translate(-(point.x), -(point.y));
56609
- // .prependMatrix(matrixStart) // would use if started new Matrix each time
56610
-
56611
- matrix.decompose(obj);
56612
-
56613
- if (obj.zimTouch.move) {
56614
- obj.x += deltaX;
56615
- obj.y += deltaY;
56616
- }
56682
+ }
56683
+ if (obj.zimTouch.rotate) {
56684
+ // rotate based on the difference of angle between the fingers at start and at current
56685
+ var startAngle = Math.atan2((point1.startY - point2.startY), (point1.startX - point2.startX)) * (180 / Math.PI);
56686
+ var currentAngle = Math.atan2((point1.y - point2.y), (point1.x - point2.x)) * (180 / Math.PI);
56687
+ var deltaR = currentAngle - startAngle;
56688
+ proxy.rotation = obj.zimTouch.startR + deltaR;
56689
+ }
56617
56690
 
56618
- // correcting for minor shifts which can magnify and set the system haywire
56619
- lastPoint = obj.localToGlobal(point.x, point.y);
56691
+ if (regControl) {
56692
+ obj.scaleX = proxy.scaleX;
56693
+ obj.scaleY = proxy.scaleY;
56694
+ obj.rotation = proxy.rotation;
56695
+ if (obj.zimTouch.move) {
56696
+ obj.x = proxy.x;
56697
+ obj.y = proxy.y;
56698
+ }
56699
+ } else {
56700
+ // transformations seem to ignore registration so need to set to 0 then reset after transformations
56701
+ obj.reg(0,0);
56620
56702
 
56621
- obj.reg(startRegX, startRegY);
56703
+ // need global data - the transformation about the pinch point is an adjustment of the system
56704
+ // originally we wanted calculations in the container of the object
56705
+ // these calculations were probably used for min and max of things, etc. so just leaving them
56706
+ // and instead, bringing the calculations back into the global - and then eventually into the local for the transformations
56707
+ var adjust = obj.parent.localToGlobal(aveX, aveY);
56708
+ aveX = adjust.x;
56709
+ aveY = adjust.y;
56710
+
56711
+ // unfortunately, system goes haywire after a while without adjusting for minor shifts
56712
+ // saving the location of the center back to global after the transformation seems to correct this
56713
+ // we set lastPoint down below after the transformation
56714
+ var point = zot(lastPoint) ? obj.globalToLocal(aveX, aveY) : obj.globalToLocal(lastPoint.x, lastPoint.y);
56715
+
56716
+ // the classic Matrix transformation - translate to the pinch point, scale and rotate, and then translate back
56717
+ // var matrix = new createjs.Matrix2D()
56718
+ var matrix = matrixStart.clone()
56719
+ .translate(point.x, point.y)
56720
+ .rotate(proxy.rotation-startRotation)
56721
+ .scale(proxy.scaleX/startScaleX,proxy.scaleY/startScaleY)
56722
+ .translate(-(point.x), -(point.y));
56723
+ // .prependMatrix(matrixStart) // would use if started new Matrix each time
56724
+
56725
+ matrix.decompose(obj);
56726
+
56727
+ if (obj.zimTouch.move) {
56728
+ obj.x += deltaX;
56729
+ obj.y += deltaY;
56622
56730
  }
56623
56731
 
56624
- if (obj.zimTouch.scale) obj.dispatchEvent("scale");
56625
- if (obj.zimTouch.rotate) obj.dispatchEvent("rotate");
56626
- if (obj.zimTouch.move) obj.dispatchEvent("move");
56732
+ // correcting for minor shifts which can magnify and set the system haywire
56733
+ lastPoint = obj.localToGlobal(point.x, point.y);
56627
56734
 
56628
- } else {
56629
- obj.x = proxy.x;
56630
- obj.y = proxy.y;
56631
- if (obj.zimTouch.move) obj.dispatchEvent("move");
56735
+ obj.reg(startRegX, startRegY);
56632
56736
  }
56633
- if (obj.type == "Tag" || obj.type == "TextArea" || obj.type == "Loader") obj.resize();
56634
56737
 
56635
- if (obj.ZIMoutlineShape) obj.outline();
56636
- if (obj.getStage && obj.stage) obj.stage.update();
56738
+ if (obj.zimTouch.scale) obj.dispatchEvent("scale");
56739
+ if (obj.zimTouch.rotate) obj.dispatchEvent("rotate");
56740
+ if (obj.zimTouch.move) obj.dispatchEvent("move");
56741
+
56742
+ } else {
56743
+ obj.x = proxy.x;
56744
+ obj.y = proxy.y;
56745
+ if (obj.zimTouch.move) obj.dispatchEvent("move");
56746
+ }
56747
+ if (obj.type == "Tag" || obj.type == "TextArea" || obj.type == "Loader") obj.resize();
56748
+
56749
+ if (obj.ZIMoutlineShape) obj.outline();
56750
+ if (obj.getStage && obj.stage) obj.stage.update();
56751
+ }, null, null, null, null, mID);
56752
+
56753
+ obj.on("mousedown", function() {
56754
+ // if an object is removed that is touched, the touch will still be registered
56755
+ // this code makes sure that no ghost touches are left by counting stagemousedown and stagemouseup events
56756
+ var mouseCount = 1;
56757
+ obj.tsmd = obj.stage.on("stagemousedown", function() {
56758
+ mouseCount++;
56637
56759
  }, null, null, null, null, mID);
56760
+ obj.tsmu = obj.stage.on("stagemouseup", function() {
56761
+ mouseCount--;
56762
+ if (mouseCount == 0) {
56763
+ setTimeout(function() {
56764
+ if (obj.zimTouch) obj.zimTouch.total = 0;
56765
+ if (obj.zimTouch) obj.zimTouch.pointers = {};
56766
+ maxTouches = null;
56767
+ }, 50);
56768
+ }
56769
+ }, null, null, null, null, mID);
56770
+ }, null, true, null, null, mID); // once
56638
56771
 
56639
- obj.on("mousedown", function() {
56640
- // if an object is removed that is touched, the touch will still be registered
56641
- // this code makes sure that no ghost touches are left by counting stagemousedown and stagemouseup events
56642
- var mouseCount = 1;
56643
- obj.tsmd = obj.stage.on("stagemousedown", function() {
56644
- mouseCount++;
56645
- }, null, null, null, null, mID);
56646
- obj.tsmu = obj.stage.on("stagemouseup", function() {
56647
- mouseCount--;
56648
- if (mouseCount == 0) {
56649
- setTimeout(function() {
56650
- if (obj.zimTouch) obj.zimTouch.total = 0;
56651
- if (obj.zimTouch) obj.zimTouch.pointers = {};
56652
- maxTouches = null;
56653
- }, 50);
56654
- }
56655
- }, null, null, null, null, mID);
56656
- }, null, true, null, null, mID); // once
56772
+ obj.zimTouch.pressup = obj.on("pressup", function(e) {
56773
+ var id = "id"+Math.abs(e.pointerID+1);
56774
+ // remove touch data for pointer
56775
+ delete obj.zimTouch.pointers[id];
56776
+ if (obj.zimTouch.move || obj.zimTouch.rotate) obj.zimTouch.total--;
56777
+ if (rotate && !zot(snapRotate) && obj.zimTouch.total == 0) {
56778
+ if (snapRotate > 0) {
56779
+ obj.rotation = Math.round(obj.rotation/snapRotate)*snapRotate;
56780
+ } else if (snapRotate == 0) {
56781
+ obj.rotation = Math.round(obj.rotation);
56782
+ }
56783
+ }
56784
+ // spinning was throwing slide off so just slide with single touch for now...
56785
+ if (slide && obj.zimTouch.total == 0 && maxTouches == 1) {
56786
+ obj.zimTouch.slideInterval.pause();
56787
+ var startSlide = slideData[(slideCount+1)%slideData.length];
56788
+ var currentSlide = slideData[(slideCount)%slideData.length];
56789
+ var newX = obj.x + (startSlide[0]-currentSlide[0]) * slideFactor;
56790
+ var newY = obj.y + (startSlide[1]-currentSlide[1]) * slideFactor;
56791
+ var result = obj.zimTouch.checkBounds(newX, newY); // es6 opportunity
56792
+ // if it is being thrown past the bounds, need to reduce time by percentage of blocked movement
56793
+ var newT = slideTotal*slideSlice*slideFactor * Math.min((obj.x-result.x)/(obj.x-newX)||1, (obj.y-result.y)/(obj.y-newY)||1);
56794
+ obj.animate({x:result.x, y:result.y}, newT/(timeType=="s"?1000:1), "quadOut", function(){obj.dispatchEvent("slidestop");});
56795
+ }
56796
+ if (obj.zimTouch.total == 0) maxTouches = null;
56797
+ if (obj.getStage && obj.stage) obj.stage.update();
56798
+ setTouches();
56799
+ }, null, null, null, null, mID);
56800
+
56801
+ if (boundary) {
56802
+ remakeBoundary();
56803
+ obj.on("move", remakeBoundary, null, null, null, null, mID);
56804
+ }
56805
+ }
56657
56806
 
56658
- obj.zimTouch.pressup = obj.on("pressup", function(e) {
56659
- var id = "id"+Math.abs(e.pointerID+1);
56660
- // remove touch data for pointer
56661
- delete obj.zimTouch.pointers[id];
56662
- if (obj.zimTouch.move || obj.zimTouch.rotate) obj.zimTouch.total--;
56663
- if (rotate && !zot(snapRotate) && obj.zimTouch.total == 0) {
56664
- if (snapRotate > 0) {
56665
- obj.rotation = Math.round(obj.rotation/snapRotate)*snapRotate;
56666
- } else if (snapRotate == 0) {
56667
- obj.rotation = Math.round(obj.rotation);
56668
- }
56807
+ // -----------------------------------------------------------------------
56808
+ // TRACKPAD SUPPORT - AI Coded Claude 5
56809
+ // Handles laptop trackpad two-finger gestures via wheel and gesturechange events.
56810
+ // Completely separate from the touch block above - own state, own canvas listeners.
56811
+ // Does not interfere with touchscreen gesture() behaviour.
56812
+ // Always transforms around the object's own (unaltered) registration point -
56813
+ // regControl is intentionally ignored here.
56814
+ // -----------------------------------------------------------------------
56815
+ if (trackpad && !obj.zimTouch.tpAttached) {
56816
+
56817
+ // Separate matrix state - never shares with the touch block vars above
56818
+ var tpStartScaleX;
56819
+ var tpStartScaleY;
56820
+ var tpStartRotation;
56821
+ var tpActive = false;
56822
+ var tpEndTimeout = null;
56823
+
56824
+ // Accumulated deltas within one gesture session (wheel burst)
56825
+ // We track total scale factor and total rotation applied since session start
56826
+ var tpAccumScale = 1; // multiplicative accumulator, applied to tpStartScaleX/Y
56827
+ var tpAccumRot = 0; // degrees accumulator, applied to tpStartRotation
56828
+
56829
+ // Safari GestureEvent state
56830
+ var tpGestureBaseScale = 1; // e.scale at gesturestart (always 1 per spec, but captured for safety)
56831
+ var tpGestureBaseRot = 0; // e.rotation at gesturestart (always 0 per spec)
56832
+ var tpGestureLastScale = 1; // e.scale at previous gesturechange, for delta
56833
+ var tpGestureLastRot = 0; // e.rotation at previous gesturechange, for delta
56834
+ var tpGestureActive = false;
56835
+
56836
+ // Begin a trackpad gesture session: snapshot current object state.
56837
+ // No registration point manipulation - obj keeps whatever regX/regY it already has.
56838
+ function tpBeginSession() {
56839
+ tpActive = true;
56840
+ tpAccumScale = 1;
56841
+ tpAccumRot = 0;
56842
+ tpStartScaleX = obj.scaleX;
56843
+ tpStartScaleY = obj.scaleY;
56844
+ tpStartRotation = obj.rotation;
56845
+ }
56846
+
56847
+ // Apply accumulated scale + rotation to the object.
56848
+ // Always transforms around obj's current registration point - regControl is ignored.
56849
+ function tpApply() {
56850
+ if (!tpActive) return;
56851
+
56852
+ var newScaleX = tpStartScaleX * tpAccumScale;
56853
+ var newScaleY = tpStartScaleY * tpAccumScale;
56854
+
56855
+ // Enforce min/max scale
56856
+ if (!zot(minScale) && Math.min(newScaleX, newScaleY) < minScale) {
56857
+ if (scaleRatio > 1) { newScaleX = minScale * scaleRatio; newScaleY = minScale; }
56858
+ else { newScaleX = minScale; newScaleY = minScale / scaleRatio; }
56859
+ }
56860
+ if (!zot(maxScale) && Math.max(newScaleX, newScaleY) > maxScale) {
56861
+ if (scaleRatio > 1) { newScaleX = maxScale; newScaleY = maxScale / scaleRatio; }
56862
+ else { newScaleX = maxScale * scaleRatio; newScaleY = maxScale; }
56863
+ }
56864
+
56865
+ var newRotation = tpStartRotation + tpAccumRot;
56866
+
56867
+ if (obj.zimTouch.scale) {
56868
+ obj.scaleX = newScaleX;
56869
+ obj.scaleY = newScaleY;
56870
+ }
56871
+ if (obj.zimTouch.rotate) {
56872
+ obj.rotation = newRotation;
56873
+ }
56874
+
56875
+ if (obj.zimTouch.scale) obj.dispatchEvent("scale");
56876
+ if (obj.zimTouch.rotate) obj.dispatchEvent("rotate");
56877
+
56878
+ if (obj.type == "Tag" || obj.type == "TextArea" || obj.type == "Loader") obj.resize();
56879
+ if (obj.ZIMoutlineShape) obj.outline();
56880
+ if (obj.getStage && obj.stage) obj.stage.update();
56881
+ }
56882
+
56883
+
56884
+ // End session: apply snapRotate and clean up
56885
+ function tpEndSession() {
56886
+ if (!tpActive) return;
56887
+ tpActive = false;
56888
+ tpEndTimeout = null;
56889
+ if (obj.zimTouch.rotate && !zot(snapRotate)) {
56890
+ if (snapRotate > 0) {
56891
+ obj.rotation = Math.round(obj.rotation / snapRotate) * snapRotate;
56892
+ } else if (snapRotate == 0) {
56893
+ obj.rotation = Math.round(obj.rotation);
56669
56894
  }
56670
- // spinning was throwing slide off so just slide with single touch for now...
56671
- if (slide && obj.zimTouch.total == 0 && maxTouches == 1) {
56672
- obj.zimTouch.slideInterval.pause();
56673
- var startSlide = slideData[(slideCount+1)%slideData.length];
56674
- var currentSlide = slideData[(slideCount)%slideData.length];
56675
- var newX = obj.x + (startSlide[0]-currentSlide[0]) * slideFactor;
56676
- var newY = obj.y + (startSlide[1]-currentSlide[1]) * slideFactor;
56677
- var result = obj.zimTouch.checkBounds(newX, newY); // es6 opportunity
56678
- // if it is being thrown past the bounds, need to reduce time by percentage of blocked movement
56679
- var newT = slideTotal*slideSlice*slideFactor * Math.min((obj.x-result.x)/(obj.x-newX)||1, (obj.y-result.y)/(obj.y-newY)||1);
56680
- obj.animate({x:result.x, y:result.y}, newT/(timeType=="s"?1000:1), "quadOut", function(){obj.dispatchEvent("slidestop");});
56681
- }
56682
- if (obj.zimTouch.total == 0) maxTouches = null;
56683
56895
  if (obj.getStage && obj.stage) obj.stage.update();
56684
- setTouches();
56685
- }, null, null, null, null, mID);
56686
-
56687
- if (boundary) {
56688
- remakeBoundary();
56689
- obj.on("move", remakeBoundary, null, null, null, null, mID);
56690
- }
56691
- }
56692
-
56693
- function setTouches() {
56694
- // anytime we add or remove a pointer we reset the start positions
56695
- // this handles cases where single touch would change the start position
56696
- // and handles removing of one of the active pairs of pointers
56697
- // to be replaced with another current pointer
56698
- obj.zimTouch.pair = [];
56699
- zim.loop(obj.zimTouch.pointers, function(id, pointer, i) {
56700
- pointer.startX = pointer.x;
56701
- pointer.startY = pointer.y;
56702
- // just record the first two pointers
56703
- // keep looping as mov uses all pointers
56704
- if (i <= 1) obj.zimTouch.pair.push(pointer);
56705
- });
56706
- // record the start position, scale and rotation
56707
- obj.zimTouch.startX = obj.x;
56708
- obj.zimTouch.startY = obj.y;
56709
- obj.zimTouch.startSX = obj.scaleX;
56710
- obj.zimTouch.startSY = obj.scaleY;
56711
- obj.zimTouch.startR = obj.rotation;
56712
- }
56713
-
56714
- function remakeBoundary() {
56715
- var p = obj.localToGlobal(obj.regX, obj.regY);
56716
- var b;
56717
- if (circularBounds) {
56718
- // assuming cropped if Bitmap and width==height
56719
- var leftTop = obj.parent.localToGlobal(obj.x-obj.width/2, obj.y-obj.height/2);
56720
- var botRight = obj.parent.localToGlobal(obj.x+obj.width/2, obj.y+obj.height/2);
56721
- b = {
56722
- x:leftTop.x,
56723
- y:leftTop.y,
56724
- width:botRight.x-leftTop.x,
56725
- height:botRight.y-leftTop.y
56726
- };
56896
+ }
56897
+ }
56898
+
56899
+ // Debounce end of wheel burst - trackpad fires no "end" event
56900
+ function tpScheduleEnd() {
56901
+ if (tpEndTimeout) clearTimeout(tpEndTimeout);
56902
+ tpEndTimeout = setTimeout(tpEndSession, 100);
56903
+ }
56904
+
56905
+ // Convert a DOM mouse/wheel event position to global stage coords
56906
+ // matching the scaling that the touch block uses (zim.scaX / zim.scaY)
56907
+ function tpEventToStage(e) {
56908
+ var canvas = obj.stage.canvas;
56909
+ obj.canvas = canvas; // for removal
56910
+ var rect = canvas.getBoundingClientRect();
56911
+ var stageX = (e.clientX - rect.left) / (zim.scaX || 1);
56912
+ var stageY = (e.clientY - rect.top) / (zim.scaY || 1);
56913
+ return {x: stageX, y: stageY};
56914
+ }
56915
+
56916
+ // ---- Object selection for trackpad ----
56917
+ // Multiple objects can each have gesture() with trackpad enabled on the
56918
+ // same canvas. Unlike mousedown/pressmove (which ZIM already hit-tests
56919
+ // to a specific display object), wheel and gesture events are not
56920
+ // targeted - they fire for whatever is listening on the canvas. So we
56921
+ // track which gesture object was most recently clicked/tapped on this
56922
+ // stage and ignore trackpad input for any other gesture object there.
56923
+ obj.zimTouch.tpSelectHandler = function() {
56924
+ obj.stage.zimGestureActive = obj;
56925
+ };
56926
+ obj.on("mousedown", obj.zimTouch.tpSelectHandler, null, null, null, null, mID);
56927
+
56928
+ // ---- wheel handler (Chrome, Firefox, and Safari pinch-as-wheel) ----
56929
+ obj.zimTouch.tpWheelHandler = function(e) {
56930
+ if (!obj.stage) return;
56931
+ // Only the last-selected gesture object responds to trackpad input -
56932
+ // otherwise every gesture()-enabled object on the same canvas would
56933
+ // react to the same wheel event at once.
56934
+ if (obj.stage.zimGestureActive !== obj) return;
56935
+
56936
+ var stagePos = tpEventToStage(e);
56937
+
56938
+ if (e.ctrlKey) {
56939
+ // ----- PINCH / SCALE -----
56940
+ // Browser sets ctrlKey=true synthetically for trackpad pinch on all platforms.
56941
+ // Prevent browser zoom.
56942
+ if (!obj.zimTouch.scale) return;
56943
+ e.preventDefault();
56944
+
56945
+ if (!tpActive) tpBeginSession();
56946
+ else if (tpEndTimeout) { clearTimeout(tpEndTimeout); tpEndTimeout = null; }
56947
+
56948
+ // deltaY: negative = fingers spreading (zoom in), positive = fingers closing (zoom out)
56949
+ var delta = e.deltaMode === 1 ? e.deltaY * 12 : e.deltaY;
56950
+ tpAccumScale *= Math.pow(1 - delta * 0.005, 1);
56951
+ tpAccumScale = Math.max(0.05, Math.min(20, tpAccumScale));
56952
+
56953
+ tpApply();
56954
+ tpScheduleEnd();
56955
+
56727
56956
  } else {
56728
- b = obj.boundsToGlobal();
56957
+ // ----- PAN and/or ROTATE -----
56958
+ // No modifier key. Split by dominant axis:
56959
+ // horizontal-dominant (|deltaX| > |deltaY|) -> rotate
56960
+ // vertical-dominant or equal -> pan
56961
+ // This works on all platforms without any key held.
56962
+ // Safari rotation also arrives via gesturechange (handled separately below),
56963
+ // so on Safari both paths may fire; they accumulate correctly.
56964
+ var dx = e.deltaMode === 1 ? e.deltaX * 12 : e.deltaX;
56965
+ var dy = e.deltaMode === 1 ? e.deltaY * 12 : e.deltaY;
56966
+ var absDx = Math.abs(dx);
56967
+ var absDy = Math.abs(dy);
56968
+
56969
+ if (obj.zimTouch.rotate && absDx > absDy) {
56970
+ // ----- ROTATE -----
56971
+ // Horizontal two-finger swipe -> rotation.
56972
+ // Sign is flipped so a rightward finger swipe (with thumb anchored)
56973
+ // rotates the way two physical fingers would twist a dial - counter-clockwise.
56974
+ e.preventDefault();
56975
+
56976
+ if (!tpActive) tpBeginSession();
56977
+ else if (tpEndTimeout) { clearTimeout(tpEndTimeout); tpEndTimeout = null; }
56978
+
56979
+ tpAccumRot -= dx * 0.3; // degrees per CSS pixel - negative so direction matches natural two-finger twist
56980
+
56981
+ tpApply();
56982
+ tpScheduleEnd();
56983
+
56984
+ } else if (obj.zimTouch.move) {
56985
+ // ----- PAN -----
56986
+ // Vertical-dominant (or purely vertical) two-finger scroll -> translate.
56987
+ // Applied incrementally so it tracks the finger naturally.
56988
+ e.preventDefault();
56989
+
56990
+ var newX = obj.x - dx / (zim.scaX || 1);
56991
+ var newY = obj.y - dy / (zim.scaY || 1);
56992
+
56993
+ var panResult = obj.zimTouch.checkBounds(newX, newY);
56994
+ obj.x = panResult.x;
56995
+ obj.y = panResult.y;
56996
+
56997
+ obj.dispatchEvent("move");
56998
+ if (obj.type == "Tag" || obj.type == "TextArea" || obj.type == "Loader") obj.resize();
56999
+ if (obj.ZIMoutlineShape) obj.outline();
57000
+ if (obj.getStage && obj.stage) obj.stage.update();
57001
+ }
56729
57002
  }
56730
- var r = {
56731
- x:obj.zimTouch.boundaryStartX+p.x-b.x,
56732
- y:obj.zimTouch.boundaryStartY+p.y-b.y,
56733
- width:obj.zimTouch.boundaryStartW-b.width,
56734
- height:obj.zimTouch.boundaryStartH-b.height
57003
+ };
57004
+
57005
+ // ---- Safari GestureEvent handlers (scale + rotation without shift key) ----
57006
+ // These fire on Safari desktop (Mac) for two-finger trackpad gestures.
57007
+ // gesturechange gives cumulative .scale and .rotation from gesture start.
57008
+ obj.zimTouch.tpGestureStartHandler = function(e) {
57009
+ if (obj.stage.zimGestureActive !== obj) return;
57010
+ e.preventDefault();
57011
+ tpGestureActive = true;
57012
+ tpGestureBaseScale = e.scale; // should be 1.0
57013
+ tpGestureBaseRot = e.rotation; // should be 0.0
57014
+ tpGestureLastScale = e.scale;
57015
+ tpGestureLastRot = e.rotation;
57016
+ var stagePos = tpEventToStage(e);
57017
+ if (!tpActive) tpBeginSession();
57018
+ if (tpEndTimeout) { clearTimeout(tpEndTimeout); tpEndTimeout = null; }
57019
+ };
57020
+
57021
+ obj.zimTouch.tpGestureChangeHandler = function(e) {
57022
+ if (obj.stage.zimGestureActive !== obj) return;
57023
+ e.preventDefault();
57024
+ if (!tpGestureActive) return;
57025
+
57026
+ // e.scale is cumulative ratio from gesturestart (1.0 = no change)
57027
+ // e.rotation is cumulative degrees from gesturestart (0 = no change)
57028
+ // We want the DELTA from the last event so we can accumulate properly
57029
+ var scaleDelta = e.scale / tpGestureLastScale;
57030
+ var rotDelta = e.rotation - tpGestureLastRot;
57031
+ tpGestureLastScale = e.scale;
57032
+ tpGestureLastRot = e.rotation;
57033
+
57034
+ if (obj.zimTouch.scale) {
57035
+ tpAccumScale *= scaleDelta;
57036
+ tpAccumScale = Math.max(0.05, Math.min(20, tpAccumScale));
57037
+ }
57038
+ if (obj.zimTouch.rotate) {
57039
+ tpAccumRot += rotDelta;
57040
+ }
57041
+
57042
+ tpApply();
57043
+ };
57044
+
57045
+ obj.zimTouch.tpGestureEndHandler = function(e) {
57046
+ if (obj.stage.zimGestureActive !== obj) return;
57047
+ e.preventDefault();
57048
+ tpGestureActive = false;
57049
+ tpEndSession();
57050
+ };
57051
+
57052
+ // Attach listeners once the object has a stage (canvas).
57053
+ // If stage exists now, attach immediately.
57054
+ // If not yet on stage, wait for the "added" event.
57055
+ obj.zimTouch.tpAttached = false;
57056
+
57057
+ function tpAttachToCanvas() {
57058
+ if (obj.zimTouch.tpAttached) return;
57059
+ if (!obj.stage) return;
57060
+ var canvas = obj.stage.canvas;
57061
+ canvas.addEventListener("wheel", obj.zimTouch.tpWheelHandler, {passive: false});
57062
+ // Safari gestureevents
57063
+ canvas.addEventListener("gesturestart", obj.zimTouch.tpGestureStartHandler, {passive: false});
57064
+ canvas.addEventListener("gesturechange", obj.zimTouch.tpGestureChangeHandler, {passive: false});
57065
+ canvas.addEventListener("gestureend", obj.zimTouch.tpGestureEndHandler, {passive: false});
57066
+ obj.zimTouch.tpCanvas = canvas;
57067
+ obj.zimTouch.tpAttached = true;
57068
+
57069
+ // Default the first gesture object attached on this stage to be selected,
57070
+ // so a single-object scene works immediately without requiring a click.
57071
+ if (zot(obj.stage.zimGestureActive)) obj.stage.zimGestureActive = obj;
57072
+ }
57073
+
57074
+ if (obj.stage) {
57075
+ tpAttachToCanvas();
57076
+ } else {
57077
+ // Defer until obj is added to the display list
57078
+ obj.on("added", function() {
57079
+ tpAttachToCanvas();
57080
+ }, null, true); // once
57081
+ }
57082
+ }
57083
+
57084
+ // END TRACKPAD SUPPORT
57085
+
57086
+ function setTouches() {
57087
+ // anytime we add or remove a pointer we reset the start positions
57088
+ // this handles cases where single touch would change the start position
57089
+ // and handles removing of one of the active pairs of pointers
57090
+ // to be replaced with another current pointer
57091
+ obj.zimTouch.pair = [];
57092
+ zim.loop(obj.zimTouch.pointers, function(id, pointer, i) {
57093
+ pointer.startX = pointer.x;
57094
+ pointer.startY = pointer.y;
57095
+ // just record the first two pointers
57096
+ // keep looping as mov uses all pointers
57097
+ if (i <= 1) obj.zimTouch.pair.push(pointer);
57098
+ });
57099
+ // record the start position, scale and rotation
57100
+ obj.zimTouch.startX = obj.x;
57101
+ obj.zimTouch.startY = obj.y;
57102
+ obj.zimTouch.startSX = obj.scaleX;
57103
+ obj.zimTouch.startSY = obj.scaleY;
57104
+ obj.zimTouch.startR = obj.rotation;
57105
+ }
57106
+
57107
+ function remakeBoundary() {
57108
+ var p = obj.localToGlobal(obj.regX, obj.regY);
57109
+ var b;
57110
+ if (circularBounds) {
57111
+ // assuming cropped if Bitmap and width==height
57112
+ var leftTop = obj.parent.localToGlobal(obj.x-obj.width/2, obj.y-obj.height/2);
57113
+ var botRight = obj.parent.localToGlobal(obj.x+obj.width/2, obj.y+obj.height/2);
57114
+ b = {
57115
+ x:leftTop.x,
57116
+ y:leftTop.y,
57117
+ width:botRight.x-leftTop.x,
57118
+ height:botRight.y-leftTop.y
56735
57119
  };
56736
- obj.gestureBoundary(r, false); // do not update the original rect
57120
+ } else {
57121
+ b = obj.boundsToGlobal();
56737
57122
  }
56738
-
56739
- return obj;
56740
- };//-34.5
57123
+ var r = {
57124
+ x:obj.zimTouch.boundaryStartX+p.x-b.x,
57125
+ y:obj.zimTouch.boundaryStartY+p.y-b.y,
57126
+ width:obj.zimTouch.boundaryStartW-b.width,
57127
+ height:obj.zimTouch.boundaryStartH-b.height
57128
+ };
57129
+ obj.gestureBoundary(r, false); // do not update the original rect
57130
+ }
57131
+
57132
+ return obj;
57133
+ };//-34.5
57134
+
56741
57135
 
56742
57136
  /*--
56743
57137
  obj.noGesture = function(move, scale, rotate)
@@ -56764,20 +57158,22 @@ rotate - (default true) - set to false not to remove rotate gesture
56764
57158
 
56765
57159
  RETURNS obj for chaining
56766
57160
  --*///+34.6
56767
- zim.noGesture = function(obj, move, scale, rotate) {
56768
- var sig = "obj, move, scale, rotate";
56769
- var duo; if (duo = zob(zim.noGesture, arguments, sig)) return duo;
56770
- z_d("34.6");
57161
+ zim.noGesture = function(obj, move, scale, rotate) {
57162
+ var sig = "obj, move, scale, rotate";
57163
+ var duo; if (duo = zob(zim.noGesture, arguments, sig)) return duo;
57164
+ z_d("34.6");
56771
57165
 
56772
- if (zot(obj) || !obj.on || !obj.zimTouch) return;
57166
+ if (zot(obj) || !obj.on || !obj.zimTouch) return;
56773
57167
 
56774
- // MONITOR
56775
- var mID = "z~noGesture";
56776
- if (obj && obj.mID && ((obj.mID[2] && obj.mID[2]=="-") || obj.mID[0]=="-")) mID = "z~-";
56777
-
56778
- if (zot(move)) move = true;
56779
- if (zot(scale)) scale = true;
56780
- if (zot(rotate)) rotate = true;
57168
+ // MONITOR
57169
+ var mID = "z~noGesture";
57170
+ if (obj && obj.mID && ((obj.mID[2] && obj.mID[2]=="-") || obj.mID[0]=="-")) mID = "z~-";
57171
+
57172
+ if (zot(move)) move = true;
57173
+ if (zot(scale)) scale = true;
57174
+ if (zot(rotate)) rotate = true;
57175
+
57176
+ if (obj.zimTouch) {
56781
57177
  obj.zimTouch.move = !move;
56782
57178
  obj.zimTouch.scale = !scale;
56783
57179
  obj.zimTouch.rotate = !rotate;
@@ -56785,13 +57181,24 @@ RETURNS obj for chaining
56785
57181
  obj.off("mousedown", obj.zimTouch.mousedown, null, mID);
56786
57182
  obj.off("pressmove", obj.zimTouch.pressmove, null, mID);
56787
57183
  obj.off("pressup", obj.zimTouch.pressup, null, mID);
57184
+
57185
+ if (obj.zimTouch.tpSelectHandler) obj.off("mousedown", obj.zimTouch.tpSelectHandler);
57186
+ var canvas = obj.canvas;
57187
+ if (canvas) {
57188
+ if (obj.zimTouch.tpWheelHandler) canvas.removeEventListener("wheel", obj.zimTouch.tpWheelHandler, {passive: false});
57189
+ if (obj.zimTouch.tpGestureStartHandler) canvas.removeEventListener("gesturestart", obj.zimTouch.tpGestureStartHandler, {passive: false});
57190
+ if (obj.zimTouch.tpGestureChangeHandler) canvas.removeEventListener("gesturechange", obj.zimTouch.tpGestureChangeHandler, {passive: false});
57191
+ if (obj.zimTouch.tpGestureEndHandler) canvas.removeEventListener("gestureend", obj.zimTouch.tpGestureEndHandler, {passive: false});
57192
+ }
56788
57193
  delete obj.zimTouch;
56789
- }
56790
- if (obj.tsmd) obj.stage.off("stagemousedown", obj.tsmd, null, mID);
56791
- if (obj.tsmu) obj.stage.off("stagemouseup", obj.tsmu, null, mID);
57194
+ }
57195
+ }
56792
57196
 
56793
- return obj;
56794
- };//-34.6
57197
+ if (obj.stage && obj.tsmd) obj.stage.off("stagemousedown", obj.tsmd, null, mID);
57198
+ if (obj.stage && obj.tsmu) obj.stage.off("stagemouseup", obj.tsmu, null, mID);
57199
+
57200
+ return obj;
57201
+ };//-34.6
56795
57202
 
56796
57203
  /*--
56797
57204
  obj.gestureBoundary = function(boundary, new)
@@ -58036,7 +58443,7 @@ RETURNS an index Number (or undefined) | col | row | an Array of [index, col, ro
58036
58443
  // SUBSECTION ANIMATE, WIGGLE, AND LOOP
58037
58444
 
58038
58445
  /*--
58039
- obj.animate = function(props, time, ease, call, params, wait, waitedCall, waitedParams, loop, loopCount, loopWait, loopCall, loopParams, loopWaitCall, loopWaitParams, loopPick, rewind, rewindWait, rewindCall, rewindParams, rewindWaitCall, rewindWaitParams, rewindTime, rewindEase, startCall, startParams, animateCall, animateParams, sequence, sequenceCall, sequenceParams, sequenceReverse, sequenceRatio, ticker, cjsProps, css, protect, override, from, set, id, events, sequenceTarget, dynamic, drag, clamp, startPaused, clean, obj, seriesWait, sequenceWait, rate, pauseOnBlur, easeAmount, easeFrequency, timeUnit, timeCheck, noAnimateCall, pathDamp, rewindPick)
58446
+ obj.animate = function(props, time, ease, call, params, wait, waitedCall, waitedParams, loop, loopCount, loopWait, loopCall, loopParams, loopWaitCall, loopWaitParams, loopPick, rewind, rewindWait, rewindCall, rewindParams, rewindWaitCall, rewindWaitParams, rewindTime, rewindEase, rewindPick, startCall, startParams, animateCall, animateParams, sequence, sequenceCall, sequenceParams, sequenceReverse, sequenceRatio, ticker, cjsProps, css, protect, override, from, set, id, events, sequenceTarget, dynamic, drag, clamp, startPaused, clean, obj, seriesWait, sequenceWait, rate, pauseOnBlur, easeAmount, easeFrequency, timeUnit, timeCheck, noAnimateCall, pathDamp, style, group)
58040
58447
 
58041
58448
  animate
58042
58449
  zim DisplayObject method
@@ -58448,6 +58855,12 @@ rewindEase - (default null) overwrite the ease for the rewind direction
58448
58855
  so setting rewindEase:"bounceOut" will bounce back at the start of the animation
58449
58856
  note - setting ease:"bounceOut" will bounce at the end of the animation
58450
58857
  this allows for a normal start with a bounce and then a normal start at rewind and a bounce
58858
+ rewindPick - (default false) set to true to pick from props as it rewinds
58859
+ this will be moved to the other rewind parameters in ZIM 019
58860
+ also see loopPick - using both loopPick and rewindPick will act like a series
58861
+ where if the property has a series it will animate one after the other
58862
+ do not use if the property is just a regular value as it will appear to stop the animation.
58863
+ Can use a series, results of a function, min max or array for random picks
58451
58864
  startCall - (default null) calls function at the start of actual animation and after any wait (and waitedCall)
58452
58865
  this is basically the same as the waitedCall but will also be called at the start of animation when there is no waitedCall
58453
58866
  startParams - (default target) parameters to send startCall function
@@ -58571,12 +58984,6 @@ timeUnit - (default TIME) override the TIME setting to "seconds" / "s" or "milli
58571
58984
  timeCheck - (default true) set to false to not have animate() warn of potentially wrong time units - see also TIMECHECK
58572
58985
  noAnimateCall - (default true) set to false to not call the callback function if ANIMATE is set to false
58573
58986
  pathDamp - (default .15) damping for drag along path
58574
- rewindPick - (default false) set to true to pick from props as it rewinds
58575
- this will be moved to the other rewind parameters in ZIM 019
58576
- also see loopPick - using both loopPick and rewindPick will act like a series
58577
- where if the property has a series it will animate one after the other
58578
- do not use if the property is just a regular value as it will appear to stop the animation.
58579
- Can use a series, results of a function, min max or array for random picks
58580
58987
  style - (default true) set to false to ignore styles set with the STYLE - will receive original parameter defaults
58581
58988
  group - (default null) set to String (or comma delimited String) so STYLE can set default styles to the group(s) (like a CSS class)
58582
58989
 
@@ -58649,8 +59056,8 @@ EVENTS - zim animate() will add an "animation" event to the target IF the events
58649
59056
 
58650
59057
  RETURNS the target for chaining (or null if no target is provided and run on zim with series)
58651
59058
  --*///+45
58652
- zim.animate = function(target, props, time, ease, call, params, wait, waitedCall, waitedParams, loop, loopCount, loopWait, loopCall, loopParams, loopWaitCall, loopWaitParams, loopPick, rewind, rewindWait, rewindCall, rewindParams, rewindWaitCall, rewindWaitParams, rewindTime, rewindEase, startCall, startParams, animateCall, animateParams, sequence, sequenceCall, sequenceParams, sequenceReverse, sequenceRatio, ticker, cjsProps, css, protect, override, from, set, id, events, sequenceTarget, dynamic, drag, clamp, startPaused, clean, obj, seriesWait, sequenceWait, rate, pauseOnBlur, easeAmount, easeFrequency, timeUnit, timeCheck, noAnimateCall, pathDamp, rewindPick, style, group) {
58653
- var sig = "target, props, time, ease, call, params, wait, waitedCall, waitedParams, loop, loopCount, loopWait, loopCall, loopParams, loopWaitCall, loopWaitParams, loopPick, rewind, rewindWait, rewindCall, rewindParams, rewindWaitCall, rewindWaitParams, rewindTime, rewindEase, startCall, startParams, animateCall, animateParams, sequence, sequenceCall, sequenceParams, sequenceReverse, sequenceRatio, ticker, cjsProps, css, protect, override, from, set, id, events, sequenceTarget, dynamic, drag, clamp, startPaused, clean, obj, seriesWait, sequenceWait, rate, pauseOnBlur, easeAmount, easeFrequency, timeUnit, timeCheck, noAnimateCall, pathDamp, rewindPick, style, group";
59059
+ 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) {
59060
+ var sig = "target, props, time, ease, call, params, wait, waitedCall, waitedParams, loop, loopCount, loopWait, loopCall, loopParams, loopWaitCall, loopWaitParams, loopPick, rewind, rewindWait, rewindCall, rewindParams, rewindWaitCall, rewindWaitParams, rewindTime, rewindEase, rewindPick, startCall, startParams, animateCall, animateParams, sequence, sequenceCall, sequenceParams, sequenceReverse, sequenceRatio, ticker, cjsProps, css, protect, override, from, set, id, events, sequenceTarget, dynamic, drag, clamp, startPaused, clean, obj, seriesWait, sequenceWait, rate, pauseOnBlur, easeAmount, easeFrequency, timeUnit, timeCheck, noAnimateCall, pathDamp, style, group";
58654
59061
 
58655
59062
  if (target && (target.props || target.obj)) {
58656
59063
  var duo; if (duo = zob(zim.animate, arguments, sig)) return duo;
@@ -58676,12 +59083,12 @@ RETURNS the target for chaining (or null if no target is provided and run on zim
58676
59083
  if (zot(waitedCall)) waitedCall = DS.waitedCall!=null?DS.waitedCall:null;
58677
59084
  if (zot(waitedParams)) waitedParams = DS.waitedParams!=null?DS.waitedParams:null;
58678
59085
  if (zot(loop)) loop = DS.loop!=null?DS.loop:null;
59086
+ if (zot(loopWaitParams)) loopWaitParams = DS.loopWaitParams!=null?DS.loopWaitParams:null;
58679
59087
  if (zot(loopCount)) loopCount = DS.loopCount!=null?DS.loopCount:null;
58680
59088
  if (zot(loopWait)) loopWait = DS.loopWait!=null?DS.loopWait:null;
58681
59089
  if (zot(loopCall)) loopCall = DS.loopCall!=null?DS.loopCall:null;
58682
59090
  if (zot(loopParams)) loopParams = DS.loopParams!=null?DS.loopParams:null;
58683
59091
  if (zot(loopWaitCall)) loopWaitCall = DS.loopWaitCall!=null?DS.loopWaitCall:null;
58684
- if (zot(loopWaitParams)) loopWaitParams = DS.loopWaitParams!=null?DS.loopWaitParams:null;
58685
59092
  if (zot(loopPick)) loopPick = DS.loopPick!=null?DS.loopPick:null;
58686
59093
  if (zot(rewind)) rewind = DS.rewind!=null?DS.rewind:null;
58687
59094
  if (zot(rewindWait)) rewindWait = DS.rewindWait!=null?DS.rewindWait:null;
@@ -58691,6 +59098,7 @@ RETURNS the target for chaining (or null if no target is provided and run on zim
58691
59098
  if (zot(rewindWaitParams)) rewindWaitParams = DS.rewindWaitParams!=null?DS.rewindWaitParams:null;
58692
59099
  if (zot(rewindTime)) rewindTime = DS.rewindTime!=null?DS.rewindTime:null;
58693
59100
  if (zot(rewindEase)) rewindEase = DS.rewindEase!=null?DS.rewindEase:null;
59101
+ if (zot(rewindPick)) rewindPick = DS.rewindPick!=null?DS.rewindPick:null;
58694
59102
  if (zot(startCall)) startCall = DS.startCall!=null?DS.startCall:null;
58695
59103
  if (zot(startParams)) startParams = DS.startParams!=null?DS.startParams:null;
58696
59104
  if (zot(animateCall)) animateCall = DS.animateCall!=null?DS.animateCall:null;
@@ -58726,7 +59134,6 @@ RETURNS the target for chaining (or null if no target is provided and run on zim
58726
59134
  if (zot(timeCheck)) timeCheck = DS.timeCheck!=null?DS.timeCheck:null;
58727
59135
  if (zot(noAnimateCall)) noAnimateCall = DS.noAnimateCall!=null?DS.noAnimateCall:null;
58728
59136
  if (zot(pathDamp)) pathDamp = DS.pathDamp!=null?DS.pathDamp:null;
58729
- if (zot(rewindPick)) rewindPick = DS.rewindPick!=null?DS.rewindPick:null;
58730
59137
 
58731
59138
  if (!target) target = {}; // ZIM 018 replacing: return; from 10.9.0
58732
59139
  var AN = zim.ANIMATE;
@@ -58939,7 +59346,7 @@ RETURNS the target for chaining (or null if no target is provided and run on zim
58939
59346
  if (i==0 && sequence!=0) seqTime = timeType=="s"?.02:20; // patched in 10.7.0 and 10.7.1
58940
59347
 
58941
59348
  // zim.animate(tar, tar.zimObj, time, ease, (i==target.length-1?call:null), (i==target.length-1?params:null)
58942
- zim.animate(tar, tar.zimObj, time, ease, (i==target.length-1?sequenceDone:null), null, wait, waitedCall, waitedParams, null, null, null, null, null, null, null, loopPick, null, null, null, null, null, null, rewindTime, rewindEase, startCall, startParams, animateCall, animateParams, null, sequenceCall, sequenceParams, null, null, ticker, zim.copy(cjsProps), css, protect, override, null, set, id, events, sequenceTarget, dynamic, drag, clamp, startPaused, clean, obj, seriesWait, seqTime, rrr, pauseOnBlur, easeAmount, easeFrequency, timeUnit, timeCheck, noAnimateCall, pathDamp, rewindPick, style, group); // do not send from!
59349
+ zim.animate(tar, tar.zimObj, time, ease, (i==target.length-1?sequenceDone:null), null, wait, waitedCall, waitedParams, null, null, null, null, null, null, null, loopPick, null, null, null, null, null, null, rewindTime, rewindEase, rewindPick, startCall, startParams, animateCall, animateParams, null, sequenceCall, sequenceParams, null, null, ticker, zim.copy(cjsProps), css, protect, override, null, set, id, events, sequenceTarget, dynamic, drag, clamp, startPaused, clean, obj, seriesWait, seqTime, rrr, pauseOnBlur, easeAmount, easeFrequency, timeUnit, timeCheck, noAnimateCall, pathDamp, style, group); // do not send from!
58943
59350
 
58944
59351
  }
58945
59352
  return sequenceTarget;
@@ -59289,7 +59696,7 @@ RETURNS the target for chaining (or null if no target is provided and run on zim
59289
59696
  }
59290
59697
  }
59291
59698
 
59292
- // props, time, ease, call, params, wait, waitedCall, waitedParams, loop, loopCount, loopWait, loopCall, loopParams, loopWaitCall, loopWaitParams, loopPick, rewind, rewindWait, rewindCall, rewindParams, rewindWaitCall, rewindWaitParams, rewindTime, rewindEase, startCall, startParams, animateCall, animateParams, sequence, sequenceCall, sequenceParams, sequenceReverse, sequenceRatio, ticker, cjsProps, css, protect, override, from, set, id, events, sequenceTarget, dynamic, drag, clamp, startPaused, clean, obj, seriesWait, sequenceWait, rate, pauseOnBlur, easeAmount, easeFrequency, timeUnit, timeCheck, noAnimateCall, pathDamp, rewindPick
59699
+ // props, time, ease, call, params, wait, waitedCall, waitedParams, loop, loopCount, loopWait, loopCall, loopParams, loopWaitCall, loopWaitParams, loopPick, rewind, rewindWait, rewindCall, rewindParams, rewindWaitCall, rewindWaitParams, rewindTime, rewindEase, rewindPick, startCall, startParams, animateCall, animateParams, sequence, sequenceCall, sequenceParams, sequenceReverse, sequenceRatio, ticker, cjsProps, css, protect, override, from, set, id, events, sequenceTarget, dynamic, drag, clamp, startPaused, clean, obj, seriesWait, sequenceWait, rate, pauseOnBlur, easeAmount, easeFrequency, timeUnit, timeCheck, noAnimateCall, pathDamp
59293
59700
 
59294
59701
  // -----------------------------
59295
59702
  // NORMALIZED TWEEN COMING THROUGH
@@ -63396,7 +63803,7 @@ Style.remove("color");
63396
63803
  // add styles for a Dial - overwriting all previous Dial styles
63397
63804
  Style.addType("Dial", {useTicks:false, backgroundColor:yellow});
63398
63805
 
63399
- // remember current style using a "default" id
63806
+ // remember current style using a "default" id - also see with ID below
63400
63807
  Style.remember();
63401
63808
 
63402
63809
  // new Dials will use ticks and not be yellow
@@ -63411,7 +63818,7 @@ Style.remember("myID");
63411
63818
  // add styles for a group (existing objects are not changed - new ones will be)
63412
63819
  Style.addGroup("big", {size:100});
63413
63820
 
63414
- the STYLE at the time myID was remembered will be active from now on
63821
+ // the STYLE at the time myID was remembered will be active from now on
63415
63822
  Style.recall("myID");
63416
63823
  END EXAMPLE
63417
63824
 
@@ -66612,6 +67019,7 @@ allowToggle - (default true) set to false to not allow grid to toggle between pe
66612
67019
  cache - (default true) cache the grid
66613
67020
  numbers - (default true) show numbers on grid
66614
67021
  mouseOutside - (default true) set to false to not move grid values if mouse is outside the grid
67022
+ cross - (default true) set to false to not show cross in grid
66615
67023
  style - (default true) set to false to ignore styles set with the STYLE - will receive original parameter defaults
66616
67024
  group - (default null) set to String (or comma delimited String) so STYLE can set default styles to the group(s) (like a CSS class)
66617
67025
  inherit - (default null) used internally but can receive an {} of styles directly
@@ -69160,6 +69568,7 @@ PROPERTIES
69160
69568
  type - holds the class name as a String
69161
69569
  items - get the original items array passed to the pack (including addAt() and removeFrom() changes)
69162
69570
  currentItems - get the array of items in the current order (this may be different if dragOrder is true)
69571
+ content - the ZIM Container holding the items
69163
69572
  cols - get the current number of columns
69164
69573
  rows - get the current number of rows
69165
69574
  iterations - get the number of times the pack was made to optimize its size
@@ -70133,6 +70542,188 @@ alpha, cursor, shadow, name, mouseChildren, mouseEnabled, parent, numChildren, e
70133
70542
  zim.extend(zim.Beads, zim.Container, ["clone","dispose"], "zimContainer", false);
70134
70543
  //-66.7
70135
70544
 
70545
+
70546
+ /*--
70547
+ zim.Bullets(list, bulletType, size, color, cols, font, italic, bold, variant, shiftH, shiftV, spacing, spacingH, spacingV, colSpacing, bulletAlign, style, group, inherit)
70548
+
70549
+ Bullets
70550
+ zim class - extends a zim.Tile which extends a zim.Container
70551
+
70552
+ DESCRIPTION
70553
+ Bullets creates a list with bullet points or custom bullet types.
70554
+ Different bullet types can be specified such as circle, square, dash, or number.
70555
+ The bullets can be arranged in multiple columns with customizable spacing.
70556
+
70557
+ EXAMPLE
70558
+ new Bullets(["First item", "Second item", "Third item"]).center();
70559
+ END EXAMPLE
70560
+
70561
+ EXAMPLE
70562
+ new Bullets({
70563
+ list:["Red bullet", "Purple bullet"],
70564
+ bulletType:"square",
70565
+ size:18,
70566
+ color:series(red, purple).every(2),
70567
+ cols:2,
70568
+ spacing:10,
70569
+ colSpacing:40
70570
+ }).center();
70571
+ END EXAMPLE
70572
+
70573
+ EXAMPLE
70574
+ // Nested Bullets
70575
+ // must import ZIM pizzazz for makeIcon
70576
+ new Bullets({
70577
+ list:["Share puzzles as present", new Bullets({
70578
+ list:["Birthdays", "Babies", "Family Pics", "Grads"],
70579
+ bulletType:makeIcon("heart", red, .5)
70580
+ }), "Share Puzzles for", new Bullets({
70581
+ list:["Company Sites", "Social Media", "Marketing Games", "Forum Fame"],
70582
+ bulletType:makeIcon("pic", purple, .5)
70583
+ })],
70584
+ bulletType:makeIcon("checkmark", green.darken(.2), .8),
70585
+ size:40,
70586
+ spacing:20,
70587
+ spacingV:40
70588
+ }).center();
70589
+ END EXAMPLE
70590
+
70591
+ PARAMETERS
70592
+ ** supports DUO - parameters or single object with properties below
70593
+ ** supports VEE - parameters marked with ZIM VEE mean a zim Pick() object or Pick Literal can be passed
70594
+ Pick Literal formats: [1,3,2] - random; {min:10, max:20} - range; series(1,2,3) - order, function(){return result;} - function
70595
+ ** supports OCT - parameter defaults can be set with STYLE control (like CSS)
70596
+ list - (default ["One", "Two", "Three"]) an array of text items for the bullet list
70597
+ bulletType - |ZIM VEE| (default "circle") the style of bullet - options: "circle", "square", "dash", "number" or "numbers", or a ZIM object
70598
+ size - (default null) the font size of the text
70599
+ color - (default null) the color of the text
70600
+ cols - (default 1) the number of columns to arrange the bullets in
70601
+ font - (default null) the font family for the text
70602
+ italic - (default null) set to true for italic text
70603
+ bold - (default null) set to true for bold text
70604
+ variant - (default null) the font variant for the text
70605
+ shiftH - (default null) horizontal shift of the bullet text
70606
+ shiftV - (default 2) vertical shift of the bullet text
70607
+ spacing - (default 14) the default tile spacing - also see spacingH and spacingV
70608
+ spacingH - (default spacing) horizontal spacing between bullet and text
70609
+ spacingV - (default spacing) vertical spacing
70610
+ colSpacing - (default spacingH) spacing between columns
70611
+ bulletAlign - (default LEFT) alignment of bullets
70612
+ style - (default true) set to false to ignore styles set with the STYLE
70613
+ group - (default null) set to String (or comma delimited String) so STYLE can set default styles to the group(s)
70614
+ inherit - (default null) used internally but can receive an {} of styles directly
70615
+
70616
+ METHODS
70617
+ clone(exact) - makes a copy with properties such as x, y, etc. also copied
70618
+ hasProp(property as String) - returns true if property exists on object else returns false
70619
+ dispose() - deletes object
70620
+
70621
+ ALSO: see ZIM Tile for methods such as:
70622
+ setProps(), setSpacing(), remake(), resize(), etc.
70623
+
70624
+ ALSO: ZIM adds all the methods listed under Container, such as:
70625
+ drag(), hitTestRect(), animate(), sca(), reg(), addTo(), removeFrom(), loop(), alp(), rot(), etc.
70626
+
70627
+ ALSO: see the CreateJS Easel Docs for Container methods, such as:
70628
+ on(), off(), getBounds(), setBounds(), cache(), uncache(), dispatchEvent(),
70629
+ addChild(), removeChild(), addChildAt(), getChildAt(), contains(), etc.
70630
+
70631
+ PROPERTIES
70632
+ type - holds the class name as a String
70633
+ list - the array of text items for the bullets
70634
+ bulletType - the bullet style being used
70635
+
70636
+ ALSO: see ZIM Container for properties such as:
70637
+ width, height, widthOnly, heightOnly, draggable, level, depth, group
70638
+ blendMode, hue, saturation, brightness, contrast, etc.
70639
+
70640
+ ALSO: see the CreateJS Easel Docs for Container properties, such as:
70641
+ x, y, rotation, scaleX, scaleY, regX, regY, skewX, skewY,
70642
+ alpha, cursor, shadow, name, mouseChildren, mouseEnabled, parent, numChildren, etc.
70643
+
70644
+ --*///+67.8
70645
+
70646
+ zim.Bullets = function(list, bulletType, size, color, cols, font, italic, bold, variant, shiftH, shiftV, spacing, spacingH, spacingV, colSpacing, bulletAlign, style, group, inherit) {
70647
+ var sig = "list, bulletType, size, color, cols, font, italic, bold, variant, shiftH, shiftV, spacing, spacingH, spacingV, colSpacing, bulletAlign, style, group, inherit";
70648
+ var duo; if (duo = zob(zim.Bullets, arguments, sig, this)) return duo;
70649
+ z_d("67.8");
70650
+
70651
+ this.group = group;
70652
+ var DS = style===false?group!=null?zim.getStyle(null,null,inherit,this.group):{}:zim.getStyle("Bullets", this.group, inherit);
70653
+
70654
+ // MONITOR
70655
+ var mID = this.mID = "z~"+(DS.monitor===false?"-":"Bullets");
70656
+
70657
+ if (zot(list)) list = DS.list!=null?DS.list:["One", "Two", "Three"];
70658
+ if (zot(bulletType)) bulletType = DS.bulletType!=null?DS.bulletType:"circle";
70659
+ if (zot(size)) size = DS.size!=null?DS.size:null;
70660
+ if (zot(color)) color = DS.color!=null?DS.color:null;
70661
+ if (zot(cols)) cols = DS.cols!=null?DS.cols:1;
70662
+ if (cols < 1) cols = 1;
70663
+ if (zot(font)) font = DS.font!=null?DS.font:null;
70664
+ if (zot(shiftH)) shiftH = DS.shiftH!=null?DS.shiftH:null;
70665
+ if (zot(italic)) italic = DS.italic!=null?DS.italic:null;
70666
+ if (zot(bold)) bold = DS.bold!=null?DS.bold:null;
70667
+ if (zot(variant)) variant = DS.variant!=null?DS.variant:null;
70668
+ if (zot(shiftV)) shiftV = DS.shiftV!=null?DS.shiftV:2;
70669
+ if (zot(spacing)) spacing = DS.spacing!=null?DS.spacing:14;
70670
+ if (zot(spacingH)) spacingH = DS.spacingH!=null?DS.spacingH:spacing;
70671
+ if (zot(spacingV)) spacingV = DS.spacingV!=null?DS.spacingV:spacing;
70672
+ if (zot(colSpacing)) colSpacing = DS.colSpacing!=null?DS.colSpacing:spacingH;
70673
+ if (zot(bulletAlign)) bulletAlign = DS.bulletAlign!=null?DS.bulletAlign:LEFT;
70674
+ var tileList = [];
70675
+ var num = 1;
70676
+ this.list = list;
70677
+ var icons = [];
70678
+ zim.loop(list, function(words, i) {
70679
+ if (words.type=="Bullets") { // nested Bullets
70680
+ tileList.push(new zim.Container(1,1));
70681
+ tileList.push(words);
70682
+ return;
70683
+ }
70684
+ const bt = zik(bulletType);
70685
+ icons.push(bt);
70686
+ if (bt.type && bt.clone) tileList.push(bt.clone());
70687
+ else if (bt == "circle") tileList.push(new zim.Circle(5, color));
70688
+ else if (bt == "square") tileList.push(new zim.Rectangle(10, 10, color));
70689
+ else if (bt == "dash") tileList.push(new zim.Label({text:"-", size:size, font:font, color:color, italic:italic, bold:bold, variant:variant, shiftH:shiftH, shiftV:shiftV-2}));
70690
+ 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}));
70691
+ tileList.push(new zim.Label({text:words, size:size, font:font, color:color, italic:italic, bold:bold, variant:variant, shiftH:shiftH, shiftV:shiftV}));
70692
+ })
70693
+ if (cols > 1 ) {
70694
+ // need to shift pairs
70695
+ // [b1, w1, b2, w2, b3, w3, b4, w4, b5, w5]
70696
+ // [b1, w1, b4, w4, b2, w2, b5, w5, b3, w3]
70697
+ var temp = [];
70698
+ // [[b1, w1, b2, w2, b3, w3], [b4, w4, b5,w5]]
70699
+ zim.loop(cols, function(){temp.push([])});
70700
+ zim.loop(tileList, function(item, i, t) {
70701
+ temp[Math.floor(i/Math.ceil(t/cols))].push(item);
70702
+ })
70703
+ tileList = [];
70704
+ zim.loop(temp[0].length, function(i) {
70705
+ zim.loop(temp, function(list) {
70706
+ tileList.push(list[i], list[i+1])
70707
+ })
70708
+ }, null, null, 2); // steps of 2
70709
+ }
70710
+ this.zimTile_constructor(tileList, cols*2, Math.ceil(list.length/cols), series(spacingH,colSpacing), spacingV, true, null, null, null, null, null, null, series(bulletAlign, LEFT), CENTER);
70711
+ this.type = "Bullets";
70712
+
70713
+ this.clone = function(exact) {
70714
+ if (exact) {
70715
+ var exactItems = [];
70716
+ for (var i=0; i<icons.length; i++) {
70717
+ var icon = icons[i];
70718
+ exactItems.push(icon.clone?icon.clone(true):icon);
70719
+ }
70720
+ }
70721
+ return that.cloneProps(new zim.Bullets(list, exact?zim.series(exactItems):bulletType, size, color, cols, font, italic, bold, variant, shiftH, shiftV, spacing, spacingH, spacingV, colSpacing, bulletAlign, this.style, this.group));
70722
+ };
70723
+ };
70724
+ zim.extend(zim.Bullets, zim.Tile, ["clone"], "zimTile", false);
70725
+ //-67.8
70726
+
70136
70727
  /*--
70137
70728
  zim.Layout = function(holder, regions, lastMargin, lastMarginMin, backgroundColor, vertical, showRegions, scalingObject, hideKey, style, group, inherit)
70138
70729
 
@@ -76133,6 +76724,7 @@ dispatches a "moving" event if target is moving and "startmoving" and "stopmovin
76133
76724
  var frame = stage.frame;
76134
76725
 
76135
76726
  if (!zot(orient)) rotate = orient; // renamed parameter to orient
76727
+ if (zot(firstPerson)) firstPerson = false;
76136
76728
 
76137
76729
  if (zot(target)) {target = new zim.Container(1,1, null, null, false);} // make a surrogate if only wanting controller data
76138
76730
  var accelerator = target.type == "Accelerator";
@@ -76142,9 +76734,10 @@ dispatches a "moving" event if target is moving and "startmoving" and "stopmovin
76142
76734
  type = "manual";
76143
76735
  if (zot(axis)) axis = dPad.axis;
76144
76736
  if (axis == "all") axis = "both";
76145
-
76737
+ first = {rotation:0, speedX:that.speed, speedY:that.speed};
76146
76738
  dPad.on("change", function() {
76147
76739
  var d = {dirX:dPad.dirX, dirY:dPad.dirY};
76740
+ if (firstPerson) {doFirstPerson(d); return;}
76148
76741
  if (tileObj) {
76149
76742
  down = [0,0,0,0];
76150
76743
  var dC = false;
@@ -76165,6 +76758,7 @@ dispatches a "moving" event if target is moving and "startmoving" and "stopmovin
76165
76758
  that.convert(target.x+dPad.dirX*speed, target.y+dPad.dirY*speed);
76166
76759
  }
76167
76760
  }, null, null, null, null, mID);
76761
+
76168
76762
  if (tileObj) {
76169
76763
  dPad.on("pressup", function() {
76170
76764
  down = [0,0,0,0];
@@ -76193,8 +76787,7 @@ dispatches a "moving" event if target is moving and "startmoving" and "stopmovin
76193
76787
  if (zot(diagonal)) diagonal = true;
76194
76788
  if (axis == "horizontal" || axis == "vertical") diagonal = false;
76195
76789
  if (zot(damp) || damp===true) damp = (type=="keydown" || type=="gamebutton") ? 1: (type=="pressmove"?.5:.1);
76196
- if (damp === false) damp = 1;
76197
- if (zot(firstPerson)) firstPerson = false;
76790
+ if (damp === false) damp = 1;
76198
76791
  if (zot(turnSpeed)) turnSpeed = speed * .4;
76199
76792
  if (zot(moveThreshold)) moveThreshold = 4;
76200
76793
  if (zot(stickThreshold)) stickThreshold = tileObj?.3:.2;
@@ -80219,7 +80812,7 @@ EXAMPLE
80219
80812
  const obj = new Container(500,500);
80220
80813
  F.makeCircles().center(obj).animate({props:{scale:2}, rewind:true, loop:true});
80221
80814
 
80222
- new zim.Perspective({
80815
+ new Perspective({
80223
80816
  obj: obj,
80224
80817
  points:[
80225
80818
  {x:-obj.width/2, y:-obj.height/2+50},
@@ -80236,7 +80829,7 @@ EXAMPLE
80236
80829
  const obj = new Container(500,500);
80237
80830
  F.makeCircles().center(obj).animate({props:{scale:2}, rewind:true, loop:true});
80238
80831
 
80239
- const perspective = new zim.Perspective(obj).center();
80832
+ const perspective = new Perspective(obj).center();
80240
80833
 
80241
80834
  perspective.selectSide(3);
80242
80835
  perspective.updateCorner(perspective.selectCorner(0).mov(0,100));
@@ -80250,7 +80843,7 @@ EXAMPLE
80250
80843
  const obj = new Container(500,500);
80251
80844
  F.makeCircles().center(obj).animate({props:{scale:2}, rewind:true, loop:true});
80252
80845
 
80253
- const perspective = new zim.Perspective(obj).center();
80846
+ const perspective = new Perspective(obj).center();
80254
80847
 
80255
80848
  perspective.selectSide(0); // comment this out to see the difference
80256
80849
  const corner = perspective.selectCorner(1).wiggle("x",null,50,100,.5,1);
@@ -80265,7 +80858,7 @@ EXAMPLE
80265
80858
  const obj = new Container(500,500);
80266
80859
  F.makeCircles().center(obj).animate({props:{scale:2}, rewind:true, loop:true});
80267
80860
 
80268
- const perspective = new zim.Perspective(obj).center();
80861
+ const perspective = new Perspective(obj).center();
80269
80862
 
80270
80863
  const point = perspective.selectCorner(2);
80271
80864
  const p = perspective.blob.globalToLocal(W,H); // the corner control is in the blob
@@ -83250,9 +83843,9 @@ EXAMPLE
83250
83843
  // With emitter on complete and re-shuffle
83251
83844
  STYLE = {Label:{backgroundColor:white}};
83252
83845
  const shuffler = new Shuffler("Will this wind be so mighty ?")
83253
- .center();
83846
+ .center();
83254
83847
  const emitter = new Emitter({startPaused:true})
83255
- .center();
83848
+ .center();
83256
83849
  shuffler.on("complete", ()=>{
83257
83850
  shuffler.shuffle(2, 2, 4);
83258
83851
  emitter.spurt(20);
@@ -90509,6 +91102,9 @@ See https://zimjs.com/frame.html for sample templates using Frame.
90509
91102
  The first frame made is called the zimDefaultFrame - or zdf.
90510
91103
  It will also have the default stage for addTo(), center(), etc.
90511
91104
  Use setDefault() on another frame to change the default frame.
91105
+ Pass a previous frame to the nextFrame parameter of a subsequent frame
91106
+ for interactivity on both frames. Any number of frames can be used.
91107
+ This is good for optimization to split interface from dynamic content.
90512
91108
 
90513
91109
  As of ZIM ZIM 01, ZIM will make F, S, W, H global variables
90514
91110
  that reference the zimDefaultFrame, its stage and the stage width and height.
@@ -90708,7 +91304,7 @@ assets - (default null) - 1. a string asset or 2. an array of assets, 3. ZIM ass
90708
91304
  2. ["logo.png", "bounce.mp3", "Reuben.otf"]
90709
91305
  3. {id:"string", src:"logo.png", path:"assets/", loadTimeout:2, noCORSonImage:true}
90710
91306
  4. [{assets:["one.png", "two.png"], path:"images/"}, {assets:["big.mp3", "oof.mp3"], path:"sounds/"}]
90711
- ** see the loadAssets() method for details - including more file types, etc.
91307
+ ** see the loadAssets() method for details - including more file types, Google fonts, Noto Emojis, etc.
90712
91308
  NOTE: "complete", "progress" and "fileLoaded" events are not dispatched
90713
91309
  use loadAssets() for these if desired
90714
91310
  the "ready" event will be dispatched when the canvas is ready and initial assets are loaded
@@ -90811,8 +91407,15 @@ loadAssets(assets, path, progress, xhr, time, loadTimeout, outputAudioSprite, cr
90811
91407
  assets - a file (url String, asset object or multi-asset object) or files in an Array
90812
91408
  each asset String is how you then access the asset with the asset() method of Frame
90813
91409
  asset types (from CreateJS PreloadJS): Image, Font, JSON, Sound, SVG, Text, XML
90814
- NOTE: as of ZIM ZIM 02, fonts can be loaded with just the font file name (including Google Fonts) rather than a ZIM font object - see FONTS in the Docs.
91410
+ NOTE: as of ZIM ZIM 02, fonts can be loaded with just the font file name (including Google Fonts)
91411
+ rather than a ZIM font object - see FONTS in the Docs.
91412
+ so for google fonts, use "gf_Font+Family" and then when assigning the font to the Label, use "Font Family" without the gf (+ is optional)
90815
91413
  NOTE: as of ZIM Cat 04, SVG will be automatically converted to a Bitmap with and svg property of the original SVG.
91414
+ NOTE: as of ZIM 020, Noto Color Emojis can be loaded with "noto_emoji"
91415
+ These look consistent across platforms (Windows, Linux, Android, iOS)
91416
+ Paste any emoji character or code after noto_ to preload the SVG for the emoji
91417
+ If color or borderColor is specified in the Emoji (or SVG) then individual parts
91418
+ can be colored, dragged, wiggled, or animated (see Emoji and SVG)
90816
91419
  asset can also be a ZIM asset object:
90817
91420
  {id:"string", src:"filename", path:"dir/", loadTimeout:1, maxNum:num, noCORSonImage:true}
90818
91421
  then can use the id to access the asset in the asset() method of Frame
@@ -90845,7 +91448,8 @@ loadAssets(assets, path, progress, xhr, time, loadTimeout, outputAudioSprite, cr
90845
91448
  ]
90846
91449
  ** then asset("one.png") will be the asset in the images folder
90847
91450
  ** and asset("portraits/one.png") will be the asset in the portraits folder
90848
- asset can also be a font object - but as of ZIM ZIM 02, fonts can be loaded with just the file name, including Google Fonts
91451
+ asset can also be a font object (DEPRECATED)
91452
+ As of ZIM ZIM 02, fonts can be loaded with just the file name, including Google Fonts ("gf_fontfamily")
90849
91453
  DO NOT use uppercase letters on mobile apps
90850
91454
  {font:name, src:url, type:string, weight:string, style:string} // with last three properties being optional
90851
91455
  eg.
@@ -90853,6 +91457,7 @@ loadAssets(assets, path, progress, xhr, time, loadTimeout, outputAudioSprite, cr
90853
91457
  {font: "regu", src:"regul-bold.woff", weight:"bold"}
90854
91458
  {src:"https://fonts.googleapis.com/css?family=Roboto"}
90855
91459
  For google fonts https://fonts.google.com/ you add extra information to the url so the font (family), type, weight and style are ignored
91460
+ It is easier to just load google fonts as "gf_fontfamily" as an asset
90856
91461
  If absolute src is used, path parameter is ignored - otherwise path is added to start of src
90857
91462
  After loading, can just use:
90858
91463
  var label = new Label("hello", 30, "wildwood") // or whatever the font property is
@@ -91899,6 +92504,56 @@ zim.Frame = function(scaling, width, height, color, outerColor, ready, assets, p
91899
92504
  that.dispatchEvent("update");
91900
92505
  };
91901
92506
 
92507
+ // Made by AI - Gemini - used to load Noto Emojis from GitHub
92508
+ function getNotoFilename(inputStr) {
92509
+ // Clean up whitespace
92510
+ var input = inputStr.trim();
92511
+ if (!input) return 'emoji_u.svg';
92512
+
92513
+ // Regex check: If it contains letters/numbers and starts with U+, contains hex prefixes,
92514
+ // or is separated by underscores/hyphens/spaces, treat it as a code string.
92515
+ var isCodeRegex = /^[0-9a-fA-F_\-\sU\+]+$/;
92516
+ var points = [];
92517
+
92518
+ if (isCodeRegex.test(input) && input.replace(/[_\-\sU\+]/g, '').length > 0) {
92519
+ // --- PROCESS AS ALPHANUMERIC CODE ---
92520
+ // Split by common delimiters: spaces, underscores, hyphens, or "U+"
92521
+ var rawSegments = input.split(/[_\-\s]+/);
92522
+
92523
+ for (var s = 0; s < rawSegments.length; s++) {
92524
+ var segment = rawSegments[s].replace(/^U\+/i, '').toLowerCase();
92525
+ if (segment && segment !== 'fe0f') {
92526
+ points.push(segment);
92527
+ }
92528
+ }
92529
+ } else {
92530
+ // --- PROCESS AS RAW EMOJI PICTURE (Legacy ES5 Surrogate Math) ---
92531
+ var i = 0;
92532
+ while (i < input.length) {
92533
+ var code = input.charCodeAt(i);
92534
+
92535
+ // Handle High/Low Surrogate pairs for 32-bit emojis
92536
+ if (code >= 0xD800 && code <= 0xDBFF && i + 1 < input.length) {
92537
+ var nextCode = input.charCodeAt(i + 1);
92538
+ if (nextCode >= 0xDC00 && nextCode <= 0xDFFF) {
92539
+ code = ((code - 0xD800) * 0x400) + (nextCode - 0xDC00) + 0x10000;
92540
+ i++;
92541
+ }
92542
+ }
92543
+
92544
+ var hex = code.toString(16).toLowerCase();
92545
+ if (hex !== 'fe0f') {
92546
+ points.push(hex);
92547
+ }
92548
+ i++;
92549
+ }
92550
+ }
92551
+
92552
+ // Join all collected hex values with underscores per Google's standard layout
92553
+ return 'emoji_u' + points.join('_') + '.svg';
92554
+ }
92555
+ this.getNotoFilename = getNotoFilename;
92556
+
91902
92557
  function setVisible() {
91903
92558
  if (scaling == "fill") {
91904
92559
  var beside = (zum(that.canvas.style.width) - zim.windowWidth()) / 2;
@@ -92009,7 +92664,6 @@ zim.Frame = function(scaling, width, height, color, outerColor, ready, assets, p
92009
92664
  // 018 TRYING TO FIX CREATEJS ERROR IF SOUND LOADED AGAIN - BUT BREAKS LAZY LOAD
92010
92665
  // var emptyAssets = false;
92011
92666
 
92012
-
92013
92667
  for (i=0; i<assets.length; i++) {
92014
92668
  a = assets[i];
92015
92669
  // if (zim.assets[a]) {
@@ -92019,14 +92673,27 @@ zim.Frame = function(scaling, width, height, color, outerColor, ready, assets, p
92019
92673
  // // continue;
92020
92674
  // // }
92021
92675
  // }
92022
- if (a.replace) a = a.replace(/gf_/i, "https://fonts.googleapis.com/css?family=");
92676
+
92677
+
92678
+
92679
+ var match;
92680
+ if (a.match) match = a.match(/^noto_(.*)/);
92681
+ if (match) {
92682
+ a = {id:a, src:"https://raw.githubusercontent.com/googlefonts/noto-emoji/main/svg/" + getNotoFilename(match[1])}
92683
+ }
92684
+ if (a.replace) a = a.replace(/gf_/i, "https://fonts.googleapis.com/css?family=");
92023
92685
  // split multi into individual ZIM asset objects and make the first of these
92024
- if (a.assets) {
92686
+ if (a.assets) {
92025
92687
  var assetMulti = [];
92026
92688
  assets.splice(i, 1);
92027
92689
  if (!Array.isArray(a.assets)) a.assets = [a.assets];
92028
92690
  for (j=0; j<a.assets.length; j++) {
92029
92691
  var aj = a.assets[j];
92692
+ match = null;
92693
+ if (aj.match) match = aj.match(/^noto_(.*)/);
92694
+ if (match) {
92695
+ aj = {id:aj, src:"https://raw.githubusercontent.com/googlefonts/noto-emoji/main/svg/" + getNotoFilename(match[1])}
92696
+ }
92030
92697
  if (aj.split) {
92031
92698
  var temp = aj.split("?");
92032
92699
  ext = temp[0].match(re);
@@ -94664,7 +95331,7 @@ zim.Dat = function(file) {
94664
95331
  zim.extend(zim.Dat, createjs.EventDispatcher, null, "cjsEventDispatcher", false);//-83.08
94665
95332
 
94666
95333
  /*--
94667
- SVG = function(svg, width, height, bitmap, splitTypes, geometric, showControls, interactive, style, group, inherit)
95334
+ SVG = function(svg, width, height, bitmap, splitTypes, geometric, showControls, interactive, color, borderColor, style, group, inherit)
94668
95335
 
94669
95336
  SVG
94670
95337
  zim class - extends a zim.Container which extends a createjs.Container
@@ -94782,10 +95449,16 @@ PARAMETERS
94782
95449
  Pick Literal formats: [1,3,2] - random; {min:10, max:20} - range; series(1,2,3) - order, function(){return result;} - function
94783
95450
  ** supports OCT - parameter defaults can be set with STYLE control (like CSS)
94784
95451
  svg - |ZIM VEE| the String file name of the SVG including file extension for instance, "pic.svg"
94785
- or an SVG tag either directly as a string or as a reference to an HTML tag - ie. zid("svgID")
94786
- There is a global PATH constant that can be set to add a path to the start of the file name
94787
- for instance setting PATH = "assets/" would then look for "assets/pic.svg".
94788
- If a path is provided to Frame() parameter or the loadAssets() then these will automatically set the global PATH constant.
95452
+ or an SVG tag either directly as a string or as a reference to an HTML tag - ie. zid("svgID")
95453
+ There is a global PATH constant that can be set to add a path to the start of the file name
95454
+ for instance setting PATH = "assets/" would then look for "assets/pic.svg".
95455
+ If a path is provided to Frame() parameter or the loadAssets() then these will automatically set the global PATH constant.
95456
+ NOTE: as of ZIM 020, Noto Color Emojis can be loaded with "noto_emoji"
95457
+ These look consistent across platforms (Windows, Linux, Android, iOS)
95458
+ Paste any emoji character or code after noto_
95459
+ Can also preload the SVG using the noto_ if SVG is to be used in Tile() for instance
95460
+ If color or borderColor is specified then an SVG Container will be nade with individual parts
95461
+ that can be colored, dragged, wiggled, or animated
94789
95462
  width - (default null) optionally predict the width of the SVG
94790
95463
  The width will be ignored and the actual width will be used if the SVG is preloaded
94791
95464
  and if lazy-loaded, the width will be replaced with the actual width after the SVG is loaded.
@@ -94801,7 +95474,10 @@ bitmap - (default true) this will show the SVG as a Bitmap (still nicely scalabl
94801
95474
  splitTypes - (default false) - set to true to split different types of paths into separate objects
94802
95475
  geometric - (default true) - set to false to load Rectangle and Circle objects as Blob objects
94803
95476
  showControls - (default true) set to false to start with controls not showing
94804
- interactive - (default true) set to false to turn off controls, move, toggle, select, edit - leaving just the shapes
95477
+ interactive - (default true) for bitmap:false, set to false to turn off controls, move, toggle, select, edit - leaving just the shapes
95478
+ color - |ZIM VEE| (default null) for bitmap:false, set to a color or an array of colors to apply to fill of children - in order of the children
95479
+ usually a series() would be used here for colors in order, or an array for random colors
95480
+ borderColor - |ZIM VEE| (default null) set to a color or an array of colors to apply to border of children - in order of the children
94805
95481
  style - (default true) set to false to ignore styles set with the STYLE - will receive original parameter defaults
94806
95482
  group - (default null) set to String (or comma delimited String) so STYLE can set default styles to the group(s) (like a CSS class)
94807
95483
  inherit - (default null) used internally but can receive an {} of styles directly
@@ -94849,8 +95525,8 @@ dispatches a "complete" and a "ready" event (use either one) when the SVG is loa
94849
95525
  See the CreateJS Easel Docs for Container events such as:
94850
95526
  added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmove, pressup, removed, rollout, rollover
94851
95527
  --*///+83.09
94852
- zim.SVG = function(svg, width, height, bitmap, splitTypes, geometric, showControls, interactive, style, group, inherit) {
94853
- var sig = "svg, width, height, bitmap, splitTypes, geometric, showControls, interactive, style, group, inherit";
95528
+ zim.SVG = function(svg, width, height, bitmap, splitTypes, geometric, showControls, interactive, color, borderColor, style, group, inherit) {
95529
+ var sig = "svg, width, height, bitmap, splitTypes, geometric, showControls, interactive, color, borderColor, style, group, inherit";
94854
95530
  var duo; if (duo = zob(zim.SVG, arguments, sig, this)) return duo;
94855
95531
  z_d("83.09");
94856
95532
 
@@ -94864,6 +95540,11 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
94864
95540
  if (zot(geometric)) geometric = DS.geometric!=null?DS.geometric:true;
94865
95541
  if (zot(showControls)) showControls = DS.showControls!=null?DS.showControls:null;
94866
95542
  if (zot(interactive)) interactive = DS.interactive!=null?DS.interactive:true;
95543
+ if (zot(color)) color = DS.color!=null?DS.color:null;
95544
+ if (zot(borderColor)) borderColor = DS.borderColor!=null?DS.borderColor:null;
95545
+
95546
+ var setColors = [];
95547
+ var setBorderColors = [];
94867
95548
 
94868
95549
  this.zimContainer_constructor(width, height);
94869
95550
  var that = this;
@@ -94942,6 +95623,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
94942
95623
  if (that.stage) that.stage.update();
94943
95624
  }
94944
95625
  setTimeout(function () {
95626
+ doColors();
94945
95627
  that.dispatchEvent("ready");
94946
95628
  that.dispatchEvent("complete");
94947
95629
  },20);
@@ -94950,6 +95632,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
94950
95632
  that.bitmap = bitmap;
94951
95633
  that.bitmap.addTo(that);
94952
95634
  applyCommands();
95635
+ doColors();
94953
95636
  that.dispatchEvent("ready");
94954
95637
  that.dispatchEvent("complete");
94955
95638
  if (that.stage) that.stage.update();
@@ -94962,11 +95645,12 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
94962
95645
  svgContainer.loop(function (obj) {
94963
95646
  if (obj) obj.addTo(that);
94964
95647
  }, true);
95648
+ doColors();
94965
95649
  if (second) {
94966
95650
  applyCommands();
94967
95651
  if (that.stage) that.stage.update();
94968
95652
  }
94969
- setTimeout(function () {
95653
+ setTimeout(function () {
94970
95654
  that.dispatchEvent("ready");
94971
95655
  that.dispatchEvent("complete");
94972
95656
  },20);
@@ -94978,6 +95662,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
94978
95662
  if (obj) obj.addTo(that);
94979
95663
  }, true);
94980
95664
  applyCommands();
95665
+ doColors();
94981
95666
  that.dispatchEvent("ready");
94982
95667
  that.dispatchEvent("complete");
94983
95668
  if (that.stage) that.stage.update();
@@ -94985,6 +95670,25 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
94985
95670
  }
94986
95671
  }
94987
95672
  }
95673
+
95674
+ function doColors() {
95675
+ if (color) {
95676
+ if (color.index) color.index = 0; // not sure where it was setting to 1 when being cloned?
95677
+ that.loop(function(obj) {
95678
+ var c = zik(color);
95679
+ if (c!=null) obj.color = c;
95680
+ setColors.push(c);
95681
+ });
95682
+ }
95683
+ if (borderColor) {
95684
+ if (borderColor.index) borderColor.index = 0;
95685
+ that.loop(function(obj) {
95686
+ var c = zik(borderColor);
95687
+ if (c!=null) obj.borderColor = c;
95688
+ setBorderColors.push(c);
95689
+ });
95690
+ }
95691
+ }
94988
95692
 
94989
95693
  function applyCommands() {
94990
95694
  if (zot(width) && zot(height)) that.setBounds(null); // resets size
@@ -95006,8 +95710,8 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
95006
95710
  }
95007
95711
 
95008
95712
  if (style!==false) zim.styleTransforms(this, DS);
95009
- that.clone = function (exact) {
95010
- return this.cloneProps(new zim.SVG(exact?svgO:originalSVG, width, height, bitmap, splitTypes, geometric, showControls, interactive, style, this.group, inherit));
95713
+ that.clone = function (exact) {
95714
+ return this.cloneProps(new zim.SVG(exact?svgO:originalSVG, width, height, bitmap, splitTypes, geometric, showControls, interactive, exact&&setColors.length>0?zim.series(setColors):color, exact&&setBoarderColors.length>0?zim.series(setBorderColors):borderColor, style, this.group, inherit));
95011
95715
  }
95012
95716
  }
95013
95717
  zim.extend(zim.SVG, zim.Container, ["clone"], "zimContainer", false);//-83.09
@@ -97648,7 +98352,7 @@ function zimify(obj, a, b, c, d, list) {
97648
98352
  hitTestGrid:function(width, height, cols, rows, x, y, offsetX, offsetY, spacingX, spacingY, local, type) {
97649
98353
  return zim.hitTestGrid(this, width, height, cols, rows, x, y, offsetX, offsetY, spacingX, spacingY, local, type);
97650
98354
  },
97651
- animate:function(props, time, ease, call, params, wait, waitedCall, waitedParams, loop, loopCount, loopWait, loopCall, loopParams, loopWaitCall, loopWaitParams, loopPick, rewind, rewindWait, rewindCall, rewindParams, rewindWaitCall, rewindWaitParams, rewindTime, rewindEase, startCall, startParams, animateCall, animateParams, sequence, sequenceCall, sequenceParams, sequenceReverse, sequenceRatio, ticker, cjsProps, css, protect, override, from, set, id, events, sequenceTarget, dynamic, drag, clamp, startPaused, clean, obj, seriesWait, sequenceWait, rate, pauseOnBlur, easeAmount, easeFrequency, timeUnit, timeCheck, noAnimateCall, pathDamp, rewindPick) {
98355
+ animate:function(props, time, ease, call, params, wait, waitedCall, waitedParams, loop, loopCount, loopWait, loopCall, loopParams, loopWaitCall, loopWaitParams, loopPick, rewind, rewindWait, rewindCall, rewindParams, rewindWaitCall, rewindWaitParams, rewindTime, rewindEase, rewindPick, startCall, startParams, animateCall, animateParams, sequence, sequenceCall, sequenceParams, sequenceReverse, sequenceRatio, ticker, cjsProps, css, protect, override, from, set, id, events, sequenceTarget, dynamic, drag, clamp, startPaused, clean, obj, seriesWait, sequenceWait, rate, pauseOnBlur, easeAmount, easeFrequency, timeUnit, timeCheck, noAnimateCall, pathDamp) {
97652
98356
  if (props && (props.props || props.obj) && isDUO(arguments)) {
97653
98357
  // run this if duo but only if props object has a props or obj object
97654
98358
  // can you believe that sentence makes sense
@@ -97657,7 +98361,7 @@ function zimify(obj, a, b, c, d, list) {
97657
98361
  // it can only be a configuration object if there is a props or obj property
97658
98362
  arguments[0].target = this; return zim.animate(arguments[0]);
97659
98363
  }
97660
- else {return zim.animate(this, props, time, ease, call, params, wait, waitedCall, waitedParams, loop, loopCount, loopWait, loopCall, loopParams, loopWaitCall, loopWaitParams, loopPick, rewind, rewindWait, rewindCall, rewindParams, rewindWaitCall, rewindWaitParams, rewindTime, rewindEase, startCall, startParams, animateCall, animateParams, sequence, sequenceCall, sequenceParams, sequenceReverse, sequenceRatio, ticker, cjsProps, css, protect, override, from, set, id, events, sequenceTarget, dynamic, drag, clamp, startPaused, clean, obj, seriesWait, sequenceWait, rate, pauseOnBlur, easeAmount, easeFrequency, timeUnit, timeCheck, noAnimateCall, pathDamp, rewindPick);}
98364
+ else {return zim.animate(this, props, time, ease, call, params, wait, waitedCall, waitedParams, loop, loopCount, loopWait, loopCall, loopParams, loopWaitCall, loopWaitParams, loopPick, rewind, rewindWait, rewindCall, rewindParams, rewindWaitCall, rewindWaitParams, rewindTime, rewindEase, rewindPick, startCall, startParams, animateCall, animateParams, sequence, sequenceCall, sequenceParams, sequenceReverse, sequenceRatio, ticker, cjsProps, css, protect, override, from, set, id, events, sequenceTarget, dynamic, drag, clamp, startPaused, clean, obj, seriesWait, sequenceWait, rate, pauseOnBlur, easeAmount, easeFrequency, timeUnit, timeCheck, noAnimateCall, pathDamp);}
97661
98365
  },
97662
98366
  pauseAnimate:function(){return this;},
97663
98367
  stopAnimate:function(){return this;},
@@ -98232,7 +98936,6 @@ zim.setBlurDetect = function() {
98232
98936
  obj = zim.pauseOnBlur[i];
98233
98937
  obj.pauseOnBlurPaused = obj.paused;
98234
98938
  obj.pause(true);
98235
- zogr(obj.type, obj.special, obj.pauseOnBlurPaused)
98236
98939
  }
98237
98940
  }
98238
98941
  if (zim.pauseAnimateOnBlur && zim.animatedObjects) {
@@ -98776,7 +99479,7 @@ getLatestVersions(function(versions) {
98776
99479
  });
98777
99480
  END EXAMPLE
98778
99481
  --*///+82.1
98779
- zim.VERSION = "019/zim";
99482
+ zim.VERSION = "020/zim";
98780
99483
  //-82.1
98781
99484
 
98782
99485
  /*--
@@ -101793,7 +102496,7 @@ SEE: https://zimjs.com/018/handtrack.html - replacing the cursor
101793
102496
  GENERAL ML5 FUNCTIONALITY
101794
102497
  ML5 can give very accurate hand poses, face poses and body poses and results return points.
101795
102498
  These points can be used to place ZIM objects or with a ZIM Shape to make circles, etc.
101796
- There are other features too like shape recognition, blurring backgrounds, etc.
102499
+ There are other features too like shape recognition, segmentation, blurring backgrounds, etc.
101797
102500
  These can all be used in ZIM - for using ML5 for interaction see the HAND TRACKING section above.
101798
102501
  SEE: https://zimjs.com/ml5/ - general ML5 integration examples
101799
102502
 
@@ -103119,6 +103822,1191 @@ https://codepen.io/zimjs/pen/ZqNYxX
103119
103822
 
103120
103823
  //-151
103121
103824
 
103825
+
103826
+ //////////////// ZIM CHART //////////////
103827
+
103828
+ // Zim Chart adds graph and chart classes and functions
103829
+
103830
+ /*--
103831
+ zim.bestFit = function (dataH, dataV)
103832
+
103833
+ bestFit
103834
+ function
103835
+
103836
+ DESCRIPTION
103837
+ Calculates a linear least-squares fit through the provided horizontal and vertical value arrays.
103838
+ Returns the slope and intercept for the best-fit line y = slope * x + intercept.
103839
+ Used internally by PlotGraph
103840
+
103841
+ EXAMPLE
103842
+ const fit = bestFit([0,50,100], [0,40,90]);
103843
+ END EXAMPLE
103844
+
103845
+ PARAMETERS
103846
+ dataH - (required) array of horizontal x values
103847
+ dataV - (required) array of vertical y values
103848
+
103849
+ RETURNS
103850
+ Object with slope and intercept properties
103851
+
103852
+ --*///+160
103853
+
103854
+ // THE CODE FOR THE CHART MODULE IS LINKED TO AT THE TOP OF THE DOCS
103855
+
103856
+ //-160
103857
+
103858
+ /*--
103859
+ 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)
103860
+
103861
+ Graph
103862
+ zim class - extends a zim.Container which extends a createjs.Container
103863
+
103864
+ DESCRIPTION
103865
+ Creates a basic chart (no data) with horizontal and vertical axes, optional title, footer, and axis labels.
103866
+ The graph can use arrays of values or a {start, end, step} object for dataH and dataV.
103867
+ Graph is used by other graphs like BarGraph, LineGraph, PlotGraph to create the axis.
103868
+ Then these other graphs draw the data.
103869
+
103870
+ EXAMPLE
103871
+ const graph = new Graph(500, 400, "Sales", "Month", "Revenue", [1,2,3,4], [100,150,200,250], "Q1")
103872
+ .center();
103873
+ END EXAMPLE
103874
+
103875
+ PARAMETERS
103876
+ ** supports DUO - parameters or single object with properties below
103877
+ ** supports OCT - parameter defaults can be set with STYLE control (like CSS)
103878
+ width - (default 500) width of the chart
103879
+ height - (default 500) height of the chart
103880
+ title - (default null) text or Label for the title
103881
+ labelH - (default null) text or Label for the horizontal axis label
103882
+ labelV - (default null) text or Label for the vertical axis label
103883
+ dataH - (default null) array of horizontal values or {start,end,step} for tick values
103884
+ dataV - (default null) array of vertical values or {start,end,step} for tick values
103885
+ footer - (default null) text or Label for the footer
103886
+ backgroundColor - (default white) background fill color
103887
+ color - (default dark) color for labels and axis lines
103888
+ font - (default null) font for labels
103889
+ size - (default 14) font size for title and labels
103890
+ dataColor - (default grey) color for axis data labels
103891
+ dataSize - (default 10) size for data labels
103892
+ padding - (default 20) padding around the chart content
103893
+ gridThickness - (default 1) thickness of the grid lines
103894
+ gridColor - (default light) color of the grid lines
103895
+ axisThickness - (default 1) thickness of the axis lines
103896
+ axisColor - (default dark) color of the axis lines
103897
+ decimalsH - (default 1) decimal precision for horizontal labels
103898
+ decimalsV - (default 1) decimal precision for vertical labels
103899
+ style - (default true) set to false to ignore STYLE defaults
103900
+ group - (default null) group name(s) for STYLE
103901
+ inherit - (default null) direct style object or inherit instruction
103902
+
103903
+ METHODS
103904
+ offsetH(offset) - update horizontal axis labels by offset
103905
+ offsetV(offset) - update vertical axis labels by offset
103906
+ clone() - copies the graph
103907
+
103908
+ ALSO: ZIM adds all the methods listed under Container, such as:
103909
+ drag(), hitTestRect(), animate(), sca(), reg(), mov(), center(), centerReg(),
103910
+ addTo(), removeFrom(), loop(), outline(), place(), pos(), alp(), rot(), setMask(), etc.
103911
+ ALSO: see the CreateJS Easel Docs for Container methods, such as:
103912
+ on(), off(), getBounds(), setBounds(), uncache(), updateCache(), dispatchEvent(),
103913
+ addChild(), removeChild(), addChildAt(), getChildAt(), contains(), removeAllChildren(), etc.
103914
+
103915
+ PROPERTIES
103916
+ type - holds the class name as a String
103917
+ axisH - the horizontal axis line
103918
+ axisV - the vertical axis line
103919
+ linesH - container for horizontal grid lines
103920
+ linesV - container for vertical grid lines
103921
+ labelsH - container for horizontal labels
103922
+ labelsV - container for vertical labels
103923
+ backgroundColor - the background fill color
103924
+ firstDataH - first horizontal data value
103925
+ lastDataH - last horizontal data value
103926
+ firstDataV - first vertical data value
103927
+ lastDataV - last vertical data value
103928
+ --*///+161
103929
+
103930
+ // THE CODE FOR THE CHART MODULE IS LINKED TO AT THE TOP OF THE DOCS
103931
+
103932
+ //-161
103933
+
103934
+ /*--
103935
+ zim.Legend = function(graph, data, colors, gradients, swatchSize, color, font, size, spacingH, spacingV, backdropColor, backdropPadding, backdropPaddingH, backdropPaddingV, style, group, inherit)
103936
+
103937
+ Legend
103938
+ zim class - extends a zim.Tile which extends a zim.Container
103939
+
103940
+ DESCRIPTION
103941
+ Creates a legend for chart series using swatches or icons and labels.
103942
+ If data is omitted and a graph is supplied, the legend uses the graph's info or data.
103943
+
103944
+ EXAMPLE
103945
+ new Legend(graph).pos(50,50,RIGHT,BOTTOM);
103946
+ END EXAMPLE
103947
+
103948
+ EXAMPLE
103949
+ const graph = new LineGraph({
103950
+ title: "Graph",
103951
+ info: {
103952
+ labelH: "Time",
103953
+ labelV: "Height",
103954
+ dataH: {start: 0, end: 70, step: 10},
103955
+ dataV: {start: 20, end: 90, step: 10}
103956
+ },
103957
+ data: [
103958
+ {item: "Elliot", icon: null, dataH: [5, 10, 15, 20], dataV: [30, 45, 65, 85]},
103959
+ {item: "Madeline", icon: null, dataH: [5, 10, 15, 20], dataV: [30, 45, 55, 60]},
103960
+ {item: "RoseAnne", icon: null, dataH: [10, 20, 30, 40, 50], dataV: [30, 40, 50, 55, 55]},
103961
+ {item: "Dan", icon: null, dataH: [10, 20, 30, 40, 50, 60], dataV: [30, 45, 75, 80, 80, 80]},
103962
+ ]
103963
+ });
103964
+ STYLE = {infoicon: {size: 12, color: white}, onTop: false, collapse: true, titleBar: "Line Graph", draggable: true};
103965
+ const panel = new Panel(graph.width, graph.height + 30, graph).center();
103966
+
103967
+ const legend = new Legend(graph);
103968
+ STYLE = {infoicon: {size: 12, color: white}, collapse: true, titleBar: "Legend", draggable: true};
103969
+ new Panel(legend.width + 20, legend.height + 30, legend).pos(60, 50, RIGHT, BOTTOM);
103970
+ END EXAMPLE
103971
+
103972
+ PARAMETERS
103973
+ ** supports DUO - parameters or single object with properties below
103974
+ ** supports OCT - parameter defaults can be set with STYLE control (like CSS)
103975
+ graph - (default null) chart instance to derive legend entries from
103976
+ data - (default null) array of labels or objects for legend entries
103977
+ colors - (default null) array of colors for legend swatches
103978
+ gradients - (default false) if true use gradient swatches
103979
+ swatchSize - (default 20) size of each legend swatch
103980
+ color - (default dark) text color for labels
103981
+ font - (default null) font for labels
103982
+ size - (default 16) font size for labels
103983
+ spacingH - (default 10) horizontal spacing between legend items
103984
+ spacingV - (default 10) vertical spacing between legend rows
103985
+ backdropColor - (default lighter) background color behind legend items
103986
+ backdropPadding - (default 20) padding inside the backdrop
103987
+ backdropPaddingH - (default 10) horizontal padding inside the backdrop
103988
+ backdropPaddingV - (default 20) vertical padding inside the backdrop
103989
+ style - (default true) set to false to ignore STYLE defaults
103990
+ group - (default null) group name(s) for STYLE
103991
+ inherit - (default null) direct style object or inherit instruction
103992
+
103993
+ METHODS
103994
+ clone() - copies the legend
103995
+
103996
+ PROPERTIES
103997
+ data - legend data array
103998
+ finalColors - computed colors used in the legend
103999
+ --*///+162
104000
+
104001
+ // THE CODE FOR THE CHART MODULE IS LINKED TO AT THE TOP OF THE DOCS
104002
+
104003
+ //-162
104004
+
104005
+ /*--
104006
+ 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)
104007
+
104008
+ LineGraph
104009
+ zim class - extends a zim.Graph which extends a zim.Container
104010
+
104011
+ DESCRIPTION
104012
+ Draws one or more series of line graphs on a shared axis system.
104013
+ Supports optional dot markers, smoothing, and fill gradients beneath the lines.
104014
+
104015
+ See: https://zimjs.com/020/linegraph.html
104016
+
104017
+ EXAMPLE
104018
+ new LineGraph(500, 400, "Performance").center();
104019
+ END EXAMPLE
104020
+
104021
+ EXAMPLE
104022
+ // must import zim_chart
104023
+ const graph = new LineGraph({
104024
+ title: "Graph",
104025
+ info: {
104026
+ labelH: "Time",
104027
+ labelV: "Height",
104028
+ dataH: {start: 0, end: 70, step: 10},
104029
+ dataV: {start: 20, end: 90, step: 10}
104030
+ },
104031
+ data: [
104032
+ {item: "Elliot", icon: null, dataH: [5, 10, 15, 20], dataV: [30, 45, 65, 85]},
104033
+ {item: "Madeline", icon: null, dataH: [5, 10, 15, 20], dataV: [30, 45, 55, 60]},
104034
+ {item: "RoseAnne", icon: null, dataH: [10, 20, 30, 40, 50], dataV: [30, 40, 50, 55, 55]},
104035
+ {item: "Dan", icon: null, dataH: [10, 20, 30, 40, 50, 60], dataV: [30, 45, 75, 80, 80, 80]},
104036
+ ],
104037
+ smooth: true,
104038
+ // showDots:true,
104039
+ // gradients:false
104040
+ });
104041
+ STYLE = {infoicon: {size: 12, color: white}, onTop: false, collapse: true, titleBar: "Line Graph", draggable: true};
104042
+ const panel = new Panel(graph.width, graph.height + 30, graph).center();
104043
+
104044
+ const legend = new Legend(graph);
104045
+ STYLE = {infoicon: {size: 12, color: white}, collapse: true, titleBar: "Legend", draggable: true};
104046
+ new Panel(legend.width + 20, legend.height + 30, legend).pos(60, 50, RIGHT, BOTTOM);
104047
+ END EXAMPLE
104048
+
104049
+ PARAMETERS
104050
+ ** supports DUO - parameters or single object with properties below
104051
+ ** supports OCT - parameter defaults can be set with STYLE control (like CSS)
104052
+ width - (default 500) width of the chart
104053
+ height - (default 500) height of the chart
104054
+ title - (default null) title text or Label
104055
+ info - (default null) object with labelH, labelV, dataH, dataV for axis definition
104056
+ data - (default null) array of objects with the following properties {item,icon,dataH,dataV}
104057
+ icon is optional
104058
+ showDots - (default !smooth) draw dots at each data point when true
104059
+ smooth - (default false) smooth the connecting lines using quadratic curves
104060
+ colors - (default series colors) array of line colors
104061
+ thickness - (default 2) line thickness
104062
+ gradients - (default true) if true draw gradient fills behind lines
104063
+ footer - (default null) footer text or Label
104064
+ backgroundColor - (default white) background fill color
104065
+ color - (default dark) color for labels and axis lines
104066
+ font - (default null) font for labels
104067
+ size - (default 14) font size for title and labels
104068
+ dataColor - (default grey) color for axis data labels
104069
+ dataSize - (default 10) size for data labels
104070
+ padding - (default 20) padding around the chart content
104071
+ gridThickness - (default 1) thickness of the grid lines
104072
+ gridColor - (default light) color of the grid lines
104073
+ axisThickness - (default 1) thickness of the axis lines
104074
+ axisColor - (default dark) color of the axis lines
104075
+ decimalsH - (default 1) decimal precision for horizontal labels
104076
+ decimalsV - (default 1) decimal precision for vertical labels
104077
+ style - (default true) set to false to ignore STYLE defaults
104078
+ group - (default null) group name(s) for STYLE
104079
+ inherit - (default null) direct style object or inherit instruction
104080
+
104081
+ METHODS
104082
+ clone() - copies the line graph
104083
+
104084
+ PROPERTIES
104085
+ info - axis definition object
104086
+ data - series data array
104087
+ finalColors - colors used for series lines
104088
+ gradients - whether gradients are enabled
104089
+ --*///+163
104090
+
104091
+ // THE CODE FOR THE CHART MODULE IS LINKED TO AT THE TOP OF THE DOCS
104092
+
104093
+ //-163
104094
+
104095
+ /*--
104096
+ 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)
104097
+
104098
+ BarGraph
104099
+ zim class - extends a zim.Graph which extends a zim.Container
104100
+
104101
+ DESCRIPTION
104102
+ Draws grouped bar charts on a shared axis system.
104103
+ Supports multiple series, optional gradients, and custom spacing between groups and bars.
104104
+
104105
+ See: https://zimjs.com/020/bargraph.html
104106
+
104107
+ EXAMPLE
104108
+ // must import zim_chart
104109
+ new BarGraph(500, 400, "Sales").center();
104110
+ END EXAMPLE
104111
+
104112
+ EXAMPLE
104113
+ // must import zim_chart
104114
+ const graph = new zim.BarGraph({
104115
+ title:"Sales of Vegetables",
104116
+ width: 700,
104117
+ // comment these out to see with light background
104118
+ backgroundColor: black,
104119
+ axisColor: light,
104120
+ gridColor: grey,
104121
+ color: lighter,
104122
+ dataColor: silver,
104123
+ // end of comment for light background
104124
+ info: {
104125
+ labelH: "Days",
104126
+ labelV: "Sales",
104127
+ dataH: {start: 1, end: 7, step: 1},
104128
+ dataV: {start: 0, end: 100, step: 10}
104129
+ },
104130
+ colors: series(purple, yellow, blue),
104131
+ data: [
104132
+ {item: "Cucumber", icon: null, dataH: [2, 3, 4, 5, 6], dataV: [10, 40, 50, 60, 20]},
104133
+ {item: "Lettuce", icon: null, dataH: [2, 3, 4, 5, 6], dataV: [70, 50, 20, 20, 40]},
104134
+ {item: "Cilantro", icon: null, dataH: [2, 3, 4, 5, 6], dataV: [20, 50, 80, 90, 50]},
104135
+ ],
104136
+ // gradients:false
104137
+ });
104138
+
104139
+ // optionally put graph in Panel
104140
+ STYLE = {infoicon: {size: 12, color: white}, onTop: false, collapse: true, titleBar: "Bar Graph", draggable: true};
104141
+ new Panel(graph.width, graph.height + 30, graph).center();
104142
+
104143
+ // optionally put legend in Panel
104144
+ const legend = new zim.Legend(graph);
104145
+ STYLE = {infoicon: {size: 12, color: white}, collapse: true, titleBar: "Legend", draggable: true};
104146
+ new Panel(legend.width + 20, legend.height + 30, legend).pos(60, 50, RIGHT, BOTTOM);
104147
+ STYLE = {}
104148
+ END EXAMPLE
104149
+
104150
+ PARAMETERS
104151
+ ** supports DUO - parameters or single object with properties below
104152
+ ** supports OCT - parameter defaults can be set with STYLE control (like CSS)
104153
+ width - (default null) width of the graph
104154
+ height - (default null) height of the graph
104155
+ title - (default null) title text or Label
104156
+ info - (default null) object with labelH, labelV, dataH, dataV for axis definition
104157
+ data - (default null) array of series objects {item,dataH,dataV}
104158
+ gap - (default 25) gap between series clusters
104159
+ spacing - (default 3) spacing between bars inside each cluster
104160
+ colors - (default series colors) array of bar colors
104161
+ thickness - (default 1) stroke thickness for bar outlines
104162
+ gradients - (default true) if true draw gradient fills for bars
104163
+ footer - (default null) footer text or Label
104164
+ backgroundColor - (default white) background fill color
104165
+ color - (default dark) color for labels and axis lines
104166
+ font - (default null) font for labels
104167
+ size - (default 14) font size for title and labels
104168
+ dataColor - (default grey) color for axis data labels
104169
+ dataSize - (default 10) size for data labels
104170
+ padding - (default 20) padding around the chart content
104171
+ gridThickness - (default 1) thickness of the grid lines
104172
+ gridColor - (default light) color of the grid lines
104173
+ axisThickness - (default 1) thickness of the axis lines
104174
+ axisColor - (default dark) color of the axis lines
104175
+ decimalsH - (default 1) decimal precision for horizontal labels
104176
+ decimalsV - (default 1) decimal precision for vertical labels
104177
+ style - (default true) set to false to ignore STYLE defaults
104178
+ group - (default null) group name(s) for STYLE
104179
+ inherit - (default null) direct style object or inherit instruction
104180
+
104181
+ METHODS
104182
+ clone() - copies the bar graph
104183
+
104184
+ PROPERTIES
104185
+ info - axis definition object
104186
+ data - series data array
104187
+ finalColors - colors used for bar series
104188
+ --*///+164
104189
+
104190
+ // THE CODE FOR THE CHART MODULE IS LINKED TO AT THE TOP OF THE DOCS
104191
+
104192
+ //-164
104193
+
104194
+ /*--
104195
+ 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)
104196
+
104197
+ PlotGraph
104198
+ zim class - extends a zim.Graph which extends a zim.Container
104199
+
104200
+ DESCRIPTION
104201
+ Draws best-fit lines for one or more series of plotted data points on a graph.
104202
+ Each series can provide horizontal and vertical values for regression plotting.
104203
+
104204
+ See: https://zimjs.com/020/plotgraph.html
104205
+
104206
+ EXAMPLE
104207
+ // must import zim_chart
104208
+ new PlotGraph(500, 400, "Trend").center();
104209
+ END EXAMPLE
104210
+
104211
+ EXAMPLE
104212
+ // must import zim_chart
104213
+ const graph = new PlotGraph({
104214
+ title: "Plot of Population over Time",
104215
+ info: {
104216
+ labelH: "Year",
104217
+ labelV: "People (Millions)",
104218
+ dataH: {start: 1991, end: 2031, step: 5},
104219
+ dataV: {start: 20, end: 80, step: 5}
104220
+ },
104221
+ data: [
104222
+ // {item:"Canada", icon:null, dataH:[1996, 2001, 2006, 2011, 2016, 2021, 2026], dataV:[30, 31, 33, 34, 36, 38, 40]},
104223
+ {item: "Italy", icon: null, dataH: [1996, 2001, 2006, 2011, 2016, 2021, 2026], dataV: [57, 57, 58, 59, 60, 59, 59]},
104224
+ {item: "France", icon: null, dataH: [1996, 2001, 2006, 2011, 2016, 2021, 2026], dataV: [60, 62, 64, 65, 66, 67, 67]},
104225
+ ],
104226
+ backgroundColor: clear,
104227
+ footer: "Historical data compiled from demographic records on Worldometer"
104228
+
104229
+ });
104230
+ STYLE = {infoicon: {size: 12, color: white}, onTop: false, collapse: true, titleBar: "Plot Graph", draggable: true};
104231
+ const panel = new Panel({width: graph.width, height: graph.height + 30, content: graph, corner: 10, backgroundColor: white}).center();
104232
+
104233
+ const legend = new Legend(graph);
104234
+ STYLE = {infoicon: {size: 12, color: white}, collapse: true, titleBar: "Legend", draggable: true};
104235
+ new Panel(legend.width + 20, legend.height + 30, legend).pos(60, 50, RIGHT, BOTTOM);
104236
+ STYLE = {}
104237
+ END EXAMPLE
104238
+
104239
+ PARAMETERS
104240
+ ** supports DUO - parameters or single object with properties below
104241
+ ** supports OCT - parameter defaults can be set with STYLE control (like CSS)
104242
+ width - (default null) width of the graph
104243
+ height - (default null) height of the graph
104244
+ title - (default null) title text or Label
104245
+ info - (default null) object with labelH, labelV, dataH, dataV for axis definition
104246
+ data - (default null) array of series objects {item,dataH,dataV}
104247
+ extrapolate - (default false) if true extend the best-fit lines to the graph edges
104248
+ colors - (default series colors) array of line colors
104249
+ thickness - (default 2) line thickness
104250
+ footer - (default null) footer text or Label
104251
+ backgroundColor - (default white) background fill color
104252
+ color - (default dark) color for labels and axis lines
104253
+ font - (default null) font for labels
104254
+ size - (default 14) font size for title and labels
104255
+ dataColor - (default grey) color for axis data labels
104256
+ dataSize - (default 10) size for data labels
104257
+ padding - (default 20) padding around the chart content
104258
+ gridThickness - (default 1) thickness of the grid lines
104259
+ gridColor - (default light) color of the grid lines
104260
+ axisThickness - (default 1) thickness of the axis lines
104261
+ axisColor - (default dark) color of the axis lines
104262
+ decimalsH - (default 1) decimal precision for horizontal labels
104263
+ decimalsV - (default 1) decimal precision for vertical labels
104264
+ style - (default true) set to false to ignore STYLE defaults
104265
+ group - (default null) group name(s) for STYLE
104266
+ inherit - (default null) direct style object or inherit instruction
104267
+
104268
+ METHODS
104269
+ clone() - copies the plot graph
104270
+
104271
+ PROPERTIES
104272
+ info - axis definition object
104273
+ data - series data array
104274
+ finalColors - colors used for series lines
104275
+ --*///+165
104276
+
104277
+ // THE CODE FOR THE CHART MODULE IS LINKED TO AT THE TOP OF THE DOCS
104278
+
104279
+ //-165
104280
+
104281
+ /*--
104282
+ 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)
104283
+
104284
+ PieChart
104285
+ zim class - extends a zim.Container which extends a createjs.Container
104286
+
104287
+ DESCRIPTION
104288
+ Creates a pie chart visualization with optional data and title labels and icons.
104289
+ Displays data as pie wedges with interactive features including hover and click detection.
104290
+ Supports wedge lifting, customizable styling, and legend display.
104291
+
104292
+ See: https://zimjs.com/020/piechart.html
104293
+
104294
+ EXAMPLE
104295
+ // must import zim_chart
104296
+ new zim.PieChart(400, 400, [{name:"A", backgroundColor:red}, {name:"B", backgroundColor:blue}], [50, 150])
104297
+ .center();
104298
+ END EXAMPLE
104299
+
104300
+ EXAMPLE
104301
+ // must import zim_chart
104302
+ // interactive Pie Chart with icons
104303
+ STYLE = {backdrop:{corner:10, shadow:true}, chartBacking:{corner:10, shadow:true}}
104304
+
104305
+ var graph = new zim.PieChart({
104306
+ backgroundColor:dark,
104307
+ color:light,
104308
+ padding:30,
104309
+ width:500,
104310
+ info:[
104311
+ {name:"Maginifying Glass", icon:pizzazz.makeIcon("magnify", white), backgroundColor:blue.darken(.1), color:white},
104312
+ {name:"Hamburger Menu", icon:pizzazz.makeIcon("menu", white), backgroundColor:orange.darken(.1), color:white},
104313
+ {name:"Settings Gear", icon:pizzazz.makeIcon("settings", white), backgroundColor:green.darken(.1), color:white},
104314
+ {name:"Edit Pencil", icon:pizzazz.makeIcon("edit", white), backgroundColor:pink.darken(.1), color:white},
104315
+ ],
104316
+ data:[35,30,20,15],
104317
+ // units:"%",
104318
+ title:"Estimated Percentage Icon Usage",
104319
+ footer:"AI generated numbers",
104320
+ dataSize:20,
104321
+ iconOrient:false,
104322
+ iconFlip:true,
104323
+ showInfo:false,
104324
+ // showData:false,
104325
+ exchange:true,
104326
+ shiftForWedge:false
104327
+ }).center().cur();
104328
+
104329
+ new Legend({graph, color:white, backdropColor:grey}).loc(690, 554); //.place()
104330
+
104331
+ // ---------------------------
104332
+ // optional handle rollover
104333
+
104334
+ let lastIndex;
104335
+ graph.movement(function() {
104336
+ if (lastIndex != graph.rollIndex) {
104337
+ if (lastIndex!=null && !selections.isSelected(lastIndex)) graph.lowerWedge(lastIndex);
104338
+ graph.raiseWedge(graph.rollIndex,10);
104339
+ lastIndex = graph.rollIndex;
104340
+ S.update();
104341
+ }
104342
+ });
104343
+
104344
+ graph.on("mouseout", ()=>{
104345
+ if (!selections.isSelected(lastIndex)) graph.lowerWedge(lastIndex);
104346
+ lastIndex = null;
104347
+ S.update();
104348
+ });
104349
+
104350
+ // ---------------------------
104351
+ // optional handle select
104352
+
104353
+ const selections = new SelectionSet();
104354
+ graph.on("mousedown", ()=>{
104355
+ selections.toggle(graph.index, true);
104356
+ loop(graph.currentWedges, (wedge,i)=>{
104357
+ if (selections.isSelected(i)) graph.raiseWedge(i);
104358
+ else graph.lowerWedge(i);
104359
+ });
104360
+ S.update();
104361
+ });
104362
+ END EXAMPLE
104363
+
104364
+ PARAMETERS
104365
+ ** supports DUO - parameters or single object with properties below
104366
+ ** supports OCT - parameter defaults can be set with STYLE control (like CSS)
104367
+ width - (400) width in pixels
104368
+ height - (width) height in pixels (defaults to width)
104369
+ info - (null) ***** array of label objects with name and backgroundColor properties
104370
+ data - (null) ***** array of numbers representing pie slice values
104371
+ units - (null) ***** unit label appended to data values
104372
+ title - (null) title label or text displayed at top
104373
+ footer - (null) footer label or text displayed at bottom in italics
104374
+ backgroundColor - (white) background color
104375
+ color - (dark) text color
104376
+ size - (14) title/footer label font size
104377
+ dataSize - (size) font size for data labels
104378
+ font - (null) font family name
104379
+ spacing - (5) spacing between elements in pixels
104380
+ iconOrient - (true) ***** whether icon graphics are oriented to angle
104381
+ iconFlip - (true) ***** whether icons are flipped
104382
+ iconWidth - (null) ***** width of icon graphics if used
104383
+ iconScale - (null) ***** scale factor for icon graphics
104384
+ dec - (0) decimal places for displayed data values
104385
+ padding - (10) padding around chart edges
104386
+ showData - (true) whether to display data values
104387
+ showInfo - (true) whether to display info labels
104388
+ exchange - (false) ***** whether to exchange display positions of data and info
104389
+ shiftForWedge - (true) whether labels shift when wedge is raised
104390
+
104391
+ METHODS
104392
+ clone() - returns a clone of the PieChart
104393
+ getIndex(x, y) - returns the pie wedge index at the given local coordinates
104394
+ raiseWedge(index, factor) - raises a wedge by the specified factor
104395
+ lowerWedge(index) - lowers the raised wedge(s) back to flat
104396
+ setChart(obj) - ***** redraws chart with new data or configuration
104397
+
104398
+ PROPERTIES
104399
+ index - the currently selected wedge index from mouse click
104400
+ rollIndex - the wedge index currently under the mouse
104401
+ angles - array of angle values for each wedge
104402
+ info - info labels array
104403
+ data - data values array
104404
+ title - title label
104405
+ footer - footer label
104406
+ backgroundColor - background color
104407
+ radius - calculated radius of the pie
104408
+
104409
+ --*///+166
104410
+
104411
+ // THE CODE FOR THE CHART MODULE IS LINKED TO AT THE TOP OF THE DOCS
104412
+
104413
+ //-166
104414
+
104415
+ /*--
104416
+ 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)
104417
+
104418
+ RadarGraph
104419
+ zim class - extends a zim.Container which extends a createjs.Container
104420
+
104421
+ DESCRIPTION
104422
+ Creates a radar chart (spider web chart) for comparing multiple data series across multiple axes.
104423
+ Displays data as colored polygons with grid circles, axis labels, and optional gradient fills.
104424
+ Supports multiple data series with customizable colors, dot markers, and numerical labels.
104425
+
104426
+ See: https://zimjs.com/020/radargraph.html
104427
+
104428
+ NOTE: as of ZIM 5.5.0 the zim namespace is no longer required (unless zns is set to true before running zim)
104429
+
104430
+ EXAMPLE
104431
+ // must import zim_chart
104432
+ let radar = new zim.RadarGraph([["Strength", "Speed", "Power"], ["Good", "Bad"], [[8,6,7], [5,9]]], 200, 10);
104433
+ radar.addTo(stage);
104434
+ END EXAMPLE
104435
+
104436
+ EXAMPLE
104437
+ // must import zim_chart
104438
+ // this data came from an export of data from ZIM Rank app https://zimjs.com/rank
104439
+ 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]');
104440
+ // data[0][0] = {icon:new Circle(10,red), name:"Sweet Chili Heat"};
104441
+
104442
+ const graph = new RadarGraph({
104443
+ data: data,
104444
+ circleColor: dark,
104445
+ backgroundColor: clear,
104446
+ gradients: true,
104447
+ title: "My Favourite Snacks",
104448
+ footer: "Data from ZIM Rank",
104449
+ dotRadius:10,
104450
+ dotColor:clear,
104451
+ dotBorderWidth:1,
104452
+ dotBorderColor:white,
104453
+ gradients:false
104454
+ }).center();
104455
+
104456
+ STYLE = {infoicon: {size: 12, color: white}, onTop: false, collapse: true, titleBar: "Radar Graph", draggable: true};
104457
+ const panel = new Panel({width: graph.width, height: graph.height + 30, draggable: false, backgroundColor: white, content: graph, corner: 10}).center();
104458
+
104459
+ const legend = new Legend(graph);
104460
+ STYLE = {infoicon: {size: 12, color: white}, collapse: true, titleBar: "Legend", draggable: true};
104461
+ new Panel(legend.width + 30, legend.height + 35, legend).pos(60, 50, RIGHT, BOTTOM);
104462
+ STYLE = {};
104463
+ END EXAMPLE
104464
+
104465
+ PARAMETERS
104466
+ ** supports DUO - parameters or single object with properties below
104467
+ ** supports OCT - parameter defaults can be set with STYLE control (like CSS)
104468
+ data - (default array) ***** 3D array [labels, seriesNames, dataPoints] where dataPoints[i] corresponds to seriesNames[i]
104469
+ radius - (200) radius of the radar chart in pixels
104470
+ num - (10) number of concentric circles
104471
+ title - (null) title label or text displayed at top
104472
+ footer - (null) footer label or text displayed at bottom
104473
+ backgroundColor - (white) background color
104474
+ color - (dark) text and axis color
104475
+ font - (null) font family name
104476
+ size - (20) font size for labels
104477
+ circleColor - (clear) fill color for concentric circles
104478
+ circleAlpha - (.05) transparency of circle fill
104479
+ circleBorderColor - (light) color of circle borders
104480
+ circleBorderWidth - (1) thickness of circle border lines
104481
+ circleBorderAlpha - (.2) transparency of circle borders
104482
+ circleLastBorderColor - (mist) color of outermost circle border
104483
+ lineThickness - (1) thickness of axis lines
104484
+ lineColor - (dark) color of axis lines
104485
+ shapeColor - (series) ***** array of colors for each data series polygon fill
104486
+ shapeAlpha - (.2) transparency of shape fills
104487
+ shapeLineThickness - (3) thickness of shape outline
104488
+ shapeLineColor - (series) ***** array of colors for shape outlines
104489
+ gradients - (true) whether to apply gradient fills to shapes
104490
+ dotRadius - (3) radius of dot markers at data points
104491
+ dotColor - (lineColor) color of dots
104492
+ dotBorderColor - (-1) border color of dots (-1 for no border)
104493
+ dotBorderWidth - (1) thickness of dot borders
104494
+ showDots - (true) whether to display dots at data points
104495
+ blendmode - (null) blend mode for rendering
104496
+ numbers - (true) whether to display circle numbers
104497
+ numbersAngle - (0) rotation angle for number labels
104498
+ numbersColor - (lineColor) color of circle numbers
104499
+ numbersSize - (12) font size for circle numbers
104500
+ numbersFactor - (1) ***** scaling factor for number values
104501
+ padding - (20) padding around chart
104502
+ labelMargin - (padding/4) additional margin for axis labels
104503
+
104504
+ METHODS
104505
+ clone() - returns a clone of the Radar chart
104506
+
104507
+ PROPERTIES
104508
+ type - "Radar"
104509
+
104510
+ --*///+167
104511
+
104512
+ // THE CODE FOR THE CHART MODULE IS LINKED TO AT THE TOP OF THE DOCS
104513
+
104514
+ //-167
104515
+
104516
+ /*--
104517
+ 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)
104518
+
104519
+ LiveGraph
104520
+ zim class - extends zim.Graph which extends a zim.Container which extends a createjs.Container
104521
+
104522
+ DESCRIPTION
104523
+ Creates a live/animated line graph that updates data over time using a WebWorker.
104524
+ Data is read in from a text file source specified in the src parameter.
104525
+ Displays multiple data series as lines with optional gradient fills and smooth curves.
104526
+ Automatically manages maxData limit, supports real-time data streaming and animation.
104527
+
104528
+ See: https://zimjs.com/020/livegraph.html
104529
+
104530
+ NOTE: as of ZIM 5.5.0 the zim namespace is no longer required (unless zns is set to true before running zim)
104531
+
104532
+ EXAMPLE
104533
+ // must import zim_chart
104534
+ let info = {labelH:["Time"], labelV:["Value"], dataH:[0,1,2,3], dataV:[0,10,20,15]};
104535
+ let liveGraph = new zim.LiveGraph(600, 400, "Live Data", info, null, null, 1);
104536
+ liveGraph.addTo(stage);
104537
+ END EXAMPLE
104538
+
104539
+ EXAMPLE
104540
+ // must import zim_chart
104541
+ const graph = new LiveGraph({
104542
+ // title:"Graph",
104543
+ width: 700,
104544
+ info: {
104545
+ labelH: "Time (s)",
104546
+ labelV: "Height",
104547
+ dataH: {start: -10, end: 0, step: 1},
104548
+ dataV: {start: 20, end: 90, step: 10}
104549
+ },
104550
+ data: [
104551
+ {item: "CPU", icon: null},
104552
+ {item: "Memory", icon: null},
104553
+ ],
104554
+ src: "url_to_live_data.txt", // with [12, 24] for instance changing over time
104555
+ timeStep: .5,
104556
+ smooth: true,
104557
+ thickness: 2,
104558
+ gradients: true,
104559
+ // animated:false,
104560
+ // fullGradients:true
104561
+ });
104562
+ STYLE = {infoicon: {size: 12, color: white}, onTop: false, collapse: true, titleBar: "Live Graph", draggable: true};
104563
+ const panel = new Panel(graph.width, graph.height + 30, graph).center().mov(0,-30);
104564
+
104565
+ const legend = new Legend(graph);
104566
+ STYLE = {infoicon: {size: 12, color: white}, collapse: true, titleBar: "Legend", draggable: true};
104567
+ new Panel(legend.width + 20, legend.height + 30, legend).pos(60, 50, RIGHT, BOTTOM);
104568
+
104569
+ STYLE = {};
104570
+ const pauseBut = new Button({label: "PAUSE", toggle: "PLAY"}).sca(.5).pos(0, 40, CENTER, BOTTOM);
104571
+ pauseBut.on("mousedown", () => {
104572
+ // const offset = graph.offset; // use to continue from paused time rather than back to live
104573
+ graph.paused = !pauseBut.toggled;
104574
+ // graph.offset = offset;
104575
+ });
104576
+ END EXAMPLE
104577
+
104578
+ PARAMETERS
104579
+ ** supports DUO - parameters or single object with properties below
104580
+ ** supports OCT - parameter defaults can be set with STYLE control (like CSS)
104581
+ width - (default null) width of the graph
104582
+ height - (default null) height of the graph
104583
+ title - (default null) title label or text displayed at top
104584
+ info - (default null) info object with labelH, labelV, dataH, dataV arrays
104585
+ data - (default null) array of data objects with dataH and dataV properties
104586
+ src - (default null) external data source URL for updates
104587
+ format [data] for one entry - this gets read over timeStep
104588
+ format [data, data, data] for three entries, etc. match number of items with data items
104589
+ timeStep - (default .5) time interval in seconds between data updates
104590
+ thickness - (default 2) line thickness in pixels
104591
+ smooth - (default true) whether to use smooth curves instead of straight lines
104592
+ footer - (default null) footer label or text displayed at bottom
104593
+ colors - (default series) array of colors for each data series
104594
+ gradients - (default true) whether to apply gradient fills under lines
104595
+ backgroundColor - (default white) background fill color
104596
+ color - (default dark) color for labels and axis lines
104597
+ font - (default null) font for labels
104598
+ size - (default 14) font size for title and labels
104599
+ dataColor - (default grey) color for axis data labels
104600
+ dataSize - (default 10) size for data labels
104601
+ padding - (default 20) padding around the chart content
104602
+ gridThickness - (default 1) thickness of the grid lines
104603
+ gridColor - (default light) color of the grid lines
104604
+ axisThickness - (default 1) thickness of the axis lines
104605
+ axisColor - (default dark) color of the axis lines
104606
+ decimalsH - (default 1) decimal precision for horizontal labels
104607
+ decimalsV - (default 1) decimal precision for vertical labels
104608
+ maxData - (1000) maximum number of data points to maintain before trimming
104609
+ fullGradients - (true) whether gradients extend full height or to min/max values
104610
+ animated - (true) whether to animate line movements
104611
+
104612
+ METHODS
104613
+ addData(data) - adds new data points and updates the graph
104614
+ pause() - pauses the live update
104615
+ resume() - resumes live update
104616
+ clone() - returns a clone of the LiveGraph
104617
+
104618
+ PROPERTIES
104619
+ type - "LiveGraph"
104620
+ info - the info object with axis configuration
104621
+ data - current data array
104622
+ gradients - gradient setting
104623
+ timeStep - current time step interval
104624
+ currentData - array of data maintained up to maxData limit
104625
+ animated - animation setting
104626
+ doDraw - whether to redraw on next update
104627
+
104628
+ --*///+168
104629
+
104630
+ // THE CODE FOR THE CHART MODULE IS LINKED TO AT THE TOP OF THE DOCS
104631
+
104632
+ //-168
104633
+
104634
+ /*--
104635
+ zim.GrowthChart = function(width, height, title, num, info, data, time, footer, backgroundColor, color, size, iconWidth, dec, spacing, padding, damp, footerAlign, favorRight, style, group, inherit)
104636
+
104637
+ GrowthChart
104638
+ zim class - extends a zim.Container which extends a createjs.Container
104639
+
104640
+ DESCRIPTION
104641
+ Creates a scrolling growth chart that cycles through data slices over time.
104642
+ Each slice is shown as a ranked bar chart with icon labels and value labels.
104643
+
104644
+ See: https://zimjs.com/020/growthchart.html
104645
+
104646
+ NOTE: as of ZIM 5.5.0 the zim namespace is no longer required (unless zns is set to true before running zim)
104647
+
104648
+ EXAMPLE
104649
+ // must import zim_chart
104650
+ const growthChart = new GrowthChart(400, 300, "Growth").center();
104651
+ new GrowthWidget(growthChart, "Growth", light, dark).loc(100,100);
104652
+ END EXAMPLE
104653
+
104654
+ PARAMETERS
104655
+ ** supports DUO - parameters or single object with properties below
104656
+ ** supports OCT - parameter defaults can be set with STYLE control (like CSS)
104657
+ width - (default 400) total width of the chart
104658
+ height - (default 300) total height of the chart
104659
+ title - (default null) title text or Label displayed at the top
104660
+ num - (default 10) number of items to show in each snapshot
104661
+ info - (default null) array of item metadata objects {icon,name,backgroundColor,color}
104662
+ data - (default null) array of arrays containing numeric values for each snapshot
104663
+ time - (default 0.5) time in seconds between automatic updates
104664
+ footer - (default null) footer text or Label displayed at the bottom
104665
+ backgroundColor - (default white) chart background fill
104666
+ color - (default dark) title and label color
104667
+ size - (default 14) base font size for item labels
104668
+ iconWidth - (default 50) width of the icon column
104669
+ dec - (default 0) decimal precision used for numeric labels
104670
+ spacing - (default 2) vertical spacing between bars
104671
+ padding - (default 10) outer padding inside the chart
104672
+ damp - (default 0.07) smoothing factor for animated bar width and position
104673
+ footerAlign - (default CENTER) alignment for the footer
104674
+ favorRight - (default false) set to true to start with data labels to right of bars
104675
+ and if they don't fit then move the data labels into the bars
104676
+ Keep set to false to start labels in bars and move to right if they don't fit
104677
+ style - (default true) set to false to ignore STYLE defaults
104678
+ group - (default null) group name(s) for STYLE
104679
+ inherit - (default null) direct style object or inherit instruction
104680
+
104681
+ METHODS
104682
+ restart() - restarts the automatic update cycle
104683
+ dispose() - clears timers and disposes the chart
104684
+ clone() - copies the chart
104685
+
104686
+ PROPERTIES
104687
+ graph - passed-in graph instance if provided
104688
+ data - current dataset array
104689
+ info - current item metadata array
104690
+ growth - array of growth values used for each snapshot
104691
+ finalColors - computed display colors for items
104692
+ --*///+169
104693
+
104694
+ // THE CODE FOR THE CHART MODULE IS LINKED TO AT THE TOP OF THE DOCS
104695
+
104696
+ //-169
104697
+
104698
+ /*--
104699
+ zim.GrowthWidget = function(graph, title, color, backgroundColor, font, size, padding, paddingInside, restart, corner, restartCorner, style, group, inherit)
104700
+
104701
+ GrowthWidget
104702
+ zim class - extends a zim.Container which extends a createjs.Container
104703
+
104704
+ DESCRIPTION
104705
+ Creates a small widget that displays the current growth amount from a GrowthChart instance.
104706
+ Includes an optional restart button to restart the GrowthChart animation.
104707
+
104708
+ See: https://zimjs.com/020/growthchart.html
104709
+
104710
+ NOTE: as of ZIM 5.5.0 the zim namespace is no longer required (unless zns is set to true before running zim)
104711
+
104712
+ EXAMPLE
104713
+ // must import zim_chart
104714
+ const growthChart = new GrowthChart(400, 300, "Growth").center();
104715
+ new GrowthWidget(growthChart, "Growth", light, dark).loc(100,100);
104716
+ END EXAMPLE
104717
+
104718
+ PARAMETERS
104719
+ ** supports DUO - parameters or single object with properties below
104720
+ ** supports OCT - parameter defaults can be set with STYLE control (like CSS)
104721
+ graph - (default null) GrowthChart instance to listen to
104722
+ title - (default "GROWTH") title text or Label shown in the widget
104723
+ color - (default light) text color for title and values
104724
+ backgroundColor - (default dark) background color for the widget tile
104725
+ font - (default null) font for text
104726
+ size - (default null) font size for text
104727
+ padding - (default 10) spacing between widget content and edge
104728
+ paddingInside - (default 10) padding inside the tile background
104729
+ restart - (default true) show a restart button when true
104730
+ corner - (default 10) corner radius for the tile background
104731
+ restartCorner - (default 0) corner radius for the restart button
104732
+ style - (default true) set to false to ignore STYLE defaults
104733
+ group - (default null) group name(s) for STYLE
104734
+ inherit - (default null) direct style object or inherit instruction
104735
+
104736
+ METHODS
104737
+ clone() - copies the widget
104738
+
104739
+ PROPERTIES
104740
+ graph - GrowthChart instance being tracked
104741
+ amount - label showing the current amount
104742
+ restart - restart button instance when enabled
104743
+ --*///+170
104744
+
104745
+ // THE CODE FOR THE CHART MODULE IS LINKED TO AT THE TOP OF THE DOCS
104746
+
104747
+ //-170
104748
+
104749
+ /*--
104750
+ zim.WordCloud = function(width, height, words, max, exclude, include, scaleFix, font, color, backgroundColor, spacing, verticalMix, uppercase, minSize, maxSize, threshold, style, group, inherit)
104751
+
104752
+ WordCloud
104753
+ zim class - extends a zim.Container which extends a createjs.Container
104754
+
104755
+ DESCRIPTION
104756
+ Creates a word cloud from text or a word-frequency array.
104757
+ Words are placed using a spiral algorithm and can be rotated vertically.
104758
+
104759
+ See: https://zimjs.com/020/wordcloud.html
104760
+
104761
+ EXAMPLE
104762
+ // must import zim_chart
104763
+ new WordCloud(800, 500, "hello world hello").center();
104764
+ END EXAMPLE
104765
+
104766
+ EXAMPLE
104767
+ // must import zim_chart
104768
+ // we can use WordCloud on raw text - but that takes extra processing
104769
+ // here are the steps to have WordCloud process and save a data list
104770
+
104771
+ // we copied the text from the ZIM Innovation page,
104772
+ // saved it as a long string `` in a const words and passed that into WordCloud
104773
+ // we ran the WordCloud and noticed words we did not want
104774
+ // so we manually created this exclude array:
104775
+ // const exclude = ["complex", "decade", "through", "last", "fully", "63", "allows", "set", "made", "friction", "other", "single", "zims", "still", "every"];
104776
+ // then we added this coding line
104777
+ // zog(JSON.stringify(cloud.prepareWordData(words, 50, 1, exclude)))
104778
+ // this we stored in this const words instead of the raw text
104779
+ // a shortened version is shown here
104780
+
104781
+ const words = [
104782
+ {"text": "Zim", "freq": 100},
104783
+ {"text": "Canvas", "freq": 44},
104784
+ // etc.,
104785
+ {"text": "Creating", "freq": 6}
104786
+ ];
104787
+
104788
+ // words, width, height, scaleFix, font, color, backgroundColor, spacing, verticalMix, uppercase, minSize, maxSize, style, group, inherit
104789
+ var cloud = new zim.WordCloud({
104790
+ width:700,
104791
+ words: words,
104792
+ // exclude:exclude,
104793
+ }).center();
104794
+
104795
+ // optionally animate the words in
104796
+ cloud.animate({
104797
+ props: {alpha: 0},
104798
+ from: true,
104799
+ time: .3,
104800
+ sequence: 0.02
104801
+ });
104802
+ END EXAMPLE
104803
+
104804
+ PARAMETERS
104805
+ ** supports DUO - parameters or single object with properties below
104806
+ ** supports OCT - parameter defaults can be set with STYLE control (like CSS)
104807
+ width - (default 800) width of the cloud area
104808
+ height - (default 500) height of the cloud area
104809
+ words - (default null) string or array of word objects to build the cloud
104810
+ max - (default 100) maximum number of words
104811
+ exclude - (default null) word or words to ignore
104812
+ include - (default null) word or words to force include
104813
+ scaleFix - (default 1 or 2 depending on width/height) internal scaling factor for smaller layouts
104814
+ font - (default null) font for word labels
104815
+ color - (default palette) color or array of colors for words
104816
+ backgroundColor - (default interstellar) background fill color
104817
+ spacing - (default 6) minimum spacing between placed words
104818
+ verticalMix - (default true) if true randomly rotate some words vertically
104819
+ uppercase - (default true) if true convert words to uppercase
104820
+ minSize - (default 10) minimum font size
104821
+ maxSize - (default 90) maximum font size
104822
+ threshold - (default 1) minimum word frequency to include
104823
+ style - (default true) set to false to ignore STYLE defaults
104824
+ group - (default null) group name(s) for STYLE
104825
+ inherit - (default null) direct style object or inherit instruction
104826
+
104827
+ METHODS
104828
+ prepareWordData(text, max, threshold, exclude, include) - prepares data from text
104829
+ max is the maximul number of words to add to the data
104830
+ threshold is the minimum occurances required to add the word to the data
104831
+ exclude is a word or an array of words to not include
104832
+ include is a word or an array of words to include
104833
+ Note - there are a number of words already excluded - see code
104834
+ clone() - copies the word cloud
104835
+
104836
+ PROPERTIES
104837
+ type - the class type as a string
104838
+ --*///+171
104839
+
104840
+ // THE CODE FOR THE CHART MODULE IS LINKED TO AT THE TOP OF THE DOCS
104841
+
104842
+ //-171
104843
+
104844
+ /*--
104845
+ 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)
104846
+
104847
+ Championship
104848
+ zim class - extends a zim.Container which extends a createjs.Container
104849
+
104850
+ DESCRIPTION
104851
+ Creates an elimination bracket chart for tournament-style data.
104852
+ Boxes are arranged in rounds and connected by bracket lines, with support for mirrored layouts.
104853
+
104854
+ EXAMPLE
104855
+ // must import zim_chart
104856
+ new Championship(500, "Tournament", 16).center();
104857
+ END EXAMPLE
104858
+
104859
+ EXAMPLE
104860
+ // must import zim_chart
104861
+ // This example is part way through an actual championship on facebook
104862
+ // Note how we darken colors where the matches are not active
104863
+ // We also provide a current challenge at the bottom
104864
+ // a custom pic is shown for the title area
104865
+ // and custom emojis are used for the challenge area
104866
+
104867
+ new Pic("logo_small.png").sca(.66).loc(589, 45); // .place()
104868
+
104869
+ STYLE = {champTitle:{size:20}}
104870
+ function getColor(color, active) {
104871
+ // if (active) return new GradientColor([color,color.lighten(.6),color], 60);
104872
+ // return new GradientColor([color.darken(.5),color,color.darken(.5)], 60);
104873
+ return color.darken(active?0:.2)
104874
+ }
104875
+ const colors = [];
104876
+ // loop(16, (i)=>{colors.push(getColor(yellow, i>1))}); // darkens
104877
+ // loop(8, (i)=>{colors.push(getColor(yellow, i<1))}); // lightens
104878
+
104879
+ loop(16, (i)=>{colors.push(getColor(yellow, false))}); // darkens
104880
+ loop(8, (i)=>{colors.push(getColor(yellow, i>=4))}); // lightens
104881
+ loop(4, (i)=>{colors.push(getColor(yellow, i<2))});
104882
+ loop(2, (i)=>{colors.push(getColor(yellow))});
104883
+ colors.push(colors.push(getColor(yellow)));
104884
+
104885
+ const graph = new Championship({
104886
+ width:W,
104887
+ num:16,
104888
+ dataSize:16,
104889
+ font:"RocknRoll+One",
104890
+ boxColor:series(colors),
104891
+ borderColor:"red".darken(.5),
104892
+ borderWidth:2,
104893
+ data:[[
104894
+ "CAPTCHAs",
104895
+ "MS Word",
104896
+ "FAQs",
104897
+ "2FA",
104898
+ "Setting Clocks",
104899
+ "Public Wi-Fi",
104900
+ "Adobe Acrobat",
104901
+ "Ticketmaster",
104902
+ "Voice Assistants",
104903
+ "Bluetooth Audio",
104904
+ "Mac Finder",
104905
+ "TV Remotes",
104906
+ "Instagram UI",
104907
+ "Bank Kiosks",
104908
+ "Smart Printers",
104909
+ "Meta B. Suite"
104910
+ ],
104911
+ ["MS Word", "2FA", "Setting Clocks","Ticketmaster","Voice Assistants","TV Remotes","Instagram UI", "Smart Printers"],
104912
+ ["2FA", "Ticketmaster"],
104913
+ [],
104914
+ ["Most Frustrating"]
104915
+ ],
104916
+ // borderWidth:0,
104917
+ curved:false,
104918
+ // color:red.lighten(.2),
104919
+ // corner:10,
104920
+ // backgroundColor:clear,
104921
+ lineColor:"red".darken(.5),
104922
+ lineThickness:2,
104923
+ // gap:null,
104924
+ // gapCount:4,
104925
+ lastFlip:true,
104926
+ // lastScale:2,
104927
+ align:CENTER,
104928
+ paddingV:8,
104929
+ spacingV:8,
104930
+ // boxColor:series(colors),
104931
+ title:"FRUSTRATING TECH",
104932
+
104933
+ }).addTo().mov(0,20)
104934
+
104935
+ graph.title.sca(1.6).pos(20,20,RIGHT,TOP)
104936
+
104937
+ // create the challenge - there is a default graph.challenge() but we customize...
104938
+ const round = 1;
104939
+ const index = 4;
104940
+ const footer = new Container(W,H).loc(0,-10).tap(()=>{
104941
+ zgo("https://facebook.com/danzen", "fb")
104942
+ }); // .place(); // place is used to position then check console for coords
104943
+ new Label("vote with icon", 30, "RocknRoll+One", lighter).loc(274, 847, footer); // .place();
104944
+ new Pic("icon_sad.png").sca(.4).reg(CENTER).loc(185, 865-10, footer).sha();
104945
+ new Pic("icon_angry.png").sca(.4).reg(CENTER).loc(582, 865-10, footer).sha();
104946
+ var challenge = graph.challenge(round, index, lighter, black).pos(0,30,CENTER,BOTTOM, footer);
104947
+ challenge.items[0].backing.sha(black.toAlpha(.2), 0, 8, 15); // adding shadow to all adds it to text too
104948
+ challenge.items[2].backing.sha(black.toAlpha(.2), 0, 8, 15);
104949
+ challenge.items[0].mov(-20);
104950
+ challenge.items[1].rot(0);
104951
+ challenge.items[2].mov(20);
104952
+ END EXAMPLE
104953
+
104954
+ PARAMETERS
104955
+ ** supports DUO - parameters or single object with properties below
104956
+ ** supports OCT - parameter defaults can be set with STYLE control (like CSS)
104957
+ width - (default 500) total width of the championship chart
104958
+ title - (default null) title text or Label shown at the top
104959
+ num - (default 16) number of competitors or slots (rounded to the next power of two)
104960
+ data - (default [[]]) nested array of competitor values or labels for each round
104961
+ textLines - (default 1) number of sample lines used to size label boxes when no data sample exists
104962
+ curved - (default spacingH/2) curve radius for bracket lines, or true to enable default curvature
104963
+ shiftFactor - (default 0) horizontal shift amount per round for layout variation
104964
+ mirror - (default null) if true reverse shift direction for the lower half of the bracket
104965
+ lastFlip - (default false) if true flip the last round's champion box horizontally
104966
+ lastCenter - (default true) if true center the final box between its feeders
104967
+ lastScale - (default 2) scale applied to the final champion box
104968
+ footer - (default null) footer text or Label shown at the bottom
104969
+ backgroundColor - (default lighter) chart background fill color
104970
+ color - (default dark) title and default text color
104971
+ font - (default null) font for competitor labels
104972
+ size - (default 12) font size for text labels
104973
+ align - (default left) alignment for box content
104974
+ boxColor - (default white) fill color for competitor boxes
104975
+ corner - (default 0) corner radius for competitor boxes
104976
+ borderColor - (default color) border stroke color for boxes
104977
+ borderWidth - (default 1) border stroke width for boxes
104978
+ dataColor - (default darker) color for values or sublabels inside boxes
104979
+ dataSize - (default 14) font size for box content
104980
+ padding - (default 20) outer padding around the chart
104981
+ spacingH - (default 20) horizontal spacing between rounds
104982
+ spacingV - (default 5) vertical spacing between boxes
104983
+ gapCount - (default 4) number of boxes between extra vertical gaps
104984
+ gap - (default spacingV * 2) extra vertical gap size after gapCount boxes
104985
+ paddingH - (default 3) horizontal padding inside boxes
104986
+ paddingV - (default 5) vertical padding inside boxes
104987
+ lineColor - (default dark) color of bracket connecting lines
104988
+ lineThickness - (default 1) thickness of bracket connecting lines
104989
+ style - (default true) set to false to ignore STYLE defaults
104990
+ group - (default null) group name(s) for STYLE
104991
+ inherit - (default null) direct style object or inherit instruction
104992
+
104993
+ METHODS
104994
+ updateData(data, merge) - updates competitor data values or labels
104995
+ if merge is true will keep previous data and replace with merged data (positional)
104996
+ challenge(round, index, bColor, fColor, obj1, obj2, extra1, extra2) - returns a battle tile for the specified match
104997
+ can overrid objects and add extras
104998
+ clone() - copies the championship chart
104999
+
105000
+ PROPERTIES
105001
+ data - data array
105002
+ rounds - containers for each round of boxes
105003
+ backgroundColor - chart background fill
105004
+ --*///+172
105005
+
105006
+ // THE CODE FOR THE CHART MODULE IS LINKED TO AT THE TOP OF THE DOCS
105007
+
105008
+ //-172
105009
+
103122
105010
  return zim;
103123
105011
  } (zim || {});
103124
105012
 
@@ -103490,6 +105378,7 @@ export let Wrapper = zim.Wrapper;
103490
105378
  export let Tile = zim.Tile;
103491
105379
  export let Pack = zim.Pack;
103492
105380
  export let Beads = zim.Beads;
105381
+ export let Bullets = zim.Bullets;
103493
105382
  export let Layout = zim.Layout;
103494
105383
  export let Accessibility = zim.Accessibility;
103495
105384
  export let TextureActive = zim.TextureActive;