jsxgraph 1.4.4 → 1.4.6

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 (56) hide show
  1. package/README.md +24 -0
  2. package/build/Readme.md +17 -0
  3. package/build/bin/jsxcompressor.js +1 -0
  4. package/build/bin/jsxgraphcore-min.js +7 -0
  5. package/build/bin/jsxgraphcore.js +83017 -0
  6. package/build/bin/jsxgraphcore.min.js +67 -0
  7. package/build/compressor.build.json +14 -0
  8. package/build/compressor.deps.js +8 -0
  9. package/build/core-amd.build.json +14 -0
  10. package/build/core-amd.deps.js +81 -0
  11. package/build/core.build.json +14 -0
  12. package/build/core.deps.js +102 -0
  13. package/build/plot.build.json +15 -0
  14. package/distrib/README.md +24 -0
  15. package/distrib/geogebra.min.js +1 -1
  16. package/distrib/geonext.min.js +1 -1
  17. package/distrib/index.d.ts +28 -7
  18. package/distrib/intergeo.min.js +1 -1
  19. package/distrib/jsxgraph.css +6 -0
  20. package/distrib/jsxgraphcore.js +3 -3
  21. package/distrib/jsxgraphsrc.js +3558 -1857
  22. package/distrib/sketch.min.js +1 -1
  23. package/package.json +1 -1
  24. package/src/3d/box3d.js +43 -38
  25. package/src/3d/curve3d.js +157 -53
  26. package/src/3d/element3d.js +84 -0
  27. package/src/3d/linspace3d.js +427 -146
  28. package/src/3d/point3d.js +360 -123
  29. package/src/3d/surface3d.js +140 -42
  30. package/src/3d/view3d.js +319 -164
  31. package/src/base/board.js +163 -78
  32. package/src/base/constants.js +8 -1
  33. package/src/base/curve.js +51 -9
  34. package/src/base/polygon.js +111 -69
  35. package/src/base/text.js +122 -19
  36. package/src/base/ticks.js +12 -3
  37. package/src/element/button.js +7 -3
  38. package/src/element/checkbox.js +8 -4
  39. package/src/element/composition.js +7 -1
  40. package/src/element/conic.js +2 -2
  41. package/src/element/input.js +9 -5
  42. package/src/jsxgraph.js +4 -1
  43. package/src/loadjsxgraph.js +13 -8
  44. package/src/math/clip.js +34 -134
  45. package/src/math/geometry.js +204 -3
  46. package/src/math/math.js +1 -2
  47. package/src/math/nlp.js +865 -774
  48. package/src/options.js +185 -12
  49. package/src/options3d.js +24 -7
  50. package/src/parser/jessiecode.js +9 -3
  51. package/src/renderer/abstract.js +26 -15
  52. package/src/renderer/canvas.js +2 -2
  53. package/src/renderer/svg.js +15 -2
  54. package/src/utils/env.js +36 -53
  55. package/src/utils/type.js +75 -2
  56. package/src/3d/threed.js +0 -38
