jsxgraph 1.4.0 → 1.4.3

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.
Files changed (98) hide show
  1. package/README.md +1 -1
  2. package/distrib/README.md +1 -1
  3. package/distrib/geogebra.min.js +3 -3
  4. package/distrib/geonext.min.js +3 -3
  5. package/distrib/index.d.ts +5205 -4629
  6. package/distrib/intergeo.min.js +3 -3
  7. package/distrib/jsxgraph.css +10 -15
  8. package/distrib/jsxgraphcore.js +9 -25
  9. package/distrib/jsxgraphsrc.js +4497 -2180
  10. package/distrib/sketch.min.js +3 -3
  11. package/package.json +3 -2
  12. package/src/3d/box3d.js +264 -0
  13. package/src/3d/curve3d.js +97 -0
  14. package/src/3d/linspace3d.js +375 -0
  15. package/src/3d/point3d.js +200 -0
  16. package/src/3d/surface3d.js +81 -0
  17. package/src/3d/threed.js +38 -0
  18. package/src/3d/view3d.js +459 -0
  19. package/src/base/board.js +139 -85
  20. package/src/base/chart.js +1 -1
  21. package/src/base/circle.js +1 -1
  22. package/src/base/composition.js +1 -1
  23. package/src/base/constants.js +15 -14
  24. package/src/base/coords.js +3 -3
  25. package/src/base/coordselement.js +5 -8
  26. package/src/base/curve.js +1 -1
  27. package/src/base/element.js +36 -28
  28. package/src/base/foreignobject.js +12 -2
  29. package/src/base/group.js +1 -1
  30. package/src/base/image.js +1 -1
  31. package/src/base/line.js +2 -2
  32. package/src/base/point.js +8 -18
  33. package/src/base/polygon.js +89 -34
  34. package/src/base/text.js +8 -7
  35. package/src/base/ticks.js +17 -3
  36. package/src/base/transformation.js +1 -1
  37. package/src/base/turtle.js +1 -1
  38. package/src/element/arc.js +1 -1
  39. package/src/element/button.js +1 -1
  40. package/src/element/checkbox.js +1 -1
  41. package/src/element/comb.js +1 -1
  42. package/src/element/composition.js +2 -2
  43. package/src/element/conic.js +3 -3
  44. package/src/element/input.js +1 -1
  45. package/src/element/locus.js +1 -1
  46. package/src/element/measure.js +9 -4
  47. package/src/element/sector.js +5 -5
  48. package/src/element/slider.js +29 -12
  49. package/src/element/slopetriangle.js +1 -1
  50. package/src/jsxgraph.js +9 -3
  51. package/src/jxg.js +3 -3
  52. package/src/loadjsxgraph.js +18 -12
  53. package/src/math/bst.js +1 -1
  54. package/src/math/clip.js +550 -345
  55. package/src/math/complex.js +1 -1
  56. package/src/math/extrapolate.js +1 -1
  57. package/src/math/geometry.js +85 -6
  58. package/src/math/ia.js +69 -69
  59. package/src/math/math.js +10 -1
  60. package/src/math/metapost.js +1 -1
  61. package/src/math/nlp.js +4 -4
  62. package/src/math/numerics.js +2 -1
  63. package/src/math/plot.js +4 -4
  64. package/src/math/poly.js +1 -1
  65. package/src/math/probfuncs.js +2 -1
  66. package/src/math/qdt.js +11 -11
  67. package/src/math/statistics.js +10 -10
  68. package/src/math/symbolic.js +1 -1
  69. package/src/options.js +96 -40
  70. package/src/options3d.js +123 -0
  71. package/src/parser/ca.js +1297 -1291
  72. package/src/parser/datasource.js +1 -1
  73. package/src/parser/geonext.js +6 -6
  74. package/src/parser/jessiecode.js +369 -73
  75. package/src/parser/jessiescript.js +1 -1
  76. package/src/reader/cinderella.js +1 -1
  77. package/src/reader/file.js +1 -1
  78. package/src/reader/geogebra.js +1 -1
  79. package/src/reader/geonext.js +1 -1
  80. package/src/reader/graph.js +1 -1
  81. package/src/reader/intergeo.js +1 -1
  82. package/src/reader/sketch.js +7 -7
  83. package/src/renderer/abstract.js +8 -2
  84. package/src/renderer/canvas.js +9 -5
  85. package/src/renderer/no.js +2 -1
  86. package/src/renderer/svg.js +10 -13
  87. package/src/renderer/vml.js +1 -1
  88. package/src/server/server.js +1 -1
  89. package/src/utils/base64.js +2 -2
  90. package/src/utils/color.js +8 -9
  91. package/src/utils/dump.js +20 -5
  92. package/src/utils/env.js +13 -54
  93. package/src/utils/event.js +1 -1
  94. package/src/utils/expect.js +1 -1
  95. package/src/utils/type.js +12 -10
  96. package/src/utils/xml.js +1 -1
  97. package/src/utils/zip.js +1 -1
  98. package/CHANGELOG.md +0 -1366
