zimjs 20.0.3 → 20.0.4
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/package.json +1 -1
- package/src/zim.js +1250 -438
- package/ts-src/typings/zim/index.d.ts +35 -0
package/src/zim.js
CHANGED
|
@@ -2747,41 +2747,99 @@ color1 - |ZIM VEE| (default null) the first color as an HTML string or hex color
|
|
|
2747
2747
|
color2 - |ZIM VEE| (default black) the second color as an HTML string or hex color (case insensitive)
|
|
2748
2748
|
ratio - (default .5) the ratio where 0 is the first color and 1 the second color
|
|
2749
2749
|
|
|
2750
|
-
RETURNS a hex color string
|
|
2750
|
+
RETURNS a hex color string or rgba if alpha is not 1
|
|
2751
2751
|
--*///+27.6
|
|
2752
|
-
zim.colorRange = function(
|
|
2752
|
+
zim.colorRange = function(c1, c2, ratio) {
|
|
2753
2753
|
if (!zim.colorRangeCheck) {z_d("27.6"); zim.colorRangeCheck=true;}
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2754
|
+
if (zot(c1)) c1 = "white";
|
|
2755
|
+
if (zot(c2)) c2 = "black";
|
|
2756
|
+
c1 = zik(c1);
|
|
2757
|
+
c2 = zik(c2);
|
|
2758
|
+
if (ratio == null) ratio = 0.5;
|
|
2758
2759
|
ratio = Math.max(0, Math.min(1, ratio));
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2760
|
+
|
|
2761
|
+
function parseColor(c) {
|
|
2762
|
+
if (!c) return [0, 0, 0, 1];
|
|
2763
|
+
if (typeof c !== "string") c = String(c);
|
|
2764
|
+
c = c.trim();
|
|
2765
|
+
|
|
2766
|
+
// 1. Match rgba(r, g, b, a) or rgb(r, g, b)
|
|
2767
|
+
var rgbaMatch = c.match(/rgba?\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)(?:\s*,\s*([\d.]+))?\s*\)/i);
|
|
2768
|
+
if (rgbaMatch) {
|
|
2769
|
+
return [
|
|
2770
|
+
parseFloat(rgbaMatch[1]),
|
|
2771
|
+
parseFloat(rgbaMatch[2]),
|
|
2772
|
+
parseFloat(rgbaMatch[3]),
|
|
2773
|
+
rgbaMatch[4] != null ? parseFloat(rgbaMatch[4]) : 1
|
|
2774
|
+
];
|
|
2775
|
+
}
|
|
2776
|
+
|
|
2777
|
+
// 2. Special ZIM / CSS keywords with built-in alpha
|
|
2778
|
+
if (c === "clear" || c === "transparent") return [0, 0, 0, 0];
|
|
2779
|
+
if (c === "faint") return [0, 0, 0, 0.05];
|
|
2780
|
+
|
|
2781
|
+
// 3. Hex formats (#rgb, #rgba, #rrggbb, #rrggbbaa)
|
|
2782
|
+
if (c.charAt(0) === "#") {
|
|
2783
|
+
var hex = c.slice(1);
|
|
2784
|
+
if (hex.length === 3) {
|
|
2785
|
+
return [
|
|
2786
|
+
parseInt(hex[0] + hex[0], 16),
|
|
2787
|
+
parseInt(hex[1] + hex[1], 16),
|
|
2788
|
+
parseInt(hex[2] + hex[2], 16),
|
|
2789
|
+
1
|
|
2790
|
+
];
|
|
2791
|
+
} else if (hex.length === 4) {
|
|
2792
|
+
return [
|
|
2793
|
+
parseInt(hex[0] + hex[0], 16),
|
|
2794
|
+
parseInt(hex[1] + hex[1], 16),
|
|
2795
|
+
parseInt(hex[2] + hex[2], 16),
|
|
2796
|
+
parseInt(hex[3] + hex[3], 16) / 255
|
|
2797
|
+
];
|
|
2798
|
+
} else if (hex.length === 6) {
|
|
2799
|
+
return [
|
|
2800
|
+
parseInt(hex.substr(0, 2), 16),
|
|
2801
|
+
parseInt(hex.substr(2, 2), 16),
|
|
2802
|
+
parseInt(hex.substr(4, 2), 16),
|
|
2803
|
+
1
|
|
2804
|
+
];
|
|
2805
|
+
} else if (hex.length === 8) {
|
|
2806
|
+
return [
|
|
2807
|
+
parseInt(hex.substr(0, 2), 16),
|
|
2808
|
+
parseInt(hex.substr(2, 2), 16),
|
|
2809
|
+
parseInt(hex.substr(4, 2), 16),
|
|
2810
|
+
parseInt(hex.substr(6, 2), 16) / 255
|
|
2811
|
+
];
|
|
2812
|
+
}
|
|
2813
|
+
}
|
|
2814
|
+
|
|
2815
|
+
// 4. Fallback for named CSS colors via temporary canvas context or lookup
|
|
2816
|
+
// If zim.color / zim.toColor is available, resolve it first
|
|
2817
|
+
if (zim.toColor && c in zim) c = zim[c];
|
|
2818
|
+
|
|
2819
|
+
// Simple 3-byte fallback if hex number without hash
|
|
2820
|
+
var num = parseInt(c, 16);
|
|
2821
|
+
if (!isNaN(num) && c.length === 6) {
|
|
2822
|
+
return [(num >> 16) & 255, (num >> 8) & 255, num & 255, 1];
|
|
2782
2823
|
}
|
|
2824
|
+
|
|
2825
|
+
return [0, 0, 0, 1];
|
|
2826
|
+
}
|
|
2827
|
+
|
|
2828
|
+
var col1 = parseColor(c1);
|
|
2829
|
+
var col2 = parseColor(c2);
|
|
2830
|
+
|
|
2831
|
+
var r = Math.round(col1[0] + (col2[0] - col1[0]) * ratio);
|
|
2832
|
+
var g = Math.round(col1[1] + (col2[1] - col1[1]) * ratio);
|
|
2833
|
+
var b = Math.round(col1[2] + (col2[2] - col1[2]) * ratio);
|
|
2834
|
+
var a = col1[3] + (col2[3] - col1[3]) * ratio;
|
|
2835
|
+
a = Math.round(a * 1000) / 1000;
|
|
2836
|
+
|
|
2837
|
+
if (a >= 0.999) {
|
|
2838
|
+
// Return standard 6-character hex for opaque colors
|
|
2839
|
+
return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
|
|
2783
2840
|
}
|
|
2784
|
-
|
|
2841
|
+
// Return rgba only when alpha is fractional
|
|
2842
|
+
return "rgba(" + r + "," + g + "," + b + "," + a + ")";
|
|
2785
2843
|
};//-27.6
|
|
2786
2844
|
|
|
2787
2845
|
/*--
|
|
@@ -18277,6 +18335,7 @@ lastSelected - access to the last selected (or created) control container
|
|
|
18277
18335
|
lastindex - the index number of the last selected controls
|
|
18278
18336
|
controlsVisible - get or set the visibility of the controls - or use showControls() and hideControls()
|
|
18279
18337
|
toggled - read-only Boolean property as to whether picker is showing
|
|
18338
|
+
controlType - get or set control types for new points
|
|
18280
18339
|
types - get or set the general array for the types ["mirror", "straight", "free", "none"]
|
|
18281
18340
|
changing this or removing a type will adjust the order when the user double clicks the points to change their type
|
|
18282
18341
|
this is not an array of types for each point - see the points property to access the types of each point
|
|
@@ -18291,11 +18350,13 @@ selectionManager - access to the SelectionManager
|
|
|
18291
18350
|
selectedBalls - access to the SelectionSet of control circles
|
|
18292
18351
|
selectedRect1s - access to the SelectionSet of control rectangles
|
|
18293
18352
|
selectedRect2s - access to the SelectionSet of control rectangles
|
|
18353
|
+
editPoints - get or set whether points can be added and removed
|
|
18354
|
+
holdPoints - get or set whether points can be held to be removed (default is editPoints)
|
|
18294
18355
|
interactive - get or set whether the shape is interactive - toggle, move, change or add controls, etc.
|
|
18295
18356
|
keyFocus - get or set the keyboard focus on the DisplayObject - see also zim.KEYFOCUS
|
|
18296
|
-
|
|
18357
|
+
will be set to true if this DisplayObject is the first made or DisplayObject is the last to be used with keyboard
|
|
18297
18358
|
veeObj - an object with ZIM VEE original parameters:value allowing the ZIM VEE values to be referenced
|
|
18298
|
-
|
|
18359
|
+
for instance, obj.prop = Pick.choose(obj.veeObj.prop); will reset the the prop to the result of the original ZIM VEE value
|
|
18299
18360
|
|
|
18300
18361
|
ALSO: see ZIM Container for properties such as:
|
|
18301
18362
|
width, height, widthOnly, heightOnly, draggable, level, depth, group
|
|
@@ -18318,7 +18379,7 @@ See the CreateJS Easel Docs for Container events such as:
|
|
|
18318
18379
|
added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmove, pressup, removed, rollout, rollover
|
|
18319
18380
|
|
|
18320
18381
|
MORE
|
|
18321
|
-
https://zimjs.com/
|
|
18382
|
+
https://zimjs.com/zapp/E_4QEJ4
|
|
18322
18383
|
https://www.youtube.com/watch?v=BA1bGBU4itI&list=PLCIzupgRt1pYtMlYPtNTKCtztFBeOtyc0
|
|
18323
18384
|
Note the points property has been split into points and pointObjects (and there have been a few property changes) since the time of the video
|
|
18324
18385
|
--*///+53.2
|
|
@@ -18391,7 +18452,7 @@ Note the points property has been split into points and pointObjects (and there
|
|
|
18391
18452
|
this.num = num;
|
|
18392
18453
|
this.onTop = onTop;
|
|
18393
18454
|
this.move = move;
|
|
18394
|
-
this.editPoints = editPoints;
|
|
18455
|
+
this.editPoints = this.holdPoints = editPoints;
|
|
18395
18456
|
this.allowToggle = allowToggle;
|
|
18396
18457
|
this.lockControlType = lockControlType;
|
|
18397
18458
|
this.selectPoints = selectPoints;
|
|
@@ -18459,6 +18520,52 @@ Note the points property has been split into points and pointObjects (and there
|
|
|
18459
18520
|
that.selectionManager = new zim.SelectionManager(null, "ctrl");
|
|
18460
18521
|
}
|
|
18461
18522
|
|
|
18523
|
+
that.selectionManager.on("keydown", function (e) {
|
|
18524
|
+
if (!that.selectPoints) return;
|
|
18525
|
+
if (!that.keyFocus) return;
|
|
18526
|
+
if (e.keyCode >= 37 && e.keyCode <= 40) {
|
|
18527
|
+
var currentSelected = getCurrentSelected();
|
|
18528
|
+
if (currentSelected.length > 0) {
|
|
18529
|
+
for(var i=0; i<currentSelected.length; i++) {
|
|
18530
|
+
var pointObj = currentSelected[i];
|
|
18531
|
+
if (e.keyCode == 37) pointObj.x -= that.selectionManager.shiftKey?10:1;
|
|
18532
|
+
else if (e.keyCode == 39) pointObj.x += that.selectionManager.shiftKey?10:1;
|
|
18533
|
+
else if (e.keyCode == 38) pointObj.y -= that.selectionManager.shiftKey?10:1;
|
|
18534
|
+
else if (e.keyCode == 40) pointObj.y += that.selectionManager.shiftKey?10:1;
|
|
18535
|
+
mapMove(pointObj);
|
|
18536
|
+
}
|
|
18537
|
+
that.drawShape();
|
|
18538
|
+
that.dispatchEvent("update");
|
|
18539
|
+
if (that.stage) that.stage.update();
|
|
18540
|
+
}
|
|
18541
|
+
}
|
|
18542
|
+
}, null, null, null, null, mID);
|
|
18543
|
+
|
|
18544
|
+
that.selectionManager.on("keyup", function (e) {
|
|
18545
|
+
if (!that.selectPoints) return;
|
|
18546
|
+
if (!that.keyFocus) return;
|
|
18547
|
+
if (e.keyCode >= 37 && e.keyCode <= 40) {
|
|
18548
|
+
var currentSelected = getCurrentSelected();
|
|
18549
|
+
if (currentSelected.length > 0) {
|
|
18550
|
+
for(var i=0; i<currentSelected.length; i++) {
|
|
18551
|
+
replaceControls(currentSelected[i]);
|
|
18552
|
+
}
|
|
18553
|
+
}
|
|
18554
|
+
}
|
|
18555
|
+
}, null, null, null, null, mID);
|
|
18556
|
+
|
|
18557
|
+
that.selectionManager.on("undo", function () {
|
|
18558
|
+
if (!that.selectPoints) return;
|
|
18559
|
+
if (!that.keyFocus) return;
|
|
18560
|
+
if (that.lastPoints) {
|
|
18561
|
+
var tempPoints = zim.copy(that.lastPoints);
|
|
18562
|
+
that.lastPoints = zim.copy(that.points);
|
|
18563
|
+
that.points = tempPoints;
|
|
18564
|
+
if (that.stage) that.stage.update();
|
|
18565
|
+
}
|
|
18566
|
+
}, null, null, null, null, mID);
|
|
18567
|
+
// }
|
|
18568
|
+
|
|
18462
18569
|
var mobile = zim.mobile();
|
|
18463
18570
|
|
|
18464
18571
|
sets = that.controls = new zim.Container({style:false}).addTo(that); // sets - a set contains a ball and two rects
|
|
@@ -19356,34 +19463,42 @@ Note the points property has been split into points and pointObjects (and there
|
|
|
19356
19463
|
}, null, null, null, null, mID);
|
|
19357
19464
|
|
|
19358
19465
|
// remove point
|
|
19359
|
-
that.controls.on("click", function (e) {
|
|
19466
|
+
that.controlsClickEvent = that.controls.on("click", function (e) {
|
|
19360
19467
|
that.lastSelected = e.target.parent;
|
|
19361
19468
|
that.lastindex = that.controls.getChildIndex(e.target.parent);
|
|
19362
19469
|
if (!that.editPoints) return;
|
|
19363
19470
|
if (that.selectionManager.shiftKey) { // remove
|
|
19364
|
-
|
|
19471
|
+
if (that.controls.noHold) that.controls.noHold();
|
|
19365
19472
|
removeControl(e);
|
|
19366
19473
|
}
|
|
19367
19474
|
}, null, null, null, null, mID);
|
|
19368
19475
|
|
|
19369
|
-
|
|
19370
|
-
if (e.target.type == "Circle") {
|
|
19371
|
-
var index = that.lastindex = that.controls.getChildIndex(e.target.parent);
|
|
19372
|
-
if (that.controls.numChildren <= 2) return;
|
|
19373
|
-
var points = that.points;
|
|
19374
|
-
if (that.selectPoints) that.lastPoints = zim.copy(points);
|
|
19375
|
-
points.splice(index, 1); // remove the point at the index
|
|
19376
|
-
that.points = points;
|
|
19377
|
-
that.stage.update();
|
|
19378
|
-
that.lastSelected = that.lastindex = null;
|
|
19379
|
-
}
|
|
19380
|
-
}
|
|
19381
|
-
if (that.editPoints) that.controls.hold(removeControl);
|
|
19476
|
+
that.controls.hold(removeControl);
|
|
19382
19477
|
|
|
19383
19478
|
if (!_controls) that.hideControls();
|
|
19384
19479
|
that.dispatchEvent("update");
|
|
19385
19480
|
} // end of init()
|
|
19386
19481
|
|
|
19482
|
+
function removeControl(e) {
|
|
19483
|
+
if (!that.editPoints || !that.holdPoints || !e || !e.target) return;
|
|
19484
|
+
if (e.target.type == "Circle" && e.target.parent && e.target.parent.parent == that.controls) {
|
|
19485
|
+
var index = that.lastindex = that.controls.getChildIndex(e.target.parent);
|
|
19486
|
+
if (index < 0 || that.controls.numChildren <= 2) return;
|
|
19487
|
+
if (that.controls.noHold) that.controls.noHold();
|
|
19488
|
+
var points = that.points;
|
|
19489
|
+
if (that.selectPoints) that.lastPoints = zim.copy(points);
|
|
19490
|
+
points.splice(index, 1); // remove the point at the index
|
|
19491
|
+
that.points = points;
|
|
19492
|
+
var ev = new createjs.Event("change");
|
|
19493
|
+
ev.controlType = "pointDelete";
|
|
19494
|
+
ev.index = index;
|
|
19495
|
+
that.dispatchEvent(ev);
|
|
19496
|
+
that.dispatchEvent("pointdelete");
|
|
19497
|
+
if (that.stage) that.stage.update();
|
|
19498
|
+
that.lastSelected = that.lastindex = null;
|
|
19499
|
+
}
|
|
19500
|
+
}
|
|
19501
|
+
|
|
19387
19502
|
// if (that.selectPoints) {
|
|
19388
19503
|
function getCurrentSelected() {
|
|
19389
19504
|
var answer = [];
|
|
@@ -19424,54 +19539,10 @@ Note the points property has been split into points and pointObjects (and there
|
|
|
19424
19539
|
ball.y = 0;
|
|
19425
19540
|
}
|
|
19426
19541
|
|
|
19427
|
-
|
|
19428
|
-
if (!that.selectPoints) return;
|
|
19429
|
-
if (!that.keyFocus) return;
|
|
19430
|
-
if (e.keyCode >= 37 && e.keyCode <= 40) {
|
|
19431
|
-
var currentSelected = getCurrentSelected();
|
|
19432
|
-
if (currentSelected.length > 0) {
|
|
19433
|
-
for(var i=0; i<currentSelected.length; i++) {
|
|
19434
|
-
var pointObj = currentSelected[i];
|
|
19435
|
-
if (e.keyCode == 37) pointObj.x -= that.selectionManager.shiftKey?10:1;
|
|
19436
|
-
else if (e.keyCode == 39) pointObj.x += that.selectionManager.shiftKey?10:1;
|
|
19437
|
-
else if (e.keyCode == 38) pointObj.y -= that.selectionManager.shiftKey?10:1;
|
|
19438
|
-
else if (e.keyCode == 40) pointObj.y += that.selectionManager.shiftKey?10:1;
|
|
19439
|
-
mapMove(pointObj);
|
|
19440
|
-
}
|
|
19441
|
-
that.drawShape();
|
|
19442
|
-
that.dispatchEvent("update");
|
|
19443
|
-
if (that.stage) that.stage.update();
|
|
19444
|
-
}
|
|
19445
|
-
}
|
|
19446
|
-
}, null, null, null, null, mID);
|
|
19447
|
-
|
|
19448
|
-
that.selectionManager.on("keyup", function (e) {
|
|
19449
|
-
if (!that.selectPoints) return;
|
|
19450
|
-
if (!that.keyFocus) return;
|
|
19451
|
-
if (e.keyCode >= 37 && e.keyCode <= 40) {
|
|
19452
|
-
var currentSelected = getCurrentSelected();
|
|
19453
|
-
if (currentSelected.length > 0) {
|
|
19454
|
-
for(var i=0; i<currentSelected.length; i++) {
|
|
19455
|
-
replaceControls(currentSelected[i]);
|
|
19456
|
-
}
|
|
19457
|
-
}
|
|
19458
|
-
}
|
|
19459
|
-
}, null, null, null, null, mID);
|
|
19460
|
-
|
|
19461
|
-
that.selectionManager.on("undo", function () {
|
|
19462
|
-
if (!that.selectPoints) return;
|
|
19463
|
-
if (!that.keyFocus) return;
|
|
19464
|
-
if (that.lastPoints) {
|
|
19465
|
-
var tempPoints = zim.copy(that.lastPoints);
|
|
19466
|
-
that.lastPoints = zim.copy(that.points);
|
|
19467
|
-
that.points = tempPoints;
|
|
19468
|
-
if (that.stage) that.stage.update();
|
|
19469
|
-
}
|
|
19470
|
-
}, null, null, null, null, mID);
|
|
19471
|
-
// }
|
|
19542
|
+
|
|
19472
19543
|
|
|
19473
19544
|
|
|
19474
|
-
|
|
19545
|
+
function mapMove(target) {
|
|
19475
19546
|
if (that.lockControls) return;
|
|
19476
19547
|
var ball;
|
|
19477
19548
|
if (target.rect1) { // pressmove on ball
|
|
@@ -19641,7 +19712,8 @@ Note the points property has been split into points and pointObjects (and there
|
|
|
19641
19712
|
zim.decimals(p[3].x),
|
|
19642
19713
|
zim.decimals(p[3].y)
|
|
19643
19714
|
];
|
|
19644
|
-
if (p[4] && p[4]!=="mirror") point.push(p[4]);
|
|
19715
|
+
// if (p[4] && p[4]!=="mirror") point.push(p[4]);
|
|
19716
|
+
if (p[4]) point.push(p[4]);
|
|
19645
19717
|
points.push(point);
|
|
19646
19718
|
}
|
|
19647
19719
|
return points;
|
|
@@ -19757,6 +19829,16 @@ Note the points property has been split into points and pointObjects (and there
|
|
|
19757
19829
|
}
|
|
19758
19830
|
});
|
|
19759
19831
|
|
|
19832
|
+
Object.defineProperty(that, 'controlType', {
|
|
19833
|
+
get: function() {
|
|
19834
|
+
return controlType;
|
|
19835
|
+
},
|
|
19836
|
+
set: function(value) {
|
|
19837
|
+
controlType = value;
|
|
19838
|
+
originalControlType = value;
|
|
19839
|
+
}
|
|
19840
|
+
});
|
|
19841
|
+
|
|
19760
19842
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
19761
19843
|
// path manipulation and animating to path methods
|
|
19762
19844
|
|
|
@@ -19996,17 +20078,28 @@ Note the points property has been split into points and pointObjects (and there
|
|
|
19996
20078
|
var index = insertPointData(points, controls, ratios, percent, controlType);
|
|
19997
20079
|
that.points = points;
|
|
19998
20080
|
that.num = points.length;
|
|
20081
|
+
var ev = new createjs.Event("change");
|
|
20082
|
+
ev.controlType = "pointAdd";
|
|
20083
|
+
ev.index = index;
|
|
20084
|
+
that.dispatchEvent(ev);
|
|
20085
|
+
that.dispatchEvent("pointadd");
|
|
20086
|
+
if (that.stage) that.stage.update();
|
|
19999
20087
|
return index;
|
|
20000
20088
|
};
|
|
20001
20089
|
|
|
20002
20090
|
this.removePoint = function(index) {
|
|
20003
|
-
if (zot(index) || index < 0) return;
|
|
20091
|
+
if (zot(index) || index < 0 || that.points.length <= 2 || index >= that.points.length) return that;
|
|
20004
20092
|
var currentPoints = zim.copy(that.points);
|
|
20005
20093
|
currentPoints.splice(index, 1);
|
|
20006
20094
|
that.points = currentPoints;
|
|
20095
|
+
var ev = new createjs.Event("change");
|
|
20096
|
+
ev.controlType = "pointDelete";
|
|
20097
|
+
ev.index = index;
|
|
20098
|
+
that.dispatchEvent(ev);
|
|
20099
|
+
that.dispatchEvent("pointdelete");
|
|
20007
20100
|
if (that.stage) that.stage.update();
|
|
20008
20101
|
return that;
|
|
20009
|
-
}
|
|
20102
|
+
};
|
|
20010
20103
|
|
|
20011
20104
|
this.addPoints = function(num, controlType, startPoint, spread, dataOnly, points, even) {
|
|
20012
20105
|
var sig = "num, controlType, startPoint, spread, dataOnly, points, even";
|
|
@@ -20464,10 +20557,12 @@ segmentRatios - a read-only array of cumulative ratio lengths of segments
|
|
|
20464
20557
|
used internally to animate to the path and attribute proportional time to each segment
|
|
20465
20558
|
controls - access to the container that holds the sets of controls
|
|
20466
20559
|
each control is given a read-only num property
|
|
20560
|
+
use blob.controls.noHold() to remove holding down a point to delete it
|
|
20467
20561
|
sticks - access to the Shape that has the control sticks
|
|
20468
20562
|
lastSelected - access to the last selected (or created) control container
|
|
20469
20563
|
lastindex - the index number of the last selected controls
|
|
20470
20564
|
controlsVisible - get or set the visibility of the controls - or use showControls() and hideControls()
|
|
20565
|
+
controlType - get or set control types for new points
|
|
20471
20566
|
types - get or set the general array for the types ["mirror", "straight", "free", "none"]
|
|
20472
20567
|
changing this or removing a type will adjust the order when the user double clicks the points to change their type
|
|
20473
20568
|
this is not an array of types for each point - see the points property to access the types of each point
|
|
@@ -20482,11 +20577,13 @@ selectionManager - access to the SelectionManager
|
|
|
20482
20577
|
selectedBalls - access to the SelectionSet of control circles
|
|
20483
20578
|
selectedRect1s - access to the SelectionSet of control rectangles
|
|
20484
20579
|
selectedRect2s - access to the SelectionSet of control rectangles
|
|
20580
|
+
editPoints - get or set whether points can be added and removed
|
|
20581
|
+
holdPoints - get or set whether points can be held to be removed (default is editPoints)
|
|
20485
20582
|
interactive - get or set whether the shape is interactive - toggle, move, change or add controls, etc.
|
|
20486
20583
|
keyFocus - get or set the keyboard focus on the DisplayObject - see also zim.KEYFOCUS
|
|
20487
|
-
|
|
20584
|
+
will be set to true if this DisplayObject is the first made or DisplayObject is the last to be used with keyboard
|
|
20488
20585
|
veeObj - an object with ZIM VEE original parameters:value allowing the ZIM VEE values to be referenced
|
|
20489
|
-
|
|
20586
|
+
for instance, obj.prop = Pick.choose(obj.veeObj.prop); will reset the the prop to the result of the original ZIM VEE value
|
|
20490
20587
|
|
|
20491
20588
|
ALSO: see ZIM Container for properties such as:
|
|
20492
20589
|
width, height, widthOnly, heightOnly, draggable, level, depth, group
|
|
@@ -20572,7 +20669,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
|
|
|
20572
20669
|
var that = this;
|
|
20573
20670
|
this.interactive = interactive;
|
|
20574
20671
|
this.num = num;
|
|
20575
|
-
this.editPoints = editPoints;
|
|
20672
|
+
this.editPoints = this.holdPoints = editPoints;
|
|
20576
20673
|
this.selectPoints = selectPoints;
|
|
20577
20674
|
this.lockControls = lockControls;
|
|
20578
20675
|
this.onTop = onTop;
|
|
@@ -20601,9 +20698,10 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
|
|
|
20601
20698
|
var min = 2; // distance within which to count as click to add point
|
|
20602
20699
|
|
|
20603
20700
|
var mapMove;
|
|
20604
|
-
var sets;
|
|
20701
|
+
var sets;
|
|
20605
20702
|
|
|
20606
20703
|
points = checkForShape(points);
|
|
20704
|
+
|
|
20607
20705
|
function checkForShape(shape) {
|
|
20608
20706
|
if (shape=="circle" || shape == "rectangle" || shape =="triangle") {
|
|
20609
20707
|
if (shape == "circle") shape = new zim.Circle(radius);
|
|
@@ -20734,6 +20832,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
|
|
|
20734
20832
|
points.pop();
|
|
20735
20833
|
}
|
|
20736
20834
|
}
|
|
20835
|
+
|
|
20737
20836
|
|
|
20738
20837
|
if (originalControlType && typeof points != "number") {
|
|
20739
20838
|
// override controlType
|
|
@@ -20743,7 +20842,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
|
|
|
20743
20842
|
point[4]=point[5]=point[6]=point[7]=0;
|
|
20744
20843
|
}
|
|
20745
20844
|
});
|
|
20746
|
-
}
|
|
20845
|
+
}
|
|
20747
20846
|
|
|
20748
20847
|
init();
|
|
20749
20848
|
function init() {
|
|
@@ -20763,6 +20862,51 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
|
|
|
20763
20862
|
that.selectionManager = new zim.SelectionManager(null, "ctrl");
|
|
20764
20863
|
}
|
|
20765
20864
|
|
|
20865
|
+
that.selectionManager.on("keydown", function (e) {
|
|
20866
|
+
if (!that.selectPoints) return;
|
|
20867
|
+
if (!that.keyFocus) return;
|
|
20868
|
+
if (e.keyCode >= 37 && e.keyCode <= 40) {
|
|
20869
|
+
var currentSelected = getCurrentSelected();
|
|
20870
|
+
if (currentSelected.length > 0) {
|
|
20871
|
+
for(var i=0; i<currentSelected.length; i++) {
|
|
20872
|
+
var pointObj = currentSelected[i];
|
|
20873
|
+
if (e.keyCode == 37) pointObj.x -= that.selectionManager.shiftKey?10:1;
|
|
20874
|
+
else if (e.keyCode == 39) pointObj.x += that.selectionManager.shiftKey?10:1;
|
|
20875
|
+
else if (e.keyCode == 38) pointObj.y -= that.selectionManager.shiftKey?10:1;
|
|
20876
|
+
else if (e.keyCode == 40) pointObj.y += that.selectionManager.shiftKey?10:1;
|
|
20877
|
+
mapMove(pointObj);
|
|
20878
|
+
}
|
|
20879
|
+
that.drawShape();
|
|
20880
|
+
that.dispatchEvent("update");
|
|
20881
|
+
if (that.stage) that.stage.update();
|
|
20882
|
+
}
|
|
20883
|
+
}
|
|
20884
|
+
}, null, null, null, null, mID);
|
|
20885
|
+
|
|
20886
|
+
that.selectionManager.on("keyup", function (e) {
|
|
20887
|
+
if (!that.selectPoints) return;
|
|
20888
|
+
if (!that.keyFocus) return;
|
|
20889
|
+
if (e.keyCode >= 37 && e.keyCode <= 40) {
|
|
20890
|
+
var currentSelected = getCurrentSelected();
|
|
20891
|
+
if (currentSelected.length > 0) {
|
|
20892
|
+
for(var i=0; i<currentSelected.length; i++) {
|
|
20893
|
+
replaceControls(currentSelected[i]);
|
|
20894
|
+
}
|
|
20895
|
+
}
|
|
20896
|
+
}
|
|
20897
|
+
}, null, null, null, null, mID);
|
|
20898
|
+
|
|
20899
|
+
that.selectionManager.on("undo", function () {
|
|
20900
|
+
if (!that.selectPoints) return;
|
|
20901
|
+
if (!that.keyFocus) return;
|
|
20902
|
+
if (that.lastPoints) {
|
|
20903
|
+
var tempPoints = zim.copy(that.lastPoints);
|
|
20904
|
+
that.lastPoints = zim.copy(that.points);
|
|
20905
|
+
that.points = tempPoints;
|
|
20906
|
+
if (that.stage) that.stage.update();
|
|
20907
|
+
}
|
|
20908
|
+
}, null, null, null, null, mID);
|
|
20909
|
+
|
|
20766
20910
|
num = typeof points == "number" ? points : points.length;
|
|
20767
20911
|
if (num <= 0) return;
|
|
20768
20912
|
if (zot(controlLengthOriginal)) controlLength = radius * 4 / num;
|
|
@@ -20788,6 +20932,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
|
|
|
20788
20932
|
_pointCircles = [];
|
|
20789
20933
|
|
|
20790
20934
|
var i, point, temp, set, rect1, rect2, ball, type, setInfo;
|
|
20935
|
+
|
|
20791
20936
|
|
|
20792
20937
|
for (i=0; i<num; i++) {
|
|
20793
20938
|
set = new zim.Container({style:false}).addTo(sets);
|
|
@@ -20837,7 +20982,6 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
|
|
|
20837
20982
|
|
|
20838
20983
|
// balls are relative to blob but handles are relative to ball
|
|
20839
20984
|
// points is an array of [[setX, setY, ballX, ballY, handleX, handleY, handle2X, handle2Y, type], etc.]
|
|
20840
|
-
|
|
20841
20985
|
setInfo = points[i];
|
|
20842
20986
|
type = setInfo[8] ? setInfo[8] : controlType;
|
|
20843
20987
|
set.loc({x:setInfo[0], y:setInfo[1]});
|
|
@@ -20886,7 +21030,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
|
|
|
20886
21030
|
point = [set, ball, rect1, rect2, setInfo?setInfo[8]:controlType];
|
|
20887
21031
|
_points.push(point);
|
|
20888
21032
|
_pointCircles.push(ball);
|
|
20889
|
-
_pointControls.push(set);
|
|
21033
|
+
_pointControls.push(set);
|
|
20890
21034
|
}
|
|
20891
21035
|
|
|
20892
21036
|
var tappedTwice = false;
|
|
@@ -21668,6 +21812,11 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
|
|
|
21668
21812
|
points.splice(pointBefore+1, 0, [point.x, point.y, 0,0, 0,0, 0,0]);
|
|
21669
21813
|
that.points = points;
|
|
21670
21814
|
that.changeControl({index:pointBefore+1, type:"mirror", update:true});
|
|
21815
|
+
var ev = new createjs.Event("change");
|
|
21816
|
+
ev.controlType = "pointAdd";
|
|
21817
|
+
ev.index = pointBefore+1;
|
|
21818
|
+
that.dispatchEvent(ev);
|
|
21819
|
+
that.dispatchEvent("pointadd");
|
|
21671
21820
|
} else { // only on edge
|
|
21672
21821
|
// test close enough to edge otherwise return
|
|
21673
21822
|
var p = that.pointsAdjusted;
|
|
@@ -21706,28 +21855,38 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
|
|
|
21706
21855
|
that.lastindex = that.controls.getChildIndex(e.target.parent);
|
|
21707
21856
|
if (!that.editPoints) return;
|
|
21708
21857
|
if (that.selectionManager.shiftKey) { // remove
|
|
21858
|
+
if (that.controls.noHold) that.controls.noHold();
|
|
21709
21859
|
removeControl(e);
|
|
21710
21860
|
}
|
|
21711
21861
|
}, null, null, null, null, mID);
|
|
21712
21862
|
|
|
21713
|
-
|
|
21714
|
-
if (e.target.type == "Circle") {
|
|
21715
|
-
var index = that.lastindex = that.controls.getChildIndex(e.target.parent);
|
|
21716
|
-
if (that.controls.numChildren <= 2) return;
|
|
21717
|
-
var points = that.points;
|
|
21718
|
-
if (that.selectPoints) that.lastPoints = zim.copy(points);
|
|
21719
|
-
points.splice(index, 1); // remove the point at the index
|
|
21720
|
-
that.points = points;
|
|
21721
|
-
that.stage.update();
|
|
21722
|
-
that.lastSelected = that.lastindex = null;
|
|
21723
|
-
}
|
|
21724
|
-
}
|
|
21725
|
-
if (that.editPoints) that.controls.hold(removeControl);
|
|
21863
|
+
that.controls.hold(removeControl);
|
|
21726
21864
|
|
|
21727
21865
|
if (!_controls) that.hideControls();
|
|
21728
21866
|
that.dispatchEvent("update");
|
|
21729
21867
|
} // end of init()
|
|
21730
21868
|
|
|
21869
|
+
function removeControl(e) {
|
|
21870
|
+
if (!that.editPoints || !that.holdPoints || !e || !e.target) return;
|
|
21871
|
+
if (e.target.type == "Circle" && e.target.parent && e.target.parent.parent == that.controls) {
|
|
21872
|
+
var index = that.lastindex = that.controls.getChildIndex(e.target.parent);
|
|
21873
|
+
if (index < 0 || that.controls.numChildren <= 2) return;
|
|
21874
|
+
if (that.controls.noHold) that.controls.noHold();
|
|
21875
|
+
var points = that.points;
|
|
21876
|
+
if (that.selectPoints) that.lastPoints = zim.copy(points);
|
|
21877
|
+
points.splice(index, 1); // remove the point at the index
|
|
21878
|
+
that.points = points;
|
|
21879
|
+
var ev = new createjs.Event("change");
|
|
21880
|
+
ev.controlType = "pointDelete";
|
|
21881
|
+
ev.index = index;
|
|
21882
|
+
that.dispatchEvent(ev);
|
|
21883
|
+
that.dispatchEvent("pointdelete");
|
|
21884
|
+
if (that.stage) that.stage.update();
|
|
21885
|
+
that.lastSelected = that.lastindex = null;
|
|
21886
|
+
}
|
|
21887
|
+
}
|
|
21888
|
+
|
|
21889
|
+
|
|
21731
21890
|
function getCurrentSelected() {
|
|
21732
21891
|
var answer = [];
|
|
21733
21892
|
var currentSet = that.selectionManager.currentSet;
|
|
@@ -21767,53 +21926,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
|
|
|
21767
21926
|
ball.y = 0;
|
|
21768
21927
|
}
|
|
21769
21928
|
|
|
21770
|
-
|
|
21771
|
-
if (!that.selectPoints) return;
|
|
21772
|
-
if (!that.keyFocus) return;
|
|
21773
|
-
if (e.keyCode >= 37 && e.keyCode <= 40) {
|
|
21774
|
-
var currentSelected = getCurrentSelected();
|
|
21775
|
-
if (currentSelected.length > 0) {
|
|
21776
|
-
for(var i=0; i<currentSelected.length; i++) {
|
|
21777
|
-
var pointObj = currentSelected[i];
|
|
21778
|
-
if (e.keyCode == 37) pointObj.x -= that.selectionManager.shiftKey?10:1;
|
|
21779
|
-
else if (e.keyCode == 39) pointObj.x += that.selectionManager.shiftKey?10:1;
|
|
21780
|
-
else if (e.keyCode == 38) pointObj.y -= that.selectionManager.shiftKey?10:1;
|
|
21781
|
-
else if (e.keyCode == 40) pointObj.y += that.selectionManager.shiftKey?10:1;
|
|
21782
|
-
mapMove(pointObj);
|
|
21783
|
-
}
|
|
21784
|
-
that.drawShape();
|
|
21785
|
-
that.dispatchEvent("update");
|
|
21786
|
-
if (that.stage) that.stage.update();
|
|
21787
|
-
}
|
|
21788
|
-
}
|
|
21789
|
-
}, null, null, null, null, mID);
|
|
21790
|
-
|
|
21791
|
-
that.selectionManager.on("keyup", function (e) {
|
|
21792
|
-
if (!that.selectPoints) return;
|
|
21793
|
-
if (!that.keyFocus) return;
|
|
21794
|
-
if (e.keyCode >= 37 && e.keyCode <= 40) {
|
|
21795
|
-
var currentSelected = getCurrentSelected();
|
|
21796
|
-
if (currentSelected.length > 0) {
|
|
21797
|
-
for(var i=0; i<currentSelected.length; i++) {
|
|
21798
|
-
replaceControls(currentSelected[i]);
|
|
21799
|
-
}
|
|
21800
|
-
}
|
|
21801
|
-
}
|
|
21802
|
-
}, null, null, null, null, mID);
|
|
21803
|
-
|
|
21804
|
-
that.selectionManager.on("undo", function () {
|
|
21805
|
-
if (!that.selectPoints) return;
|
|
21806
|
-
if (!that.keyFocus) return;
|
|
21807
|
-
if (that.lastPoints) {
|
|
21808
|
-
var tempPoints = zim.copy(that.lastPoints);
|
|
21809
|
-
that.lastPoints = zim.copy(that.points);
|
|
21810
|
-
that.points = tempPoints;
|
|
21811
|
-
if (that.stage) that.stage.update();
|
|
21812
|
-
}
|
|
21813
|
-
}, null, null, null, null, mID);
|
|
21814
|
-
|
|
21815
|
-
|
|
21816
|
-
mapMove = function (target) {
|
|
21929
|
+
function mapMove (target) {
|
|
21817
21930
|
if (that.lockControls) return;
|
|
21818
21931
|
var ball;
|
|
21819
21932
|
if (target.rect1) { // pressmove on ball
|
|
@@ -21948,6 +22061,16 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
|
|
|
21948
22061
|
});
|
|
21949
22062
|
that.lockControls = _lockControls;
|
|
21950
22063
|
|
|
22064
|
+
Object.defineProperty(that, 'controlType', {
|
|
22065
|
+
get: function() {
|
|
22066
|
+
return controlType;
|
|
22067
|
+
},
|
|
22068
|
+
set: function(value) {
|
|
22069
|
+
controlType = value;
|
|
22070
|
+
originalControlType = value;
|
|
22071
|
+
}
|
|
22072
|
+
});
|
|
22073
|
+
|
|
21951
22074
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
21952
22075
|
// NOTE: extends ZIM CustomShape for more properties and a few functions.
|
|
21953
22076
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
@@ -21963,7 +22086,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
|
|
|
21963
22086
|
});
|
|
21964
22087
|
if (that.selectPoints && !zim.KEYFOCUS) setFocus();
|
|
21965
22088
|
function setFocus() {that.keyFocus = true; var d=document.activeElement; if (d) d.blur();}
|
|
21966
|
-
|
|
22089
|
+
|
|
21967
22090
|
|
|
21968
22091
|
Object.defineProperty(that, 'points', {
|
|
21969
22092
|
get: function() {
|
|
@@ -21981,9 +22104,10 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
|
|
|
21981
22104
|
zim.decimals(p[3].x),
|
|
21982
22105
|
zim.decimals(p[3].y)
|
|
21983
22106
|
];
|
|
21984
|
-
if (p[4]
|
|
22107
|
+
if (p[4]) point.push(p[4]);
|
|
22108
|
+
// if (p[4] && p[4]!=="straight") point.push(p[4]);
|
|
21985
22109
|
points.push(point);
|
|
21986
|
-
}
|
|
22110
|
+
}
|
|
21987
22111
|
return points;
|
|
21988
22112
|
},
|
|
21989
22113
|
set: function(value) {
|
|
@@ -22137,6 +22261,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
|
|
|
22137
22261
|
if (zon) {zogy("Blob() - segmentRatios is read only");}
|
|
22138
22262
|
}
|
|
22139
22263
|
});
|
|
22264
|
+
|
|
22140
22265
|
|
|
22141
22266
|
that.approximateBounds = function(num, showPoints) {
|
|
22142
22267
|
if (zot(num)) num = 80;
|
|
@@ -22339,17 +22464,28 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
|
|
|
22339
22464
|
var index = insertPointData(points, controls, ratios, percent, controlType);
|
|
22340
22465
|
that.points = points;
|
|
22341
22466
|
that.num = points.length;
|
|
22467
|
+
var ev = new createjs.Event("change");
|
|
22468
|
+
ev.controlType = "pointAdd";
|
|
22469
|
+
ev.index = index;
|
|
22470
|
+
that.dispatchEvent(ev);
|
|
22471
|
+
that.dispatchEvent("pointadd");
|
|
22472
|
+
if (that.stage) that.stage.update();
|
|
22342
22473
|
return index;
|
|
22343
22474
|
};
|
|
22344
22475
|
|
|
22345
22476
|
this.removePoint = function(index) {
|
|
22346
|
-
if (zot(index) || index < 0) return;
|
|
22477
|
+
if (zot(index) || index < 0 || that.points.length <= 2 || index >= that.points.length) return that;
|
|
22347
22478
|
var currentPoints = zim.copy(that.points);
|
|
22348
22479
|
currentPoints.splice(index, 1);
|
|
22349
22480
|
that.points = currentPoints;
|
|
22481
|
+
var ev = new createjs.Event("change");
|
|
22482
|
+
ev.controlType = "pointDelete";
|
|
22483
|
+
ev.index = index;
|
|
22484
|
+
that.dispatchEvent(ev);
|
|
22485
|
+
that.dispatchEvent("pointdelete");
|
|
22350
22486
|
if (that.stage) that.stage.update();
|
|
22351
22487
|
return that;
|
|
22352
|
-
}
|
|
22488
|
+
};
|
|
22353
22489
|
|
|
22354
22490
|
this.addPoints = function(num, controlType, startPoint, spread, dataOnly, points, even) {
|
|
22355
22491
|
var sig = "num, controlType, startPoint, spread, dataOnly, points, even";
|
|
@@ -29425,7 +29561,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
|
|
|
29425
29561
|
that.toggled = false;
|
|
29426
29562
|
var ch,i;
|
|
29427
29563
|
var tar = that.content||that.contentContainer||that;
|
|
29428
|
-
if (tar.type != "Container") tar = that.contentContainer||that;
|
|
29564
|
+
if (tar.type != "Container" && tar.type != "Tile") tar = that.contentContainer||that;
|
|
29429
29565
|
for (i=0; i<tar.numChildren; i++) { // record depths first
|
|
29430
29566
|
ch = tar.getChildAt(i);
|
|
29431
29567
|
if (ch.type == "TextArea" || ch.type == "Loader" || ch.type == "Tag") {
|
|
@@ -29513,7 +29649,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
|
|
|
29513
29649
|
this.on("added", show2, null, null, null, null, mID);
|
|
29514
29650
|
function show2() {
|
|
29515
29651
|
var tar = that.content||that.contentContainer||that;
|
|
29516
|
-
if (tar.type != "Container") tar = that.contentContainer||that;
|
|
29652
|
+
if (tar.type != "Container" && tar.type != "Tile") tar = that.contentContainer||that;
|
|
29517
29653
|
for (var i=0; i<htmlList.length; i++) {
|
|
29518
29654
|
tar.addChildAt(htmlList.values[i].obj, htmlList.values[i].depth);
|
|
29519
29655
|
}
|
|
@@ -29727,7 +29863,6 @@ panelHeight - get and set the height of the panel without scaling it as height d
|
|
|
29727
29863
|
titleBar - access to the titleBar container - which also has a backing property
|
|
29728
29864
|
titleBarlabel - access to the label of the current panel
|
|
29729
29865
|
text - access to the text of the current panel
|
|
29730
|
-
titleBarLabel - gives access to the titleBar label
|
|
29731
29866
|
closeIcon - access to the close button
|
|
29732
29867
|
collapseIcon - access to the ZIM Shape if there is a collapse triangle
|
|
29733
29868
|
collapsed - get or set whether the panel is collapsed - must start with collapse parameter set to true
|
|
@@ -29907,7 +30042,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
|
|
|
29907
30042
|
that.drag({rect:boundary, currentTarget:true, onTop:onTop});
|
|
29908
30043
|
var ch,i;
|
|
29909
30044
|
var tar = that.content||that.contentContainer||that;
|
|
29910
|
-
if (tar.type != "Container") tar = that.contentContainer||that;
|
|
30045
|
+
if (tar.type != "Container" && tar.type != "Tile") tar = that.contentContainer||that;
|
|
29911
30046
|
for (i=0; i<tar.numChildren; i++) { // record depths first
|
|
29912
30047
|
ch = tar.getChildAt(i);
|
|
29913
30048
|
if (ch.type == "TextArea" || ch.type == "Loader" || ch.type == "Tag") {
|
|
@@ -30009,7 +30144,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
|
|
|
30009
30144
|
function hide2() {
|
|
30010
30145
|
var ch,i;
|
|
30011
30146
|
var tar = that.content||that.contentContainer||that;
|
|
30012
|
-
if (tar.type != "Container") tar = that.contentContainer||that;
|
|
30147
|
+
if (tar.type != "Container" && tar.type != "Tile") tar = that.contentContainer||that;
|
|
30013
30148
|
for (i=0; i<tar.numChildren; i++) { // record depths first
|
|
30014
30149
|
ch = tar.getChildAt(i);
|
|
30015
30150
|
if (ch.type == "TextArea" || ch.type == "Loader" || ch.type == "Tag") {
|
|
@@ -30904,7 +31039,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
|
|
|
30904
31039
|
function hide2() {
|
|
30905
31040
|
var ch,i;
|
|
30906
31041
|
var tar = that.content||that.contentContainer||that;
|
|
30907
|
-
if (tar.type != "Container") tar = that.contentContainer||that;
|
|
31042
|
+
if (tar.type != "Container" && tar.type != "Tile") tar = that.contentContainer||that;
|
|
30908
31043
|
for (i=0; i<tar.numChildren; i++) { // record depths first
|
|
30909
31044
|
ch = tar.getChildAt(i);
|
|
30910
31045
|
if (ch.type == "TextArea" || ch.type == "Loader" || ch.type == "Tag") {
|
|
@@ -37115,49 +37250,49 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
|
|
|
37115
37250
|
setLabel(stepperType=="number"?numVal:list[index], stepperType=="number"?numVal:index);
|
|
37116
37251
|
|
|
37117
37252
|
function doStep(n) {
|
|
37118
|
-
|
|
37119
|
-
|
|
37120
|
-
|
|
37121
|
-
|
|
37122
|
-
|
|
37123
|
-
|
|
37124
|
-
|
|
37125
|
-
|
|
37126
|
-
|
|
37127
|
-
|
|
37128
|
-
|
|
37129
|
-
if (display) box.cur("pointer");
|
|
37130
|
-
}
|
|
37131
|
-
if (numVal < that.min) {
|
|
37132
|
-
numVal = step==1?that.min:lastNumVal;
|
|
37133
|
-
}
|
|
37253
|
+
var lastValue = that.value; // <-- CAPTURE CURRENT VALUE BEFORE STEPPING
|
|
37254
|
+
var nextIndex;
|
|
37255
|
+
if (stepperType == "number") {
|
|
37256
|
+
numVal = Number(numVal);
|
|
37257
|
+
var lastNumVal = numVal;
|
|
37258
|
+
numVal += Number(actualStep * n * numDir);
|
|
37259
|
+
numVal = zim.decimals(numVal, decimals);
|
|
37260
|
+
if (!continuous) {
|
|
37261
|
+
if (numVal > that.max) {
|
|
37262
|
+
numVal = step==1?that.max:lastNumVal;
|
|
37263
|
+
if (display) box.cur("default");
|
|
37134
37264
|
} else {
|
|
37135
|
-
if (
|
|
37136
|
-
|
|
37137
|
-
|
|
37138
|
-
|
|
37139
|
-
}
|
|
37265
|
+
if (display) box.cur("pointer");
|
|
37266
|
+
}
|
|
37267
|
+
if (numVal < that.min) {
|
|
37268
|
+
numVal = step==1?that.min:lastNumVal;
|
|
37140
37269
|
}
|
|
37141
37270
|
} else {
|
|
37142
|
-
|
|
37143
|
-
|
|
37144
|
-
|
|
37145
|
-
|
|
37146
|
-
|
|
37147
|
-
|
|
37148
|
-
|
|
37149
|
-
|
|
37150
|
-
|
|
37271
|
+
if (numVal > that.max) {
|
|
37272
|
+
numVal = that.min;
|
|
37273
|
+
} else if (numVal < that.min) {
|
|
37274
|
+
numVal = that.max;
|
|
37275
|
+
}
|
|
37276
|
+
}
|
|
37277
|
+
} else {
|
|
37278
|
+
nextIndex = index + n;
|
|
37279
|
+
if (!continuous) {
|
|
37280
|
+
if (nextIndex > list.length-1) {
|
|
37281
|
+
if (display) box.cur("default");
|
|
37282
|
+
return;
|
|
37151
37283
|
} else {
|
|
37152
|
-
if (
|
|
37153
|
-
if (nextIndex < 0) nextIndex = list.length-1;
|
|
37284
|
+
if (display) box.cur("pointer");
|
|
37154
37285
|
}
|
|
37155
|
-
|
|
37286
|
+
if (nextIndex < 0) return;
|
|
37287
|
+
} else {
|
|
37288
|
+
if (nextIndex > list.length-1) nextIndex = 0;
|
|
37289
|
+
if (nextIndex < 0) nextIndex = list.length-1;
|
|
37156
37290
|
}
|
|
37157
|
-
|
|
37158
|
-
if (that.value != lastValue) that.dispatchEvent("change");
|
|
37159
|
-
lastValue = that.value;
|
|
37291
|
+
index = nextIndex;
|
|
37160
37292
|
}
|
|
37293
|
+
setLabel(stepperType=="number"?numVal:list[index], stepperType=="number"?numVal:index);
|
|
37294
|
+
if (that.value != lastValue) that.dispatchEvent("change");
|
|
37295
|
+
}
|
|
37161
37296
|
|
|
37162
37297
|
|
|
37163
37298
|
Object.defineProperty(this, 'index', {
|
|
@@ -37395,6 +37530,7 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
|
|
|
37395
37530
|
|
|
37396
37531
|
function setLabel(text, n, update) {
|
|
37397
37532
|
index = n;
|
|
37533
|
+
lastValue = that.value; // <-- KEEPS OUTER lastValue IN SYNC ON PROGRAMMATIC SET
|
|
37398
37534
|
if (zot(update)) update = true;
|
|
37399
37535
|
if (display) {
|
|
37400
37536
|
if (stepperType == "number") {
|
|
@@ -37404,8 +37540,6 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
|
|
|
37404
37540
|
}
|
|
37405
37541
|
label.text = text;
|
|
37406
37542
|
label.center(that);
|
|
37407
|
-
// label.x = box.x+box.getBounds().width/2;
|
|
37408
|
-
// label.y = box.y+(box.getBounds().height-label.getBounds().height)/2;
|
|
37409
37543
|
}
|
|
37410
37544
|
if (arrows) setArrows();
|
|
37411
37545
|
if (update && next && ((!zim.OPTIMIZE&&(zns||!WW.OPTIMIZE)) && next.stage)) {
|
|
@@ -57641,7 +57775,7 @@ zim.noGesture = function(obj, move, scale, rotate) {
|
|
|
57641
57775
|
};//-34.6
|
|
57642
57776
|
|
|
57643
57777
|
/*--
|
|
57644
|
-
obj.gestureBoundary = function(boundary,
|
|
57778
|
+
obj.gestureBoundary = function(boundary, update)
|
|
57645
57779
|
|
|
57646
57780
|
gestureBoundary
|
|
57647
57781
|
zim DisplayObject method
|
|
@@ -57682,7 +57816,260 @@ RETURNS obj for chaining
|
|
|
57682
57816
|
return obj;
|
|
57683
57817
|
};//-34.7
|
|
57684
57818
|
|
|
57685
|
-
|
|
57819
|
+
|
|
57820
|
+
/*--
|
|
57821
|
+
obj.tilt = function(boundary, damp, factor, mode, type, call)
|
|
57822
|
+
|
|
57823
|
+
tilt
|
|
57824
|
+
zim DisplayObject method
|
|
57825
|
+
|
|
57826
|
+
DESCRIPTION
|
|
57827
|
+
Moves or positions an object based on device sensors (deviceorientation or devicemotion).
|
|
57828
|
+
Automatically manages user sensor permission via ZIM PermissionAsk if permission has not yet been requested.
|
|
57829
|
+
|
|
57830
|
+
NOTE
|
|
57831
|
+
If permission has already been granted, tilt activates immediately.
|
|
57832
|
+
If multiple objects call tilt() before permission is granted, they are queued and activated together once the user accepts.
|
|
57833
|
+
ALSO see noTilt() to remove tilt behaviors.
|
|
57834
|
+
ALSO see tiltBoundary() to dynamically change or clear the boundary rectangle.
|
|
57835
|
+
|
|
57836
|
+
EXAMPLE
|
|
57837
|
+
// Basic rolling ball constrained to stage bounds
|
|
57838
|
+
const ball = new Circle(30, red)
|
|
57839
|
+
.center()
|
|
57840
|
+
.tilt(true);
|
|
57841
|
+
END EXAMPLE
|
|
57842
|
+
|
|
57843
|
+
EXAMPLE
|
|
57844
|
+
// Custom damping, sensitivity factor, and boundary
|
|
57845
|
+
new Rectangle(80, 80, blue)
|
|
57846
|
+
.center()
|
|
57847
|
+
.tilt({
|
|
57848
|
+
boundary: new Boundary(50, 50, W - 100, H - 100),
|
|
57849
|
+
damp: 0.08,
|
|
57850
|
+
factor: 0.75,
|
|
57851
|
+
call: (success, obj) => {
|
|
57852
|
+
if (!success) new Pane("Device orientation not available", yellow).show();
|
|
57853
|
+
}
|
|
57854
|
+
});
|
|
57855
|
+
END EXAMPLE
|
|
57856
|
+
|
|
57857
|
+
PARAMETERS
|
|
57858
|
+
** supports DUO - parameters or single object with properties below
|
|
57859
|
+
boundary - (default null) a ZIM Boundary object, an Array of [x, y, width, height], or true for the Stage dimensions
|
|
57860
|
+
damp - (default 0.05) smoothing factor via ZIM Damp, or null / false for immediate direct tracking
|
|
57861
|
+
factor - (default 0.5) sensitivity factor multiplier, or an Object with {x, y} for independent axis sensitivity
|
|
57862
|
+
mode - (default "move") "move" for continuous velocity / rolling behavior, or "position" for tilt offset relative to starting coordinates
|
|
57863
|
+
type - (default "deviceorientation") the sensor event type ("deviceorientation" or "devicemotion")
|
|
57864
|
+
call - (default null) callback function called when permission resolves, receiving (success:Boolean, obj:DisplayObject)
|
|
57865
|
+
|
|
57866
|
+
RETURNS obj for chaining
|
|
57867
|
+
--*///+34.75
|
|
57868
|
+
zim.tilt = function(obj, boundary, damp, factor, mode, type, call) {
|
|
57869
|
+
var sig = "obj, boundary, damp, factor, mode, type, call";
|
|
57870
|
+
var duo; if (duo = zob(zim.tilt, arguments, sig)) return duo;
|
|
57871
|
+
if ((obj.type=="AC"||(obj.type=="Emoji"&&obj.svg&&obj.svg.type=="AC"))&&WW.zdf) {WW.zdf.ac("tilt", arguments); return obj;}
|
|
57872
|
+
z_d("34.75");
|
|
57873
|
+
|
|
57874
|
+
// MONITOR
|
|
57875
|
+
var mID = "z~tilt";
|
|
57876
|
+
if (obj && obj.mID && ((obj.mID[2] && obj.mID[2]=="-") || obj.mID[0]=="-")) mID = "z~-";
|
|
57877
|
+
|
|
57878
|
+
if (zot(obj)) return;
|
|
57879
|
+
|
|
57880
|
+
// Clean up any existing tilt on this object first
|
|
57881
|
+
if (obj._tiltTicker) zim.noTilt(obj);
|
|
57882
|
+
|
|
57883
|
+
var f = obj.frame || (typeof zdf != "undefined" ? zdf : WW.zdf);
|
|
57884
|
+
var s = obj.stage || (f ? f.stage : null);
|
|
57885
|
+
|
|
57886
|
+
// Set initial boundary
|
|
57887
|
+
zim.tiltBoundary(obj, boundary);
|
|
57888
|
+
|
|
57889
|
+
if (zot(damp)) damp = 0.05;
|
|
57890
|
+
if (zot(factor)) factor = 0.5;
|
|
57891
|
+
var factorX = typeof factor === "object" ? factor.x : factor;
|
|
57892
|
+
var factorY = typeof factor === "object" ? factor.y : factor;
|
|
57893
|
+
if (zot(mode)) mode = "move"; // "move" | "position" | "rotation"
|
|
57894
|
+
if (zot(type)) type = "deviceorientation";
|
|
57895
|
+
|
|
57896
|
+
// Damp angles for "move" mode (starts at 0) or positions for "position" mode
|
|
57897
|
+
var dampX = damp ? new zim.Damp(mode == "position" ? obj.x : 0, damp) : null;
|
|
57898
|
+
var dampY = damp ? new zim.Damp(mode == "position" ? obj.y : 0, damp) : null;
|
|
57899
|
+
var currentRot = {x: 0, y: 0, z: 0};
|
|
57900
|
+
|
|
57901
|
+
function updateTilt() {
|
|
57902
|
+
if (mode == "move") {
|
|
57903
|
+
// Damping the rotation angle gives smooth acceleration & deceleration
|
|
57904
|
+
var rotY = dampX ? dampX.convert(currentRot.y) : currentRot.y;
|
|
57905
|
+
var rotX = dampY ? dampY.convert(currentRot.x) : currentRot.x;
|
|
57906
|
+
obj.x += rotY * factorX;
|
|
57907
|
+
obj.y += rotX * factorY;
|
|
57908
|
+
} else if (mode == "position") {
|
|
57909
|
+
var targetX = (obj._tiltStartX != null ? obj._tiltStartX : obj.x) + currentRot.y * factorX * 10;
|
|
57910
|
+
var targetY = (obj._tiltStartY != null ? obj._tiltStartY : obj.y) + currentRot.x * factorY * 10;
|
|
57911
|
+
obj.x = dampX ? dampX.convert(targetX) : targetX;
|
|
57912
|
+
obj.y = dampY ? dampY.convert(targetY) : targetY;
|
|
57913
|
+
}
|
|
57914
|
+
|
|
57915
|
+
// Dynamically applies boundary constraint
|
|
57916
|
+
if (obj._tiltBoundary) {
|
|
57917
|
+
obj.x = zim.constrain(obj.x, obj._tiltBoundary.x, obj._tiltBoundary.x + obj._tiltBoundary.width);
|
|
57918
|
+
obj.y = zim.constrain(obj.y, obj._tiltBoundary.y, obj._tiltBoundary.y + obj._tiltBoundary.height);
|
|
57919
|
+
}
|
|
57920
|
+
|
|
57921
|
+
if (s) s.update();
|
|
57922
|
+
}
|
|
57923
|
+
|
|
57924
|
+
function activate() {
|
|
57925
|
+
obj._tiltStartX = obj.x;
|
|
57926
|
+
obj._tiltStartY = obj.y;
|
|
57927
|
+
if (mode == "position" && dampX && dampY) {
|
|
57928
|
+
dampX.immediate(obj.x);
|
|
57929
|
+
dampY.immediate(obj.y);
|
|
57930
|
+
}
|
|
57931
|
+
|
|
57932
|
+
obj._tiltType = type;
|
|
57933
|
+
obj._tiltListener = function(e) {
|
|
57934
|
+
if (e.rotation) {
|
|
57935
|
+
currentRot.x = e.rotation.x || 0;
|
|
57936
|
+
currentRot.y = e.rotation.y || 0;
|
|
57937
|
+
currentRot.z = e.rotation.z || 0;
|
|
57938
|
+
} else {
|
|
57939
|
+
currentRot.x = e.beta || 0;
|
|
57940
|
+
currentRot.y = e.gamma || 0;
|
|
57941
|
+
currentRot.z = e.alpha || 0;
|
|
57942
|
+
}
|
|
57943
|
+
};
|
|
57944
|
+
f.on(type, obj._tiltListener);
|
|
57945
|
+
|
|
57946
|
+
obj._tiltTicker = zim.Ticker.add(updateTilt);
|
|
57947
|
+
if (call) call(true, obj);
|
|
57948
|
+
}
|
|
57949
|
+
|
|
57950
|
+
// Permission check & queueing
|
|
57951
|
+
if (f._permissionGranted) {
|
|
57952
|
+
activate();
|
|
57953
|
+
} else if (f._permissionPending) {
|
|
57954
|
+
f._permissionQueue.push(activate);
|
|
57955
|
+
} else {
|
|
57956
|
+
f._permissionPending = true;
|
|
57957
|
+
f._permissionQueue = [activate];
|
|
57958
|
+
|
|
57959
|
+
new zim.PermissionAsk(function(yes) {
|
|
57960
|
+
f._permissionPending = false;
|
|
57961
|
+
if (yes) {
|
|
57962
|
+
f._permissionGranted = true;
|
|
57963
|
+
zim.loop(f._permissionQueue, function(fn) { fn(); });
|
|
57964
|
+
f._permissionQueue = [];
|
|
57965
|
+
} else {
|
|
57966
|
+
if (call) call(false, obj);
|
|
57967
|
+
}
|
|
57968
|
+
}, type);
|
|
57969
|
+
}
|
|
57970
|
+
|
|
57971
|
+
return obj;
|
|
57972
|
+
};//-34.75
|
|
57973
|
+
|
|
57974
|
+
|
|
57975
|
+
/*--
|
|
57976
|
+
obj.noTilt = function()
|
|
57977
|
+
|
|
57978
|
+
noTilt
|
|
57979
|
+
zim DisplayObject method
|
|
57980
|
+
|
|
57981
|
+
DESCRIPTION
|
|
57982
|
+
Removes tilt listeners, removes internal ticker updates, and clears tilt boundary properties from the object.
|
|
57983
|
+
|
|
57984
|
+
EXAMPLE
|
|
57985
|
+
const player = new Circle(25, green).center().tilt(true);
|
|
57986
|
+
|
|
57987
|
+
// Stop tilt control when game ends or is paused
|
|
57988
|
+
player.noTilt();
|
|
57989
|
+
END EXAMPLE
|
|
57990
|
+
|
|
57991
|
+
RETURNS obj for chaining
|
|
57992
|
+
--*///+34.76
|
|
57993
|
+
zim.noTilt = function(obj) {
|
|
57994
|
+
var sig = "obj";
|
|
57995
|
+
var duo; if (duo = zob(zim.noTilt, arguments, sig)) return duo;
|
|
57996
|
+
z_d("34.76");
|
|
57997
|
+
|
|
57998
|
+
if (zot(obj) || !obj.on || !obj.zimTouch) return;
|
|
57999
|
+
|
|
58000
|
+
// MONITOR
|
|
58001
|
+
var mID = "z~noTilt";
|
|
58002
|
+
if (obj && obj.mID && ((obj.mID[2] && obj.mID[2]=="-") || obj.mID[0]=="-")) mID = "z~-";
|
|
58003
|
+
|
|
58004
|
+
if (zot(obj)) return;
|
|
58005
|
+
var f = obj.frame || (typeof zdf != "undefined" ? zdf : WW.zdf);
|
|
58006
|
+
|
|
58007
|
+
if (obj._tiltListener && f) {
|
|
58008
|
+
f.off(obj._tiltType || "deviceorientation", obj._tiltListener);
|
|
58009
|
+
obj._tiltListener = null;
|
|
58010
|
+
}
|
|
58011
|
+
if (obj._tiltTicker) {
|
|
58012
|
+
zim.Ticker.remove(obj._tiltTicker);
|
|
58013
|
+
obj._tiltTicker = null;
|
|
58014
|
+
}
|
|
58015
|
+
obj._tiltBoundary = null;
|
|
58016
|
+
|
|
58017
|
+
return obj;
|
|
58018
|
+
|
|
58019
|
+
};//-34.76
|
|
58020
|
+
|
|
58021
|
+
/*--
|
|
58022
|
+
obj.tiltBoundary = function(boundary, y, width, height)
|
|
58023
|
+
|
|
58024
|
+
tiltBoundary
|
|
58025
|
+
zim DisplayObject method
|
|
58026
|
+
|
|
58027
|
+
DESCRIPTION
|
|
58028
|
+
Dynamically sets, updates, or removes the boundary rectangle for an object with tilt().
|
|
58029
|
+
|
|
58030
|
+
EXAMPLE
|
|
58031
|
+
const marble = new Circle(20, purple).center().tilt(true);
|
|
58032
|
+
|
|
58033
|
+
// Update boundary dynamically later (e.g., on resize or game level change)
|
|
58034
|
+
marble.tiltBoundary(new Boundary(50, 50, W - 100, H - 100));
|
|
58035
|
+
|
|
58036
|
+
// Or clear the boundary
|
|
58037
|
+
// marble.tiltBoundary(null);
|
|
58038
|
+
END EXAMPLE
|
|
58039
|
+
|
|
58040
|
+
PARAMETERS
|
|
58041
|
+
** supports DUO - parameters or single object with properties below
|
|
58042
|
+
boundary - (default null) a ZIM Boundary object, an Array of [x, y, width, height], true for Frame bounds, null / false to remove boundary, or the x position if passing (x, y, width, height) positionally
|
|
58043
|
+
y - (default null) y coordinate if boundary parameter is used as x
|
|
58044
|
+
width - (default null) width if boundary parameter is used as x
|
|
58045
|
+
height - (default null) height if boundary parameter is used as x
|
|
58046
|
+
|
|
58047
|
+
RETURNS obj for chaining
|
|
58048
|
+
--*///+34.77
|
|
58049
|
+
zim.tiltBoundary = function(obj, boundary, y, width, height) {
|
|
58050
|
+
var sig = "obj, boundary, y, width, height";
|
|
58051
|
+
var duo; if (duo = zob(zim.tiltBoundary, arguments, sig)) return duo;
|
|
58052
|
+
z_d("34.77");
|
|
58053
|
+
if (zot(obj) || !obj.on) return;
|
|
58054
|
+
var f = obj.frame || (typeof zdf != "undefined" ? zdf : WW.zdf);
|
|
58055
|
+
|
|
58056
|
+
if (zot(boundary) || boundary === false || boundary === null) {
|
|
58057
|
+
obj._tiltBoundary = null;
|
|
58058
|
+
} else if (boundary === true && f) {
|
|
58059
|
+
obj._tiltBoundary = new zim.Boundary(0, 0, f.width, f.height);
|
|
58060
|
+
} else if (Array.isArray(boundary)) {
|
|
58061
|
+
obj._tiltBoundary = new zim.Boundary(boundary[0], boundary[1], boundary[2], boundary[3]);
|
|
58062
|
+
} else if (typeof boundary === "number" && !zot(y)) {
|
|
58063
|
+
obj._tiltBoundary = new zim.Boundary(boundary, y, width, height);
|
|
58064
|
+
} else if (boundary && boundary.type == "Boundary") {
|
|
58065
|
+
obj._tiltBoundary = boundary;
|
|
58066
|
+
} else {
|
|
58067
|
+
obj._tiltBoundary = null;
|
|
58068
|
+
}
|
|
58069
|
+
|
|
58070
|
+
return obj;
|
|
58071
|
+
};//-34.77
|
|
58072
|
+
|
|
57686
58073
|
/*--
|
|
57687
58074
|
obj.effect = function(effect, x, y, width, height)
|
|
57688
58075
|
|
|
@@ -75313,6 +75700,7 @@ multiple - true if the multipleSelect key is being pressed otherwise false
|
|
|
75313
75700
|
ctrlKey - true if the ctrlKey key is being pressed otherwise false
|
|
75314
75701
|
shiftKey - true if the shiftKey key is being pressed otherwise false
|
|
75315
75702
|
metaKey - true if the metaKey key is being pressed otherwise false
|
|
75703
|
+
undoKey - true set to false to not handle undo
|
|
75316
75704
|
enabled - set to false to disable and true to enable - will remember selections when enabled
|
|
75317
75705
|
|
|
75318
75706
|
EVENTS
|
|
@@ -75326,6 +75714,7 @@ dispatches an "undo" event if a CTRL or META plus the U key is pressed
|
|
|
75326
75714
|
// MONITOR
|
|
75327
75715
|
this.mID = "z~"+this.type;
|
|
75328
75716
|
|
|
75717
|
+
|
|
75329
75718
|
if (zot(sets)) sets = [];
|
|
75330
75719
|
if (zot(multipleSets)) multipleSets = true;
|
|
75331
75720
|
if (!Array.isArray(sets)) sets = [sets];
|
|
@@ -75333,6 +75722,7 @@ dispatches an "undo" event if a CTRL or META plus the U key is pressed
|
|
|
75333
75722
|
this.multipleKey = multipleKey;
|
|
75334
75723
|
this.multipleSets = multipleSets;
|
|
75335
75724
|
this.multiple = false;
|
|
75725
|
+
this.undoKey = true;
|
|
75336
75726
|
var that = this;
|
|
75337
75727
|
var _enabled = true;
|
|
75338
75728
|
for (var i=0; i<sets.length; i++) {
|
|
@@ -75361,7 +75751,7 @@ dispatches an "undo" event if a CTRL or META plus the U key is pressed
|
|
|
75361
75751
|
that.metaKey = e.metaKey;
|
|
75362
75752
|
if (!_enabled) return;
|
|
75363
75753
|
that.dispatchEvent(e);
|
|
75364
|
-
if (e.keyCode==90 && (that.ctrlKey || that.metaKey)) {
|
|
75754
|
+
if (that.undoKey && e.keyCode==90 && (that.ctrlKey || that.metaKey)) {
|
|
75365
75755
|
that.dispatchEvent("undo");
|
|
75366
75756
|
}
|
|
75367
75757
|
};
|
|
@@ -81218,7 +81608,7 @@ alpha, cursor, shadow, name, mouseChildren, mouseEnabled, parent, numChildren, e
|
|
|
81218
81608
|
//-69.9747
|
|
81219
81609
|
|
|
81220
81610
|
/*--
|
|
81221
|
-
zim.Perspective = function(obj, points, interactive, showControls, allowToggle, move, borderColor, borderWidth, dashed, plane, fade, dynamic, frame, resolution, maskShape, feather, onTop, overlay, clipping, passthrough, passthroughScale, passthroughShiftX, passthroughShiftY, style, group, inherit)
|
|
81611
|
+
zim.Perspective = function(obj, points, interactive, showControls, allowToggle, move, borderColor, borderWidth, dashed, plane, fade, dynamic, frame, resolution, maskShape, feather, onTop, overlay, clipping, passthrough, passthroughScale, passthroughShiftX, passthroughShiftY, passthroughRotation, style, group, inherit)
|
|
81222
81612
|
|
|
81223
81613
|
Perspective
|
|
81224
81614
|
zim class extends ZIM Container which extends CreateJS Container
|
|
@@ -81357,8 +81747,9 @@ fade - (default true) if a plane is set, this will fade the distance
|
|
|
81357
81747
|
dynamic - (default true unless obj is Pic, then false) set to false if a Container, etc. does not change or animate
|
|
81358
81748
|
frame - (default zimDefaultFrame) set the zim Frame the perspective is in if in a different frame than the default frame
|
|
81359
81749
|
resolution - (default 1) the resolution multiplier for the internal WebGL shader canvas (e.g. 0.5 for half-resolution to boost GPU performance on laptops and mobile).
|
|
81360
|
-
maskShape - (default
|
|
81750
|
+
maskShape - (default eye) the cutout mask shape: "rect" (standard 4-corner quad), "circle" (1:1 true circle with aspect-ratio correction), or "ellipse" (stretches to the quad bounds)
|
|
81361
81751
|
or a ZIM DisplayObject (such as a Blob, Circle, or Container) to use as a dynamic GPU alpha mask texture (passed into iChannel1 with multi-tap blur spread).
|
|
81752
|
+
or true to get a Blob in eye shape points radius min of width and height / 2
|
|
81362
81753
|
feather - (default 0) edge softness from 0 to 1 applied to the quad edges, circle/ellipse borders, or texture mask in the GPU shader.
|
|
81363
81754
|
onTop - (default true) set to false to not bring the object to the top of its container when pressed
|
|
81364
81755
|
overlay - (default false) set to true to use a DOM ShaderOverlay (Tag) rather than an in-canvas Shader (Bitmap)
|
|
@@ -81372,6 +81763,7 @@ passthrough - (default false) set to true to display the asset unwarped (at orig
|
|
|
81372
81763
|
passthroughScale - (default 1) scale multiplier for the asset when passthrough is true, scaling from the center of the asset.
|
|
81373
81764
|
passthroughShiftX - (default 0) horizontal pixel offset for the asset beneath the crop window when passthrough is true.
|
|
81374
81765
|
passthroughShiftY - (default 0) vertical pixel offset for the asset beneath the crop window when passthrough is true.
|
|
81766
|
+
passthroughRotation - (default 0) rotation for the asset beneath the crop window when passthrough is true.
|
|
81375
81767
|
style - (default true) set to false to ignore styles set with the STYLE - will receive original parameter defaults
|
|
81376
81768
|
group - (default null) set to String (or comma delimited String) so STYLE can set default styles to the group(s) (like a CSS class)
|
|
81377
81769
|
inherit - (default null) used internally but can receive an {} of styles directly
|
|
@@ -81417,7 +81809,6 @@ toggled - get control state - true if showing and false if not - see toggle() me
|
|
|
81417
81809
|
maskShape - get or set the cutout shape "rect", "circle", "ellipse", or the DisplayObject provided
|
|
81418
81810
|
feather - get or set the edge softness / feathering amount (0 to 1).
|
|
81419
81811
|
resolution - the resolution multiplier of the shader canvas.
|
|
81420
|
-
mask - reference to the mask DisplayObject container if a mask was provided.
|
|
81421
81812
|
onTop - get or set whether the perspective comes to the top of its container when pressed
|
|
81422
81813
|
overlay - get or set whether to render as a DOM ShaderOverlay - see overlay parameter
|
|
81423
81814
|
clipping - get or set whether the overlay canvas bounding box is clamped to the stage boundaries
|
|
@@ -81435,8 +81826,8 @@ x, y, rotation, scaleX, scaleY, regX, regY, skewX, skewY,
|
|
|
81435
81826
|
alpha, cursor, shadow, name, mouseChildren, mouseEnabled, parent, numChildren, etc.
|
|
81436
81827
|
|
|
81437
81828
|
--*///+69.9748
|
|
81438
|
-
zim.Perspective = function(obj, points, interactive, showControls, allowToggle, move, borderColor, borderWidth, dashed, plane, fade, dynamic, frame, resolution, maskShape, feather, onTop, overlay, clipping, passthrough, passthroughScale, passthroughShiftX, passthroughShiftY, style, group, inherit) {
|
|
81439
|
-
var sig = "obj, points, interactive, showControls, allowToggle, move, borderColor, borderWidth, dashed, plane, fade, dynamic, frame, resolution, maskShape, feather, onTop, overlay, clipping, passthrough, passthroughScale, passthroughShiftX, passthroughShiftY, style, group, inherit";
|
|
81829
|
+
zim.Perspective = function(obj, points, interactive, showControls, allowToggle, move, borderColor, borderWidth, dashed, plane, fade, dynamic, frame, resolution, maskShape, feather, onTop, overlay, clipping, passthrough, passthroughScale, passthroughShiftX, passthroughShiftY, passthroughRotation, style, group, inherit) {
|
|
81830
|
+
var sig = "obj, points, interactive, showControls, allowToggle, move, borderColor, borderWidth, dashed, plane, fade, dynamic, frame, resolution, maskShape, feather, onTop, overlay, clipping, passthrough, passthroughScale, passthroughShiftX, passthroughShiftY, passthroughRotation, style, group, inherit";
|
|
81440
81831
|
var duo; if (duo = zob(zim.Perspective, arguments, sig, this)) return duo;
|
|
81441
81832
|
z_d("69.9770");
|
|
81442
81833
|
this.group = group;
|
|
@@ -81459,6 +81850,28 @@ zim.Perspective = function(obj, points, interactive, showControls, allowToggle,
|
|
|
81459
81850
|
if (zot(frame)) frame = DS.frame != null ? DS.frame : zdf;
|
|
81460
81851
|
if (zot(resolution)) resolution = DS.resolution != null ? DS.resolution : 1;
|
|
81461
81852
|
if (zot(maskShape)) maskShape = DS.maskShape != null ? DS.maskShape : "rect";
|
|
81853
|
+
if (maskShape === true) {
|
|
81854
|
+
maskShape = new zim.Blob({
|
|
81855
|
+
points:[
|
|
81856
|
+
[0,90,0,0,-80,0,80,0,"straight"],
|
|
81857
|
+
[150,0,0,0,0,0,0,0,"none"],
|
|
81858
|
+
[0,-90,0,0,80,0,-80,0,"straight"],
|
|
81859
|
+
[-150,0,0,0,0,0,0,0,"none"]
|
|
81860
|
+
],
|
|
81861
|
+
interactive: false
|
|
81862
|
+
})
|
|
81863
|
+
if (obj && obj.width) {
|
|
81864
|
+
var targetW = obj.width;
|
|
81865
|
+
var targetH = obj.height || 1;
|
|
81866
|
+
var factor = Math.min(targetW / maskShape.width, targetH / maskShape.height);
|
|
81867
|
+
maskShape.transformPoints("scale", factor);
|
|
81868
|
+
}
|
|
81869
|
+
} else if (maskShape && maskShape.type=="Blob" && maskShape.scale != 1) {
|
|
81870
|
+
var factor = maskShape.scale;
|
|
81871
|
+
maskShape.scale = 1;
|
|
81872
|
+
maskShape.transformPoints("scale", factor);
|
|
81873
|
+
}
|
|
81874
|
+
if (maskShape && maskShape.type=="Blob") maskShape.hideControls();
|
|
81462
81875
|
if (zot(feather)) feather = DS.feather != null ? DS.feather : 0;
|
|
81463
81876
|
if (zot(onTop)) onTop = DS.onTop != null ? DS.onTop : true;
|
|
81464
81877
|
if (zot(overlay)) overlay = DS.overlay != null ? DS.overlay : false;
|
|
@@ -81467,6 +81880,7 @@ zim.Perspective = function(obj, points, interactive, showControls, allowToggle,
|
|
|
81467
81880
|
if (zot(passthroughScale)) passthroughScale = DS.passthroughScale != null ? DS.passthroughScale : 1;
|
|
81468
81881
|
if (zot(passthroughShiftX)) passthroughShiftX = DS.passthroughShiftX != null ? DS.passthroughShiftX : 0;
|
|
81469
81882
|
if (zot(passthroughShiftY)) passthroughShiftY = DS.passthroughShiftY != null ? DS.passthroughShiftY : 0;
|
|
81883
|
+
if (zot(passthroughRotation)) passthroughRotation = DS.passthroughRotation != null ? DS.passthroughRotation : 0;
|
|
81470
81884
|
|
|
81471
81885
|
var size = Math.max(frame.width, frame.height);
|
|
81472
81886
|
|
|
@@ -81484,7 +81898,7 @@ zim.Perspective = function(obj, points, interactive, showControls, allowToggle,
|
|
|
81484
81898
|
var frag = "uniform vec2 a; uniform vec2 b; uniform vec2 c; uniform vec2 d;\n";
|
|
81485
81899
|
frag += "uniform float plane;\nuniform float fade;\n";
|
|
81486
81900
|
frag += "uniform float shape;\nuniform float feather;\nuniform float aspect;\nuniform float useMaskTex;\n";
|
|
81487
|
-
frag += "uniform float passthrough;\nuniform float passthroughScale;\nuniform vec2 passthroughCenter;\nuniform vec2 passthroughShift;\nuniform vec2 assetNormSize;\n";
|
|
81901
|
+
frag += "uniform float passthrough;\nuniform float passthroughScale;\nuniform float passthroughRotation;\nuniform vec2 passthroughCenter;\nuniform vec2 passthroughShift;\nuniform vec2 assetNormSize;\n";
|
|
81488
81902
|
frag += "#define map(screenpos) ((2.0*(screenpos)-iResolution.xy)/iResolution.y)\n";
|
|
81489
81903
|
frag += "mat3 rproject(vec3 p0, vec3 p1, vec3 p2, vec3 p3) {\n";
|
|
81490
81904
|
frag += " mat3 m = inverse(mat3(p0,p1,p2));\n";
|
|
@@ -81516,7 +81930,12 @@ zim.Perspective = function(obj, points, interactive, showControls, allowToggle,
|
|
|
81516
81930
|
frag += " vec2 texUV;\n";
|
|
81517
81931
|
frag += " if (passthrough > 0.5) {\n";
|
|
81518
81932
|
frag += " vec2 pScale = max(vec2(0.0001), assetNormSize * passthroughScale);\n";
|
|
81519
|
-
frag += "
|
|
81933
|
+
frag += " vec2 pDiff = p - passthroughCenter - passthroughShift;\n";
|
|
81934
|
+
frag += " float rad = radians(-passthroughRotation);\n";
|
|
81935
|
+
frag += " float cosA = cos(rad);\n";
|
|
81936
|
+
frag += " float sinA = sin(rad);\n";
|
|
81937
|
+
frag += " pDiff = mat2(cosA, -sinA, sinA, cosA) * pDiff;\n";
|
|
81938
|
+
frag += " texUV = pDiff / pScale + vec2(0.5);\n";
|
|
81520
81939
|
frag += " if (texUV.x < 0.0 || texUV.x > 1.0 || texUV.y < 0.0 || texUV.y > 1.0) {\n";
|
|
81521
81940
|
frag += " fragColor = vec4(0.0);\n";
|
|
81522
81941
|
frag += " return;\n";
|
|
@@ -81525,9 +81944,13 @@ zim.Perspective = function(obj, points, interactive, showControls, allowToggle,
|
|
|
81525
81944
|
frag += " texUV = tileUV;\n";
|
|
81526
81945
|
frag += " }\n";
|
|
81527
81946
|
frag += " vec4 texColor = texture(iChannel0, texUV);\n";
|
|
81947
|
+
frag += " float alpha = texColor.a;\n";
|
|
81948
|
+
frag += " if (alpha <= 0.0) {\n";
|
|
81949
|
+
frag += " fragColor = vec4(0.0);\n";
|
|
81950
|
+
frag += " return;\n";
|
|
81951
|
+
frag += " }\n";
|
|
81528
81952
|
frag += " vec3 color = pow(texColor.rgb, vec3(2.2));\n";
|
|
81529
81953
|
frag += " color = pow(color, vec3(0.4545));\n";
|
|
81530
|
-
frag += " float alpha = texColor.a;\n";
|
|
81531
81954
|
frag += " // 3. Circle / Ellipse Feather (applied to tileUV)\n";
|
|
81532
81955
|
frag += " if (shape > 0.5) {\n";
|
|
81533
81956
|
frag += " vec2 centerCoord = (tileUV - vec2(0.5)) * 2.0;\n";
|
|
@@ -81578,7 +82001,7 @@ zim.Perspective = function(obj, points, interactive, showControls, allowToggle,
|
|
|
81578
82001
|
frag += " color *= distFade;\n";
|
|
81579
82002
|
frag += " alpha *= distFade;\n";
|
|
81580
82003
|
frag += " }\n";
|
|
81581
|
-
frag += " fragColor = vec4(color, alpha);\n";
|
|
82004
|
+
frag += " fragColor = vec4(color * alpha, alpha);\n";
|
|
81582
82005
|
frag += "}\n";
|
|
81583
82006
|
|
|
81584
82007
|
this.zimContainer_constructor(size, size, null, null, false);
|
|
@@ -81594,6 +82017,7 @@ zim.Perspective = function(obj, points, interactive, showControls, allowToggle,
|
|
|
81594
82017
|
var _maskShape = maskShape;
|
|
81595
82018
|
var _passthrough = Boolean(passthrough);
|
|
81596
82019
|
var _passthroughScale = Number(passthroughScale) || 1;
|
|
82020
|
+
var _passthroughRotation = Number(passthroughRotation) || 0;
|
|
81597
82021
|
var _passthroughShiftX = Number(passthroughShiftX) || 0;
|
|
81598
82022
|
var _passthroughShiftY = Number(passthroughShiftY) || 0;
|
|
81599
82023
|
var _passthroughCenter = null;
|
|
@@ -81744,6 +82168,10 @@ zim.Perspective = function(obj, points, interactive, showControls, allowToggle,
|
|
|
81744
82168
|
var objH = obj.height || (obj.getBounds ? (obj.getBounds() ? obj.getBounds().height : size) : size);
|
|
81745
82169
|
var aspect = objW / objH;
|
|
81746
82170
|
|
|
82171
|
+
// FIX: Shift registration to the internal buffer center and set bounds to the actual object size
|
|
82172
|
+
that.reg(size/2, size/2);
|
|
82173
|
+
that.setBounds(size/2 - objW/2, size/2 - objH/2, objW, objH);
|
|
82174
|
+
|
|
81747
82175
|
var shapeVal = 0;
|
|
81748
82176
|
var useMaskTexVal = 0;
|
|
81749
82177
|
if (typeof _maskShape === "string") {
|
|
@@ -81769,6 +82197,7 @@ zim.Perspective = function(obj, points, interactive, showControls, allowToggle,
|
|
|
81769
82197
|
useMaskTex: useMaskTexVal,
|
|
81770
82198
|
passthrough: _passthrough ? 1 : 0,
|
|
81771
82199
|
passthroughScale: _passthroughScale,
|
|
82200
|
+
passthroughRotation: _passthroughRotation,
|
|
81772
82201
|
passthroughCenter: [initCx, initCy],
|
|
81773
82202
|
passthroughShift: [_passthroughShiftX / size, -_passthroughShiftY / size],
|
|
81774
82203
|
assetNormSize: [objW / size, objH / size]
|
|
@@ -81936,6 +82365,9 @@ zim.Perspective = function(obj, points, interactive, showControls, allowToggle,
|
|
|
81936
82365
|
uniforms.useMaskTex = 1;
|
|
81937
82366
|
setupMaskSource(value);
|
|
81938
82367
|
if (that.shader) that.shader.replaceChannel(maskContainer, 1, false);
|
|
82368
|
+
} else {
|
|
82369
|
+
uniforms.shape = 0;
|
|
82370
|
+
uniforms.useMaskTex = 0;
|
|
81939
82371
|
}
|
|
81940
82372
|
}
|
|
81941
82373
|
});
|
|
@@ -81970,6 +82402,16 @@ zim.Perspective = function(obj, points, interactive, showControls, allowToggle,
|
|
|
81970
82402
|
}
|
|
81971
82403
|
});
|
|
81972
82404
|
|
|
82405
|
+
Object.defineProperty(this, "passthroughRotation", {
|
|
82406
|
+
get: function() {
|
|
82407
|
+
return _passthroughRotation;
|
|
82408
|
+
},
|
|
82409
|
+
set: function(value) {
|
|
82410
|
+
_passthroughRotation = Number(value) || 0;
|
|
82411
|
+
uniforms.passthroughRotation = _passthroughRotation;
|
|
82412
|
+
}
|
|
82413
|
+
});
|
|
82414
|
+
|
|
81973
82415
|
Object.defineProperty(this, "passthroughShiftX", {
|
|
81974
82416
|
get: function() {
|
|
81975
82417
|
return _passthroughShiftX;
|
|
@@ -82296,7 +82738,7 @@ zim.Perspective = function(obj, points, interactive, showControls, allowToggle,
|
|
|
82296
82738
|
if (style !== false) zim.styleTransforms(this, DS);
|
|
82297
82739
|
|
|
82298
82740
|
this.clone = function(exact) {
|
|
82299
|
-
return that.cloneProps(new zim.Perspective((exact || !zim.isPick(oa[0])) ? obj : oa[0], points, interactive, showControls, allowToggle, move, (exact || !zim.isPick(oa[1])) ? borderColor : oa[1], (exact || !zim.isPick(oa[2])) ? borderWidth : oa[2], (exact || !zim.isPick(oa[3])) ? dashed : oa[3], plane, fade, dynamic, frame, resolution, _maskShape, feather, _onTop, _overlay, _clipping, _passthrough, _passthroughScale, _passthroughShiftX, _passthroughShiftY, style, this.group, inherit));
|
|
82741
|
+
return that.cloneProps(new zim.Perspective((exact || !zim.isPick(oa[0])) ? obj : oa[0], points, interactive, showControls, allowToggle, move, (exact || !zim.isPick(oa[1])) ? borderColor : oa[1], (exact || !zim.isPick(oa[2])) ? borderWidth : oa[2], (exact || !zim.isPick(oa[3])) ? dashed : oa[3], plane, fade, dynamic, frame, resolution, _maskShape, feather, _onTop, _overlay, _clipping, _passthrough, _passthroughScale, _passthroughShiftX, _passthroughShiftY, _passthroughRotation, style, this.group, inherit));
|
|
82300
82742
|
};
|
|
82301
82743
|
};
|
|
82302
82744
|
zim.extend(zim.Perspective, zim.Container, ["clone", "dispose"], "zimContainer", false);
|
|
@@ -93556,6 +93998,13 @@ zim.Frame = function(scaling, width, height, color, outerColor, ready, assets, p
|
|
|
93556
93998
|
var imagesNoCORS = [];
|
|
93557
93999
|
var mainCount = 0;
|
|
93558
94000
|
var firstSoundCheck = true;
|
|
94001
|
+
|
|
94002
|
+
var videoRegex = /\.(mp4|mkv|webm|avi|mov|wmv|flv|m4v|3gp|ts)(?=[?#]|$)/i;
|
|
94003
|
+
function isVideoUrl(url) {
|
|
94004
|
+
if (url && url.src) url = url.src;
|
|
94005
|
+
if (typeof url !== 'string') return false;
|
|
94006
|
+
return videoRegex.test(url);
|
|
94007
|
+
}
|
|
93559
94008
|
|
|
93560
94009
|
// 018 TRYING TO FIX CREATEJS ERROR IF SOUND LOADED AGAIN - BUT BREAKS LAZY LOAD
|
|
93561
94010
|
// var emptyAssets = false;
|
|
@@ -93570,7 +94019,7 @@ zim.Frame = function(scaling, width, height, color, outerColor, ready, assets, p
|
|
|
93570
94019
|
// // }
|
|
93571
94020
|
// }
|
|
93572
94021
|
|
|
93573
|
-
|
|
94022
|
+
|
|
93574
94023
|
|
|
93575
94024
|
var match;
|
|
93576
94025
|
if (a.match) match = a.match(/^noto_(.*)/);
|
|
@@ -93586,6 +94035,7 @@ zim.Frame = function(scaling, width, height, color, outerColor, ready, assets, p
|
|
|
93586
94035
|
for (j=0; j<a.assets.length; j++) {
|
|
93587
94036
|
var aj = a.assets[j];
|
|
93588
94037
|
match = null;
|
|
94038
|
+
if (isVideoUrl(aj)) continue;
|
|
93589
94039
|
if (aj.match) match = aj.match(/^noto_(.*)/);
|
|
93590
94040
|
if (match) {
|
|
93591
94041
|
aj = {id:aj, src:"https://raw.githubusercontent.com/googlefonts/noto-emoji/main/svg/" + getNotoFilename(match[1])}
|
|
@@ -93619,7 +94069,8 @@ zim.Frame = function(scaling, width, height, color, outerColor, ready, assets, p
|
|
|
93619
94069
|
}
|
|
93620
94070
|
a = assetMulti[0];
|
|
93621
94071
|
if (a==undefined) continue;
|
|
93622
|
-
}
|
|
94072
|
+
}
|
|
94073
|
+
if (isVideoUrl(a))continue;
|
|
93623
94074
|
|
|
93624
94075
|
// catch {src} without id and just replace it with src unless google font
|
|
93625
94076
|
if (a.constructor == {}.constructor) {
|
|
@@ -94005,6 +94456,11 @@ zim.Frame = function(scaling, width, height, color, outerColor, ready, assets, p
|
|
|
94005
94456
|
if (!queueOnly) that.dispatchEvent(completeEventObject);
|
|
94006
94457
|
}, time*(timeType=="s"?1000:1));
|
|
94007
94458
|
}
|
|
94459
|
+
|
|
94460
|
+
if (queue.loadAssetsCount == 0) {
|
|
94461
|
+
endAssetLoad();
|
|
94462
|
+
}
|
|
94463
|
+
|
|
94008
94464
|
return queue;
|
|
94009
94465
|
};
|
|
94010
94466
|
|
|
@@ -96366,11 +96822,12 @@ bitmap - (default true) this will show the SVG as a Bitmap (still nicely scalabl
|
|
|
96366
96822
|
or set to false to use an SVGContainer() which converts the SVG to Blob, Squiggle and ZIM Shapes with transforms.
|
|
96367
96823
|
This allows for editable paths - but perhaps not all aspects of SVGs are supported such as CSS styles on SVGs.
|
|
96368
96824
|
Alternatively, a single SVG path can be passed to a ZIM Blob() or Squiggle() and SVG() can be avoided.
|
|
96825
|
+
Note: when color, borderColor, or order is set then bitmap is set to false
|
|
96369
96826
|
** these parameters are NOT for the bitmap option but rather for the SVGContainer
|
|
96370
96827
|
splitTypes - (default false) - set to true to split different types of paths into separate objects
|
|
96371
96828
|
geometric - (default true) - set to false to load Rectangle and Circle objects as Blob objects
|
|
96372
96829
|
showControls - (default true) set to false to start with controls not showing
|
|
96373
|
-
interactive - (default true
|
|
96830
|
+
interactive - (default true or false if bitmap or colored below) set to false to turn off controls, move, toggle, select, edit - leaving just the shapes
|
|
96374
96831
|
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
|
|
96375
96832
|
usually a series() would be used here for colors in order, or an array for random colors
|
|
96376
96833
|
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
|
|
@@ -96437,10 +96894,16 @@ added, click, dblclick, mousedown, mouseout, mouseover, pressdown (ZIM), pressmo
|
|
|
96437
96894
|
if (zot(splitTypes)) splitTypes = DS.splitTypes!=null?DS.splitTypes:false;
|
|
96438
96895
|
if (zot(geometric)) geometric = DS.geometric!=null?DS.geometric:true;
|
|
96439
96896
|
if (zot(showControls)) showControls = DS.showControls!=null?DS.showControls:null;
|
|
96440
|
-
if (zot(interactive)) interactive = DS.interactive!=null?DS.interactive:true;
|
|
96441
96897
|
if (zot(color)) color = DS.color!=null?DS.color:null;
|
|
96442
96898
|
if (zot(borderColor)) borderColor = DS.borderColor!=null?DS.borderColor:null;
|
|
96443
96899
|
if (zot(order)) order = DS.order!=null?DS.order:null;
|
|
96900
|
+
|
|
96901
|
+
var colored = false;
|
|
96902
|
+
if (color || borderColor || order) {
|
|
96903
|
+
bitmap = false;
|
|
96904
|
+
colored = true;
|
|
96905
|
+
}
|
|
96906
|
+
if (zot(interactive)) interactive = DS.interactive!=null?DS.interactive:!colored; // don't set to interactive if colored
|
|
96444
96907
|
|
|
96445
96908
|
var setColors = [];
|
|
96446
96909
|
var setBorderColors = [];
|
|
@@ -96871,277 +97334,606 @@ Note: there are more features to the Web Speech API - see the HTML docs
|
|
|
96871
97334
|
//-83.095
|
|
96872
97335
|
|
|
96873
97336
|
/*--
|
|
96874
|
-
Hardware = function(callback, baudRate, delimiter)
|
|
97337
|
+
Hardware = function(preset, callback, baudRate, delimiter, mode, autoParse)
|
|
96875
97338
|
|
|
96876
97339
|
Hardware
|
|
96877
97340
|
zim class - extends a createjs.EventDispatcher
|
|
97341
|
+
Supports DUO - pass parameters positionally or as a single configuration object {preset: "microblocks", callback: ...}
|
|
96878
97342
|
|
|
96879
97343
|
DESCRIPTION
|
|
96880
|
-
|
|
96881
|
-
|
|
96882
|
-
|
|
96883
|
-
|
|
97344
|
+
Connects interactive ZIM canvas applications directly to physical microcontrollers, sensors, dials, and actuators.
|
|
97345
|
+
Communicates via standard USB cables using the JS Web Serial API or wirelessly via the JS Web Bluetooth (BLE UART) API.
|
|
97346
|
+
Works with MicroBlocks, BBC micro:bit, Raspberry Pi Pico / RP2040, Arduino, Adafruit Circuit Playground / Feather (CircuitPython / MicroPython), ESP32, and LEGO SPIKE Prime.
|
|
97347
|
+
Automatically parses incoming data into JavaScript numbers, key-value pairs, or JSON objects.
|
|
96884
97348
|
|
|
96885
97349
|
See: https://zimjs.com/hardware/
|
|
96886
97350
|
|
|
96887
|
-
NOTE:
|
|
97351
|
+
NOTE: Browser security requires that hardware.connect() be called inside a user gesture (such as a Button tap or Pane close). Supported in Chromium-based browsers (Chrome, Edge, Opera) on desktop, Android, and Chromebooks.
|
|
96888
97352
|
|
|
96889
97353
|
EXAMPLE
|
|
96890
|
-
//
|
|
96891
|
-
|
|
96892
|
-
//
|
|
96893
|
-
//
|
|
96894
|
-
|
|
96895
|
-
// ------------------------
|
|
96896
|
-
// ---- Arduinin Code -----
|
|
97354
|
+
// -------------------------------------------------------
|
|
97355
|
+
// ---- EXAMPLE 1: ARDUINO (Bidirectional LED & Dial) ----
|
|
97356
|
+
// -------------------------------------------------------
|
|
97357
|
+
// On Arduino Uno/Nano: connect a potentiometer to A0 and built-in LED on Pin 13
|
|
97358
|
+
// Upload the following Arduino C++ code:
|
|
96897
97359
|
|
|
96898
|
-
const int
|
|
97360
|
+
const int potPin = A0;
|
|
97361
|
+
const int ledPin = 13;
|
|
96899
97362
|
void setup() {
|
|
96900
|
-
Serial.begin(9600);
|
|
96901
|
-
pinMode(
|
|
97363
|
+
Serial.begin(9600);
|
|
97364
|
+
pinMode(ledPin, OUTPUT);
|
|
96902
97365
|
}
|
|
96903
97366
|
void loop() {
|
|
96904
|
-
//
|
|
97367
|
+
// Read Potentiometer and send to ZIM
|
|
97368
|
+
int potValue = analogRead(potPin);
|
|
97369
|
+
Serial.println(potValue); // sends number + \n
|
|
97370
|
+
|
|
97371
|
+
// Receive LED command from ZIM
|
|
96905
97372
|
if (Serial.available() > 0) {
|
|
96906
|
-
char
|
|
96907
|
-
if (
|
|
96908
|
-
|
|
96909
|
-
}
|
|
96910
|
-
else if (incomingChar == '0') {
|
|
96911
|
-
digitalWrite(LED_PIN, LOW); // Turn physical light OFF
|
|
96912
|
-
}
|
|
97373
|
+
char c = Serial.read();
|
|
97374
|
+
if (c == '1') digitalWrite(ledPin, HIGH);
|
|
97375
|
+
else if (c == '0') digitalWrite(ledPin, LOW);
|
|
96913
97376
|
}
|
|
97377
|
+
delay(30);
|
|
96914
97378
|
}
|
|
96915
97379
|
|
|
96916
|
-
//
|
|
96917
|
-
//
|
|
97380
|
+
// ZIM Front-End Code:
|
|
97381
|
+
// Preset "arduino" sets baud rate to 9600 automatically
|
|
97382
|
+
const device = new Hardware("arduino", data => {
|
|
97383
|
+
dial.currentValue = data; // data automatically parsed as Number (0-1023)
|
|
97384
|
+
S.update();
|
|
97385
|
+
});
|
|
96918
97386
|
|
|
96919
|
-
const
|
|
97387
|
+
const dial = new Dial({min: 0, max: 1023}).center();
|
|
96920
97388
|
|
|
96921
|
-
const toggle = new Toggle({
|
|
96922
|
-
|
|
96923
|
-
toggleBackgroundColor: green,
|
|
96924
|
-
color: white
|
|
96925
|
-
})
|
|
96926
|
-
.center()
|
|
97389
|
+
const toggle = new Toggle({label: "ARDUINO LED", toggleBackgroundColor: green})
|
|
97390
|
+
.pos(0, 100, CENTER, BOTTOM)
|
|
96927
97391
|
.change(() => {
|
|
96928
|
-
|
|
96929
|
-
device.write("1"); // note a \n will be automatically added if missing
|
|
96930
|
-
} else {
|
|
96931
|
-
device.write("0");
|
|
96932
|
-
}
|
|
97392
|
+
device.write(toggle.toggled ? "1" : "0");
|
|
96933
97393
|
});
|
|
96934
97394
|
|
|
96935
|
-
//
|
|
96936
|
-
|
|
96937
|
-
|
|
96938
|
-
|
|
96939
|
-
|
|
96940
|
-
device.on("disconnected", () => {
|
|
96941
|
-
pane.show(() => { // remember to add the callback again
|
|
97395
|
+
// Connect on user interaction
|
|
97396
|
+
new Button({label: "CONNECT", width:AUTO})
|
|
97397
|
+
.pos(30, 30, RIGHT, TOP)
|
|
97398
|
+
.tap(e => {
|
|
96942
97399
|
device.connect();
|
|
97400
|
+
e.target.removeFrom();
|
|
97401
|
+
S.update();
|
|
96943
97402
|
});
|
|
97403
|
+
END EXAMPLE
|
|
97404
|
+
|
|
97405
|
+
EXAMPLE
|
|
97406
|
+
// ----------------------------------------------------
|
|
97407
|
+
// ---- EXAMPLE 2: MICROBLOCKS (Live Block Scripting) -
|
|
97408
|
+
// ----------------------------------------------------
|
|
97409
|
+
// MicroBlocks (https://microblocks.fun) runs live on micro:bit, ESP32, RP2040, etc.
|
|
97410
|
+
// In MicroBlocks, use the Serial library blocks:
|
|
97411
|
+
// [when started]
|
|
97412
|
+
// [forever]
|
|
97413
|
+
// [serial write line (join "pot:" (analog pin 1))]
|
|
97414
|
+
// [wait 50 ms]
|
|
97415
|
+
// [when serial received]
|
|
97416
|
+
// [if ((last serial line) == "beep")]
|
|
97417
|
+
// [play tone 440 for 200 ms]
|
|
97418
|
+
|
|
97419
|
+
// ZIM Front-End Code:
|
|
97420
|
+
// Default preset is "microblocks" (115200 baud)
|
|
97421
|
+
const hw = new Hardware("microblocks", data => {
|
|
97422
|
+
// Key-value pairs like "pot:512" automatically parse into hw.data.pot or hw.get("pot")
|
|
97423
|
+
circle.sca(map(hw.get("pot"), 0, 1023, 0.5, 3));
|
|
97424
|
+
S.update();
|
|
97425
|
+
});
|
|
97426
|
+
|
|
97427
|
+
const circle = new Circle(60, orange).center();
|
|
97428
|
+
|
|
97429
|
+
circle.tap(() => {
|
|
97430
|
+
hw.write("beep"); // Triggers tone on the microcontroller
|
|
97431
|
+
});
|
|
97432
|
+
|
|
97433
|
+
new Button({label: "CONNECT", width:AUTO}).pos(30, 30, RIGHT, TOP).tap(e => {
|
|
97434
|
+
hw.connect();
|
|
97435
|
+
e.target.removeFrom();
|
|
97436
|
+
S.update();
|
|
96944
97437
|
});
|
|
96945
97438
|
END EXAMPLE
|
|
96946
97439
|
|
|
96947
97440
|
EXAMPLE
|
|
96948
|
-
//
|
|
96949
|
-
|
|
97441
|
+
// ----------------------------------------------------
|
|
97442
|
+
// ---- EXAMPLE 3: BBC MICRO:BIT (MakeCode Serial) ----
|
|
97443
|
+
// ----------------------------------------------------
|
|
97444
|
+
// In MakeCode (https://makecode.microbit.org):
|
|
97445
|
+
// basic.forever(function () {
|
|
97446
|
+
// serial.writeLine("x:" + input.acceleration(Dimension.X))
|
|
97447
|
+
// basic.pause(50)
|
|
97448
|
+
// })
|
|
97449
|
+
// serial.onDataReceived(serial.delimiters(Delimiters.NewLine), function () {
|
|
97450
|
+
// let msg = serial.readString()
|
|
97451
|
+
// if (msg.includes("icon")) basic.showIcon(IconNames.Heart)
|
|
97452
|
+
// })
|
|
97453
|
+
|
|
97454
|
+
// ZIM Front-End Code:
|
|
97455
|
+
const mb = new Hardware("microbit");
|
|
97456
|
+
const pd = new ProportionDamp(-1023, 1023, 0, W);
|
|
97457
|
+
mb.on("data", e => {
|
|
97458
|
+
if (e.key === "x") {
|
|
97459
|
+
character.x = pd.convert(e.val);
|
|
97460
|
+
S.update();
|
|
97461
|
+
}
|
|
97462
|
+
});
|
|
96950
97463
|
|
|
96951
|
-
|
|
96952
|
-
// with a potentiometer (pot) dial
|
|
96953
|
-
// (probably on a breadboard)
|
|
96954
|
-
// with outside pins goint to ground and 5V
|
|
96955
|
-
// and middle pin goint to analogue A0
|
|
96956
|
-
// with the following .ino file loaded onto it
|
|
97464
|
+
const character = new Rectangle(60, 60, purple).centerReg();
|
|
96957
97465
|
|
|
96958
|
-
|
|
96959
|
-
|
|
97466
|
+
character.tap(() => {
|
|
97467
|
+
mb.write("icon");
|
|
97468
|
+
});
|
|
97469
|
+
|
|
97470
|
+
new Button({label: "CONNECT MICRO:BIT", width:AUTO}).center().tap(e => {
|
|
97471
|
+
mb.connect();
|
|
97472
|
+
e.target.removeFrom();
|
|
97473
|
+
S.update();
|
|
97474
|
+
});
|
|
97475
|
+
END EXAMPLE
|
|
97476
|
+
|
|
97477
|
+
EXAMPLE
|
|
97478
|
+
// ----------------------------------------------------
|
|
97479
|
+
// ---- EXAMPLE 4: CIRCUITPYTHON / MICROPYTHON (PICO) -
|
|
97480
|
+
// ----------------------------------------------------
|
|
97481
|
+
// On Raspberry Pi Pico / Adafruit boards running CircuitPython or MicroPython (code.py):
|
|
97482
|
+
|
|
97483
|
+
import time
|
|
97484
|
+
import json
|
|
97485
|
+
import board
|
|
97486
|
+
import analogio
|
|
97487
|
+
|
|
97488
|
+
pot = analogio.AnalogIn(board.A0)
|
|
97489
|
+
while True:
|
|
97490
|
+
# Send JSON packet
|
|
97491
|
+
data = {"pot": pot.value, "time": time.monotonic()}
|
|
97492
|
+
print(json.dumps(data))
|
|
97493
|
+
time.sleep(0.05)
|
|
96960
97494
|
|
|
96961
|
-
const int potPin = A0;
|
|
96962
|
-
void setup() {
|
|
96963
|
-
Serial.begin(9600);
|
|
96964
|
-
}
|
|
96965
|
-
void loop() {
|
|
96966
|
-
int potValue = analogRead(potPin);
|
|
96967
|
-
Serial.println(potValue);
|
|
96968
|
-
delay(20);
|
|
96969
|
-
}
|
|
96970
97495
|
|
|
96971
|
-
//
|
|
96972
|
-
|
|
97496
|
+
// ZIM Front-End Code:
|
|
97497
|
+
const pico = new Hardware("pico", data => {
|
|
97498
|
+
// JSON is automatically parsed into a native object:
|
|
97499
|
+
slider.currentValue = data.pot;
|
|
97500
|
+
S.update();
|
|
97501
|
+
});
|
|
96973
97502
|
|
|
96974
|
-
const
|
|
96975
|
-
|
|
97503
|
+
const slider = new Slider({min: 0, max: 65535}).center();
|
|
97504
|
+
|
|
97505
|
+
new Button({label: "CONNECT PICO", width:AUTO}).center().tap(e => {
|
|
97506
|
+
pico.connect();
|
|
97507
|
+
e.target.removeFrom();
|
|
97508
|
+
S.update();
|
|
96976
97509
|
});
|
|
97510
|
+
END EXAMPLE
|
|
96977
97511
|
|
|
96978
|
-
|
|
96979
|
-
|
|
96980
|
-
|
|
97512
|
+
EXAMPLE
|
|
97513
|
+
// ----------------------------------------------------
|
|
97514
|
+
// ---- EXAMPLE 5: WIRELESS BLUETOOTH (BLE UART) ------
|
|
97515
|
+
// ----------------------------------------------------
|
|
97516
|
+
// Connects wirelessly to BBC micro:bit, ESP32, or Adafruit Bluefruit boards advertising Nordic UART Service
|
|
97517
|
+
const wireless = new Hardware("ble", data => {
|
|
97518
|
+
label.text = "Received: " + data;
|
|
97519
|
+
S.update();
|
|
96981
97520
|
});
|
|
96982
97521
|
|
|
96983
|
-
|
|
96984
|
-
|
|
96985
|
-
|
|
96986
|
-
|
|
97522
|
+
const label = new Label("Waiting for BLE...").center();
|
|
97523
|
+
|
|
97524
|
+
new Button({label: "CONNECT BLUETOOTH", width:AUTO}).pos(0, 100, CENTER, BOTTOM).tap(e => {
|
|
97525
|
+
wireless.connect();
|
|
97526
|
+
e.target.removeFrom();
|
|
97527
|
+
S.update();
|
|
96987
97528
|
});
|
|
96988
|
-
END EXAMPLE
|
|
97529
|
+
END EXAMPLE
|
|
96989
97530
|
|
|
96990
|
-
PARAMETERS
|
|
96991
|
-
|
|
96992
|
-
|
|
96993
|
-
|
|
97531
|
+
PARAMETERS
|
|
97532
|
+
** supports DUO - parameters or single object with properties below
|
|
97533
|
+
preset - (default "arduino") target hardware profile ("arduino", "microblocks", "microbit", "pico", "circuitpython", "micropython", "lego", "spike", "ble", "bluetooth")
|
|
97534
|
+
Note: if a function is passed as the first parameter, it is treated as the callback. If a number is passed, it is treated as baudRate.
|
|
97535
|
+
callback - (default null) function called when data arrives: callback(data, raw, event)
|
|
97536
|
+
baudRate - (default 9600 for "arduino", 115200 for modern platforms) serial transmission speed
|
|
97537
|
+
delimiter - (default "\n") character or regex string used to split incoming messages and appended to outgoing writes
|
|
97538
|
+
mode - (default "serial") transport layer: "serial" (Web Serial via USB) or "bluetooth" (Web Bluetooth BLE UART)
|
|
97539
|
+
autoParse - (default true) automatically parses incoming lines into Numbers, Key-Value objects, or JSON objects
|
|
96994
97540
|
|
|
96995
97541
|
METHODS
|
|
96996
|
-
connect() -
|
|
96997
|
-
|
|
96998
|
-
|
|
97542
|
+
connect() - triggers browser connection dialog to choose device.
|
|
97543
|
+
Must be called inside user interaction
|
|
97544
|
+
For example, use a ZIM Pane().show(()={// put connect here})
|
|
97545
|
+
Dispatches "connected" event. Returns this for chaining.
|
|
97546
|
+
write(data) - sends string or number to hardware. Automatically appends delimiter if missing. Returns this for chaining.
|
|
97547
|
+
disconnect() - cleanly shuts down streams and closes connection. Dispatches "disconnected" event. Returns this for chaining.
|
|
97548
|
+
get(name) - returns latest value received for a given key name (e.g. hw.get("pot") or hw.get("x")).
|
|
96999
97549
|
|
|
97000
97550
|
PROPERTIES
|
|
97001
|
-
type - holds the class name as a String
|
|
97002
|
-
|
|
97003
|
-
|
|
97004
|
-
|
|
97005
|
-
|
|
97006
|
-
|
|
97007
|
-
|
|
97008
|
-
|
|
97009
|
-
|
|
97551
|
+
type - holds the class name as a String ("Hardware")
|
|
97552
|
+
preset - the hardware profile name in use
|
|
97553
|
+
callback - the function assigned to receive incoming data
|
|
97554
|
+
baudRate - the baud rate in use
|
|
97555
|
+
delimiter - the delimiter string
|
|
97556
|
+
mode - "serial" or "bluetooth"
|
|
97557
|
+
autoParse - boolean indicating if auto-parsing is active
|
|
97558
|
+
connected - boolean indicating if currently connected to hardware
|
|
97559
|
+
isListening - boolean indicating if reading loop is active
|
|
97560
|
+
data - object holding latest key-value state received
|
|
97561
|
+
raw - String of the most recent raw unparsed line
|
|
97562
|
+
value - most recent parsed value (Number, Object, or String)
|
|
97563
|
+
port - readonly Web Serial port instance (serial mode)
|
|
97564
|
+
reader - readonly stream reader instance (serial mode)
|
|
97565
|
+
writer - readonly stream writer instance (serial mode)
|
|
97566
|
+
bleDevice - readonly Web Bluetooth device instance (bluetooth mode)
|
|
97010
97567
|
|
|
97011
97568
|
EVENTS
|
|
97012
|
-
dispatches "connected" when
|
|
97013
|
-
dispatches "disconnected" when disconnected
|
|
97569
|
+
dispatches "connected" when hardware connection opens successfully
|
|
97570
|
+
dispatches "disconnected" when hardware is manually disconnected or cable is pulled
|
|
97571
|
+
dispatches "data" when a line/packet of data is received. Event object contains:
|
|
97572
|
+
e.data (or e.value) - parsed data (Number, Object, String)
|
|
97573
|
+
e.raw - original raw line String
|
|
97574
|
+
e.key - key String if received as key:value or key=value
|
|
97575
|
+
e.val - value if received as key:value or key=value
|
|
97576
|
+
dispatches "error" if connection or transmission fails
|
|
97014
97577
|
--*///+83.097
|
|
97015
|
-
|
|
97016
|
-
|
|
97017
|
-
|
|
97018
|
-
this.type = "Hardware";
|
|
97019
|
-
var that = this;
|
|
97578
|
+
zim.Hardware = function(preset, callback, baudRate, delimiter, mode, autoParse) {
|
|
97579
|
+
var sig = "preset, callback, baudRate, delimiter, mode, autoParse";
|
|
97580
|
+
var duo; if (duo = zot(arguments, sig, this)) return duo;
|
|
97020
97581
|
|
|
97021
|
-
|
|
97022
|
-
|
|
97582
|
+
this.cjsEventDispatcher_constructor();
|
|
97583
|
+
this.type = "Hardware";
|
|
97584
|
+
var that = this;
|
|
97023
97585
|
|
|
97024
|
-
|
|
97025
|
-
|
|
97026
|
-
|
|
97027
|
-
|
|
97028
|
-
|
|
97029
|
-
|
|
97030
|
-
|
|
97031
|
-
|
|
97032
|
-
|
|
97033
|
-
|
|
97034
|
-
|
|
97035
|
-
|
|
97036
|
-
|
|
97037
|
-
|
|
97038
|
-
|
|
97039
|
-
that.isListening = false;
|
|
97586
|
+
// MONITOR
|
|
97587
|
+
this.mID = "z~" + this.type;
|
|
97588
|
+
|
|
97589
|
+
// Backward Compatibility & Flexible Parameter Detection
|
|
97590
|
+
if (typeof preset === "function") {
|
|
97591
|
+
callback = preset;
|
|
97592
|
+
preset = "arduino";
|
|
97593
|
+
} else if (typeof preset === "number") {
|
|
97594
|
+
baudRate = preset;
|
|
97595
|
+
preset = "custom";
|
|
97596
|
+
}
|
|
97597
|
+
if (typeof callback === "number") {
|
|
97598
|
+
baudRate = callback;
|
|
97599
|
+
callback = null;
|
|
97600
|
+
}
|
|
97040
97601
|
|
|
97041
|
-
|
|
97042
|
-
|
|
97043
|
-
|
|
97044
|
-
|
|
97045
|
-
|
|
97046
|
-
|
|
97047
|
-
|
|
97048
|
-
|
|
97049
|
-
|
|
97050
|
-
|
|
97051
|
-
|
|
97052
|
-
|
|
97602
|
+
// Platform Presets (Default baud rates & transport modes)
|
|
97603
|
+
var presets = {
|
|
97604
|
+
"microblocks": { baudRate: 115200, delimiter: "\n", mode: "serial" },
|
|
97605
|
+
"microbit": { baudRate: 115200, delimiter: "\n", mode: "serial" },
|
|
97606
|
+
"pico": { baudRate: 115200, delimiter: "\n", mode: "serial" },
|
|
97607
|
+
"circuitpython": { baudRate: 115200, delimiter: "\n", mode: "serial" },
|
|
97608
|
+
"micropython": { baudRate: 115200, delimiter: "\n", mode: "serial" },
|
|
97609
|
+
"lego": { baudRate: 115200, delimiter: "\n", mode: "serial" },
|
|
97610
|
+
"spike": { baudRate: 115200, delimiter: "\n", mode: "serial" },
|
|
97611
|
+
"arduino": { baudRate: 9600, delimiter: "\n", mode: "serial" },
|
|
97612
|
+
"ble": { baudRate: null, delimiter: "\n", mode: "bluetooth" },
|
|
97613
|
+
"bluetooth": { baudRate: null, delimiter: "\n", mode: "bluetooth" }
|
|
97614
|
+
};
|
|
97615
|
+
|
|
97616
|
+
var pKey = preset ? String(preset).toLowerCase() : "arduino";
|
|
97617
|
+
var profile = presets[pKey] || presets["arduino"];
|
|
97618
|
+
|
|
97619
|
+
// Core Properties
|
|
97620
|
+
that.preset = preset || "arduino";
|
|
97621
|
+
that.callback = callback;
|
|
97622
|
+
that.baudRate = baudRate || profile.baudRate || 115200;
|
|
97623
|
+
that.delimiter = delimiter != null ? delimiter : profile.delimiter;
|
|
97624
|
+
that.mode = (mode || profile.mode || "serial").toLowerCase();
|
|
97625
|
+
that.autoParse = autoParse != null ? autoParse : true;
|
|
97626
|
+
|
|
97627
|
+
// Connection State
|
|
97628
|
+
that.port = null;
|
|
97629
|
+
that.reader = null;
|
|
97630
|
+
that.writer = null;
|
|
97631
|
+
that.textDecoder = null;
|
|
97632
|
+
that.isListening = false;
|
|
97633
|
+
that.connected = false;
|
|
97634
|
+
|
|
97635
|
+
// Bluetooth Properties
|
|
97636
|
+
that.bleDevice = null;
|
|
97637
|
+
that.bleServer = null;
|
|
97638
|
+
that.bleRxCharacteristic = null; // write
|
|
97639
|
+
that.bleTxCharacteristic = null; // notify/read
|
|
97640
|
+
|
|
97641
|
+
// Data Cache
|
|
97642
|
+
that.data = {};
|
|
97643
|
+
that.raw = "";
|
|
97644
|
+
that.value = null;
|
|
97645
|
+
that._buffer = "";
|
|
97646
|
+
|
|
97647
|
+
// Universal Nordic UART Service UUIDs (micro:bit, Adafruit Bluefruit, ESP32, Arduino BLE)
|
|
97648
|
+
var UART_SERVICE_UUID = "6e400001-b5a3-f393-e0a9-e50e24dcca9e";
|
|
97649
|
+
var UART_RX_UUID = "6e400002-b5a3-f393-e0a9-e50e24dcca9e";
|
|
97650
|
+
var UART_TX_UUID = "6e400003-b5a3-f393-e0a9-e50e24dcca9e";
|
|
97651
|
+
|
|
97652
|
+
// GLOBAL HARDWARE DISCONNECT MONITOR (Web Serial)
|
|
97653
|
+
if (navigator.serial) {
|
|
97654
|
+
navigator.serial.addEventListener("disconnect", function(event) {
|
|
97655
|
+
if (event.target === that.port) {
|
|
97656
|
+
zogy("ZIM Hardware: serial device physically disconnected");
|
|
97657
|
+
that._handleDisconnect();
|
|
97658
|
+
}
|
|
97659
|
+
});
|
|
97660
|
+
}
|
|
97661
|
+
|
|
97662
|
+
// CONNECT METHOD (Web Serial or Web Bluetooth)
|
|
97663
|
+
that.connect = function() {
|
|
97664
|
+
if (that.mode === "bluetooth" || that.mode === "ble") {
|
|
97665
|
+
that._connectBluetooth();
|
|
97666
|
+
} else {
|
|
97667
|
+
that._connectSerial();
|
|
97668
|
+
}
|
|
97669
|
+
return that;
|
|
97670
|
+
};
|
|
97671
|
+
|
|
97672
|
+
// SERIAL CONNECTION
|
|
97673
|
+
that._connectSerial = function() {
|
|
97674
|
+
if (!navigator.serial) {
|
|
97675
|
+
console.error("ZIM Hardware: Web Serial API is not supported in this browser. Please use Chrome, Edge, or Opera.");
|
|
97676
|
+
that.dispatchEvent({ type: "error", error: "Web Serial not supported" });
|
|
97677
|
+
return;
|
|
97678
|
+
}
|
|
97679
|
+
|
|
97680
|
+
navigator.serial.requestPort()
|
|
97681
|
+
.then(function(selectedPort) {
|
|
97682
|
+
that.port = selectedPort;
|
|
97683
|
+
return that.port.open({ baudRate: that.baudRate });
|
|
97684
|
+
})
|
|
97685
|
+
.then(function() {
|
|
97686
|
+
zogy("ZIM Hardware: serial connected (" + that.preset + " @ " + that.baudRate + " baud)");
|
|
97687
|
+
that.isListening = true;
|
|
97688
|
+
that.connected = true;
|
|
97689
|
+
that._buffer = "";
|
|
97690
|
+
|
|
97691
|
+
// Output Stream (Browser to Microcontroller)
|
|
97692
|
+
var textEncoder = new TextEncoderStream();
|
|
97693
|
+
textEncoder.readable.pipeTo(that.port.writable);
|
|
97694
|
+
that.writer = textEncoder.writable.getWriter();
|
|
97695
|
+
|
|
97696
|
+
// Input Stream (Microcontroller to Browser)
|
|
97697
|
+
that.textDecoder = new TextDecoderStream();
|
|
97698
|
+
that.port.readable.pipeTo(that.textDecoder.writable);
|
|
97699
|
+
that.reader = that.textDecoder.readable.getReader();
|
|
97700
|
+
|
|
97701
|
+
// Start background reader
|
|
97702
|
+
that._readLoop();
|
|
97703
|
+
that.dispatchEvent("connected");
|
|
97704
|
+
})
|
|
97705
|
+
.catch(function(error) {
|
|
97706
|
+
console.error("ZIM Hardware: serial connection failed:", error);
|
|
97707
|
+
that.dispatchEvent({ type: "error", error: error });
|
|
97053
97708
|
});
|
|
97709
|
+
};
|
|
97710
|
+
|
|
97711
|
+
// BLUETOOTH (BLE UART) CONNECTION
|
|
97712
|
+
that._connectBluetooth = function() {
|
|
97713
|
+
if (!navigator.bluetooth) {
|
|
97714
|
+
console.error("ZIM Hardware: Web Bluetooth API is not supported in this browser. Please use Chrome or Edge.");
|
|
97715
|
+
that.dispatchEvent({ type: "error", error: "Web Bluetooth not supported" });
|
|
97716
|
+
return;
|
|
97054
97717
|
}
|
|
97055
97718
|
|
|
97056
|
-
|
|
97057
|
-
|
|
97058
|
-
|
|
97059
|
-
|
|
97060
|
-
|
|
97061
|
-
|
|
97719
|
+
navigator.bluetooth.requestDevice({
|
|
97720
|
+
filters: [
|
|
97721
|
+
{ services: [UART_SERVICE_UUID] },
|
|
97722
|
+
{ namePrefix: "BBC micro:bit" },
|
|
97723
|
+
{ namePrefix: "micro:bit" },
|
|
97724
|
+
{ namePrefix: "MicroBlocks" },
|
|
97725
|
+
{ namePrefix: "CircuitPlayground" }
|
|
97726
|
+
],
|
|
97727
|
+
optionalServices: [UART_SERVICE_UUID, 0xffe0]
|
|
97728
|
+
})
|
|
97729
|
+
.then(function(device) {
|
|
97730
|
+
that.bleDevice = device;
|
|
97731
|
+
that.bleDevice.addEventListener("gattserverdisconnected", function() {
|
|
97732
|
+
zogy("ZIM Hardware: Bluetooth device disconnected");
|
|
97733
|
+
that._handleDisconnect();
|
|
97734
|
+
});
|
|
97735
|
+
return device.gatt.connect();
|
|
97736
|
+
})
|
|
97737
|
+
.then(function(server) {
|
|
97738
|
+
that.bleServer = server;
|
|
97739
|
+
return server.getPrimaryService(UART_SERVICE_UUID);
|
|
97740
|
+
})
|
|
97741
|
+
.then(function(service) {
|
|
97742
|
+
return Promise.all([
|
|
97743
|
+
service.getCharacteristic(UART_RX_UUID),
|
|
97744
|
+
service.getCharacteristic(UART_TX_UUID)
|
|
97745
|
+
]);
|
|
97746
|
+
})
|
|
97747
|
+
.then(function(characteristics) {
|
|
97748
|
+
that.bleRxCharacteristic = characteristics[0];
|
|
97749
|
+
that.bleTxCharacteristic = characteristics[1];
|
|
97750
|
+
return that.bleTxCharacteristic.startNotifications();
|
|
97751
|
+
})
|
|
97752
|
+
.then(function() {
|
|
97753
|
+
that.bleTxCharacteristic.addEventListener("characteristicvaluechanged", function(event) {
|
|
97754
|
+
var decoder = new TextDecoder();
|
|
97755
|
+
var chunk = decoder.decode(event.target.value);
|
|
97756
|
+
that._processChunk(chunk);
|
|
97757
|
+
});
|
|
97062
97758
|
|
|
97063
|
-
|
|
97064
|
-
.
|
|
97065
|
-
|
|
97066
|
-
|
|
97067
|
-
|
|
97068
|
-
|
|
97069
|
-
|
|
97070
|
-
|
|
97071
|
-
|
|
97072
|
-
|
|
97073
|
-
|
|
97074
|
-
|
|
97075
|
-
|
|
97076
|
-
|
|
97077
|
-
|
|
97078
|
-
|
|
97079
|
-
|
|
97080
|
-
that.reader = that.textDecoder.readable.getReader()
|
|
97081
|
-
|
|
97082
|
-
// Start recursive background reader
|
|
97083
|
-
that._readLoop("");
|
|
97084
|
-
that.dispatchEvent("connected");
|
|
97085
|
-
})
|
|
97086
|
-
.catch(function (error) {
|
|
97087
|
-
console.error("Hardware connection failed:", error)
|
|
97088
|
-
})
|
|
97759
|
+
zogy("ZIM Hardware: Bluetooth connected successfully");
|
|
97760
|
+
that.isListening = true;
|
|
97761
|
+
that.connected = true;
|
|
97762
|
+
that._buffer = "";
|
|
97763
|
+
that.dispatchEvent("connected");
|
|
97764
|
+
})
|
|
97765
|
+
.catch(function(error) {
|
|
97766
|
+
console.error("ZIM Hardware: Bluetooth connection failed:", error);
|
|
97767
|
+
that.dispatchEvent({ type: "error", error: error });
|
|
97768
|
+
});
|
|
97769
|
+
};
|
|
97770
|
+
|
|
97771
|
+
// TRANSMIT DATA METHOD (Hardware.write)
|
|
97772
|
+
that.write = function(data) {
|
|
97773
|
+
var message = String(data);
|
|
97774
|
+
if (typeof that.delimiter === "string" && !message.endsWith(that.delimiter)) {
|
|
97775
|
+
message += that.delimiter;
|
|
97089
97776
|
}
|
|
97090
97777
|
|
|
97091
|
-
that.
|
|
97092
|
-
|
|
97093
|
-
|
|
97094
|
-
|
|
97095
|
-
|
|
97096
|
-
}
|
|
97097
|
-
|
|
97098
|
-
|
|
97099
|
-
|
|
97100
|
-
|
|
97101
|
-
|
|
97102
|
-
|
|
97103
|
-
|
|
97778
|
+
if (that.mode === "bluetooth" && that.bleRxCharacteristic) {
|
|
97779
|
+
var encoder = new TextEncoder();
|
|
97780
|
+
that.bleRxCharacteristic.writeValue(encoder.encode(message))
|
|
97781
|
+
.catch(function(error) {
|
|
97782
|
+
console.error("ZIM Hardware: failed to transmit BLE data:", error);
|
|
97783
|
+
});
|
|
97784
|
+
} else if (that.writer && that.isListening) {
|
|
97785
|
+
that.writer.write(message)
|
|
97786
|
+
.catch(function(error) {
|
|
97787
|
+
console.error("ZIM Hardware: failed to transmit serial data:", error);
|
|
97788
|
+
});
|
|
97789
|
+
} else {
|
|
97790
|
+
console.warn("ZIM Hardware: cannot write data, device is not connected.");
|
|
97104
97791
|
}
|
|
97792
|
+
return that;
|
|
97793
|
+
};
|
|
97794
|
+
|
|
97795
|
+
// DISCONNECT METHOD (Manual Shutdown)
|
|
97796
|
+
that.disconnect = function() {
|
|
97797
|
+
that.isListening = false;
|
|
97798
|
+
that.connected = false;
|
|
97105
97799
|
|
|
97106
|
-
|
|
97107
|
-
|
|
97108
|
-
|
|
97109
|
-
if (that.reader && that.writer) {
|
|
97110
|
-
that.reader.cancel()
|
|
97111
|
-
.then(function () { return that.writer.close() })
|
|
97112
|
-
.then(function () { if (that.port) return that.port.close() })
|
|
97113
|
-
.then(function () { zogy("ZIM Hardware: cleanly disconnected.") })
|
|
97114
|
-
.catch(function (err) { console.error("Error during disconnect process:", err) })
|
|
97800
|
+
if (that.mode === "bluetooth" && that.bleDevice) {
|
|
97801
|
+
if (that.bleDevice.gatt && that.bleDevice.gatt.connected) {
|
|
97802
|
+
that.bleDevice.gatt.disconnect();
|
|
97115
97803
|
}
|
|
97804
|
+
that._handleDisconnect();
|
|
97805
|
+
return that;
|
|
97806
|
+
}
|
|
97807
|
+
|
|
97808
|
+
if (that.reader && that.writer) {
|
|
97809
|
+
that.reader.cancel()
|
|
97810
|
+
.then(function() { return that.writer.close(); })
|
|
97811
|
+
.then(function() { if (that.port) return that.port.close(); })
|
|
97812
|
+
.then(function() {
|
|
97813
|
+
that._handleDisconnect();
|
|
97814
|
+
zogy("ZIM Hardware: cleanly disconnected");
|
|
97815
|
+
})
|
|
97816
|
+
.catch(function(err) {
|
|
97817
|
+
console.error("ZIM Hardware: error during disconnect:", err);
|
|
97818
|
+
that._handleDisconnect();
|
|
97819
|
+
});
|
|
97116
97820
|
}
|
|
97821
|
+
return that;
|
|
97822
|
+
};
|
|
97117
97823
|
|
|
97118
|
-
|
|
97119
|
-
|
|
97120
|
-
|
|
97824
|
+
// DISCONNECT CLEANUP HELPER
|
|
97825
|
+
that._handleDisconnect = function() {
|
|
97826
|
+
that.isListening = false;
|
|
97827
|
+
that.connected = false;
|
|
97121
97828
|
|
|
97122
|
-
|
|
97123
|
-
|
|
97124
|
-
|
|
97125
|
-
|
|
97126
|
-
|
|
97829
|
+
if (that.reader) {
|
|
97830
|
+
try { that.reader.releaseLock(); } catch (e) {}
|
|
97831
|
+
that.reader = null;
|
|
97832
|
+
}
|
|
97833
|
+
if (that.writer) {
|
|
97834
|
+
try { that.writer.releaseLock(); } catch (e) {}
|
|
97835
|
+
that.writer = null;
|
|
97836
|
+
}
|
|
97837
|
+
that.port = null;
|
|
97838
|
+
that.bleDevice = null;
|
|
97839
|
+
that.bleServer = null;
|
|
97840
|
+
that.bleRxCharacteristic = null;
|
|
97841
|
+
that.bleTxCharacteristic = null;
|
|
97842
|
+
that._buffer = "";
|
|
97843
|
+
|
|
97844
|
+
that.dispatchEvent("disconnected");
|
|
97845
|
+
};
|
|
97846
|
+
|
|
97847
|
+
// SERIAL RECURSIVE STREAM READER
|
|
97848
|
+
that._readLoop = function() {
|
|
97849
|
+
if (!that.isListening || !that.reader) return;
|
|
97850
|
+
|
|
97851
|
+
that.reader.read()
|
|
97852
|
+
.then(function(result) {
|
|
97853
|
+
if (result.done) {
|
|
97854
|
+
that.isListening = false;
|
|
97855
|
+
return;
|
|
97856
|
+
}
|
|
97857
|
+
that._processChunk(result.value);
|
|
97858
|
+
that._readLoop();
|
|
97859
|
+
})
|
|
97860
|
+
.catch(function(error) {
|
|
97861
|
+
that.isListening = false;
|
|
97862
|
+
});
|
|
97863
|
+
};
|
|
97864
|
+
|
|
97865
|
+
// PARSING & DISPATCH PIPELINE
|
|
97866
|
+
that._processChunk = function(chunk) {
|
|
97867
|
+
that._buffer += chunk;
|
|
97868
|
+
var delimiterPattern = that.delimiter === "\n" ? /\r?\n/ : (that.delimiter instanceof RegExp ? that.delimiter : new RegExp(that.delimiter));
|
|
97869
|
+
var lines = that._buffer.split(delimiterPattern);
|
|
97870
|
+
that._buffer = lines.pop(); // Retain incomplete tail segment
|
|
97871
|
+
|
|
97872
|
+
for (var i = 0; i < lines.length; i++) {
|
|
97873
|
+
var cleanLine = lines[i].trim();
|
|
97874
|
+
if (cleanLine.length === 0) continue;
|
|
97875
|
+
|
|
97876
|
+
that.raw = cleanLine;
|
|
97877
|
+
var parsed = cleanLine;
|
|
97878
|
+
var key = null;
|
|
97879
|
+
var val = null;
|
|
97880
|
+
|
|
97881
|
+
if (that.autoParse) {
|
|
97882
|
+
// 1. JSON Payload Parsing
|
|
97883
|
+
if ((cleanLine.charAt(0) === "{" && cleanLine.charAt(cleanLine.length - 1) === "}") ||
|
|
97884
|
+
(cleanLine.charAt(0) === "[" && cleanLine.charAt(cleanLine.length - 1) === "]")) {
|
|
97885
|
+
try {
|
|
97886
|
+
parsed = JSON.parse(cleanLine);
|
|
97887
|
+
if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
|
|
97888
|
+
for (var k in parsed) {
|
|
97889
|
+
that.data[k] = parsed[k];
|
|
97890
|
+
}
|
|
97891
|
+
}
|
|
97892
|
+
} catch (e) {
|
|
97893
|
+
parsed = cleanLine;
|
|
97127
97894
|
}
|
|
97128
|
-
|
|
97129
|
-
|
|
97130
|
-
|
|
97131
|
-
|
|
97132
|
-
|
|
97133
|
-
|
|
97134
|
-
|
|
97895
|
+
}
|
|
97896
|
+
// 2. Pure Numeric String Parsing
|
|
97897
|
+
else if (!isNaN(cleanLine)) {
|
|
97898
|
+
parsed = Number(cleanLine);
|
|
97899
|
+
}
|
|
97900
|
+
// 3. Key-Value Formatting (e.g. "pot:512", "x=10", "btn: 1")
|
|
97901
|
+
else {
|
|
97902
|
+
var match = cleanLine.match(/^([a-zA-Z0-9_.-]+)\s*[:=]\s*(.*)$/);
|
|
97903
|
+
if (match) {
|
|
97904
|
+
key = match[1];
|
|
97905
|
+
var rawVal = match[2].trim();
|
|
97906
|
+
val = (!isNaN(rawVal) && rawVal !== "") ? Number(rawVal) : rawVal;
|
|
97907
|
+
that.data[key] = val;
|
|
97908
|
+
parsed = val;
|
|
97135
97909
|
}
|
|
97136
|
-
|
|
97137
|
-
|
|
97138
|
-
|
|
97139
|
-
|
|
97140
|
-
|
|
97141
|
-
|
|
97910
|
+
}
|
|
97911
|
+
}
|
|
97912
|
+
|
|
97913
|
+
that.value = parsed;
|
|
97914
|
+
|
|
97915
|
+
var eventObj = {
|
|
97916
|
+
type: "data",
|
|
97917
|
+
data: parsed,
|
|
97918
|
+
value: parsed,
|
|
97919
|
+
raw: cleanLine,
|
|
97920
|
+
key: key,
|
|
97921
|
+
val: val,
|
|
97922
|
+
target: that
|
|
97923
|
+
};
|
|
97924
|
+
|
|
97925
|
+
that.dispatchEvent(eventObj);
|
|
97926
|
+
if (typeof that.callback === "function") (that.callback)(parsed, cleanLine, eventObj);
|
|
97142
97927
|
}
|
|
97143
|
-
}
|
|
97144
|
-
|
|
97928
|
+
};
|
|
97929
|
+
|
|
97930
|
+
// VALUE QUERY HELPER (e.g. hardware.get("pot"))
|
|
97931
|
+
that.get = function(name) {
|
|
97932
|
+
return that.data[name];
|
|
97933
|
+
};
|
|
97934
|
+
};
|
|
97935
|
+
|
|
97936
|
+
zim.extend(zim.Hardware, createjs.EventDispatcher, null, "cjsEventDispatcher", false);
|
|
97145
97937
|
//-83.097
|
|
97146
97938
|
|
|
97147
97939
|
|
|
@@ -97287,11 +98079,15 @@ DESCRIPTION
|
|
|
97287
98079
|
The Frame has a "deviceorientation" event to capture tilt or device rotation (like a compass)
|
|
97288
98080
|
and a "devicemotion" event to capture shaking the device with the accelerometer.
|
|
97289
98081
|
|
|
98082
|
+
SEE: the tilt() method (just after gesture()) for a one line version
|
|
98083
|
+
|
|
97290
98084
|
SEE: Shake - for the "devicemotion" event for accelerometer motion
|
|
97291
98085
|
|
|
97292
98086
|
SEE: the PermissionAsk() class which will handle asking for permissions on devices.
|
|
97293
98087
|
|
|
97294
98088
|
EXAMPLE
|
|
98089
|
+
// SEE ALSO THE TILT METHOD FOR A ONE LINE VERSION
|
|
98090
|
+
|
|
97295
98091
|
// TILT OR COMPASS - https://zimjs.com/zapp/Z_Q5UYS
|
|
97296
98092
|
// for capturing tilt on device (rotation about an axis)
|
|
97297
98093
|
// be on a mobile device or a device with sensors
|
|
@@ -99493,6 +100289,19 @@ function zimify(obj, a, b, c, d, list) {
|
|
|
99493
100289
|
gestureRect:function(boundary, update) {
|
|
99494
100290
|
return zim.gestureBoundary(this, boundary, update);
|
|
99495
100291
|
},
|
|
100292
|
+
|
|
100293
|
+
tilt:function(boundary, damp, factor, mode, type, call) {
|
|
100294
|
+
if (isDUO(arguments)) {arguments[0].obj = this; return zim.tilt(arguments[0]);}
|
|
100295
|
+
else {return zim.tilt(this, boundary, damp, factor, mode, type, call);}
|
|
100296
|
+
},
|
|
100297
|
+
noTilt:function() {
|
|
100298
|
+
if (isDUO(arguments)) {arguments[0].obj = this; return zim.noTilt(arguments[0]);}
|
|
100299
|
+
else {return zim.noTilt(this);}
|
|
100300
|
+
},
|
|
100301
|
+
tiltBoundary:function(boundary, update) {
|
|
100302
|
+
return zim.tiltBoundary(this, boundary, update);
|
|
100303
|
+
},
|
|
100304
|
+
|
|
99496
100305
|
addPhysics:function(dynamic, contract, shape, friction, linear, angular, density, restitution, maskBits, categoryBits, physics) {
|
|
99497
100306
|
if (isDUO(arguments)) {arguments[0].obj = this; return zim.addPhysics(arguments[0]);}
|
|
99498
100307
|
else {return zim.addPhysics(this, dynamic, contract, shape, friction, linear, angular, density, restitution, maskBits, categoryBits, physics);}
|
|
@@ -106252,7 +107061,7 @@ for (z_i = 0; z_i < globalFunctions.length; z_i++) {
|
|
|
106252
107061
|
["FILL", zim.FILL],
|
|
106253
107062
|
["FULL", zim.FULL],
|
|
106254
107063
|
["LEFT", zim.LEFT],
|
|
106255
|
-
["RIGHT", zim.RIGHT],
|
|
107064
|
+
["RIGHT", zim.RIGHT],
|
|
106256
107065
|
["CENTER", zim.CENTER],
|
|
106257
107066
|
["MIDDLE", zim.MIDDLE],
|
|
106258
107067
|
["JUSTIFY", zim.JUSTIFY],
|
|
@@ -106527,6 +107336,9 @@ export let transform = zim.transform;
|
|
|
106527
107336
|
export let gesture = zim.gesture;
|
|
106528
107337
|
export let noGesture = zim.noGesture;
|
|
106529
107338
|
export let gestureBoundary = zim.gestureBoundary;
|
|
107339
|
+
export let tilt = zim.tilt;
|
|
107340
|
+
export let noTilt = zim.noTilt;
|
|
107341
|
+
export let tiltBoundary = zim.tiltBoundary;
|
|
106530
107342
|
export let effect = zim.effect;
|
|
106531
107343
|
export let updateEffects = zim.updateEffects;
|
|
106532
107344
|
export let noEffect = zim.noEffect;
|