jsxgraph 1.3.0 → 1.4.1

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 (90) hide show
  1. package/README.md +2 -2
  2. package/distrib/README.md +2 -2
  3. package/distrib/geogebra.min.js +3 -3
  4. package/distrib/geonext.min.js +3 -3
  5. package/distrib/index.d.ts +651 -448
  6. package/distrib/intergeo.min.js +3 -3
  7. package/distrib/jsxgraph.css +4 -13
  8. package/distrib/jsxgraphcore.js +9 -25
  9. package/distrib/jsxgraphsrc.js +28203 -25234
  10. package/distrib/sketch.min.js +3 -3
  11. package/package.json +11 -22
  12. package/src/base/board.js +674 -469
  13. package/src/base/chart.js +1 -1
  14. package/src/base/circle.js +23 -1
  15. package/src/base/composition.js +1 -1
  16. package/src/base/constants.js +32 -11
  17. package/src/base/coords.js +4 -4
  18. package/src/base/coordselement.js +51 -24
  19. package/src/base/curve.js +308 -117
  20. package/src/base/element.js +79 -50
  21. package/src/base/foreignobject.js +463 -0
  22. package/src/base/group.js +2 -2
  23. package/src/base/image.js +12 -15
  24. package/src/base/line.js +108 -21
  25. package/src/base/point.js +24 -28
  26. package/src/base/polygon.js +75 -18
  27. package/src/base/text.js +116 -63
  28. package/src/base/ticks.js +29 -11
  29. package/src/base/transformation.js +1 -1
  30. package/src/base/turtle.js +1 -1
  31. package/src/element/arc.js +1 -1
  32. package/src/element/button.js +29 -2
  33. package/src/element/checkbox.js +31 -1
  34. package/src/element/comb.js +5 -2
  35. package/src/element/composition.js +127 -19
  36. package/src/element/conic.js +46 -5
  37. package/src/element/input.js +32 -1
  38. package/src/element/locus.js +2 -2
  39. package/src/element/measure.js +9 -4
  40. package/src/element/sector.js +46 -12
  41. package/src/element/slider.js +17 -12
  42. package/src/element/slopetriangle.js +1 -1
  43. package/src/jsxgraph.js +28 -9
  44. package/src/jxg.js +4 -3
  45. package/src/loadjsxgraph.js +3 -2
  46. package/src/math/bst.js +1 -1
  47. package/src/math/clip.js +550 -345
  48. package/src/math/complex.js +1 -1
  49. package/src/math/extrapolate.js +1 -1
  50. package/src/math/geometry.js +155 -126
  51. package/src/math/ia.js +290 -21
  52. package/src/math/math.js +30 -1
  53. package/src/math/metapost.js +1 -1
  54. package/src/math/nlp.js +25 -5
  55. package/src/math/numerics.js +183 -4
  56. package/src/math/plot.js +4 -4
  57. package/src/math/poly.js +1 -1
  58. package/src/math/probfuncs.js +2 -1
  59. package/src/math/qdt.js +68 -62
  60. package/src/math/statistics.js +58 -7
  61. package/src/math/symbolic.js +1 -1
  62. package/src/options.js +377 -114
  63. package/src/parser/ca.js +1297 -1291
  64. package/src/parser/datasource.js +1 -1
  65. package/src/parser/geonext.js +6 -6
  66. package/src/parser/jessiecode.js +275 -79
  67. package/src/parser/jessiescript.js +1 -1
  68. package/src/reader/cinderella.js +1 -1
  69. package/src/reader/file.js +1 -1
  70. package/src/reader/geogebra.js +1 -1
  71. package/src/reader/geonext.js +1 -1
  72. package/src/reader/graph.js +1 -1
  73. package/src/reader/intergeo.js +1 -1
  74. package/src/reader/sketch.js +21 -13
  75. package/src/renderer/abstract.js +21 -6
  76. package/src/renderer/canvas.js +22 -15
  77. package/src/renderer/no.js +11 -4
  78. package/src/renderer/svg.js +76 -53
  79. package/src/renderer/vml.js +36 -32
  80. package/src/server/server.js +1 -1
  81. package/src/utils/base64.js +2 -2
  82. package/src/utils/color.js +148 -3
  83. package/src/utils/dump.js +21 -15
  84. package/src/utils/env.js +63 -104
  85. package/src/utils/event.js +1 -1
  86. package/src/utils/expect.js +1 -1
  87. package/src/utils/type.js +30 -19
  88. package/src/utils/xml.js +1 -1
  89. package/src/utils/zip.js +1 -1
  90. package/CHANGELOG.md +0 -1281
