zimjs 20.0.4 → 20.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/zim.js CHANGED
@@ -57817,259 +57817,6 @@ RETURNS obj for chaining
57817
57817
  };//-34.7
57818
57818
 
57819
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
-
58073
57820
  /*--
58074
57821
  obj.effect = function(effect, x, y, width, height)
58075
57822
 
@@ -58524,6 +58271,808 @@ RETURNS obj for chaining
58524
58271
  return obj;
58525
58272
  };//-34.85
58526
58273
 
58274
+
58275
+ // SUBSECTION SENSORS
58276
+
58277
+ /*--
58278
+ obj.tilt = function(boundary, damp, factor, mode, type, ready)
58279
+
58280
+ tilt
58281
+ zim DisplayObject method
58282
+
58283
+ DESCRIPTION
58284
+ Moves or positions an object based on device sensors (deviceorientation or devicemotion).
58285
+ Automatically manages user sensor permission via ZIM PermissionAsk if permission has not yet been requested.
58286
+
58287
+ NOTE: If permission has already been granted, tilt activates immediately.
58288
+ If multiple objects call tilt(), turn(), or shake() before permission is granted, they are queued and activated together once the user accepts.
58289
+
58290
+ ALSO: see noTilt() to remove tilt behaviors.
58291
+
58292
+ ALSO: see tiltBoundary() to dynamically change or clear the boundary rectangle.
58293
+
58294
+ EXAMPLE
58295
+ // Basic rolling ball constrained to stage bounds
58296
+ const ball = new Circle(30, red)
58297
+ .center()
58298
+ .tilt(S);
58299
+ END EXAMPLE
58300
+
58301
+ EXAMPLE
58302
+ // Custom damping, sensitivity factor, and boundary with ready callback
58303
+ new Rectangle(80, 80, blue)
58304
+ .center()
58305
+ .tilt({
58306
+ boundary: new Boundary(50, 50, W - 100, H - 100),
58307
+ damp: 0.08,
58308
+ factor: 0.75,
58309
+ ready: (success, obj) => {
58310
+ if (!success) new Pane("Device orientation not available", yellow).show();
58311
+ }
58312
+ });
58313
+ END EXAMPLE
58314
+
58315
+ PARAMETERS
58316
+ ** supports DUO - parameters or single object with properties below
58317
+ boundary - (default null) a ZIM Boundary object, an Array of [x, y, width, height], or true for the Stage dimensions
58318
+ damp - (default 0.05) smoothing factor via ZIM Damp, or null / false for immediate direct tracking
58319
+ factor - (default 0.5) sensitivity factor multiplier, or an Object with {x, y} for independent axis sensitivity
58320
+ mode - (default "move") "move" for continuous velocity / rolling behavior, or "position" for tilt offset relative to starting coordinates
58321
+ type - (default "deviceorientation") the sensor event type ("deviceorientation" or "devicemotion")
58322
+ ready - (default null) callback function called when permission resolves, receiving (success:Boolean, obj:DisplayObject)
58323
+
58324
+ RETURNS obj for chaining
58325
+ --*///+34.9
58326
+ zim.tilt = function(obj, boundary, damp, factor, mode, type, ready) {
58327
+ var sig = "obj, boundary, damp, factor, mode, type, ready";
58328
+ var duo; if (duo = zob(zim.tilt, arguments, sig)) return duo;
58329
+ if ((obj.type=="AC"||(obj.type=="Emoji"&&obj.svg&&obj.svg.type=="AC"))&&WW.zdf) {WW.zdf.ac("tilt", arguments); return obj;}
58330
+ z_d("34.9");
58331
+
58332
+ // MONITOR
58333
+ var mID = "z~tilt";
58334
+ if (obj && obj.mID && ((obj.mID[2] && obj.mID[2]=="-") || obj.mID[0]=="-")) mID = "z~-";
58335
+
58336
+ if (zot(obj)) return;
58337
+
58338
+ // Clean up any existing tilt on this object first
58339
+ if (obj._tiltTicker) zim.noTilt(obj);
58340
+
58341
+ var f = obj.frame || (typeof zdf != "undefined" ? zdf : WW.zdf);
58342
+ var s = obj.stage || (f ? f.stage : null);
58343
+
58344
+ // Set initial boundary
58345
+ zim.tiltBoundary(obj, boundary);
58346
+
58347
+ if (zot(damp)) damp = 0.05;
58348
+ if (zot(factor)) factor = 0.5;
58349
+ var factorX = typeof factor === "object" ? factor.x : factor;
58350
+ var factorY = typeof factor === "object" ? factor.y : factor;
58351
+ if (zot(mode)) mode = "move";
58352
+ if (zot(type)) type = "deviceorientation";
58353
+
58354
+ var dampX = damp ? new zim.Damp(mode == "position" ? obj.x : 0, damp) : null;
58355
+ var dampY = damp ? new zim.Damp(mode == "position" ? obj.y : 0, damp) : null;
58356
+ var currentRot = {x: 0, y: 0, z: 0};
58357
+
58358
+ function updateTilt() {
58359
+ var orient = 0;
58360
+ if (typeof WW != "undefined") {
58361
+ if (WW.screen && WW.screen.orientation && WW.screen.orientation.angle != null) {
58362
+ orient = WW.screen.orientation.angle;
58363
+ } else if (typeof WW.orientation != "undefined") {
58364
+ orient = WW.orientation;
58365
+ }
58366
+ }
58367
+
58368
+ var beta = currentRot.x;
58369
+ var gamma = currentRot.y;
58370
+ var tiltX, tiltY;
58371
+
58372
+ if (orient == 90) {
58373
+ tiltX = beta;
58374
+ tiltY = -gamma;
58375
+ } else if (orient == -90 || orient == 270) {
58376
+ tiltX = -beta;
58377
+ tiltY = gamma;
58378
+ } else if (orient == 180) {
58379
+ tiltX = -gamma;
58380
+ tiltY = -beta;
58381
+ } else {
58382
+ tiltX = gamma;
58383
+ tiltY = beta;
58384
+ }
58385
+
58386
+ if (mode == "move") {
58387
+ var rotX = dampX ? dampX.convert(tiltX) : tiltX;
58388
+ var rotY = dampY ? dampY.convert(tiltY) : tiltY;
58389
+ obj.x += rotX * factorX;
58390
+ obj.y += rotY * factorY;
58391
+ } else if (mode == "position") {
58392
+ var targetX = (obj._tiltStartX != null ? obj._tiltStartX : obj.x) + tiltX * factorX * 10;
58393
+ var targetY = (obj._tiltStartY != null ? obj._tiltStartY : obj.y) + tiltY * factorY * 10;
58394
+ obj.x = dampX ? dampX.convert(targetX) : targetX;
58395
+ obj.y = dampY ? dampY.convert(targetY) : targetY;
58396
+ }
58397
+
58398
+ if (obj._tiltBoundary) {
58399
+ obj.x = zim.constrain(obj.x, obj._tiltBoundary.x, obj._tiltBoundary.x + obj._tiltBoundary.width);
58400
+ obj.y = zim.constrain(obj.y, obj._tiltBoundary.y, obj._tiltBoundary.y + obj._tiltBoundary.height);
58401
+ }
58402
+
58403
+ if (s) s.update();
58404
+ }
58405
+
58406
+ function activate() {
58407
+ obj._tiltStartX = obj.x;
58408
+ obj._tiltStartY = obj.y;
58409
+ if (mode == "position" && dampX && dampY) {
58410
+ dampX.immediate(obj.x);
58411
+ dampY.immediate(obj.y);
58412
+ }
58413
+
58414
+ obj._tiltType = type;
58415
+ obj._tiltListener = function(e) {
58416
+ if (e.rotation) {
58417
+ currentRot.x = e.rotation.x || 0;
58418
+ currentRot.y = e.rotation.y || 0;
58419
+ currentRot.z = e.rotation.z || 0;
58420
+ } else {
58421
+ currentRot.x = e.beta || 0;
58422
+ currentRot.y = e.gamma || 0;
58423
+ currentRot.z = e.alpha || 0;
58424
+ }
58425
+ };
58426
+ f.on(type, obj._tiltListener);
58427
+
58428
+ obj._tiltTicker = zim.Ticker.add(updateTilt);
58429
+ if (ready) ready(true, obj);
58430
+ }
58431
+
58432
+ // Simple function queue
58433
+ if (f._permissionGranted) {
58434
+ activate();
58435
+ } else if (f._permissionPending) {
58436
+ f._permissionQueue.push(activate);
58437
+ } else {
58438
+ f._permissionPending = true;
58439
+ f._permissionQueue = [activate];
58440
+
58441
+ new zim.PermissionAsk(function(yes) {
58442
+ f._permissionPending = false;
58443
+ if (yes) {
58444
+ f._permissionGranted = true;
58445
+ zim.loop(f._permissionQueue, function(fn) { fn(); });
58446
+ f._permissionQueue = [];
58447
+ } else {
58448
+ if (ready) ready(false, obj);
58449
+ }
58450
+ }, type);
58451
+ }
58452
+
58453
+ return obj;
58454
+ };//-34.9
58455
+
58456
+
58457
+ /*--
58458
+ obj.noTilt = function()
58459
+
58460
+ noTilt
58461
+ zim DisplayObject method
58462
+
58463
+ DESCRIPTION
58464
+ Removes tilt listeners, ticker updates, and clears tilt boundary properties from the object.
58465
+
58466
+ EXAMPLE
58467
+ const player = new Circle(25, green).center().tilt(true);
58468
+
58469
+ // Stop tilt control when game ends or is paused
58470
+ player.noTilt();
58471
+ END EXAMPLE
58472
+
58473
+ RETURNS obj for chaining
58474
+ --*///+34.91
58475
+ zim.noTilt = function(obj) {
58476
+ var sig = "obj";
58477
+ var duo; if (duo = zob(zim.noTilt, arguments, sig)) return duo;
58478
+ z_d("34.91");
58479
+
58480
+ if (zot(obj) || !obj.on || !obj.zimTouch) return;
58481
+
58482
+ // MONITOR
58483
+ var mID = "z~noTilt";
58484
+ if (obj && obj.mID && ((obj.mID[2] && obj.mID[2]=="-") || obj.mID[0]=="-")) mID = "z~-";
58485
+
58486
+ if (zot(obj)) return;
58487
+ var f = obj.frame || (typeof zdf != "undefined" ? zdf : WW.zdf);
58488
+
58489
+ if (obj._tiltListener && f) {
58490
+ f.off(obj._tiltType || "deviceorientation", obj._tiltListener);
58491
+ obj._tiltListener = null;
58492
+ }
58493
+ if (obj._tiltTicker) {
58494
+ zim.Ticker.remove(obj._tiltTicker);
58495
+ obj._tiltTicker = null;
58496
+ }
58497
+ obj._tiltBoundary = null;
58498
+
58499
+ return obj;
58500
+
58501
+ };//-34.91
58502
+
58503
+
58504
+ /*--
58505
+ obj.tiltBoundary = function(boundary, y, width, height)
58506
+
58507
+ tiltBoundary
58508
+ zim DisplayObject method
58509
+
58510
+ DESCRIPTION
58511
+ Dynamically sets, updates, or removes the boundary rectangle for an object with tilt().
58512
+ Accurately accounts for registration points (like centerReg), scaling, and rotation using zim.boundsToGlobal().
58513
+
58514
+ EXAMPLE
58515
+ const rect = new Rectangle(120, 80, purple).centerReg().tilt(S);
58516
+
58517
+ // Update boundary dynamically later
58518
+ rect.tiltBoundary(new Boundary(50, 50, W - 100, H - 100));
58519
+
58520
+ // Or clear the boundary
58521
+ // rect.tiltBoundary(null);
58522
+ END EXAMPLE
58523
+
58524
+ PARAMETERS
58525
+ ** supports DUO - parameters or single object with properties below
58526
+ 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
58527
+ y - (default null) y coordinate if boundary parameter is used as x
58528
+ width - (default null) width if boundary parameter is used as x
58529
+ height - (default null) height if boundary parameter is used as x
58530
+
58531
+ RETURNS obj for chaining
58532
+ --*///+34.92
58533
+ zim.tiltBoundary = function(obj, boundary, y, width, height) {
58534
+ var sig = "obj, boundary, y, width, height";
58535
+ var duo; if (duo = zob(zim.tiltBoundary, arguments, sig)) return duo;
58536
+ z_d("34.92");
58537
+ if (zot(obj) || !obj.on) return;
58538
+ var f = obj.frame || (typeof zdf != "undefined" ? zdf : WW.zdf);
58539
+ var s = obj.stage || (f ? f.stage : null);
58540
+
58541
+ function getContainedBoundary(bx, by, bw, bh) {
58542
+ var gb = zim.boundsToGlobal ? zim.boundsToGlobal(obj) : (obj.getTransformedBounds ? obj.getTransformedBounds() : null);
58543
+ if (!gb) return new zim.Boundary(bx, by, bw, bh);
58544
+
58545
+ var leftOffset = gb.x - obj.x;
58546
+ var rightOffset = (gb.x + gb.width) - obj.x;
58547
+ var topOffset = gb.y - obj.y;
58548
+ var bottomOffset = (gb.y + gb.height) - obj.y;
58549
+
58550
+ var minXAllowed = bx - leftOffset;
58551
+ var maxXAllowed = bx + bw - rightOffset;
58552
+ var minYAllowed = by - topOffset;
58553
+ var maxYAllowed = by + bh - bottomOffset;
58554
+
58555
+ if (maxXAllowed < minXAllowed) maxXAllowed = minXAllowed;
58556
+ if (maxYAllowed < minYAllowed) maxYAllowed = minYAllowed;
58557
+
58558
+ return new zim.Boundary(
58559
+ minXAllowed,
58560
+ minYAllowed,
58561
+ maxXAllowed - minXAllowed,
58562
+ maxYAllowed - minYAllowed
58563
+ );
58564
+ }
58565
+
58566
+ if (zot(boundary) || boundary === false || boundary === null) {
58567
+ obj._tiltBoundary = null;
58568
+ } else if (boundary === true) {
58569
+ var sw = f ? f.width : (s ? s.width : 0);
58570
+ var sh = f ? f.height : (s ? s.height : 0);
58571
+ obj._tiltBoundary = getContainedBoundary(0, 0, sw, sh);
58572
+ } else if (boundary && (boundary.type == "Stage" || boundary == s || (s && boundary == s.canvas))) {
58573
+ var sw = boundary.width || (f ? f.width : 0);
58574
+ var sh = boundary.height || (f ? f.height : 0);
58575
+ obj._tiltBoundary = getContainedBoundary(0, 0, sw, sh);
58576
+ } else if (boundary && boundary.type != "Boundary" && !Array.isArray(boundary) && (boundary.getBounds || boundary.width != null)) {
58577
+ var b = boundary.getBounds ? boundary.getBounds() : null;
58578
+ var bw = boundary.width != null ? boundary.width : (b ? b.width : 0);
58579
+ var bh = boundary.height != null ? boundary.height : (b ? b.height : 0);
58580
+ var bx = boundary.x || 0;
58581
+ var by = boundary.y || 0;
58582
+ obj._tiltBoundary = getContainedBoundary(bx, by, bw, bh);
58583
+ } else if (Array.isArray(boundary)) {
58584
+ obj._tiltBoundary = getContainedBoundary(boundary[0], boundary[1], boundary[2], boundary[3]);
58585
+ } else if (typeof boundary === "number" && !zot(y)) {
58586
+ obj._tiltBoundary = getContainedBoundary(boundary, y, width, height);
58587
+ } else if (boundary && boundary.type == "Boundary") {
58588
+ obj._tiltBoundary = getContainedBoundary(boundary.x, boundary.y, boundary.width, boundary.height);
58589
+ } else {
58590
+ obj._tiltBoundary = null;
58591
+ }
58592
+
58593
+ return obj;
58594
+ };//-34.92
58595
+
58596
+
58597
+ /*--
58598
+ obj.turn = function(damp, factor, mode, min, max, type, ready)
58599
+
58600
+ turn
58601
+ zim DisplayObject method
58602
+
58603
+ DESCRIPTION
58604
+ Rotates an object based on device yaw / roll orientation (turning the device like a steering wheel, dial, or compass).
58605
+ Automatically detects whether the device is held upright (full 360-degree steering wheel) or flat (compass) with seamless transitions between both.
58606
+ By default, inverts rotation so the object stays oriented relative to the world as the device turns.
58607
+ Automatically manages user sensor permission via ZIM PermissionAsk if permission has not yet been requested.
58608
+
58609
+ NOTE: If permission has already been granted, turn activates immediately.
58610
+ If multiple objects call tilt(), turn(), or shake() before permission is granted, they are queued and activated together once the user accepts.
58611
+ Rotation is applied relative to the object's initial rotation when turn() is called (for example, an arrow rotated -90 to point up will maintain that -90 offset).
58612
+
58613
+ ALSO: see noTurn() to remove turning behaviors.
58614
+
58615
+ EXAMPLE
58616
+ // Point an arrow with device heading (stays pointing up in world space)
58617
+ const arrow = new Arrow({type:"thick"}).sca(4).rot(-90).centerReg().turn();
58618
+ END EXAMPLE
58619
+
58620
+ EXAMPLE
58621
+ // Continuous steering wheel mode with damping and rotation limits
58622
+ const wheel = new Circle(80, red).center().turn({
58623
+ damp: 0.1,
58624
+ factor: 1.5,
58625
+ mode: "relative",
58626
+ min: -90,
58627
+ max: 90,
58628
+ ready: (success, obj) => {
58629
+ if (!success) zog("Sensors denied");
58630
+ }
58631
+ });
58632
+ END EXAMPLE
58633
+
58634
+ PARAMETERS
58635
+ ** supports DUO - parameters or single object with properties below
58636
+ damp - (default 0.05) smoothing factor via ZIM Damp, or null / false for direct tracking
58637
+ factor - (default 1) sensitivity factor multiplier (use negative to invert rotation direction)
58638
+ mode - (default "relative") "relative" (offset from starting device orientation), "absolute" (compass heading), or "continuous" (continuous spin based on turn angle)
58639
+ min - (default null) minimum rotation angle limit in degrees, or null for unrestricted
58640
+ max - (default null) maximum rotation angle limit in degrees, or null for unrestricted
58641
+ type - (default "deviceorientation") the sensor event type ("deviceorientation")
58642
+ ready - (default null) callback function called when permission resolves, receiving (success:Boolean, obj:DisplayObject)
58643
+
58644
+ RETURNS obj for chaining
58645
+ --*///+34.93
58646
+ zim.turn = function(obj, damp, factor, mode, min, max, type, ready) {
58647
+ var sig = "obj, damp, factor, mode, min, max, type, ready";
58648
+ var duo; if (duo = zob(zim.turn, arguments, sig)) return duo;
58649
+ if ((obj.type=="AC"||(obj.type=="Emoji"&&obj.svg&&obj.svg.type=="AC"))&&WW.zdf) {WW.zdf.ac("turn", arguments); return obj;}
58650
+ z_d("34.93");
58651
+
58652
+ // MONITOR
58653
+ var mID = "z~turn";
58654
+ if (obj && obj.mID && ((obj.mID[2] && obj.mID[2]=="-") || obj.mID[0]=="-")) mID = "z~-";
58655
+
58656
+ if (zot(obj)) return;
58657
+
58658
+ // Clean up any existing turn on this object first
58659
+ if (obj._turnTicker) zim.noTurn(obj);
58660
+
58661
+ var f = obj.frame || (typeof zdf != "undefined" ? zdf : WW.zdf);
58662
+ var s = obj.stage || (f ? f.stage : null);
58663
+
58664
+ if (zot(damp)) damp = 0.05;
58665
+ if (zot(factor)) factor = 1;
58666
+ if (zot(mode)) mode = "relative";
58667
+ if (zot(type)) type = "deviceorientation";
58668
+
58669
+ var dampRot = damp ? new zim.Damp(obj.rotation, damp) : null;
58670
+ var startDeviceAngle = null;
58671
+ var currentDeviceAngle = null;
58672
+ var lastMode = null;
58673
+
58674
+ function angleDiff(a, b) {
58675
+ var diff = (a - b) % 360;
58676
+ if (diff < -180) diff += 360;
58677
+ if (diff > 180) diff -= 360;
58678
+ return diff;
58679
+ }
58680
+
58681
+ function unwrap(target, current) {
58682
+ var diff = (target - current) % 360;
58683
+ if (diff < -180) diff += 360;
58684
+ if (diff > 180) diff -= 360;
58685
+ return current + diff;
58686
+ }
58687
+
58688
+ function updateTurn() {
58689
+ if (startDeviceAngle === null || currentDeviceAngle === null) return;
58690
+
58691
+ var orient = 0;
58692
+ if (typeof WW != "undefined") {
58693
+ if (WW.screen && WW.screen.orientation && WW.screen.orientation.angle != null) {
58694
+ orient = WW.screen.orientation.angle;
58695
+ } else if (typeof WW.orientation != "undefined") {
58696
+ orient = WW.orientation;
58697
+ }
58698
+ }
58699
+
58700
+ var startRot = obj._turnStartRot != null ? obj._turnStartRot : 0;
58701
+ var targetRot = obj.rotation;
58702
+
58703
+ if (mode == "relative") {
58704
+ var diff = angleDiff(currentDeviceAngle, startDeviceAngle);
58705
+ targetRot = startRot - diff * factor;
58706
+ } else if (mode == "absolute") {
58707
+ var absHeading = (currentDeviceAngle - orient + 360) % 360;
58708
+ targetRot = startRot - absHeading * factor;
58709
+ } else if (mode == "continuous") {
58710
+ var cDiff = angleDiff(currentDeviceAngle, startDeviceAngle);
58711
+ targetRot = obj.rotation - (cDiff * factor * 0.05);
58712
+ }
58713
+
58714
+ if (min != null || max != null) {
58715
+ targetRot = zim.constrain(targetRot, min != null ? min : -Infinity, max != null ? max : Infinity);
58716
+ }
58717
+
58718
+ if (dampRot) {
58719
+ var unwrapped = unwrap(targetRot, obj.rotation);
58720
+ obj.rotation = dampRot.convert(unwrapped);
58721
+ } else {
58722
+ obj.rotation = targetRot;
58723
+ }
58724
+
58725
+ if (s) s.update();
58726
+ }
58727
+
58728
+ function activate() {
58729
+ obj._turnStartRot = obj.rotation;
58730
+ startDeviceAngle = null;
58731
+ currentDeviceAngle = null;
58732
+ lastMode = null;
58733
+ if (dampRot) dampRot.immediate(obj.rotation);
58734
+
58735
+ obj._turnType = type;
58736
+ obj._turnListener = function(e) {
58737
+ var beta = e.rotation ? e.rotation.x : (e.beta || 0);
58738
+ var gamma = e.rotation ? e.rotation.y : (e.gamma || 0);
58739
+ var alpha = e.rotation && e.rotation.z != null ? e.rotation.z : (e.alpha != null ? (360 - e.alpha) : 0);
58740
+
58741
+ var isUpright = Math.abs(beta) > 20 || Math.abs(gamma) > 20;
58742
+ var curMode = isUpright ? "upright" : "flat";
58743
+ var ang;
58744
+
58745
+ if (isUpright) {
58746
+ var radB = beta * (Math.PI / 180);
58747
+ var radG = gamma * (Math.PI / 180);
58748
+ ang = Math.atan2(Math.sin(radG), Math.cos(radG) * Math.sin(radB)) * (180 / Math.PI);
58749
+ } else {
58750
+ ang = alpha;
58751
+ }
58752
+
58753
+ if (startDeviceAngle === null) {
58754
+ startDeviceAngle = ang;
58755
+ lastMode = curMode;
58756
+ if (dampRot) dampRot.immediate(obj.rotation);
58757
+ } else if (lastMode !== null && curMode !== lastMode) {
58758
+ // Seamless transition between upright and flat
58759
+ var prevDiff = angleDiff(currentDeviceAngle, startDeviceAngle);
58760
+ startDeviceAngle = ang - prevDiff;
58761
+ lastMode = curMode;
58762
+ }
58763
+
58764
+ currentDeviceAngle = ang;
58765
+ };
58766
+ f.on(type, obj._turnListener);
58767
+
58768
+ obj._turnTicker = zim.Ticker.add(updateTurn);
58769
+ if (ready) ready(true, obj);
58770
+ }
58771
+
58772
+ // Simple function queue
58773
+ if (f._permissionGranted) {
58774
+ activate();
58775
+ } else if (f._permissionPending) {
58776
+ f._permissionQueue.push(activate);
58777
+ } else {
58778
+ f._permissionPending = true;
58779
+ f._permissionQueue = [activate];
58780
+
58781
+ new zim.PermissionAsk(function(yes) {
58782
+ f._permissionPending = false;
58783
+ if (yes) {
58784
+ f._permissionGranted = true;
58785
+ zim.loop(f._permissionQueue, function(fn) { fn(); });
58786
+ f._permissionQueue = [];
58787
+ } else {
58788
+ if (ready) ready(false, obj);
58789
+ }
58790
+ }, type);
58791
+ }
58792
+
58793
+ return obj;
58794
+ };//-34.93
58795
+
58796
+ /*--
58797
+ obj.noTurn = function()
58798
+
58799
+ noTurn
58800
+ zim DisplayObject method
58801
+
58802
+ DESCRIPTION
58803
+ Removes turn listeners and ticker updates from the object.
58804
+
58805
+ EXAMPLE
58806
+ const compass = new Triangle().center().turn();
58807
+
58808
+ // Stop turn tracking
58809
+ compass.noTurn();
58810
+ END EXAMPLE
58811
+
58812
+ RETURNS obj for chaining
58813
+ --*///+34.94
58814
+ zim.noTurn = function(obj) {
58815
+ var sig = "obj";
58816
+ var duo; if (duo = zob(zim.noTurn, arguments, sig)) return duo;
58817
+ z_d("34.94");
58818
+
58819
+ if (zot(obj) || !obj.on || !obj.zimTouch) return;
58820
+
58821
+ // MONITOR
58822
+ var mID = "z~noTurn";
58823
+ if (obj && obj.mID && ((obj.mID[2] && obj.mID[2]=="-") || obj.mID[0]=="-")) mID = "z~-";
58824
+
58825
+ var f = obj.frame || (typeof zdf != "undefined" ? zdf : WW.zdf);
58826
+
58827
+ if (obj._turnListener && f) {
58828
+ f.off(obj._turnType || "deviceorientation", obj._turnListener);
58829
+ obj._turnListener = null;
58830
+ }
58831
+ if (obj._turnTicker) {
58832
+ zim.Ticker.remove(obj._turnTicker);
58833
+ obj._turnTicker = null;
58834
+ }
58835
+
58836
+ return obj;
58837
+ };//-34.94
58838
+
58839
+
58840
+ /*--
58841
+ obj.shake = function(call, stopCall, threshold, wait, factor, type, ready)
58842
+
58843
+ shake
58844
+ zim DisplayObject method
58845
+
58846
+ DESCRIPTION
58847
+ Triggers a callback and dispatches a "shake" event whenever the device is shaken beyond a threshold acceleration force.
58848
+ Also triggers a stopCall and dispatches a "shakestop" event when the device stops shaking.
58849
+ Automatically manages user sensor permission via ZIM PermissionAsk if permission has not yet been requested.
58850
+
58851
+ NOTE: If permission has already been granted, shake activates immediately.
58852
+ If multiple objects call tilt(), turn(), or shake() before permission is granted, they are queued and activated together once the user accepts.
58853
+
58854
+ ALSO: see noShake() to remove shake listeners.
58855
+
58856
+ EXAMPLE
58857
+ const color = series(red,green,blue);
58858
+ const bottle = new Rectangle(80, 160, purple).centerReg().shake({
58859
+ call: (total) => {
58860
+ bottle.color = color();
58861
+ S.update();
58862
+ },
58863
+ stopCall: (obj) => {
58864
+ emitter.spurt(20);
58865
+ obj.color = purple;
58866
+ }
58867
+ });
58868
+ const emitter = new Emitter({startPaused:true}).loc(bottle);
58869
+ END EXAMPLE
58870
+
58871
+ EXAMPLE
58872
+ // Custom sensitivity threshold with ready callback
58873
+ const circle = new Circle().center().shake(
58874
+ (total, x, y) => { circle.impulse(x * 10, y * 10); },
58875
+ () => { zog("Stopped shaking!"); },
58876
+ 12, // threshold
58877
+ 0.4, // wait
58878
+ 1, // factor
58879
+ "devicemotion",
58880
+ (success) => { if (!success) zog("Sensors unavailable"); }
58881
+ );
58882
+ END EXAMPLE
58883
+
58884
+ PARAMETERS
58885
+ ** supports DUO - parameters or single object with properties below
58886
+ call - (default null) callback function when shaken, receiving (total:Number, x:Number, y:Number, z:Number, obj:DisplayObject, event:Object)
58887
+ stopCall - (default null) callback function called when shaking stops after wait seconds of stillness, receiving (obj:DisplayObject)
58888
+ threshold - (default 10) minimum 3D acceleration magnitude delta required to trigger a shake
58889
+ wait - (default 0.5) stillness duration in seconds before triggering stopCall, and cooldown between repeat shake pulses
58890
+ factor - (default 1) sensitivity factor multiplier
58891
+ type - (default "devicemotion") the sensor event type ("devicemotion")
58892
+ ready - (default null) callback function called when permission resolves, receiving (success:Boolean, obj:DisplayObject)
58893
+
58894
+ EVENTS
58895
+ Dispatches a "shake" event on obj with event properties: total, x, y, z, and event.
58896
+ Dispatches a "shakestop" event on obj when shaking stops.
58897
+
58898
+ RETURNS obj for chaining
58899
+ --*///+34.95
58900
+ zim.shake = function(obj, call, stopCall, threshold, wait, factor, type, ready) {
58901
+ var sig = "obj, call, stopCall, threshold, wait, factor, type, ready";
58902
+ var duo; if (duo = zob(zim.shake, arguments, sig)) return duo;
58903
+ if ((obj.type=="AC"||(obj.type=="Emoji"&&obj.svg&&obj.svg.type=="AC"))&&WW.zdf) {WW.zdf.ac("shake", arguments); return obj;}
58904
+ z_d("34.95");
58905
+
58906
+ // MONITOR
58907
+ var mID = "z~shake";
58908
+ if (obj && obj.mID && ((obj.mID[2] && obj.mID[2]=="-") || obj.mID[0]=="-")) mID = "z~-";
58909
+
58910
+ if (zot(obj)) return;
58911
+
58912
+ // Clean up any existing shake on this object first
58913
+ if (obj._shakeListener) zim.noShake(obj);
58914
+
58915
+ var f = obj.frame || (typeof zdf != "undefined" ? zdf : WW.zdf);
58916
+ var s = obj.stage || (f ? f.stage : null);
58917
+
58918
+ if (zot(threshold)) threshold = 10;
58919
+ if (zot(wait)) wait = 0.5;
58920
+ if (zot(factor)) factor = 1;
58921
+ if (zot(type)) type = "devicemotion";
58922
+
58923
+ var lastX = 0, lastY = 0, lastZ = 0;
58924
+ var lastTime = 0;
58925
+
58926
+ function handleMotion(e) {
58927
+ var acc = e.acceleration && (e.acceleration.x != null || e.acceleration.y != null) ?
58928
+ e.acceleration : (e.accelerationIncludingGravity || e);
58929
+
58930
+ var ax = acc.x || 0;
58931
+ var ay = acc.y || 0;
58932
+ var az = acc.z || 0;
58933
+
58934
+ var deltaX = ax - lastX;
58935
+ var deltaY = ay - lastY;
58936
+ var deltaZ = az - lastZ;
58937
+
58938
+ lastX = ax;
58939
+ lastY = ay;
58940
+ lastZ = az;
58941
+
58942
+ var mag = Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ) * factor;
58943
+
58944
+ if (mag >= threshold) {
58945
+ var now = Date.now();
58946
+
58947
+ // Reset stop timer on active motion
58948
+ if (obj._shakeStopTimeout) obj._shakeStopTimeout.clear();
58949
+
58950
+ obj._shakeStopTimeout = zim.timeout(wait, function() {
58951
+ obj._shakeStopTimeout = null;
58952
+ if (stopCall) stopCall(obj);
58953
+ obj.dispatchEvent({
58954
+ type: "shakestop",
58955
+ event: e
58956
+ });
58957
+ if (s) s.update();
58958
+ });
58959
+
58960
+ if (now - lastTime >= wait * 1000) {
58961
+ lastTime = now;
58962
+
58963
+ var orient = 0;
58964
+ if (typeof WW != "undefined") {
58965
+ if (WW.screen && WW.screen.orientation && WW.screen.orientation.angle != null) {
58966
+ orient = WW.screen.orientation.angle;
58967
+ } else if (typeof WW.orientation != "undefined") {
58968
+ orient = WW.orientation;
58969
+ }
58970
+ }
58971
+
58972
+ var shakeX, shakeY, shakeZ = deltaZ * factor;
58973
+ if (orient == 90) {
58974
+ shakeX = deltaY * factor;
58975
+ shakeY = -deltaX * factor;
58976
+ } else if (orient == -90 || orient == 270) {
58977
+ shakeX = -deltaY * factor;
58978
+ shakeY = deltaX * factor;
58979
+ } else if (orient == 180) {
58980
+ shakeX = -deltaX * factor;
58981
+ shakeY = -deltaY * factor;
58982
+ } else { // 0 portrait
58983
+ shakeX = deltaX * factor;
58984
+ shakeY = deltaY * factor;
58985
+ }
58986
+
58987
+ if (call) call(mag, shakeX, shakeY, shakeZ, obj, e);
58988
+ obj.dispatchEvent({
58989
+ type: "shake",
58990
+ total: mag,
58991
+ x: shakeX,
58992
+ y: shakeY,
58993
+ z: shakeZ,
58994
+ event: e
58995
+ });
58996
+
58997
+ }
58998
+ }
58999
+ }
59000
+
59001
+ function activate() {
59002
+ obj._shakeType = type;
59003
+ obj._shakeListener = handleMotion;
59004
+ f.on(type, obj._shakeListener);
59005
+ if (ready) ready(true, obj);
59006
+ }
59007
+
59008
+ // Simple function queue
59009
+ if (f._permissionGranted) {
59010
+ activate();
59011
+ } else if (f._permissionPending) {
59012
+ f._permissionQueue.push(activate);
59013
+ } else {
59014
+ f._permissionPending = true;
59015
+ f._permissionQueue = [activate];
59016
+
59017
+ new zim.PermissionAsk(function(yes) {
59018
+ f._permissionPending = false;
59019
+ if (yes) {
59020
+ f._permissionGranted = true;
59021
+ zim.loop(f._permissionQueue, function(fn) { fn(); });
59022
+ f._permissionQueue = [];
59023
+ } else {
59024
+ if (ready) ready(false, obj);
59025
+ }
59026
+ }, type);
59027
+ }
59028
+
59029
+ return obj;
59030
+ };//-34.95
59031
+
59032
+
59033
+ /*--
59034
+ obj.noShake = function()
59035
+
59036
+ noShake
59037
+ zim DisplayObject method
59038
+
59039
+ DESCRIPTION
59040
+ Removes shake listeners and pending stop timers from the object.
59041
+
59042
+ EXAMPLE
59043
+ const box = new Rectangle(80, 80, red).center().shake(onShake);
59044
+
59045
+ // Stop shake listening
59046
+ box.noShake();
59047
+ END EXAMPLE
59048
+
59049
+ RETURNS obj for chaining
59050
+ --*///+34.96
59051
+ zim.noShake = function(obj) {
59052
+ var sig = "obj";
59053
+ var duo; if (duo = zob(zim.noShake, arguments, sig)) return duo;
59054
+ z_d("34.96");
59055
+
59056
+ if (zot(obj) || !obj.on || !obj.zimTouch) return;
59057
+
59058
+ // MONITOR
59059
+ var mID = "z~noShake";
59060
+ if (obj && obj.mID && ((obj.mID[2] && obj.mID[2]=="-") || obj.mID[0]=="-")) mID = "z~-";
59061
+
59062
+ var f = obj.frame || (typeof zdf != "undefined" ? zdf : WW.zdf);
59063
+
59064
+ if (obj._shakeListener && f) {
59065
+ f.off(obj._shakeType || "devicemotion", obj._shakeListener);
59066
+ obj._shakeListener = null;
59067
+ }
59068
+ if (obj._shakeStopTimeout) {
59069
+ obj._shakeStopTimeout.clear();
59070
+ obj._shakeStopTimeout = null;
59071
+ }
59072
+
59073
+ return obj;
59074
+ };//-34.96
59075
+
58527
59076
  // SUBSECTION HIT TESTS