package/src/base/board.js CHANGED
@@ -334,7 +334,7 @@ define([
334
334
  this.numObjects = 0;
335
335
 
336
336
  /**
337
- * An associative array to store the objects of the board by name. the name of the object is the key and value is a reference to the object.
337
+ * An associative array / dictionary to store the objects of the board by name. The name of the object is the key and value is a reference to the object.
338
338
  * @type Object
339
339
  */
340
340
  this.elementsByName = {};
@@ -819,7 +819,7 @@ define([
819
819
  // In ownerDoc we need the "real" document object.
820
820
  // The first version is used in the case of shadowDom,
821
821
  // the second case in the "normal" case.
822
- ownerDoc = this.document.ownerDocument || this.document,
822
+ ownerDoc = this.document.ownerDocument || this.document,
823
823
  docElement = ownerDoc.documentElement || this.document.body.parentNode,
824
824
  docBody = ownerDoc.body,
825
825
  container = this.containerObj,
@@ -1196,7 +1196,8 @@ define([
1196
1196
  */
1197
1197
  twoFingerTouchObject: function (tar, drag, id) {
1198
1198
  var np, op, nd, od,
1199
- d, alpha,
1199
+ d,
1200
+ alpha = 0,
1200
1201
  S, t1, t3, t4, t5,
1201
1202
  ar, i, len,
1202
1203
  fixEl, moveEl, fix;
@@ -1230,7 +1231,9 @@ define([
1230
1231
  return;
1231
1232
  }
1232
1233
 
1233
- alpha = Geometry.rad(op.slice(1), fix.slice(1), np.slice(1));
1234
+ if (Type.evaluate(drag.visProp.rotatable)) {
1235
+ alpha = Geometry.rad(op.slice(1), fix.slice(1), np.slice(1));
1236
+ }
1234
1237
 
1235
1238
  t1 = this.create('transform', [alpha, [fix[1], fix[2]]], {type: 'rotate'});
1236
1239
  t1.update();
@@ -2401,7 +2404,8 @@ define([
2401
2404
  * @returns {Boolean}
2402
2405
  */
2403
2406
  pointerUpListener: function (evt) {
2404
- var i, j, found, touchTargets;
2407
+ var i, j, found, touchTargets,
2408
+ updateNeeded = false;
2405
2409
 
2406
2410
  this.triggerEventHandlers(['touchend', 'up', 'pointerup', 'MSPointerUp'], [evt]);
2407
2411
  this.displayInfobox(false);
@@ -2439,8 +2443,14 @@ define([
2439
2443
  }
2440
2444
  if (!found) {
2441
2445
  this.downObjects[i].triggerEventHandlers(['touchend', 'up', 'pointerup', 'MSPointerUp'], [evt]);
2442
- // this.downObjects[i].snapToGrid();
2443
- // this.downObjects[i].snapToPoints();
2446
+ if (!Type.exists(this.downObjects[i].coords)) {
2447
+ // snapTo methods have to be called e.g. for line elements here.
2448
+ // For coordsElements there might be a conflict with
2449
+ // attractors, see commit from 2022.04.08, 11:12:18.
2450
+ this.downObjects[i].snapToGrid();
2451
+ this.downObjects[i].snapToPoints();
2452
+ updateNeeded = true;
2453
+ }
2444
2454
  this.downObjects.splice(i, 1);
2445
2455
  }
2446
2456
  }
@@ -2461,7 +2471,9 @@ define([
2461
2471
  // this.mode = this.BOARD_MODE_NONE;
2462
2472
 
2463
2473
  // this.originMoveEnd();
2464
- // this.update();
2474
+ if (updateNeeded) {
2475
+ this.update();
2476
+ }
2465
2477
 
2466
2478
  // After one finger leaves the screen the gesture is stopped.
2467
2479
  this._pointerClearTouches();
@@ -2796,7 +2808,8 @@ define([
2796
2808
  eps = this.options.precision.touch,
2797
2809
  tmpTouches = [], found, foundNumber,
2798
2810
  evtTouches = evt && evt[JXG.touchProperty],
2799
- touchTargets;
2811
+ touchTargets,
2812
+ updateNeeded = false;
2800
2813
 
2801
2814
  this.triggerEventHandlers(['touchend', 'up'], [evt]);
2802
2815
  this.displayInfobox(false);
@@ -2897,8 +2910,14 @@ define([
2897
2910
  }
2898
2911
  if (!found) {
2899
2912
  this.downObjects[i].triggerEventHandlers(['touchup', 'up'], [evt]);
2900
- // this.downObjects[i].snapToGrid();
2901
- // this.downObjects[i].snapToPoints();
2913
+ if (!Type.exists(this.downObjects[i].coords)) {
2914
+ // snapTo methods have to be called e.g. for line elements here.
2915
+ // For coordsElements there might be a conflict with
2916
+ // attractors, see commit from 2022.04.08, 11:12:18.
2917
+ this.downObjects[i].snapToGrid();
2918
+ this.downObjects[i].snapToPoints();
2919
+ updateNeeded = true;
2920
+ }
2902
2921
  this.downObjects.splice(i, 1);
2903
2922
  }
2904
2923
  }
@@ -2914,7 +2933,9 @@ define([
2914
2933
  this.updateQuality = this.BOARD_QUALITY_HIGH;
2915
2934
 
2916
2935
  this.originMoveEnd();
2917
- this.update();
2936
+ if (updateNeeded) {
2937
+ this.update();
2938
+ }
2918
2939
  }
2919
2940
 
2920
2941
  return true;
@@ -3061,11 +3082,16 @@ define([
3061
3082
  // redraw with high precision
3062
3083
  this.updateQuality = this.BOARD_QUALITY_HIGH;
3063
3084
 
3064
- // if (this.mouse && this.mouse.obj) {
3065
- // // The parameter is needed for lines with snapToGrid enabled
3066
- // this.mouse.obj.snapToGrid(this.mouse.targets[0]);
3067
- // this.mouse.obj.snapToPoints();
3068
- // }
3085
+ if (this.mouse && this.mouse.obj) {
3086
+ if (!Type.exists(this.mouse.obj.coords)) {
3087
+ // snapTo methods have to be called e.g. for line elements here.
3088
+ // For coordsElements there might be a conflict with
3089
+ // attractors, see commit from 2022.04.08, 11:12:18.
3090
+ // The parameter is needed for lines with snapToGrid enabled
3091
+ this.mouse.obj.snapToGrid(this.mouse.targets[0]);
3092
+ this.mouse.obj.snapToPoints();
3093
+ }
3094
+ }
3069
3095
 
3070
3096
  this.originMoveEnd();
3071
3097
  this.dehighlightAll();
@@ -3121,11 +3147,18 @@ define([
3121
3147
  },
3122
3148
 
3123
3149
  /**
3124
- * Allow moving of JSXGraph elements with arrow keys
3125
- * and zooming of the construction with + / -.
3150
+ * Allow moving of JSXGraph elements with arrow keys.
3151
+ * The selection of the element is done with the tab key. For this,
3152
+ * the attribute "tabindex" of the element has to be set to some number (default=0).
3153
+ * tabindex corresponds to the HTML attribute of the same name.
3154
+ * <p>
3126
3155
  * Panning of the construction is done with arrow keys
3127
- * if the pan key (shift or ctrl) is pressed.
3128
- * The selection of the element is done with the tab key.
3156
+ * if the pan key (shift or ctrl - depending on the board attributes) is pressed.
3157
+ * <p>
3158
+ * Zooming is triggered with the keys +, o, -, if
3159
+ * the pan key (shift or ctrl - depending on the board attributes) is pressed.
3160
+ * <p>
3161
+ * Keyboard control (move, pan, and zoom) is disabled if an HTML element of type input or textarea has received focus.
3129
3162
  *
3130
3163
  * @param {Event} evt The browser's event object
3131
3164
  *
@@ -3136,7 +3169,7 @@ define([
3136
3169
  */
3137
3170
  keyDownListener: function (evt) {
3138
3171
  var id_node = evt.target.id,
3139
- id, el, res,
3172
+ id, el, res, doc,
3140
3173
  sX = 0,
3141
3174
  sY = 0,
3142
3175
  // dx, dy are provided in screen units and
@@ -3151,6 +3184,15 @@ define([
3151
3184
  return false;
3152
3185
  }
3153
3186
 
3187
+ // An element of type input or textarea has foxus, get out of here.
3188
+ doc = this.containerObj.shadowRoot || document;
3189
+ if (doc.activeElement) {
3190
+ el = doc.activeElement;
3191
+ if (el.tagName === 'INPUT' || el.tagName === 'textarea') {
3192
+ return false;
3193
+ }
3194
+ }
3195
+
3154
3196
  // Get the JSXGraph id from the id of the SVG node.
3155
3197
  id = id_node.replace(this.containerObj.id + '_', '');
3156
3198
  el = this.select(id);
@@ -3159,12 +3201,15 @@ define([
3159
3201
  actPos = el.coords.usrCoords.slice(1);
3160
3202
  }
3161
3203
 
3162
- if (Type.evaluate(this.attr.keyboard.panshift) || Type.evaluate(this.attr.keyboard.panctrl)) {
3163
- doZoom = true;
3164
- }
3165
-
3166
3204
  if ((Type.evaluate(this.attr.keyboard.panshift) && evt.shiftKey) ||
3167
3205
  (Type.evaluate(this.attr.keyboard.panctrl) && evt.ctrlKey)) {
3206
+ // Pan key has been pressed
3207
+
3208
+ if (Type.evaluate(this.attr.zoom.enabled) === true) {
3209
+ doZoom = true;
3210
+ }
3211
+
3212
+ // Arrow keys
3168
3213
  if (evt.keyCode === 38) { // up
3169
3214
  this.clickUpArrow();
3170
3215
  } else if (evt.keyCode === 40) { // down
@@ -3173,10 +3218,20 @@ define([
3173
3218
  this.clickLeftArrow();
3174
3219
  } else if (evt.keyCode === 39) { // right
3175
3220
  this.clickRightArrow();
3221
+
3222
+ // Zoom keys
3223
+ } else if (doZoom && evt.keyCode === 171) { // +
3224
+ this.zoomIn();
3225
+ } else if (doZoom && evt.keyCode === 173) { // -
3226
+ this.zoomOut();
3227
+ } else if (doZoom && evt.keyCode === 79) { // o
3228
+ this.zoom100();
3229
+
3176
3230
  } else {
3177
3231
  done = false;
3178
3232
  }
3179
3233
  } else {
3234
+
3180
3235
  // Adapt dx, dy to snapToGrid and attractToGrid
3181
3236
  // snapToGrid has priority.
3182
3237
  if (Type.exists(el.visProp)) {
@@ -3219,14 +3274,6 @@ define([
3219
3274
  dir = [-dx, 0];
3220
3275
  } else if (evt.keyCode === 39) { // right
3221
3276
  dir = [dx, 0];
3222
- // } else if (evt.keyCode === 9) { // tab
3223
-
3224
- } else if (doZoom && evt.key === '+') { // +
3225
- this.zoomIn();
3226
- } else if (doZoom && evt.key === '-') { // -
3227
- this.zoomOut();
3228
- } else if (doZoom && evt.key === 'o') { // o
3229
- this.zoom100();
3230
3277
  } else {
3231
3278
  done = false;
3232
3279
  }
@@ -3259,12 +3306,13 @@ define([
3259
3306
  if (done && Type.exists(evt.preventDefault)) {
3260
3307
  evt.preventDefault();
3261
3308
  }
3262
- return true;
3309
+ return done;
3263
3310
  },
3264
3311
 
3265
3312
  /**
3266
3313
  * Event listener for SVG elements getting focus.
3267
3314
  * This is needed for highlighting when using keyboard control.
3315
+ * Only elements having the attribute "tabindex" can receive focus.
3268
3316
  *
3269
3317
  * @see JXG.Board#keyFocusOutListener
3270
3318
  * @see JXG.Board#keyDownListener
@@ -3294,6 +3342,7 @@ define([
3294
3342
  /**
3295
3343
  * Event listener for SVG elements losing focus.
3296
3344
  * This is needed for dehighlighting when using keyboard control.
3345
+ * Only elements having the attribute "tabindex" can receive focus.
3297
3346
  *
3298
3347
  * @see JXG.Board#keyFocusInListener
3299
3348
  * @see JXG.Board#keyDownListener
@@ -3344,8 +3393,8 @@ define([
3344
3393
  }
3345
3394
 
3346
3395
  // If div is invisible - do nothing
3347
- if (w <= 0 || h <= 0 || Type.isNaN(w) || Type.isNaN(h)) {
3348
- return;
3396
+ if (w <= 0 || h <= 0 || isNaN(w) || isNaN(h)) {
3397
+ return;
3349
3398
  }
3350
3399
 
3351
3400
  // If bounding box is not yet initialized, do it now.
@@ -5296,7 +5345,7 @@ define([
5296
5345
  return s;
5297
5346
  }
5298
5347
 
5299
- // it's a string, most likely an id or a name.
5348
+ // It's a string, most likely an id or a name.
5300
5349
  if (Type.isString(s) && s !== '') {
5301
5350
  // Search by ID
5302
5351
  if (Type.exists(this.objects[s])) {
@@ -5308,7 +5357,8 @@ define([
5308
5357
  } else if (Type.exists(this.groups[s])) {
5309
5358
  s = this.groups[s];
5310
5359
  }
5311
- // it's a function or an object, but not an element
5360
+
5361
+ // It's a function or an object, but not an element
5312
5362
  } else if (!onlyByIdOrName &&
5313
5363
  (Type.isFunction(s) ||
5314
5364
  (Type.isObject(s) && !Type.isFunction(s.setAttribute))
@@ -5321,7 +5371,8 @@ define([
5321
5371
  olist[flist[i].id] = flist[i];
5322
5372
  }
5323
5373
  s = new Composition(olist);
5324
- // it's an element which has been deleted (and still hangs around, e.g. in an attractor list
5374
+
5375
+ // It's an element which has been deleted (and still hangs around, e.g. in an attractor list
5325
5376
  } else if (Type.isObject(s) && Type.exists(s.id) && !Type.exists(this.objects[s.id])) {
5326
5377
  s = null;
5327
5378
  }
@@ -5359,31 +5410,43 @@ define([
5359
5410
  */
5360
5411
  updateCSSTransforms: function () {
5361
5412
  var obj = this.containerObj,
5362
- o = obj,
5363
- o2 = obj;
5413
+ o = obj;
5414
+ // o2 = obj;
5364
5415
 
5365
5416
  this.cssTransMat = Env.getCSSTransformMatrix(o);
5366
5417
 
5418
+ // Newer variant of walking up the tree.
5419
+ // We walk up all parent nodes and collect possible CSS transforms.
5420
+ // Works also for ShadowDOM
5421
+ o = o.parentNode === o.getRootNode() ? o.parentNode.host : o.parentNode;
5422
+ while (o) {
5423
+ this.cssTransMat = Mat.matMatMult(Env.getCSSTransformMatrix(o), this.cssTransMat);
5424
+ o = o.parentNode === o.getRootNode() ? o.parentNode.host : o.parentNode;
5425
+ }
5426
+ this.cssTransMat = Mat.inverse(this.cssTransMat);
5427
+
5367
5428
  /*
5368
5429
  * In Mozilla and Webkit: offsetParent seems to jump at least to the next iframe,
5369
5430
  * if not to the body. In IE and if we are in an position:absolute environment
5370
5431
  * offsetParent walks up the DOM hierarchy.
5371
5432
  * In order to walk up the DOM hierarchy also in Mozilla and Webkit
5372
5433
  * we need the parentNode steps.
5434
+ *
5435
+ * Seems to be outdated
5373
5436
  */
5374
- o = o.offsetParent;
5375
- while (o) {
5376
- this.cssTransMat = Mat.matMatMult(Env.getCSSTransformMatrix(o), this.cssTransMat);
5437
+ // o = o.offsetParent;
5438
+ // while (o) {
5439
+ // this.cssTransMat = Mat.matMatMult(Env.getCSSTransformMatrix(o), this.cssTransMat);
5377
5440
 
5378
- o2 = o2.parentNode;
5379
- while (o2 !== o) {
5380
- this.cssTransMat = Mat.matMatMult(Env.getCSSTransformMatrix(o), this.cssTransMat);
5381
- o2 = o2.parentNode || o2.host;
5382
- }
5441
+ // o2 = o2.parentNode;
5442
+ // while (o2 !== o) {
5443
+ // this.cssTransMat = Mat.matMatMult(Env.getCSSTransformMatrix(o), this.cssTransMat);
5444
+ // o2 = o2.parentNode;
5445
+ // }
5383
5446
 
5384
- o = o.offsetParent;
5385
- }
5386
- this.cssTransMat = Mat.inverse(this.cssTransMat);
5447
+ // o = o.offsetParent;
5448
+ // }
5449
+ // this.cssTransMat = Mat.inverse(this.cssTransMat);
5387
5450
 
5388
5451
  return this;
5389
5452
  },
@@ -5944,16 +6007,17 @@ define([
5944
6007
  *
5945
6008
  */
5946
6009
  toFullscreen: function (id) {
5947
- var wrap_id, wrap_node, inner_node;
6010
+ var wrap_id, wrap_node, inner_node,
6011
+ doc = this.document, fullscreenElement;
5948
6012
 
5949
6013
  id = id || this.container;
5950
6014
  this._fullscreen_inner_id = id;
5951
- inner_node = this.document.getElementById(id);
6015
+ inner_node = doc.getElementById(id);
5952
6016
  wrap_id = 'fullscreenwrap_' + id;
5953
6017
 
5954
6018
  // Wrap a div around the JSXGraph div.
5955
- if (this.document.getElementById(wrap_id)) {
5956
- wrap_node = this.document.getElementById(wrap_id);
6019
+ if (doc.getElementById(wrap_id)) {
6020
+ wrap_node = doc.getElementById(wrap_id);
5957
6021
  } else {
5958
6022
  wrap_node = document.createElement('div');
5959
6023
  wrap_node.classList.add('JXG_wrap_private');
@@ -5964,7 +6028,7 @@ define([
5964
6028
 
5965
6029
  // Get the real width and height of the JSXGraph div
5966
6030
  // and determine the scaling and vertical shift amount
5967
- this._fullscreen_res = Env._getScaleFactors(inner_node);
6031
+ // this._fullscreen_res = Env._getScaleFactors(inner_node);
5968
6032
 
5969
6033
  // Trigger fullscreen mode
5970
6034
  wrap_node.requestFullscreen = wrap_node.requestFullscreen ||
@@ -5972,8 +6036,24 @@ define([
5972
6036
  wrap_node.mozRequestFullScreen ||
5973
6037
  wrap_node.msRequestFullscreen;
5974
6038
 
5975
- if (wrap_node.requestFullscreen) {
5976
- wrap_node.requestFullscreen();
6039
+ if (doc.fullscreenElement !== undefined) {
6040
+ fullscreenElement = doc.fullscreenElement;
6041
+ } else if (doc.webkitFullscreenElement !== undefined) {
6042
+ fullscreenElement = doc.webkitFullscreenElement;
6043
+ } else {
6044
+ fullscreenElement = doc.msFullscreenElement;
6045
+ }
6046
+ if (fullscreenElement === null) {
6047
+ // Start fullscreen mode
6048
+ if (wrap_node.requestFullscreen) {
6049
+ wrap_node.requestFullscreen();
6050
+ }
6051
+ } else {
6052
+ if (Type.exists(document.exitFullscreen)) {
6053
+ document.exitFullscreen();
6054
+ } else if (Type.exists(document.webkitExitFullscreen)) {
6055
+ document.webkitExitFullscreen();
6056
+ }
5977
6057
  }
5978
6058
 
5979
6059
  return this;
@@ -5987,27 +6067,31 @@ define([
5987
6067
  * @param {Object} evt fullscreen event object (unused)
5988
6068
  */
5989
6069
  fullscreenListener: function (evt) {
5990
- var res, inner_id, inner_node;
6070
+ var inner_id, inner_node, fullscreenElement, // res,
6071
+ doc = this.document;
5991
6072
 
5992
6073
  inner_id = this._fullscreen_inner_id;
5993
6074
  if (!Type.exists(inner_id)) {
5994
6075
  return;
5995
6076
  }
5996
6077
 
5997
- this.document.fullscreenElement = this.document.fullscreenElement ||
5998
- this.document.webkitFullscreenElement ||
5999
- this.document.mozFullscreenElement ||
6000
- this.document.msFullscreenElement;
6078
+ if (doc.fullscreenElement !== undefined) {
6079
+ fullscreenElement = doc.fullscreenElement;
6080
+ } else if (doc.webkitFullscreenElement !== undefined) {
6081
+ fullscreenElement = doc.webkitFullscreenElement;
6082
+ } else {
6083
+ fullscreenElement = doc.msFullscreenElement;
6084
+ }
6001
6085
 
6002
- inner_node = this.document.getElementById(inner_id);
6086
+ inner_node = doc.getElementById(inner_id);
6003
6087
  // If full screen mode is started we have to remove CSS margin around the JSXGraph div.
6004
6088
  // Otherwise, the positioning of the fullscreen div will be false.
6005
6089
  // When leaving the fullscreen mode, the margin is put back in.
6006
- if (this.document.fullscreenElement) {
6090
+ if (fullscreenElement) {
6007
6091
  // Just entered fullscreen mode
6008
6092
 
6009
6093
  // Get the data computed in board.toFullscreen()
6010
- res = this._fullscreen_res;
6094
+ // res = this._fullscreen_res;
6011
6095
 
6012
6096
  // Store the scaling data.
6013
6097
  // It is used in AbstractRenderer.updateText to restore the scaling matrix
@@ -6015,39 +6099,40 @@ define([
6015
6099
  // Further, the CSS margin has to be removed when in fullscreen mode,
6016
6100
  // and must be restored later.
6017
6101
  inner_node._cssFullscreenStore = {
6018
- id: this.document.fullscreenElement.id,
6102
+ id: fullscreenElement.id,
6019
6103
  isFullscreen: true,
6020
6104
  margin: inner_node.style.margin,
6021
- width: inner_node.style.width,
6022
- scale: res.scale,
6023
- vshift: res.vshift
6105
+ // width: inner_node.style.width
6106
+ // scale: res.scale,
6107
+ // vshift: res.vshift
6024
6108
  };
6025
6109
 
6026
6110
  inner_node.style.margin = '';
6027
- inner_node.style.width = res.width + 'px';
6111
+ // inner_node.style.width = res.width + 'px';
6028
6112
 
6029
6113
  // Do the shifting and scaling via CSS pseudo rules
6030
6114
  // We do this after fullscreen mode has been established to get the correct size
6031
6115
  // of the JSXGraph div.
6032
- Env.scaleJSXGraphDiv(document.fullscreenElement.id, inner_id, res.scale, res.vshift);
6116
+ // Env.scaleJSXGraphDiv(fullscreenElement.id, inner_id, res.scale, res.vshift, res.ratio, doc);
6117
+ Env.scaleJSXGraphDiv(fullscreenElement.id, inner_id, doc);
6033
6118
 
6034
- // Clear this.document.fullscreenElement, because Safari doesn't to it and
6119
+ // Clear this.doc.fullscreenElement, because Safari doesn't to it and
6035
6120
  // when leaving full screen mode it is still set.
6036
- this.document.fullscreenElement = null;
6121
+ fullscreenElement = null;
6037
6122
 
6038
6123
  } else if (Type.exists(inner_node._cssFullscreenStore)) {
6039
6124
  // Just left the fullscreen mode
6040
6125
 
6041
6126
  // Remove the CSS rules added in Env.scaleJSXGraphDiv
6042
6127
  try {
6043
- this.document.styleSheets[this.document.styleSheets.length - 1].deleteRule(0);
6128
+ doc.styleSheets[doc.styleSheets.length - 1].deleteRule(0);
6044
6129
  } catch (err) {
6045
6130
  console.log('JSXGraph: Could not remove CSS rules for full screen mode');
6046
6131
  }
6047
6132
 
6048
6133
  inner_node._cssFullscreenStore.isFullscreen = false;
6049
6134
  inner_node.style.margin = inner_node._cssFullscreenStore.margin;
6050
- inner_node.style.width = inner_node._cssFullscreenStore.width;
6135
+ // inner_node.style.width = inner_node._cssFullscreenStore.width;
6051
6136
  }
6052
6137
 
6053
6138
  this.updateCSSTransforms();
@@ -42,7 +42,7 @@ define(['jxg'], function (JXG) {
42
42
 
43
43
  var major = 1,
44
44
  minor = 4,
45
- patch = 4,
45
+ patch = 6,
46
46
  add = '', //'dev'
47
47
  version = major + '.' + minor + '.' + patch + (add ? '-' + add : ''),
48
48
  constants;
@@ -111,7 +111,13 @@ define(['jxg'], function (JXG) {
111
111
  OBJECT_TYPE_BUTTON: 29,
112
112
  OBJECT_TYPE_TRANSFORMATION: 30,
113
113
  OBJECT_TYPE_FOREIGNOBJECT: 31,
114
+
114
115
  OBJECT_TYPE_VIEW3D: 32,
116
+ OBJECT_TYPE_POINT3D: 33,
117
+ OBJECT_TYPE_LINE3D: 34,
118
+ OBJECT_TYPE_PLANE3D: 35,
119
+ OBJECT_TYPE_CURVE3D: 36,
120
+ OBJECT_TYPE_SURFACE3D: 37,
115
121
 
116
122
  // IMPORTANT:
117
123
  // ----------
@@ -127,6 +133,7 @@ define(['jxg'], function (JXG) {
127
133
  OBJECT_CLASS_AREA: 5,
128
134
  OBJECT_CLASS_OTHER: 6,
129
135
  OBJECT_CLASS_TEXT: 7,
136
+ OBJECT_CLASS_3D: 8,
130
137
 
131
138
  // SketchReader constants
132
139
  GENTYPE_ABC: 1, // unused
package/src/base/curve.js CHANGED
@@ -235,7 +235,7 @@ define([
235
235
  */
236
236
  hasPoint: function (x, y, start) {
237
237
  var t, checkPoint, len, invMat, c,
238
- i, tX, tY,
238
+ i, tX, tY, isIn,
239
239
  res = [],
240
240
  points, qdt,
241
241
  steps = Type.evaluate(this.visProp.numberpointslow),
@@ -255,10 +255,20 @@ define([
255
255
  // 'inherit'
256
256
  prec = this.board.options.precision.hasPoint;
257
257
  }
258
+
259
+ // From now on, x,y are usrCoords
258
260
  checkPoint = new Coords(Const.COORDS_BY_SCREEN, [x, y], this.board, false);
259
261
  x = checkPoint.usrCoords[1];
260
262
  y = checkPoint.usrCoords[2];
261
263
 
264
+ // Handle inner points of the curve
265
+ if (this.bezierDegree === 1 && Type.evaluate(this.visProp.hasinnerpoints)) {
266
+ isIn = Geometry.windingNumber([1, x, y], this.points, true);
267
+ if (isIn !== 0) {
268
+ return true;
269
+ }
270
+ }
271
+
262
272
  // We use usrCoords. Only in the final distance calculation
263
273
  // screen coords are used
264
274
  prec += Type.evaluate(this.visProp.strokewidth) * 0.5;
@@ -276,11 +286,11 @@ define([
276
286
 
277
287
  ev_ct = Type.evaluate(this.visProp.curvetype);
278
288
  if (ev_ct === 'parameter' || ev_ct === 'polar') {
289
+
290
+ // Transform the mouse/touch coordinates
291
+ // back to the original position of the curve.
292
+ // This is needed, because we work with the function terms, not the points.
279
293
  if (this.transformations.length > 0) {
280
- /**
281
- * Transform the mouse/touch coordinates
282
- * back to the original position of the curve.
283
- */
284
294
  this.updateTransformMatrix();
285
295
  invMat = Mat.inverse(this.transformMat);
286
296
  c = Mat.matVecMult(invMat, [1, x, y]);
@@ -304,6 +314,9 @@ define([
304
314
  } else if (ev_ct === 'plot' ||
305
315
  ev_ct === 'functiongraph') {
306
316
 
317
+ // Here, we can ignore transformations of the curve,
318
+ // since we are working directly with the points.
319
+
307
320
  if (!Type.exists(start) || start < 0) {
308
321
  start = 0;
309
322
  }
@@ -1209,8 +1222,37 @@ define([
1209
1222
  }
1210
1223
  }
1211
1224
  return [isTransformed, curve_org];
1225
+ },
1226
+
1227
+ pnpoly: function(x_in, y_in, coord_type) {
1228
+ var i, j, len,
1229
+ x, y, crds,
1230
+ v = this.points,
1231
+ isIn = false;
1232
+
1233
+ if (coord_type === Const.COORDS_BY_USER) {
1234
+ crds = new Coords(Const.COORDS_BY_USER, [x_in, y_in], this.board);
1235
+ x = crds.scrCoords[1];
1236
+ y = crds.scrCoords[2];
1237
+ } else {
1238
+ x = x_in;
1239
+ y = y_in;
1240
+ }
1241
+
1242
+ len = this.points.length;
1243
+ for (i = 0, j = len - 2; i < len - 1; j = i++) {
1244
+ if (((v[i].scrCoords[2] > y) !== (v[j].scrCoords[2] > y)) &&
1245
+ (x < (v[j].scrCoords[1] - v[i].scrCoords[1]) *
1246
+ (y - v[i].scrCoords[2]) / (v[j].scrCoords[2] - v[i].scrCoords[2]) + v[i].scrCoords[1])
1247
+ ) {
1248
+ isIn = !isIn;
1249
+ }
1250
+ }
1251
+
1252
+ return isIn;
1212
1253
  }
1213
1254
 
1255
+
1214
1256
  });
1215
1257
 
1216
1258
  /**
@@ -1378,13 +1420,13 @@ define([
1378
1420
  attr = Type.copyAttributes(attributes, board.options, 'curve');
1379
1421
 
1380
1422
  obj = board.select(parents[0], true);
1381
- if (Type.isObject(obj) &&
1423
+ if (Type.isTransformationOrArray(parents[1]) &&
1424
+ Type.isObject(obj) &&
1382
1425
  (obj.type === Const.OBJECT_TYPE_CURVE ||
1383
1426
  obj.type === Const.OBJECT_TYPE_ANGLE ||
1384
1427
  obj.type === Const.OBJECT_TYPE_ARC ||
1385
1428
  obj.type === Const.OBJECT_TYPE_CONIC ||
1386
- obj.type === Const.OBJECT_TYPE_SECTOR) &&
1387
- Type.isTransformationOrArray(parents[1])) {
1429
+ obj.type === Const.OBJECT_TYPE_SECTOR) ) {
1388
1430
 
1389
1431
  if (obj.type === Const.OBJECT_TYPE_SECTOR) {
1390
1432
  attr = Type.copyAttributes(attributes, board.options, 'sector');
@@ -2326,7 +2368,7 @@ define([
2326
2368
  /**
2327
2369
  * @ignore
2328
2370
  */
2329
- c.updateDataArray = function () {
2371
+ c.updateDataArray = function () {
2330
2372
  var i, j = 0,
2331
2373
  len = this.xterm.length;
2332
2374