@@ -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,
@@ -231,7 +231,7 @@ define([
231
231
 
232
232
  /**
233
233
  * The position of this element inside the {@link JXG.Board#objectsList}.
234
- * @type {Number}
234
+ * @type Number
235
235
  * @default -1
236
236
  * @private
237
237
  */
@@ -1565,7 +1565,7 @@ define([
1565
1565
  // initiated by the user, e.g. through custom DOM events. We can't just pick one because this would break user
1566
1566
  // defined highlighting in many ways:
1567
1567
  // * if overriding the highlight() methods the user had to handle the highlightedObjects stuff, otherwise he'd break
1568
- // everything (e.g. the pie chart example http://jsxgraph.uni-bayreuth.de/wiki/index.php/Pie_chart (not exactly
1568
+ // everything (e.g. the pie chart example https://jsxgraph.org/wiki/index.php/Pie_chart (not exactly
1569
1569
  // user defined but for this type of chart the highlight method was overridden and not adjusted to the changes in here)
1570
1570
  // where it just kept highlighting until the radius of the pie was far beyond infinity...
1571
1571
  // * user defined highlighting would get pointless, everytime the user highlights something using .highlight(), it would get
@@ -1625,6 +1625,8 @@ define([
1625
1625
  * Dimensions of the smallest rectangle enclosing the element.
1626
1626
  * @returns {Array} The coordinates of the enclosing rectangle in a format
1627
1627
  * like the bounding box in {@link JXG.Board#setBoundingBox}.
1628
+ *
1629
+ * @returns {Array} similar to {@link JXG.Board#setBoundingBox}.
1628
1630
  */
1629
1631
  bounds: function () {
1630
1632
  return [0, 0, 0, 0];
@@ -1925,10 +1927,9 @@ define([
1925
1927
  */
1926
1928
  removeAllTicks: function () {
1927
1929
  var t;
1928
-
1929
1930
  if (Type.exists(this.ticks)) {
1930
- for (t = this.ticks.length; t > 0; t--) {
1931
- this.removeTicks(this.ticks[t - 1]);
1931
+ for (t = this.ticks.length - 1; t >= 0; t--) {
1932
+ this.removeTicks(this.ticks[t]);
1932
1933
  }
1933
1934
  this.ticks = [];
1934
1935
  this.board.update();
@@ -1947,29 +1948,56 @@ define([
1947
1948
  }
1948
1949
 
1949
1950
  if (Type.exists(this.ticks)) {
1950
- for (t = this.ticks.length; t > 0; t--) {
1951
- if (this.ticks[t - 1] === tick) {
1952
- this.board.removeObject(this.ticks[t - 1]);
1953
-
1954
- if (this.ticks[t - 1].ticks) {
1955
- for (j = 0; j < this.ticks[t - 1].ticks.length; j++) {
1956
- if (Type.exists(this.ticks[t - 1].labels[j])) {
1957
- this.board.removeObject(this.ticks[t - 1].labels[j]);
1951
+ for (t = this.ticks.length - 1; t >= 0; t--) {
1952
+ if (this.ticks[t] === tick) {
1953
+ this.board.removeObject(this.ticks[t]);
1954
+
1955
+ if (this.ticks[t].ticks) {
1956
+ for (j = 0; j < this.ticks[t].ticks.length; j++) {
1957
+ if (Type.exists(this.ticks[t].labels[j])) {
1958
+ this.board.removeObject(this.ticks[t].labels[j]);
1958
1959
  }
1959
1960
  }
1960
1961
  }
1961
1962
 
1962
- delete this.ticks[t - 1];
1963
+ delete this.ticks[t];
1963
1964
  break;
1964
1965
  }
1965
1966
  }
1966
1967
  }
1967
1968
  },
1968
1969
 
1970
+ /**
1971
+ * Determine values of snapSizeX and snapSizeY. If the attributes
1972
+ * snapSizex and snapSizeY are greater than zero, these values are taken.
1973
+ * Otherwise, determine the distance between major ticks of the
1974
+ * default axes.
1975
+ * @returns {Array} containing the snap sizes for x and y direction.
1976
+ * @private
1977
+ */
1978
+ getSnapSizes: function() {
1979
+ var sX, sY, ticks;
1980
+
1981
+ sX = Type.evaluate(this.visProp.snapsizex);
1982
+ sY = Type.evaluate(this.visProp.snapsizey);
1983
+
1984
+ if (sX <= 0 && this.board.defaultAxes && this.board.defaultAxes.x.defaultTicks) {
1985
+ ticks = this.board.defaultAxes.x.defaultTicks;
1986
+ sX = ticks.ticksDelta * (Type.evaluate(ticks.visProp.minorticks) + 1);
1987
+ }
1988
+
1989
+ if (sY <= 0 && this.board.defaultAxes && this.board.defaultAxes.y.defaultTicks) {
1990
+ ticks = this.board.defaultAxes.y.defaultTicks;
1991
+ sY = ticks.ticksDelta * (Type.evaluate(ticks.visProp.minorticks) + 1);
1992
+ }
1993
+
1994
+ return [sX, sY];
1995
+ },
1996
+
1969
1997
  /**
1970
1998
  * Move an element to its nearest grid point.
1971
1999
  * The function uses the coords object of the element as
1972
- * its actual position. If there is no coords object, nothing is done.
2000
+ * its actual position. If there is no coords object or if the object is fixed, nothing is done.
1973
2001
  * @param {Boolean} force force snapping independent from what the snaptogrid attribute says
1974
2002
  * @param {Boolean} fromParent True if the drag comes from a child element. This is the case if a line
1975
2003
  * through two points is dragged. In this case we do not try to force the points to stay inside of
@@ -1977,55 +2005,56 @@ define([
1977
2005
  * @returns {JXG.GeometryElement} Reference to this element
1978
2006
  */
1979
2007
  handleSnapToGrid: function (force, fromParent) {
1980
- var x, y, ticks,
1981
- //i, len, g, el, p,
1982
- boardBB,
2008
+ var x, y, rx, ry, rcoords,
2009
+ boardBB, res, sX, sY,
1983
2010
  needsSnapToGrid = false,
1984
- sX = Type.evaluate(this.visProp.snapsizex),
1985
- sY = Type.evaluate(this.visProp.snapsizey);
2011
+ attractToGrid = Type.evaluate(this.visProp.attracttogrid),
2012
+ ev_au = Type.evaluate(this.visProp.attractorunit),
2013
+ ev_ad = Type.evaluate(this.visProp.attractordistance);
1986
2014
 
1987
- if (!Type.exists(this.coords)) {
2015
+ if (!Type.exists(this.coords) || Type.evaluate(this.visProp.fixed)) {
1988
2016
  return this;
1989
2017
  }
1990
2018
 
1991
- needsSnapToGrid = Type.evaluate(this.visProp.snaptogrid) || force === true;
2019
+ needsSnapToGrid = Type.evaluate(this.visProp.snaptogrid) || attractToGrid || force === true;
1992
2020
 
1993
2021
  if (needsSnapToGrid) {
1994
2022
  x = this.coords.usrCoords[1];
1995
2023
  y = this.coords.usrCoords[2];
2024
+ res = this.getSnapSizes();
2025
+ sX = res[0];
2026
+ sY = res[1];
1996
2027
 
1997
- if (sX <= 0 && this.board.defaultAxes && this.board.defaultAxes.x.defaultTicks) {
1998
- ticks = this.board.defaultAxes.x.defaultTicks;
1999
- sX = ticks.ticksDelta * (Type.evaluate(ticks.visProp.minorticks) + 1);
2000
- }
2001
-
2002
- if (sY <= 0 && this.board.defaultAxes && this.board.defaultAxes.y.defaultTicks) {
2003
- ticks = this.board.defaultAxes.y.defaultTicks;
2004
- sY = ticks.ticksDelta * (Type.evaluate(ticks.visProp.minorticks) + 1);
2005
- }
2006
-
2007
- // if no valid snap sizes are available, don't change the coords.
2028
+ // If no valid snap sizes are available, don't change the coords.
2008
2029
  if (sX > 0 && sY > 0) {
2009
2030
  boardBB = this.board.getBoundingBox();
2010
- x = Math.round(x / sX) * sX;
2011
- y = Math.round(y / sY) * sY;
2012
-
2013
- // checking whether x and y are still within boundingBox,
2014
- // if not, adjust them to remain within the board
2015
- if (!fromParent) {
2016
- if (x < boardBB[0]) {
2017
- x += sX;
2018
- } else if (x > boardBB[2]) {
2019
- x -= sX;
2020
- }
2031
+ rx = Math.round(x / sX) * sX;
2032
+ ry = Math.round(y / sY) * sY;
2033
+ rcoords = new JXG.Coords(Const.COORDS_BY_USER, [rx, ry], this.board);
2034
+ if (!attractToGrid ||
2035
+ rcoords.distance(
2036
+ ev_au === 'screen' ? Const.COORDS_BY_SCREEN : Const.COORDS_BY_USER, this.coords
2037
+ ) < ev_ad) {
2038
+ x = rx;
2039
+ y = ry;
2040
+ // Checking whether x and y are still within boundingBox.
2041
+ // If not, adjust them to remain within the board.
2042
+ // Otherwise a point may become invisible.
2043
+ if (!fromParent) {
2044
+ if (x < boardBB[0]) {
2045
+ x += sX;
2046
+ } else if (x > boardBB[2]) {
2047
+ x -= sX;
2048
+ }
2021
2049
 
2022
- if (y < boardBB[3]) {
2023
- y += sY;
2024
- } else if (y > boardBB[1]) {
2025
- y -= sY;
2050
+ if (y < boardBB[3]) {
2051
+ y += sY;
2052
+ } else if (y > boardBB[1]) {
2053
+ y -= sY;
2054
+ }
2026
2055
  }
2056
+ this.coords.setCoordinates(Const.COORDS_BY_USER, [x, y]);
2027
2057
  }
2028
- this.coords.setCoordinates(Const.COORDS_BY_USER, [x, y]);
2029
2058
  }
2030
2059
  }
2031
2060
  return this;
@@ -0,0 +1,463 @@
1
+ /*
2
+ Copyright 2008-2022
3
+ Matthias Ehmann,
4
+ Michael Gerhaeuser,
5
+ Carsten Miller,
6
+ Bianca Valentin,
7
+ Alfred Wassermann,
8
+ Peter Wilfahrt
9
+
10
+ This file is part of JSXGraph.
11
+
12
+ JSXGraph is free software dual licensed under the GNU LGPL or MIT License.
13
+
14
+ You can redistribute it and/or modify it under the terms of the
15
+
16
+ * GNU Lesser General Public License as published by
17
+ the Free Software Foundation, either version 3 of the License, or
18
+ (at your option) any later version
19
+ OR
20
+ * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT
21
+
22
+ JSXGraph is distributed in the hope that it will be useful,
23
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
24
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25
+ GNU Lesser General Public License for more details.
26
+
27
+ You should have received a copy of the GNU Lesser General Public License and
28
+ the MIT License along with JSXGraph. If not, see <http://www.gnu.org/licenses/>
29
+ and <http://opensource.org/licenses/MIT/>.
30
+ */
31
+
32
+
33
+ /*global JXG: true, define: true, window: true*/
34
+ /*jslint nomen: true, plusplus: true*/
35
+
36
+ /* depends:
37
+ jxg
38
+ base/constants
39
+ base/coords
40
+ base/element
41
+ math/math
42
+ utils/type
43
+ */
44
+
45
+ /**
46
+ * @fileoverview In this file the ForeignObject element is defined.
47
+ */
48
+
49
+ define([
50
+ 'jxg', 'base/constants', 'base/coords', 'base/element', 'math/math', 'utils/type', 'base/coordselement'
51
+ ], function (JXG, Const, Coords, GeometryElement, Mat, Type, CoordsElement) {
52
+
53
+ "use strict";
54
+
55
+ /**
56
+ * Construct and handle SVG foreignObjects.
57
+ *
58
+ * @class Creates a new foreignObject object. Do not use this constructor to create a foreignObject. Use {@link JXG.Board#create} with
59
+ * type {@link foreignobject} instead.
60
+ * @augments JXG.GeometryElement
61
+ * @augments JXG.CoordsElement
62
+ * @param {string|JXG.Board} board The board the new foreignObject is drawn on.
63
+ * @param {Array} coordinates An array with the user coordinates of the foreignObject.
64
+ * @param {Object} attributes An object containing visual and - optionally - a name and an id.
65
+ * @param {string|function} url An URL string or a function returning an URL string.
66
+ * @param {Array} size Array containing width and height of the foreignObject in user coordinates.
67
+ *
68
+ */
69
+ JXG.ForeignObject = function (board, coords, attributes, content, size) {
70
+ this.constructor(board, attributes, Const.OBJECT_TYPE_FOREIGNOBJECT, Const.OBJECT_CLASS_OTHER);
71
+ this.element = this.board.select(attributes.anchor);
72
+ this.coordsConstructor(coords);
73
+
74
+ this._useUserSize = false;
75
+
76
+ /**
77
+ * Array of length two containing [width, height] of the foreignObject in pixel.
78
+ * @type Array
79
+ */
80
+ this.size = [1, 1];
81
+ if (Type.exists(size) && size.length > 0) {
82
+ this._useUserSize = true;
83
+
84
+ this.W = Type.createFunction(size[0], this.board, '');
85
+ this.H = Type.createFunction(size[1], this.board, '');
86
+ this.usrSize = [this.W(), this.H()];
87
+ }
88
+
89
+ // this.size = [Math.abs(this.usrSize[0] * board.unitX), Math.abs(this.usrSize[1] * board.unitY)];
90
+
91
+ /**
92
+ * 'href' of the foreignObject.
93
+ * @type {string}
94
+ */
95
+ this.content = content;
96
+
97
+ this.elType = 'foreignobject';
98
+
99
+ // span contains the anchor point and the two vectors
100
+ // spanning the foreignObject rectangle.
101
+ // this.span = [
102
+ // this.coords.usrCoords.slice(0),
103
+ // [this.coords.usrCoords[0], this.W(), 0],
104
+ // [this.coords.usrCoords[0], 0, this.H()]
105
+ // ];
106
+ //this.parent = board.select(attributes.anchor);
107
+
108
+ this.id = this.board.setId(this, 'Im');
109
+
110
+ this.board.renderer.drawForeignObject(this);
111
+ this.board.finalizeAdding(this);
112
+
113
+ this.methodMap = JXG.deepCopy(this.methodMap, {
114
+ addTransformation: 'addTransform',
115
+ trans: 'addTransform'
116
+ });
117
+ };
118
+
119
+ JXG.ForeignObject.prototype = new GeometryElement();
120
+ Type.copyPrototypeMethods(JXG.ForeignObject, CoordsElement, 'coordsConstructor');
121
+
122
+ JXG.extend(JXG.ForeignObject.prototype, /** @lends JXG.ForeignObject.prototype */ {
123
+
124
+ /**
125
+ * Checks whether (x,y) is over or near the image;
126
+ * @param {Number} x Coordinate in x direction, screen coordinates.
127
+ * @param {Number} y Coordinate in y direction, screen coordinates.
128
+ * @returns {Boolean} True if (x,y) is over the image, False otherwise.
129
+ */
130
+ hasPoint: function (x, y) {
131
+ var dx, dy, r, type, prec,
132
+ c, v, p, dot,
133
+ len = this.transformations.length;
134
+
135
+ if (Type.isObject(Type.evaluate(this.visProp.precision))) {
136
+ type = this.board._inputDevice;
137
+ prec = Type.evaluate(this.visProp.precision[type]);
138
+ } else {
139
+ // 'inherit'
140
+ prec = this.board.options.precision.hasPoint;
141
+ }
142
+
143
+ // Easy case: no transformation
144
+ if (len === 0) {
145
+ dx = x - this.coords.scrCoords[1];
146
+ dy = this.coords.scrCoords[2] - y;
147
+ r = prec;
148
+
149
+ return dx >= -r && dx - this.size[0] <= r &&
150
+ dy >= -r && dy - this.size[1] <= r;
151
+ }
152
+
153
+ // foreignObject is transformed
154
+ c = new Coords(Const.COORDS_BY_SCREEN, [x, y], this.board);
155
+ // v is the vector from anchor point to the drag point
156
+ c = c.usrCoords;
157
+ v = [c[0] - this.span[0][0],
158
+ c[1] - this.span[0][1],
159
+ c[2] - this.span[0][2]];
160
+ dot = Mat.innerProduct; // shortcut
161
+
162
+ // Project the drag point to the sides.
163
+ p = dot(v, this.span[1]);
164
+ if (0 <= p && p <= dot(this.span[1], this.span[1])) {
165
+ p = dot(v, this.span[2]);
166
+
167
+ if (0 <= p && p <= dot(this.span[2], this.span[2])) {
168
+ return true;
169
+ }
170
+ }
171
+ return false;
172
+ },
173
+
174
+ /**
175
+ * Recalculate the coordinates of lower left corner and the width and height.
176
+ *
177
+ * @returns {JXG.ForeignObject} A reference to the element
178
+ * @private
179
+ */
180
+ update: function (fromParent) {
181
+ if (!this.needsUpdate) {
182
+ return this;
183
+ }
184
+ this.updateCoords(fromParent);
185
+ this.updateSize();
186
+ // this.updateSpan();
187
+ return this;
188
+ },
189
+
190
+ /**
191
+ * Send an update request to the renderer.
192
+ * @private
193
+ */
194
+ updateRenderer: function () {
195
+ return this.updateRendererGeneric('updateForeignObject');
196
+ },
197
+
198
+ /**
199
+ * Updates the internal arrays containing size of the foreignObject.
200
+ * @returns {JXG.ForeignObject} A reference to the element
201
+ * @private
202
+ */
203
+ updateSize: function () {
204
+ var bb = [0, 0];
205
+
206
+ if (this._useUserSize) {
207
+ this.usrSize = [this.W(), this.H()];
208
+ this.size = [Math.abs(this.usrSize[0] * this.board.unitX),
209
+ Math.abs(this.usrSize[1] * this.board.unitY)];
210
+ } else {
211
+ if (this.rendNode.hasChildNodes()) {
212
+ bb = this.rendNode.childNodes[0].getBoundingClientRect();
213
+ this.size = [bb.width, bb.height];
214
+ }
215
+ }
216
+
217
+ return this;
218
+ },
219
+
220
+ /**
221
+ * Update the anchor point of the foreignObject, i.e. the lower left corner
222
+ * and the two vectors which span the rectangle.
223
+ * @returns {JXG.ForeignObject} A reference to the element
224
+ * @private
225
+ *
226
+ */
227
+ updateSpan: function () {
228
+ var i, j, len = this.transformations.length, v = [];
229
+
230
+ if (len === 0) {
231
+ this.span = [[this.Z(), this.X(), this.Y()],
232
+ [this.Z(), this.W(), 0],
233
+ [this.Z(), 0, this.H()]];
234
+ } else {
235
+ // v contains the three defining corners of the rectangle/image
236
+ v[0] = [this.Z(), this.X(), this.Y()];
237
+ v[1] = [this.Z(), this.X() + this.W(), this.Y()];
238
+ v[2] = [this.Z(), this.X(), this.Y() + this.H()];
239
+
240
+ // Transform the three corners
241
+ for (i = 0; i < len; i++) {
242
+ for (j = 0; j < 3; j++) {
243
+ v[j] = Mat.matVecMult(this.transformations[i].matrix, v[j]);
244
+ }
245
+ }
246
+ // Normalize the vectors
247
+ for (j = 0; j < 3; j++) {
248
+ v[j][1] /= v[j][0];
249
+ v[j][2] /= v[j][0];
250
+ v[j][0] /= v[j][0];
251
+ }
252
+ // Compute the two vectors spanning the rectangle
253
+ // by subtracting the anchor point.
254
+ for (j = 1; j < 3; j++) {
255
+ v[j][0] -= v[0][0];
256
+ v[j][1] -= v[0][1];
257
+ v[j][2] -= v[0][2];
258
+ }
259
+ this.span = v;
260
+ }
261
+
262
+ return this;
263
+ },
264
+
265
+ addTransform: function (transform) {
266
+ var i;
267
+
268
+ if (Type.isArray(transform)) {
269
+ for (i = 0; i < transform.length; i++) {
270
+ this.transformations.push(transform[i]);
271
+ }
272
+ } else {
273
+ this.transformations.push(transform);
274
+ }
275
+
276
+ return this;
277
+ },
278
+
279
+ // Documented in element.js
280
+ getParents: function () {
281
+ var p = [this.url, [this.Z(), this.X(), this.Y()], this.usrSize];
282
+
283
+ if (this.parents.length !== 0) {
284
+ p = this.parents;
285
+ }
286
+
287
+ return p;
288
+ },
289
+
290
+ /**
291
+ * Set the width and height of the foreignObject. After setting a new size,
292
+ * board.update() or foreignobject.fullUpdate()
293
+ * has to be called to make the change visible.
294
+ * @param {number, function, string} width Number, function or string
295
+ * that determines the new width of the foreignObject
296
+ * @param {number, function, string} height Number, function or string
297
+ * that determines the new height of the foreignObject
298
+ * @returns {JXG.ForeignObject} A reference to the element
299
+ *
300
+ */
301
+ setSize: function(width, height) {
302
+ this.W = Type.createFunction(width, this.board, '');
303
+ this.H = Type.createFunction(height, this.board, '');
304
+ this._useUserSize = true;
305
+
306
+ return this;
307
+ },
308
+
309
+ /**
310
+ * Returns the width of the foreignObject in user coordinates.
311
+ * @returns {number} width of the image in user coordinates
312
+ */
313
+ W: function() {}, // Needed for docs, defined in constructor
314
+
315
+ /**
316
+ * Returns the height of the foreignObject in user coordinates.
317
+ * @returns {number} height of the image in user coordinates
318
+ */
319
+ H: function() {} // Needed for docs, defined in constructor
320
+ });
321
+
322
+ /**
323
+ * @class This element is used to provide a constructor for arbitrary content in
324
+ * an SVG foreignObject container.
325
+ * <p>
326
+ * Instead of board.create('foreignobject') the shortcut board.create('fo') may be used.
327
+ *
328
+ * @pseudo
329
+ * @description
330
+ * @name ForeignObject
331
+ * @augments JXG.ForeignObject
332
+ * @constructor
333
+ * @type JXG.ForeignObject
334
+ *
335
+ * @param {String} content HTML content of the foreignObject. May also be &lt;video&gt; or &lt;iframe&gt;
336
+ * @param {Array} position Position of the foreignObject given by [x, y] in user coordinates. Same as for images.
337
+ * @param {Array} [size] (Optional) argument size of the foreignObject in user coordinates. If not given, size is specified by the HTML attributes
338
+ * or CSS properties of the content.
339
+ *
340
+ * @see Image
341
+ *
342
+ * @example
343
+ * var p = board.create('point', [1, 7], {size: 16});
344
+ * var fo = board.create('foreignobject', [
345
+ * '&lt;video width="300" height="200" src="https://eucbeniki.sio.si/vega2/278/Video_metanje_oge_.mp4" type="html5video" controls&gt;',
346
+ * [0, -3], [9, 6]],
347
+ * {layer: 8, fixed: true}
348
+ * );
349
+ *
350
+ * </pre><div id="JXG0c122f2c-3671-4a28-80a9-f4c523eeda89" class="jxgbox" style="width: 500px; height: 500px;"></div>
351
+ * <script type="text/javascript">
352
+ * (function() {
353
+ * var board = JXG.JSXGraph.initBoard('JXG0c122f2c-3671-4a28-80a9-f4c523eeda89',
354
+ * {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
355
+ * var p = board.create('point', [1, 7], {size: 16});
356
+ * var fo = board.create('foreignobject', [
357
+ * '<video width="300" height="200" src="https://eucbeniki.sio.si/vega2/278/Video_metanje_oge_.mp4" type="html5video" controls>',
358
+ * [0, -3], [9, 6]],
359
+ * {layer: 8, fixed: true}
360
+ * );
361
+ *
362
+ * })();
363
+ *
364
+ * </script><pre>
365
+ *
366
+ * @example
367
+ * var p = board.create('point', [1, 7], {size: 16});
368
+ * var fo = board.create('fo', [
369
+ * '&lt;div style="background-color:blue; color: yellow; padding:20px; width:200px; height:50px; "&gt;Hello&lt;/div&gt;',
370
+ * [-7, -6]],
371
+ * {layer: 1, fixed: false}
372
+ * );
373
+ *
374
+ * </pre><div id="JXG1759c868-1a4a-4767-802c-91f84902e3ec" class="jxgbox" style="width: 500px; height: 500px;"></div>
375
+ * <script type="text/javascript">
376
+ * (function() {
377
+ * var board = JXG.JSXGraph.initBoard('JXG1759c868-1a4a-4767-802c-91f84902e3ec',
378
+ * {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
379
+ * var p = board.create('point', [1, 7], {size: 16});
380
+ * var fo = board.create('foreignobject', [
381
+ * '<div style="background-color:blue; color: yellow; padding:20px; width:200px; height:50px; ">Hello</div>',
382
+ * [-7, -6]],
383
+ * {layer: 1, fixed: false}
384
+ * );
385
+ *
386
+ * })();
387
+ *
388
+ * </script><pre>
389
+ *
390
+ * @example
391
+ * board.renderer.container.style.backgroundColor = 'lightblue';
392
+ * var points = [];
393
+ * points.push( board.create('point', [-2, 3.5], {fixed:false,color: 'yellow', size: 6,name:'6 am'}) );
394
+ * points.push( board.create('point', [0, 3.5], {fixed:false,color: 'yellow', size: 6,name:'12 pm'}) );
395
+ * points.push( board.create('point', [2, 3.5], {fixed:false,color: 'yellow', size: 6,name:'6 pm'}) );
396
+ *
397
+ * var fo = board.create('fo', [
398
+ * '&lt;video width="100%" height="100%" src="https://benedu.net/moodle/aaimg/ajx_img/astro/tr/1vd.mp4" type="html5video" controls&gt;',
399
+ * [-6, -4], [12, 8]],
400
+ * {layer: 0, fixed: true}
401
+ * );
402
+ *
403
+ * var f = JXG.Math.Numerics.lagrangePolynomial(points);
404
+ * var graph = board.create('functiongraph', [f, -10, 10], {fixed:true,strokeWidth:3, layer: 8});
405
+ *
406
+ * </pre><div id="JXGc3fc5520-13aa-4f66-abaa-42e9dc3fbf3f" class="jxgbox" style="width: 500px; height: 500px;"></div>
407
+ * <script type="text/javascript">
408
+ * (function() {
409
+ * var board = JXG.JSXGraph.initBoard('JXGc3fc5520-13aa-4f66-abaa-42e9dc3fbf3f',
410
+ * {boundingbox: [-6,4,6,-4], axis: true, showcopyright: false, shownavigation: false});
411
+ * board.renderer.container.style.backgroundColor = 'lightblue';
412
+ * var points = [];
413
+ * points.push( board.create('point', [-2, 3.5], {fixed:false,color: 'yellow', size: 6,name:'6 am'}) );
414
+ * points.push( board.create('point', [0, 3.5], {fixed:false,color: 'yellow', size: 6,name:'12 pm'}) );
415
+ * points.push( board.create('point', [2, 3.5], {fixed:false,color: 'yellow', size: 6,name:'6 pm'}) );
416
+ *
417
+ * var fo = board.create('fo', [
418
+ * '<video width="100%" height="100%" src="https://benedu.net/moodle/aaimg/ajx_img/astro/tr/1vd.mp4" type="html5video" controls>',
419
+ * [-6, -4], [12, 8]],
420
+ * {layer: 0, fixed: true}
421
+ * );
422
+ *
423
+ * var f = JXG.Math.Numerics.lagrangePolynomial(points);
424
+ * var graph = board.create('functiongraph', [f, -10, 10], {fixed:true,strokeWidth:3, layer: 8});
425
+ *
426
+ * })();
427
+ *
428
+ * </script><pre>
429
+ *
430
+ * Video "24-hour time-lapse in Cascais, Portugal. Produced by Nuno Miguel Duarte" adapted from
431
+ * <a href="https://www.pbslearningmedia.org/resource/buac18-k2-sci-ess-sunposition/changing-position-of-the-sun-in-the-sky/">https://www.pbslearningmedia.org/resource/buac18-k2-sci-ess-sunposition/changing-position-of-the-sun-in-the-sky/</a>,
432
+ * ©2016 Nuno Miguel Duarte.
433
+ *
434
+ */
435
+ JXG.createForeignObject = function (board, parents, attributes) {
436
+ var attr, fo,
437
+ content = parents[0],
438
+ coords = parents[1],
439
+ size = [];
440
+
441
+ if (parents.length >= 2) {
442
+ size = parents[2];
443
+ }
444
+
445
+ attr = Type.copyAttributes(attributes, board.options, 'foreignobject');
446
+ fo = CoordsElement.create(JXG.ForeignObject, board, coords, attr, content, size);
447
+ if (!fo) {
448
+ throw new Error("JSXGraph: Can't create foreignObject with parent types '" +
449
+ (typeof parents[0]) + "' and '" + (typeof parents[1]) + "'." +
450
+ "\nPossible parent types: [string, [x, y], [w, h]], [string, [x, y]], [element,transformation]");
451
+ }
452
+
453
+ return fo;
454
+ };
455
+
456
+ JXG.registerElement('foreignobject', JXG.createForeignObject);
457
+ JXG.registerElement('fo', JXG.createForeignObject);
458
+
459
+ return {
460
+ ForeignObject: JXG.ForeignObject,
461
+ createForeignobject: JXG.createForeignObject
462
+ };
463
+ });
package/src/base/group.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,
@@ -93,7 +93,7 @@ define([
93
93
  * It has to be kept updated in this class "by hand"-
94
94
  *
95
95
  * @private
96
- * @type {Object}
96
+ * @type Object
97
97
  * @see JXG.Group#_updateCoordsCache
98
98
  */
99
99
  this.coords = {};