58528
59077
 
58529
59078
  /*--
@@ -93048,6 +93597,10 @@ loadFailObj - the object that shows if images are broken - will be given a type
93048
93597
  startTime - datestamp of when frame was made - used internally
93049
93598
  retina - read-only Boolean as to whether stage (as opposed to the canvas) was scaled for pixelDensity during Frame creation
93050
93599
  reloaded - read-only Boolean as to whether page has been reloaded - uses window.performance.getEntriesByType
93600
+ sensorText - (default null) a String to customize the label inside the PermissionAsk popup for device sensors
93601
+ sensorAsk - reference to the PermissionAsk Pane instance created for device sensors
93602
+ camText - (default null) a String to customize the label inside the PermissionAsk popup for camera/mic
93603
+ camAsk - reference to the PermissionAsk Pane instance created for camera/mic
93051
93604
 
93052
93605
  ALSO see F, S, W, H, M global variables which reference the default frame, its stage and width and height, and if on mobile
93053
93606
 
@@ -93302,6 +93855,15 @@ zim.Frame = function(scaling, width, height, color, outerColor, ready, assets, p
93302
93855
  var tagID;
93303
93856
  var tag;
93304
93857
 
93858
+ // ZIM 020 Sensors Patch
93859
+ this.sensorText = null; // custom text for sensor PermissionAsk dialog
93860
+ this.sensorAsk = null; // reference to PermissionAsk instance for sensors
93861
+ this.camText = null; // custom text for camera/mic PermissionAsk dialog
93862
+ this.camAsk = null; // reference to PermissionAsk instance for camera/mic
93863
+ this._permissionGranted = false;
93864
+ this._permissionPending = false;
93865
+ this._permissionQueue = [];
93866
+
93305
93867
  // 0. part of TEN PATCH
93306
93868
  // need to keep check for resize and assets for dispatching ready
93307
93869
  var resizeReady = false;
@@ -98196,32 +98758,27 @@ Pre ZIM 018, this was done with a sensors parameter on the Frame.
98196
98758
  The sensors parameter has now been removed and the events are handled with PermissionAsk.
98197
98759
 
98198
98760
  NOTE: this started as SensorAsk but the class has been adjusted to handle other permissions and the name has been changed in ZIM 016
98199
-
98200
98761
  NOTE: as of ZIM 5.5.0 the zim namespace is no longer required (unless zns is set to true before running zim)
98762
+ NOTE: sensor prompt text can be customized prior to calling with F.sensorText = "Custom message";
98201
98763
 
98202
98764
  EXAMPLE
98203
98765
  // DEVICE ORIENTATION - gives angle of device in all 3 dimensions
98204
98766
  // See https://zimjs.com/zapp/Z_Q5UYS
98205
- // Note: this is NOT an orientation event to see if phone is portrait or landscape (see Frame orientation event)
98206
98767
  new PermissionAsk(yes=>{
98207
- if (yes) { // the user answered yes to PermissionAsk
98208
- // all code goes in here
98768
+ if (yes) {
98209
98769
  new Label("Tilt the device to move circle").alp(.3).pos(0,30,CENTER);
98210
98770
  const circle = new Circle().center();
98211
98771
  const amount = .5;
98212
- const compass = new Line(60, 4, light, "arrow").rot(90).centerReg(circle); // point up
98772
+ const compass = new Line(60, 4, light, "arrow").rot(90).centerReg(circle);
98213
98773
  F.on("deviceorientation", e=>{
98214
- // for tilt
98215
98774
  circle.mov(e.rotation.y*amount, e.rotation.x*amount);
98216
98775
  circle.x = constrain(circle.x, 0, W);
98217
98776
  circle.y = constrain(circle.y, 0, H);
98218
- // for compass use e.rotation.z
98219
- // which has 0 angle at device start rotation (not necessarily North)
98220
- compass.rot(90-e.rotation.z); // rotate opposite device rotation
98777
+ compass.rot(90-e.rotation.z);
98221
98778
  S.update();
98222
98779
  });
98223
- } else { // the user answered no to PermissionAsk
98224
- new Pane("SENSOR not available",yellow).show();
98780
+ } else {
98781
+ new Pane("SENSOR not available", yellow).show();
98225
98782
  }
98226
98783
  });
98227
98784
  END EXAMPLE
@@ -98231,13 +98788,11 @@ EXAMPLE
98231
98788
  // See https://zimjs.com/zapp/Z_XF8JM
98232
98789
  new PermissionAsk(init, "devicemotion");
98233
98790
  function init(yes) {
98234
- if (yes) { // the user answered yes to PermissionAsk
98235
- // all code goes in here
98791
+ if (yes) {
98236
98792
  new Label("Shake the device").center();
98237
98793
  S.update();
98238
98794
  let id;
98239
98795
  F.on("devicemotion", e=>{
98240
- // for shake
98241
98796
  if (
98242
98797
  Math.abs(e.acceleration.x) > 5 ||
98243
98798
  Math.abs(e.acceleration.y) > 5 ||
@@ -98254,36 +98809,12 @@ function init(yes) {
98254
98809
  });
98255
98810
  }
98256
98811
  });
98257
- } else { // the user answered no to PermissionAsk
98258
- new Pane("SENSOR not available",yellow).show();
98812
+ } else {
98813
+ new Pane("SENSOR not available", yellow).show();
98259
98814
  }
98260
98815
  }
98261
98816
  END EXAMPLE
98262
98817
 
98263
- EXAMPLE
98264
- // CAM
98265
- // on iOS, the app must be interacted with before using mic or cam
98266
- // goes right to permissions on computer and android
98267
- // pops up a PermissionAsk Pane on iOS then if yes, goes to permissions on iOS
98268
- new PermissionAsk(init, "cam");
98269
- function init(val) {
98270
- new Label(val).center(); // media stream if yes to permissions otherwise false
98271
- S.update();
98272
- }
98273
- END EXAMPLE
98274
-
98275
- EXAMPLE
98276
- // MIC
98277
- // on iOS, the app must be interacted with before using mic or cam
98278
- // this goes right to permissions on computer and android
98279
- // but pops up a PermissionAsk Pane on iOS then if yes, goes to permissions on iOS
98280
- new PermissionAsk(init, "mic"); // or "cam" or "miccam"
98281
- function init(val) {
98282
- new Label(val).center(); // media stream if yes to permissions otherwise false
98283
- S.update();
98284
- }
98285
- END EXAMPLE
98286
-
98287
98818
  PARAMETERS - accepts ZIM DUO regular parameters in order or a configuration object with parameters as properties
98288
98819
  callback - the function to callback when permission is accepted
98289
98820
  if the permissionType is deviceorientation or devicemotion this will receive true for accept or false for no permission
@@ -98313,13 +98844,6 @@ dispose() - dispose the PermissionAsk
98313
98844
  ALSO: see all the methods of a zim Pane()
98314
98845
  including hide()
98315
98846
 
98316
- ALSO: ZIM 4TH adds all the methods listed under Container (see above), such as:
98317
- drag(), hitTestRect(), animate(), sca(), reg(), mov(), center(), centerReg(),
98318
- addTo(), removeFrom(), loop(), outline(), place(), pos(), alp(), rot(), setMask(), etc.
98319
- ALSO: see the CreateJS Easel Docs for Container methods, such as:
98320
- on(), off(), getBounds(), setBounds(), cache(), uncache(), updateCache(), dispatchEvent(),
98321
- addChild(), removeChild(), addChildAt(), getChildAt(), contains(), removeAllChildren(), etc.
98322
-
98323
98847
  PROPERTIES
98324
98848
  type - name of class as a string
98325
98849
  permissionType - the type of permission requested
@@ -98327,17 +98851,6 @@ label - reference to the zim Label
98327
98851
  yes - reference to the zim Button with YES
98328
98852
  no - reference to the zim Button with NO
98329
98853
 
98330
- ALSO: see ZIM Pane for properties such as:
98331
- backdropColor, etc.
98332
-
98333
- ALSO: see ZIM Container for properties such as:
98334
- width, height, widthOnly, heightOnly, draggable, level, depth, group
98335
- blendMode, hue, saturation, brightness, contrast, etc.
98336
-
98337
- ALSO: see the CreateJS Easel Docs for Container properties, such as:
98338
- x, y, rotation, scaleX, scaleY, regX, regY, skewX, skewY,
98339
- alpha, cursor, shadow, name, mouseChildren, mouseEnabled, parent, numChildren, etc.
98340
-
98341
98854
  --*///+83.01