package/src/base/board.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2008-2021
2
+ Copyright 2008-2022
3
3
  Matthias Ehmann,
4
4
  Michael Gerhaeuser,
5
5
  Carsten Miller,
@@ -1213,7 +1213,7 @@ define([
1213
1213
  op = (new Coords(Const.COORDS_BY_SCREEN, [moveEl.Xprev, moveEl.Yprev], this)).usrCoords;
1214
1214
  // New finger position
1215
1215
  np = (new Coords(Const.COORDS_BY_SCREEN, [moveEl.X, moveEl.Y], this)).usrCoords;
1216
-
1216
+
1217
1217
  // Old and new directions
1218
1218
  od = Mat.crossProduct(fix, op);
1219
1219
  nd = Mat.crossProduct(fix, np);
@@ -1296,7 +1296,7 @@ define([
1296
1296
  op = (new Coords(Const.COORDS_BY_SCREEN, [moveEl.Xprev, moveEl.Yprev], this)).usrCoords;
1297
1297
  // New finger position
1298
1298
  np = (new Coords(Const.COORDS_BY_SCREEN, [moveEl.X, moveEl.Y], this)).usrCoords;
1299
-
1299
+
1300
1300
  alpha = Geometry.rad(op.slice(1), fix.slice(1), np.slice(1));
1301
1301
 
1302
1302
  // Rotate and scale by the movement of the second finger
@@ -1664,7 +1664,7 @@ define([
1664
1664
  },
1665
1665
 
1666
1666
  addKeyboardEventHandlers: function() {
1667
- if (!this.hasKeyboardHandlers && Env.isBrowser) {
1667
+ if (this.attr.keyboard.enabled && !this.hasKeyboardHandlers && Env.isBrowser) {
1668
1668
  Env.addEvent(this.containerObj, 'keydown', this.keyDownListener, this);
1669
1669
  Env.addEvent(this.containerObj, 'focusin', this.keyFocusInListener, this);
1670
1670
  Env.addEvent(this.containerObj, 'focusout', this.keyFocusOutListener, this);
@@ -2161,7 +2161,7 @@ define([
2161
2161
  type = this._inputDevice;
2162
2162
  this.options.precision.hasPoint = this.options.precision[type];
2163
2163
 
2164
- // Handling of multi touch with pointer events should be easier than the touch events.
2164
+ // Handling of multi touch with pointer events should be easier than the touch events.
2165
2165
  // Every pointer device has its own pointerId, e.g. the mouse
2166
2166
  // always has id 1 or 0, fingers and pens get unique ids every time a pointerDown event is fired and they will
2167
2167
  // keep this id until a pointerUp event is fired. What we have to do here is:
@@ -2203,7 +2203,7 @@ define([
2203
2203
  target = elements[elements.length - 1];
2204
2204
  found = false;
2205
2205
 
2206
- // Reminder: this.touches is the list of elements which
2206
+ // Reminder: this.touches is the list of elements which
2207
2207
  // currently "possess" a pointer (mouse, pen, finger)
2208
2208
  for (i = 0; i < this.touches.length; i++) {
2209
2209
  // An element receives a further touch, i.e.
@@ -2257,10 +2257,11 @@ define([
2257
2257
 
2258
2258
  // Touch events on empty areas of the board are handled here, see also touchStartListener
2259
2259
  // 1. case: one finger. If allowed, this triggers pan with one finger
2260
- if (evt.touches.length == 1 &&
2260
+ if (evt.touches.length === 1 &&
2261
2261
  this.mode === this.BOARD_MODE_NONE &&
2262
2262
  this.touchStartMoveOriginOneFinger(evt)) {
2263
- } else if (evt.touches.length == 2 &&
2263
+ // Empty by purpose
2264
+ } else if (evt.touches.length === 2 &&
2264
2265
  (this.mode === this.BOARD_MODE_NONE || this.mode === this.BOARD_MODE_MOVE_ORIGIN)
2265
2266
  ) {
2266
2267
  // 2. case: two fingers: pinch to zoom or pan with two fingers needed.
@@ -2342,7 +2343,7 @@ define([
2342
2343
  // Run through all touch events which have been started on this jsxgraph element.
2343
2344
  for (j = 0; j < touchTargets.length; j++) {
2344
2345
  if (touchTargets[j].num === evt.pointerId) {
2345
-
2346
+
2346
2347
  pos = this.getMousePosition(evt);
2347
2348
  touchTargets[j].X = pos[0];
2348
2349
  touchTargets[j].Y = pos[1];
@@ -2416,10 +2417,14 @@ define([
2416
2417
  }
2417
2418
  }
2418
2419
 
2420
+ this.originMoveEnd();
2421
+ this.update();
2422
+
2419
2423
  // selection
2420
2424
  if (this.selectingMode) {
2421
2425
  this._stopSelecting(evt);
2422
2426
  this.triggerEventHandlers(['touchstopselecting', 'pointerstopselecting', 'stopselecting'], [evt]);
2427
+ this.stopSelectionMode();
2423
2428
  } else {
2424
2429
  for (i = this.downObjects.length - 1; i > -1; i--) {
2425
2430
  found = false;
@@ -2430,32 +2435,30 @@ define([
2430
2435
  }
2431
2436
  if (!found) {
2432
2437
  this.downObjects[i].triggerEventHandlers(['touchend', 'up', 'pointerup', 'MSPointerUp'], [evt]);
2433
- this.downObjects[i].snapToGrid();
2434
- this.downObjects[i].snapToPoints();
2438
+ // this.downObjects[i].snapToGrid();
2439
+ // this.downObjects[i].snapToPoints();
2435
2440
  this.downObjects.splice(i, 1);
2436
2441
  }
2437
2442
  }
2438
2443
  }
2439
2444
 
2440
- // this._pointerRemoveTouches(evt);
2441
- // if (this._board_touches.length === 0) {
2442
- if (this.hasPointerUp) {
2443
- if (window.navigator.msPointerEnabled) { // IE10-
2444
- Env.removeEvent(this.document, 'MSPointerUp', this.pointerUpListener, this);
2445
- } else {
2446
- Env.removeEvent(this.document, 'pointerup', this.pointerUpListener, this);
2447
- Env.removeEvent(this.document, 'pointercancel', this.pointerUpListener, this);
2448
- }
2449
- this.hasPointerUp = false;
2445
+ if (this.hasPointerUp) {
2446
+ if (window.navigator.msPointerEnabled) { // IE10-
2447
+ Env.removeEvent(this.document, 'MSPointerUp', this.pointerUpListener, this);
2448
+ } else {
2449
+ Env.removeEvent(this.document, 'pointerup', this.pointerUpListener, this);
2450
+ Env.removeEvent(this.document, 'pointercancel', this.pointerUpListener, this);
2450
2451
  }
2452
+ this.hasPointerUp = false;
2453
+ }
2451
2454
 
2452
- // this.dehighlightAll();
2453
- // this.updateQuality = this.BOARD_QUALITY_HIGH;
2454
- // this.mode = this.BOARD_MODE_NONE;
2455
+ // this.dehighlightAll();
2456
+ // this.updateQuality = this.BOARD_QUALITY_HIGH;
2457
+ // this.mode = this.BOARD_MODE_NONE;
2458
+
2459
+ // this.originMoveEnd();
2460
+ // this.update();
2455
2461
 
2456
- this.originMoveEnd();
2457
- this.update();
2458
- // }
2459
2462
  // After one finger leaves the screen the gesture is stopped.
2460
2463
  this._pointerClearTouches();
2461
2464
  return true;
@@ -2582,7 +2585,7 @@ define([
2582
2585
  Yprev: NaN,
2583
2586
  Xstart: [],
2584
2587
  Ystart: [],
2585
- Zstart: []
2588
+ Zstart: []
2586
2589
  };
2587
2590
 
2588
2591
  if (Type.isPoint(obj) ||
@@ -2590,7 +2593,7 @@ define([
2590
2593
  obj.type === Const.OBJECT_TYPE_TICKS ||
2591
2594
  obj.type === Const.OBJECT_TYPE_IMAGE) {
2592
2595
  // It's a point, so it's single touch, so we just push it to our touches
2593
- targets = [target_obj];
2596
+ targets = [target];
2594
2597
 
2595
2598
  // For the UNDO/REDO of object moves
2596
2599
  this.saveStartPos(obj, targets[0]);
@@ -2670,8 +2673,8 @@ define([
2670
2673
  * @returns {Boolean}
2671
2674
  */
2672
2675
  touchMoveListener: function (evt) {
2673
- var i, pos1, pos2,
2674
- time, touchTargets,
2676
+ var i, pos1, pos2,
2677
+ touchTargets,
2675
2678
  evtTouches = evt[JXG.touchProperty];
2676
2679
 
2677
2680
  if (!this.checkFrameRate(evt)) {
@@ -2798,6 +2801,7 @@ define([
2798
2801
  if (this.selectingMode) {
2799
2802
  this._stopSelecting(evt);
2800
2803
  this.triggerEventHandlers(['touchstopselecting', 'stopselecting'], [evt]);
2804
+ this.stopSelectionMode();
2801
2805
  } else if (evtTouches && evtTouches.length > 0) {
2802
2806
  for (i = 0; i < this.touches.length; i++) {
2803
2807
  tmpTouches[i] = this.touches[i];
@@ -2889,8 +2893,8 @@ define([
2889
2893
  }
2890
2894
  if (!found) {
2891
2895
  this.downObjects[i].triggerEventHandlers(['touchup', 'up'], [evt]);
2892
- this.downObjects[i].snapToGrid();
2893
- this.downObjects[i].snapToPoints();
2896
+ // this.downObjects[i].snapToGrid();
2897
+ // this.downObjects[i].snapToPoints();
2894
2898
  this.downObjects.splice(i, 1);
2895
2899
  }
2896
2900
  }
@@ -3053,11 +3057,11 @@ define([
3053
3057
  // redraw with high precision
3054
3058
  this.updateQuality = this.BOARD_QUALITY_HIGH;
3055
3059
 
3056
- if (this.mouse && this.mouse.obj) {
3057
- // The parameter is needed for lines with snapToGrid enabled
3058
- this.mouse.obj.snapToGrid(this.mouse.targets[0]);
3059
- this.mouse.obj.snapToPoints();
3060
- }
3060
+ // if (this.mouse && this.mouse.obj) {
3061
+ // // The parameter is needed for lines with snapToGrid enabled
3062
+ // this.mouse.obj.snapToGrid(this.mouse.targets[0]);
3063
+ // this.mouse.obj.snapToPoints();
3064
+ // }
3061
3065
 
3062
3066
  this.originMoveEnd();
3063
3067
  this.dehighlightAll();
@@ -3067,6 +3071,7 @@ define([
3067
3071
  if (this.selectingMode) {
3068
3072
  this._stopSelecting(evt);
3069
3073
  this.triggerEventHandlers(['mousestopselecting', 'stopselecting'], [evt]);
3074
+ this.stopSelectionMode();
3070
3075
  } else {
3071
3076
  for (i = 0; i < this.downObjects.length; i++) {
3072
3077
  this.downObjects[i].triggerEventHandlers(['mouseup', 'up'], [evt]);
@@ -3135,6 +3140,7 @@ define([
3135
3140
  dx = Type.evaluate(this.attr.keyboard.dx) / this.unitX,
3136
3141
  dy = Type.evaluate(this.attr.keyboard.dy) / this.unitY,
3137
3142
  doZoom = false,
3143
+ done = true,
3138
3144
  dir, actPos;
3139
3145
 
3140
3146
  if (!this.attr.keyboard.enabled || id_node === '') {
@@ -3163,6 +3169,8 @@ define([
3163
3169
  this.clickLeftArrow();
3164
3170
  } else if (evt.keyCode === 39) { // right
3165
3171
  this.clickRightArrow();
3172
+ } else {
3173
+ done = false;
3166
3174
  }
3167
3175
  } else {
3168
3176
  // Adapt dx, dy to snapToGrid and attractToGrid
@@ -3189,7 +3197,7 @@ define([
3189
3197
  sX = 1.1 * Type.evaluate(el.visProp.attractordistance);
3190
3198
  sY = sX;
3191
3199
 
3192
- if (Type.evaluate(el.visProp.attractorunit) == 'screen') {
3200
+ if (Type.evaluate(el.visProp.attractorunit) === 'screen') {
3193
3201
  sX /= this.unitX;
3194
3202
  sY /= this.unitX;
3195
3203
  }
@@ -3215,7 +3223,10 @@ define([
3215
3223
  this.zoomOut();
3216
3224
  } else if (doZoom && evt.key === 'o') { // o
3217
3225
  this.zoom100();
3226
+ } else {
3227
+ done = false;
3218
3228
  }
3229
+
3219
3230
  if (dir && el.isDraggable &&
3220
3231
  el.visPropCalc.visible &&
3221
3232
  ((this.geonextCompatibilityMode &&
@@ -3241,6 +3252,9 @@ define([
3241
3252
 
3242
3253
  this.update();
3243
3254
 
3255
+ if (done && Type.exists(evt.preventDefault)) {
3256
+ evt.preventDefault();
3257
+ }
3244
3258
  return true;
3245
3259
  },
3246
3260
 
@@ -3704,11 +3718,11 @@ define([
3704
3718
  * // Shorter version:
3705
3719
  * //somePoint = board.create('point', a, {name:'SomePoint',size:4});
3706
3720
  * });
3707
- *
3721
+ *
3708
3722
  * })();
3709
3723
  *
3710
3724
  * </script><pre>
3711
- *
3725
+ *
3712
3726
  * @see JXG.Board#getScrCoordsOfMouse
3713
3727
  * @see JXG.Board#getAllUnderMouse
3714
3728
  */
@@ -3830,7 +3844,7 @@ define([
3830
3844
  addConditions: function (str) {
3831
3845
  var term, m, left, right, name, el, property,
3832
3846
  functions = [],
3833
- plaintext = 'var el, x, y, c, rgbo;\n',
3847
+ // plaintext = 'var el, x, y, c, rgbo;\n',
3834
3848
  i = str.indexOf('<data>'),
3835
3849
  j = str.indexOf('<' + '/data>'),
3836
3850
 
@@ -3914,7 +3928,7 @@ define([
3914
3928
  if (!Type.exists(this.elementsByName[name])) {
3915
3929
  JXG.debug("debug conditions: |" + name + "| undefined");
3916
3930
  } else {
3917
- plaintext += "el = this.objects[\"" + el.id + "\"];\n";
3931
+ // plaintext += "el = this.objects[\"" + el.id + "\"];\n";
3918
3932
 
3919
3933
  switch (property) {
3920
3934
  case 'x':
@@ -4389,34 +4403,38 @@ define([
4389
4403
  * @returns {JXG.Board} Reference to the board
4390
4404
  */
4391
4405
  resizeContainer: function (canvasWidth, canvasHeight, dontset, dontSetBoundingBox) {
4392
- var box_act, box, w, h, cx, cy,
4393
- shift_x = 0,
4394
- shift_y = 0;
4406
+ var box;
4407
+ // w, h, cx, cy;
4408
+ // box_act,
4409
+ // shift_x = 0,
4410
+ // shift_y = 0;
4395
4411
 
4396
4412
  if (!dontSetBoundingBox) {
4397
- box_act = this.getBoundingBox(); // This is the actual bounding box.
4413
+ // box_act = this.getBoundingBox(); // This is the actual bounding box.
4414
+ box = this.getBoundingBox(); // This is the actual bounding box.
4398
4415
  }
4399
4416
 
4400
4417
  this.canvasWidth = parseFloat(canvasWidth);
4401
4418
  this.canvasHeight = parseFloat(canvasHeight);
4402
4419
 
4403
- if (!dontSetBoundingBox) {
4404
- box = this.attr.boundingbox; // This is the intended bounding box.
4405
-
4406
- // The shift values compensate the follow-up correction
4407
- // in setBoundingBox in case of "this.keepaspectratio==true"
4408
- // Otherwise, shift_x and shift_y will be zero.
4409
- shift_x = box_act[0] - box[0] / this.zoomX;
4410
- shift_y = box_act[1] - box[1] / this.zoomY;
4420
+ // if (!dontSetBoundingBox) {
4421
+ // box = this.attr.boundingbox; // This is the intended bounding box.
4411
4422
 
4412
- cx = (box[2] + box[0]) * 0.5 + shift_x;
4413
- cy = (box[3] + box[1]) * 0.5 + shift_y;
4423
+ // // The shift values compensate the follow-up correction
4424
+ // // in setBoundingBox in case of "this.keepaspectratio==true"
4425
+ // // Otherwise, shift_x and shift_y will be zero.
4426
+ // // Obsolet since setBoundingBox centers in case of "this.keepaspectratio==true".
4427
+ // // shift_x = box_act[0] - box[0] / this.zoomX;
4428
+ // // shift_y = box_act[1] - box[1] / this.zoomY;
4414
4429
 
4415
- w = (box[2] - box[0]) * 0.5 / this.zoomX;
4416
- h = (box[1] - box[3]) * 0.5 / this.zoomY;
4430
+ // cx = (box[2] + box[0]) * 0.5; // + shift_x;
4431
+ // cy = (box[3] + box[1]) * 0.5; // + shift_y;
4417
4432
 
4418
- box = [cx - w, cy + h, cx + w, cy - h];
4419
- }
4433
+ // w = (box[2] - box[0]) * 0.5 / this.zoomX;
4434
+ // h = (box[1] - box[3]) * 0.5 / this.zoomY;
4435
+
4436
+ // box = [cx - w, cy + h, cx + w, cy - h];
4437
+ // }
4420
4438
 
4421
4439
  if (!dontset) {
4422
4440
  this.containerObj.style.width = (this.canvasWidth) + 'px';
@@ -4532,7 +4550,7 @@ define([
4532
4550
 
4533
4551
  for (el = 0; el < this.objectsList.length; el++) {
4534
4552
  pEl = this.objectsList[el];
4535
- if (this.needsFullUpdate && pEl.elementClass == Const.OBJECT_CLASS_TEXT) {
4553
+ if (this.needsFullUpdate && pEl.elementClass === Const.OBJECT_CLASS_TEXT) {
4536
4554
  pEl.updateSize();
4537
4555
  }
4538
4556
 
@@ -4835,6 +4853,7 @@ define([
4835
4853
  for (i = 0; i < parents.length; i++) {
4836
4854
  if (Type.isString(parents[i]) &&
4837
4855
  !(elementType === 'text' && i === 2) &&
4856
+ !(elementType === 'solidofrevolution3d' && i === 2) &&
4838
4857
  !((elementType === 'input' || elementType === 'checkbox' || elementType === 'button') &&
4839
4858
  (i === 2 || i === 3)) &&
4840
4859
  !(elementType === 'curve' && i > 0) // Allow curve plots with jessiecode
@@ -4919,11 +4938,14 @@ define([
4919
4938
  */
4920
4939
  setBoundingBox: function (bbox, keepaspectratio, setZoom) {
4921
4940
  var h, w, ux, uy,
4941
+ offX = 0,
4942
+ offY = 0,
4922
4943
  dim = Env.getDimensions(this.container, this.document);
4923
4944
 
4924
4945
  if (!Type.isArray(bbox)) {
4925
4946
  return this;
4926
4947
  }
4948
+
4927
4949
  if (bbox[0] < this.maxboundingbox[0] ||
4928
4950
  bbox[1] > this.maxboundingbox[1] ||
4929
4951
  bbox[2] > this.maxboundingbox[2] ||
@@ -4942,14 +4964,17 @@ define([
4942
4964
  this.canvasHeight = parseInt(dim.height, 10);
4943
4965
  w = this.canvasWidth;
4944
4966
  h = this.canvasHeight;
4945
-
4946
4967
  if (keepaspectratio) {
4947
4968
  this.unitX = w / (bbox[2] - bbox[0]);
4948
4969
  this.unitY = h / (bbox[1] - bbox[3]);
4949
4970
  if (Math.abs(this.unitX) < Math.abs(this.unitY)) {
4950
4971
  this.unitY = Math.abs(this.unitX) * this.unitY / Math.abs(this.unitY);
4972
+ // Add the additional units in equal portions above and below
4973
+ offY = (h / this.unitY - (bbox[1] - bbox[3])) * 0.5;
4951
4974
  } else {
4952
4975
  this.unitX = Math.abs(this.unitY) * this.unitX / Math.abs(this.unitX);
4976
+ // Add the additional units in equal portions left and right
4977
+ offX = (w / this.unitX - (bbox[2] - bbox[0])) * 0.5;
4953
4978
  }
4954
4979
  this.keepaspectratio = true;
4955
4980
  } else {
@@ -4957,8 +4982,8 @@ define([
4957
4982
  this.unitY = h / (bbox[1] - bbox[3]);
4958
4983
  this.keepaspectratio = false;
4959
4984
  }
4960
-
4961
- this.moveOrigin(-this.unitX * bbox[0], this.unitY * bbox[1]);
4985
+
4986
+ this.moveOrigin(-this.unitX * (bbox[0] - offX), this.unitY * (bbox[1] + offY));
4962
4987
 
4963
4988
  if (setZoom === 'update') {
4964
4989
  this.zoomX *= this.unitX / ux;
@@ -5849,6 +5874,8 @@ define([
5849
5874
  * <p>
5850
5875
  * The wrapping div has the CSS class 'jxgbox_wrap_private' which is
5851
5876
  * defined in the file 'jsxgraph.css'
5877
+ * <p>
5878
+ * This feature is not available on iPhones (as of December 2021).
5852
5879
  *
5853
5880
  * @param {String} id (Optional) id of the div element which is brought to fullscreen.
5854
5881
  * If not provided, this defaults to the JSXGraph div. However, it may be necessary for the aspect ratio trick
@@ -5912,28 +5939,38 @@ define([
5912
5939
  *
5913
5940
  *
5914
5941
  */
5915
- toFullscreen: function(id) {
5942
+ toFullscreen: function (id) {
5916
5943
  var wrap_id, wrap_node, inner_node;
5917
5944
 
5918
5945
  id = id || this.container;
5919
-
5920
5946
  this._fullscreen_inner_id = id;
5921
- // inner_node = this.containerObj;
5922
5947
  inner_node = document.getElementById(id);
5923
-
5924
5948
  wrap_id = 'fullscreenwrap_' + id;
5925
- wrap_node = document.createElement('div');
5926
5949
 
5927
- // If necessary, wrap a div around the JSXGraph div.
5928
- if (!this.document.getElementById(wrap_id)) {
5950
+ // Wrap a div around the JSXGraph div.
5951
+ if (this.document.getElementById(wrap_id)) {
5952
+ wrap_node = this.document.getElementById(wrap_id);
5953
+ } else {
5954
+ wrap_node = document.createElement('div');
5929
5955
  wrap_node.classList.add('JXG_wrap_private');
5930
5956
  wrap_node.setAttribute('id', wrap_id);
5931
5957
  inner_node.parentNode.insertBefore(wrap_node, inner_node);
5932
5958
  wrap_node.appendChild(inner_node);
5933
5959
  }
5934
5960
 
5935
- // Start fullscreen mode
5936
- Env.toFullscreen(wrap_id, id);
5961
+ // Get the real width and height of the JSXGraph div
5962
+ // and determine the scaling and vertical shift amount
5963
+ this._fullscreen_res = Env._getScaleFactors(inner_node);
5964
+
5965
+ // Trigger fullscreen mode
5966
+ wrap_node.requestFullscreen = wrap_node.requestFullscreen ||
5967
+ wrap_node.webkitRequestFullscreen ||
5968
+ wrap_node.mozRequestFullScreen ||
5969
+ wrap_node.msRequestFullscreen;
5970
+
5971
+ if (wrap_node.requestFullscreen) {
5972
+ wrap_node.requestFullscreen();
5973
+ }
5937
5974
 
5938
5975
  return this;
5939
5976
  },
@@ -5945,7 +5982,7 @@ define([
5945
5982
  *
5946
5983
  * @param {Object} evt fullscreen event object (unused)
5947
5984
  */
5948
- fullscreenListener: function(evt) {
5985
+ fullscreenListener: function (evt) {
5949
5986
  var res, inner_id, inner_node;
5950
5987
 
5951
5988
  inner_id = this._fullscreen_inner_id;
@@ -5953,20 +5990,20 @@ define([
5953
5990
  return;
5954
5991
  }
5955
5992
 
5993
+ document.fullscreenElement = document.fullscreenElement ||
5994
+ document.webkitFullscreenElement ||
5995
+ document.mozFullscreenElement ||
5996
+ document.msFullscreenElement;
5997
+
5956
5998
  inner_node = document.getElementById(inner_id);
5957
5999
  // If full screen mode is started we have to remove CSS margin around the JSXGraph div.
5958
6000
  // Otherwise, the positioning of the fullscreen div will be false.
5959
6001
  // When leaving the fullscreen mode, the margin is put back in.
5960
6002
  if (document.fullscreenElement) {
5961
- // Entered fullscreen mode
6003
+ // Just entered fullscreen mode
5962
6004
 
5963
- inner_node.style.margin = '';
5964
-
5965
- // Do the shifting and scaling via CSS pseudo rules
5966
- // We do this after fullscreen mode has been established to get the correct size
5967
- // of the JSXGraph div
5968
- res = Env._getScaleFactors(inner_node);
5969
- Env.scaleJSXGraphDiv(document.fullscreenElement.id, inner_id, res.scale, res.vshift);
6005
+ // Get the data computed in board.toFullscreen()
6006
+ res = this._fullscreen_res;
5970
6007
 
5971
6008
  // Store the scaling data.
5972
6009
  // It is used in AbstractRenderer.updateText to restore the scaling matrix
@@ -5977,11 +6014,25 @@ define([
5977
6014
  id: document.fullscreenElement.id,
5978
6015
  isFullscreen: true,
5979
6016
  margin: inner_node.style.margin,
5980
- scale: res.scale,
6017
+ width: inner_node.style.width,
6018
+ scale: res.scale,
5981
6019
  vshift: res.vshift
5982
6020
  };
6021
+
6022
+ inner_node.style.margin = '';
6023
+ inner_node.style.width = res.width + 'px';
6024
+
6025
+ // Do the shifting and scaling via CSS pseudo rules
6026
+ // We do this after fullscreen mode has been established to get the correct size
6027
+ // of the JSXGraph div.
6028
+ Env.scaleJSXGraphDiv(document.fullscreenElement.id, inner_id, res.scale, res.vshift);
6029
+
6030
+ // Clear document.fullscreenElement, because Safari doesn't to it and
6031
+ // when leaving full screen mode it is still set.
6032
+ document.fullscreenElement = null;
6033
+
5983
6034
  } else if (Type.exists(inner_node._cssFullscreenStore)) {
5984
- // Left fullscreen mode
6035
+ // Just left the fullscreen mode
5985
6036
 
5986
6037
  // Remove the CSS rules added in Env.scaleJSXGraphDiv
5987
6038
  try {
@@ -5989,8 +6040,11 @@ define([
5989
6040
  } catch (err) {
5990
6041
  console.log('JSXGraph: Could not remove CSS rules for full screen mode');
5991
6042
  }
6043
+
5992
6044
  inner_node._cssFullscreenStore.isFullscreen = false;
5993
6045
  inner_node.style.margin = inner_node._cssFullscreenStore.margin;
6046
+ inner_node.style.width = inner_node._cssFullscreenStore.width;
6047
+
5994
6048
  }
5995
6049
 
5996
6050
  this.updateCSSTransforms();
package/src/base/chart.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2008-2021
2
+ Copyright 2008-2022
3
3
  Matthias Ehmann,
4
4
  Michael Gerhaeuser,
5
5
  Carsten Miller,
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2008-2021
2
+ Copyright 2008-2022
3
3
  Matthias Ehmann,
4
4
  Michael Gerhaeuser,
5
5
  Carsten Miller,
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2008-2021
2
+ Copyright 2008-2022
3
3
  Matthias Ehmann,
4
4
  Michael Gerhaeuser,
5
5
  Carsten Miller,
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2008-2021
2
+ Copyright 2008-2022
3
3
  Matthias Ehmann,
4
4
  Michael Gerhaeuser,
5
5
  Carsten Miller,
@@ -42,7 +42,7 @@ define(['jxg'], function (JXG) {
42
42
 
43
43
  var major = 1,
44
44
  minor = 4,
45
- patch = 0,
45
+ patch = 3,
46
46
  add = '', //'dev'
47
47
  version = major + '.' + minor + '.' + patch + (add ? '-' + add : ''),
48
48
  constants;
@@ -111,6 +111,7 @@ define(['jxg'], function (JXG) {
111
111
  OBJECT_TYPE_BUTTON: 29,
112
112
  OBJECT_TYPE_TRANSFORMATION: 30,
113
113
  OBJECT_TYPE_FOREIGNOBJECT: 31,
114
+ OBJECT_TYPE_VIEW3D: 32,
114
115
 
115
116
  // IMPORTANT:
116
117
  // ----------
@@ -132,16 +133,16 @@ define(['jxg'], function (JXG) {
132
133
  GENTYPE_AXIS: 2,
133
134
  GENTYPE_MID: 3,
134
135
 
135
- /**
136
+ /**
136
137
  * @ignore
137
- * @deprecated, now use {@link JXG.GENTYPE_REFLECTION_ON_LINE}
138
- *
139
- */
138
+ * @deprecated, now use {@link JXG.GENTYPE_REFLECTION_ON_LINE}
139
+ *
140
+ */
140
141
  GENTYPE_REFLECTION: 4,
141
- /**
142
- * @ignore
143
- * @deprecated, now use {@link JXG.GENTYPE_REFLECTION_ON_POINT}
144
- */
142
+ /**
143
+ * @ignore
144
+ * @deprecated, now use {@link JXG.GENTYPE_REFLECTION_ON_POINT}
145
+ */
145
146
  GENTYPE_MIRRORELEMENT: 5,
146
147
 
147
148
  GENTYPE_REFLECTION_ON_LINE: 4,
@@ -156,9 +157,9 @@ define(['jxg'], function (JXG) {
156
157
  GENTYPE_GLIDER: 13,
157
158
  GENTYPE_INTERSECTION: 14,
158
159
  GENTYPE_CIRCLE: 15,
159
- /**
160
- * @ignore @deprecated NOT USED ANY MORE SINCE SKETCHOMETRY 2.0 (only for old constructions needed)
161
- */
160
+ /**
161
+ * @ignore @deprecated NOT USED ANY MORE SINCE SKETCHOMETRY 2.0 (only for old constructions needed)
162
+ */
162
163
  GENTYPE_CIRCLE2POINTS: 16,
163
164
 
164
165
  GENTYPE_LINE: 17,
@@ -197,7 +198,7 @@ define(['jxg'], function (JXG) {
197
198
  * @name Constants
198
199
  * @namespace
199
200
  */
200
-
201
+
201
202
  // GENTYPE_TRANSFORM: 48, // unused
202
203
  // 49 ... 50 // unused ...
203
204
 
@@ -1,5 +1,5 @@
1
1
  /*
2
- Copyright 2008-2021
2
+ Copyright 2008-2022
3
3
  Matthias Ehmann,
4
4
  Michael Gerhaeuser,
5
5
  Carsten Miller,
@@ -234,11 +234,11 @@ define([
234
234
  },
235
235
 
236
236
  /**
237
- * Copy array, either srcCoords or usrCoords
237
+ * Copy array, either scrCoords or usrCoords
238
238
  * Uses slice() in case of standard arrays and set() in case of
239
239
  * typed arrays.
240
240
  * @private
241
- * @param {String} obj Either 'srcCoords' or 'usrCoords'
241
+ * @param {String} obj Either 'scrCoords' or 'usrCoords'
242
242
  * @param {Number} offset Offset, defaults to 0 if not given
243
243
  * @returns {Array} Returns copy of the coords array either as standard array or as
244
244
  * typed array.