98342
98855
  zim.PermissionAsk = function(callback, permissionType, color, backgroundColor, style, group, inherit) {
98343
98856
  var sig = "callback, permissionType, color, backgroundColor, style, group, inherit";
@@ -98360,6 +98873,15 @@ alpha, cursor, shadow, name, mouseChildren, mouseEnabled, parent, numChildren, e
98360
98873
  this.mID = "z~"+(DS.monitor===false?"-":this.type);
98361
98874
 
98362
98875
  var that = this;
98876
+ var frame = WW.zdf;
98877
+
98878
+ if (frame) {
98879
+ if (permissionType == "mic" || permissionType == "cam" || permissionType == "miccam") {
98880
+ frame.camAsk = that;
98881
+ } else {
98882
+ frame.sensorAsk = that;
98883
+ }
98884
+ }
98363
98885
 
98364
98886
  Style.addGroup("PermissionAsk", {
98365
98887
  color:color,
@@ -98375,7 +98897,15 @@ alpha, cursor, shadow, name, mouseChildren, mouseEnabled, parent, numChildren, e
98375
98897
  var okay = false;
98376
98898
  that.yes = new zim.Button({label:"YES", width:100, group:"PermissionAsk"}).sca(.65).pos(0,30,CENTER,TOP,this);
98377
98899
  var words = {deviceorientation:"sensors", devicemotion:"sensors", mic:"mic", cam:"cam", miccam:"mic/cam"};
98378
- that.label = new zim.Label("Use " + (words[pt]?words[pt]:"feature") + "?", 30, null, color, null, null, null, "center").sca(.9).centerReg(this);
98900
+
98901
+ var defaultMsg = "Use " + (words[pt]?words[pt]:"feature") + "?";
98902
+ var promptMsg = defaultMsg;
98903
+ if (frame) {
98904
+ if ((pt == "mic" || pt == "cam" || pt == "miccam") && frame.camText) promptMsg = frame.camText;
98905
+ else if (frame.sensorText) promptMsg = frame.sensorText;
98906
+ }
98907
+
98908
+ that.label = new zim.Label(promptMsg, 30, null, color, null, null, null, "center").sca(.9).centerReg(this);
98379
98909
  that.no = new zim.Button({label:"NO", width:100, group:"PermissionAsk"}).sca(.65).pos(0,30,CENTER,BOTTOM,this);
98380
98910
 
98381
98911
  new zim.Circle(110, zim.clear, color, 1).center(this).alp(.8);
@@ -98383,7 +98913,6 @@ alpha, cursor, shadow, name, mouseChildren, mouseEnabled, parent, numChildren, e
98383
98913
  new zim.Circle(130, zim.clear, color, 1).center(this).alp(.2);
98384
98914
  if (style!==false) zim.styleTransforms(this, DS);
98385
98915
 
98386
- var frame = WW.zdf;
98387
98916
  if (pt == "mic" || pt == "cam" || pt == "miccam") {
98388
98917
  if (M=="ios") {
98389
98918
  setPane();
@@ -98407,14 +98936,12 @@ alpha, cursor, shadow, name, mouseChildren, mouseEnabled, parent, numChildren, e
98407
98936
  } else {
98408
98937
  var called = false;
98409
98938
  WW.addEventListener(permissionType, testMe);
98410
- // instead of testing for mobile - some laptops like chromebook have sensors so test for a reading
98411
98939
  function testMe(e) {
98412
98940
  if (okay) return;
98413
98941
  if (permissionType=="deviceorientation") {
98414
98942
  if (e.alpha==null || (e.alpha==0&&e.beta==0&&e.gamma==0)) callback(false, 1);
98415
98943
  else setEvents();
98416
98944
  } else {
98417
- // if (!e.acceleration || e.acceleration.x==null || (e.acceleration.x==0&&e.acceleration.y==0&&e.acceleration.z==0)) callback(false);
98418
98945
  if (!e.acceleration || e.acceleration.x==null) callback(false, 2);
98419
98946
  else setEvents();
98420
98947
  }
@@ -98429,12 +98956,7 @@ alpha, cursor, shadow, name, mouseChildren, mouseEnabled, parent, numChildren, e
98429
98956
  var lastZ = 0;
98430
98957
  var flip = 0;
98431
98958
  function deviceorientationEvent(e) {
98432
- // for some reason, reporting alpha as increasing going counter counterclockwise
98433
- // so this code makes it increase going clockwise
98434
98959
  var z = 360-e.alpha;
98435
- // compass is subtracting 180 if device screen is pointing down
98436
- // in a VR helmet this would be looking slightly up from the horizon...
98437
- // so removing this flip with the following code
98438
98960
  if (Math.abs(z-lastZ) > 180 - 45 && Math.abs(z-lastZ) < 180 + 45) flip = flip == 0 ? 180 : 0;
98439
98961
  lastZ = z;
98440
98962
  e.rotation = {x:e.beta, y:e.gamma, z:(z + flip) % 360};
@@ -100289,25 +100811,40 @@ function zimify(obj, a, b, c, d, list) {
100289
100811
  gestureRect:function(boundary, update) {
100290
100812
  return zim.gestureBoundary(this, boundary, update);
100291
100813
  },
100292
-
100293
- tilt:function(boundary, damp, factor, mode, type, call) {
100814
+ addPhysics:function(dynamic, contract, shape, friction, linear, angular, density, restitution, maskBits, categoryBits, physics) {
100815
+ if (isDUO(arguments)) {arguments[0].obj = this; return zim.addPhysics(arguments[0]);}
100816
+ else {return zim.addPhysics(this, dynamic, contract, shape, friction, linear, angular, density, restitution, maskBits, categoryBits, physics);}
100817
+ },
100818
+ removePhysics:function() {
100819
+ return zim.removePhysics(this);
100820
+ },
100821
+ tilt:function(boundary, damp, factor, mode, type, ready) {
100294
100822
  if (isDUO(arguments)) {arguments[0].obj = this; return zim.tilt(arguments[0]);}
100295
- else {return zim.tilt(this, boundary, damp, factor, mode, type, call);}
100823
+ else {return zim.tilt(this, boundary, damp, factor, mode, type, ready);}
100296
100824
  },
100297
100825
  noTilt:function() {
100298
100826
  if (isDUO(arguments)) {arguments[0].obj = this; return zim.noTilt(arguments[0]);}
100299
100827
  else {return zim.noTilt(this);}
100300
100828
  },
100301
- tiltBoundary:function(boundary, update) {
100302
- return zim.tiltBoundary(this, boundary, update);
100829
+ tiltBoundary:function(boundary, y, width, height) {
100830
+ if (isDUO(arguments)) {arguments[0].obj = this; return zim.tiltBoundary(arguments[0]);}
100831
+ else {return zim.tiltBoundary(this, boundary, y, width, height);}
100303
100832
  },
100304
-
100305
- addPhysics:function(dynamic, contract, shape, friction, linear, angular, density, restitution, maskBits, categoryBits, physics) {
100306
- if (isDUO(arguments)) {arguments[0].obj = this; return zim.addPhysics(arguments[0]);}
100307
- else {return zim.addPhysics(this, dynamic, contract, shape, friction, linear, angular, density, restitution, maskBits, categoryBits, physics);}
100833
+ turn:function(damp, factor, mode, min, max, type, ready) {
100834
+ if (isDUO(arguments)) {arguments[0].obj = this; return zim.turn(arguments[0]);}
100835
+ else {return zim.turn(this, damp, factor, mode, min, max, type, ready);}
100308
100836
  },
100309
- removePhysics:function() {
100310
- return zim.removePhysics(this);
100837
+ noTurn:function() {
100838
+ if (isDUO(arguments)) {arguments[0].obj = this; return zim.noTurn(arguments[0]);}
100839
+ else {return zim.noTurn(this);}
100840
+ },
100841
+ shake:function(call, stopCall, threshold, wait, factor, type, ready) {
100842
+ if (isDUO(arguments)) {arguments[0].obj = this; return zim.shake(arguments[0]);}
100843
+ else {return zim.shake(this, call, stopCall, threshold, wait, factor, type, ready);}
100844
+ },
100845
+ noShake:function() {
100846
+ if (isDUO(arguments)) {arguments[0].obj = this; return zim.noShake(arguments[0]);}
100847
+ else {return zim.noShake(this);}
100311
100848
  },
100312
100849
  hitTestPoint:function(x, y, boundsCheck) {
100313
100850
  return zim.hitTestPoint(this, x, y, boundsCheck);
@@ -107336,14 +107873,18 @@ export let transform = zim.transform;
107336
107873
  export let gesture = zim.gesture;
107337
107874
  export let noGesture = zim.noGesture;
107338
107875
  export let gestureBoundary = zim.gestureBoundary;
107339
- export let tilt = zim.tilt;
107340
- export let noTilt = zim.noTilt;
107341
- export let tiltBoundary = zim.tiltBoundary;
107342
107876
  export let effect = zim.effect;
107343
107877
  export let updateEffects = zim.updateEffects;
107344
107878
  export let noEffect = zim.noEffect;
107345
107879
  export let addPhysics = zim.addPhysics;
107346
107880
  export let removePhysics = zim.removePhysics;
107881
+ export let tilt = zim.tilt;
107882
+ export let noTilt = zim.noTilt;
107883
+ export let tiltBoundary = zim.tiltBoundary;
107884
+ export let turn = zim.turn;
107885
+ export let noTurn = zim.noTurn;
107886
+ export let shake = zim.shake;
107887
+ export let noShake = zim.noShake;
107347
107888
  export let hitTestPoint = zim.hitTestPoint;
107348
107889
  export let hitTestReg = zim.hitTestReg;
107349
107890
  export let hitTestRect = zim.hitTestRect;