jsxgraph 1.4.2 → 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.
- package/distrib/geogebra.min.js +1 -1
- package/distrib/geonext.min.js +1 -1
- package/distrib/index.d.ts +269 -30
- package/distrib/intergeo.min.js +1 -1
- package/distrib/jsxgraphcore.js +4 -4
- package/distrib/jsxgraphsrc.js +1789 -93
- package/distrib/sketch.min.js +2 -2
- package/package.json +1 -1
- package/src/3d/box3d.js +264 -0
- package/src/3d/curve3d.js +97 -0
- package/src/3d/linspace3d.js +375 -0
- package/src/3d/point3d.js +200 -0
- package/src/3d/surface3d.js +81 -0
- package/src/3d/threed.js +38 -0
- package/src/3d/view3d.js +459 -0
- package/src/base/board.js +30 -26
- package/src/base/constants.js +1 -1
- package/src/base/coordselement.js +1 -4
- package/src/base/element.js +22 -13
- package/src/base/foreignobject.js +7 -1
- package/src/base/line.js +1 -1
- package/src/base/polygon.js +88 -33
- package/src/base/ticks.js +2 -0
- package/src/element/composition.js +1 -1
- package/src/element/slider.js +12 -0
- package/src/loadjsxgraph.js +17 -11
- package/src/math/geometry.js +80 -1
- package/src/math/math.js +9 -0
- package/src/options.js +8 -8
- package/src/options3d.js +123 -0
- package/src/reader/sketch.js +2 -2
- package/src/utils/type.js +2 -2
package/src/3d/view3d.js
ADDED
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2008-2022
|
|
3
|
+
Matthias Ehmann,
|
|
4
|
+
Carsten Miller,
|
|
5
|
+
Andreas Walter,
|
|
6
|
+
Alfred Wassermann
|
|
7
|
+
|
|
8
|
+
This file is part of JSXGraph.
|
|
9
|
+
|
|
10
|
+
JSXGraph is free software dual licensed under the GNU LGPL or MIT License.
|
|
11
|
+
|
|
12
|
+
You can redistribute it and/or modify it under the terms of the
|
|
13
|
+
|
|
14
|
+
* GNU Lesser General Public License as published by
|
|
15
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
16
|
+
(at your option) any later version
|
|
17
|
+
OR
|
|
18
|
+
* MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT
|
|
19
|
+
|
|
20
|
+
JSXGraph is distributed in the hope that it will be useful,
|
|
21
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
22
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
23
|
+
GNU Lesser General Public License for more details.
|
|
24
|
+
|
|
25
|
+
You should have received a copy of the GNU Lesser General Public License and
|
|
26
|
+
the MIT License along with JSXGraph. If not, see <http://www.gnu.org/licenses/>
|
|
27
|
+
and <http://opensource.org/licenses/MIT/>.
|
|
28
|
+
*/
|
|
29
|
+
/*global JXG:true, define: true*/
|
|
30
|
+
|
|
31
|
+
define(['jxg', 'options', 'base/constants', 'utils/type', 'math/math', 'base/element', '3d/threed',
|
|
32
|
+
], function (JXG, Options, Const, Type, Mat, GeometryElement, ThreeD) {
|
|
33
|
+
"use strict";
|
|
34
|
+
|
|
35
|
+
ThreeD.View3D = function (board, parents, attributes) {
|
|
36
|
+
var bbox3d, coords, size;
|
|
37
|
+
this.constructor(board, attributes, Const.OBJECT_TYPE_VIEW3D, Const.OBJECT_CLASS_CURVE);
|
|
38
|
+
|
|
39
|
+
bbox3d = parents[2]; // [[x1, x2], [y1,y2], [z1,z2]]
|
|
40
|
+
coords = parents[0]; // llft corner
|
|
41
|
+
size = parents[1]; // [w, h]
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* "Namespace" for all 3D handling
|
|
45
|
+
*/
|
|
46
|
+
this.D3 = {};
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* An associative array containing all geometric objects belonging to the view.
|
|
50
|
+
* Key is the id of the object and value is a reference to the object.
|
|
51
|
+
* @type Object
|
|
52
|
+
*/
|
|
53
|
+
this.D3.objects = {};
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* An array containing all geometric objects in this view in the order of construction.
|
|
57
|
+
* @type Array
|
|
58
|
+
*/
|
|
59
|
+
this.D3.objectsList = [];
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @type {Object} contains the axes of the view or null
|
|
63
|
+
* @default null
|
|
64
|
+
*/
|
|
65
|
+
this.D3.defaultAxes = null;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* 3D-to-2D transformation matrix
|
|
69
|
+
* @type {Array} 3 x 4 mattrix
|
|
70
|
+
*/
|
|
71
|
+
this.D3.matrix = [
|
|
72
|
+
[1, 0, 0, 0],
|
|
73
|
+
[0, 1, 0, 0],
|
|
74
|
+
[0, 0, 1, 0]
|
|
75
|
+
];
|
|
76
|
+
|
|
77
|
+
// Bounding box (cube) [[x1, x2], [y1,y2], [z1,z2]]:
|
|
78
|
+
this.D3.bbox3d = bbox3d;
|
|
79
|
+
this.D3.coords = coords;
|
|
80
|
+
this.D3.size = size;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Distance of the view to the origin. In other words, its
|
|
84
|
+
* the radius of the sphere where the camera sits.
|
|
85
|
+
*/
|
|
86
|
+
this.D3.r = -1;
|
|
87
|
+
|
|
88
|
+
this.timeoutAzimuth = null;
|
|
89
|
+
|
|
90
|
+
this.id = this.board.setId(this, 'V');
|
|
91
|
+
this.board.finalizeAdding(this);
|
|
92
|
+
this.elType = 'view3d';
|
|
93
|
+
this.methodMap = Type.deepCopy(this.methodMap, {
|
|
94
|
+
});
|
|
95
|
+
};
|
|
96
|
+
ThreeD.View3D.prototype = new GeometryElement();
|
|
97
|
+
|
|
98
|
+
JXG.extend(ThreeD.View3D.prototype, /** @lends ThreeD.View3D.prototype */ {
|
|
99
|
+
create: function (elementType, parents, attributes) {
|
|
100
|
+
var prefix = [],
|
|
101
|
+
is3D = false,
|
|
102
|
+
el;
|
|
103
|
+
|
|
104
|
+
if (elementType.indexOf('3d') > 0) {
|
|
105
|
+
is3D = true;
|
|
106
|
+
prefix.push(this);
|
|
107
|
+
}
|
|
108
|
+
el = this.board.create(elementType, prefix.concat(parents), attributes);
|
|
109
|
+
if (true || is3D) {
|
|
110
|
+
this.add(el);
|
|
111
|
+
}
|
|
112
|
+
return el;
|
|
113
|
+
},
|
|
114
|
+
|
|
115
|
+
add: function (el) {
|
|
116
|
+
this.D3.objects[el.id] = el;
|
|
117
|
+
this.D3.objectsList.push(el);
|
|
118
|
+
},
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Update 3D-to-2D transformation matrix with the actual
|
|
122
|
+
* elevation and azimuth angles.
|
|
123
|
+
*
|
|
124
|
+
* @private
|
|
125
|
+
*/
|
|
126
|
+
update: function () {
|
|
127
|
+
var D3 = this.D3,
|
|
128
|
+
e, r, a, f, mat;
|
|
129
|
+
|
|
130
|
+
if (!Type.exists(D3.el_slide) ||
|
|
131
|
+
!Type.exists(D3.az_slide) ||
|
|
132
|
+
!this.needsUpdate) {
|
|
133
|
+
return this;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
e = D3.el_slide.Value();
|
|
137
|
+
r = D3.r;
|
|
138
|
+
a = D3.az_slide.Value();
|
|
139
|
+
f = r * Math.sin(e);
|
|
140
|
+
mat = [[1, 0, 0,], [0, 1, 0], [0, 0, 1]];
|
|
141
|
+
|
|
142
|
+
D3.matrix = [
|
|
143
|
+
[1, 0, 0, 0],
|
|
144
|
+
[0, 1, 0, 0],
|
|
145
|
+
[0, 0, 1, 0]
|
|
146
|
+
];
|
|
147
|
+
|
|
148
|
+
D3.matrix[1][1] = r * Math.cos(a);
|
|
149
|
+
D3.matrix[1][2] = -r * Math.sin(a);
|
|
150
|
+
D3.matrix[2][1] = f * Math.sin(a);
|
|
151
|
+
D3.matrix[2][2] = f * Math.cos(a);
|
|
152
|
+
D3.matrix[2][3] = Math.cos(e);
|
|
153
|
+
|
|
154
|
+
if (true) {
|
|
155
|
+
mat[1][1] = D3.size[0] / (D3.bbox3d[0][1] - D3.bbox3d[0][0]); // w / d_x
|
|
156
|
+
mat[2][2] = D3.size[1] / (D3.bbox3d[1][1] - D3.bbox3d[1][0]); // h / d_y
|
|
157
|
+
mat[1][0] = D3.coords[0] - mat[1][1] * D3.bbox3d[0][0]; // llft_x
|
|
158
|
+
mat[2][0] = D3.coords[1] - mat[2][2] * D3.bbox3d[1][0]; // llft_y
|
|
159
|
+
|
|
160
|
+
D3.matrix = Mat.matMatMult(mat, D3.matrix);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return this;
|
|
164
|
+
},
|
|
165
|
+
|
|
166
|
+
updateRenderer: function () {
|
|
167
|
+
this.needsUpdate = false;
|
|
168
|
+
return this;
|
|
169
|
+
},
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Project 3D coordinates to 2D board coordinates
|
|
173
|
+
* The 3D coordinates are provides as three numbers x, y, z or one array of length 3.
|
|
174
|
+
*
|
|
175
|
+
* @param {Number|Array} x
|
|
176
|
+
* @param {[Number]} y
|
|
177
|
+
* @param {[Number]} z
|
|
178
|
+
* @returns {Array} Array of length 3 containing the projection on to the board
|
|
179
|
+
* in homogeneous user coordinates.
|
|
180
|
+
*/
|
|
181
|
+
project3DTo2D: function (x, y, z) {
|
|
182
|
+
var vec;
|
|
183
|
+
if (arguments.length === 3) {
|
|
184
|
+
vec = [1, x, y, z];
|
|
185
|
+
} else {
|
|
186
|
+
// Argument is an array
|
|
187
|
+
if (x.length === 3) {
|
|
188
|
+
vec = [1].concat(x);
|
|
189
|
+
} else {
|
|
190
|
+
vec = x;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return Mat.matVecMult(this.D3.matrix, vec);
|
|
194
|
+
},
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Project a 2D coordinate to the plane through the origin
|
|
198
|
+
* defined by its normal vector `normal`.
|
|
199
|
+
*
|
|
200
|
+
* @param {JXG.Point} point
|
|
201
|
+
* @param {Array} normal
|
|
202
|
+
* @returns Array of length 4 containing the projected
|
|
203
|
+
* point in homogeneous coordinates.
|
|
204
|
+
*/
|
|
205
|
+
project2DTo3DPlane: function (point, normal, foot) {
|
|
206
|
+
var mat, rhs, d, le,
|
|
207
|
+
n = normal.slice(1),
|
|
208
|
+
sol = [1, 0, 0, 0];
|
|
209
|
+
|
|
210
|
+
foot = foot || [1, 0, 0, 0];
|
|
211
|
+
le = Mat.norm(n, 3);
|
|
212
|
+
d = Mat.innerProduct(foot.slice(1), n, 3) / le;
|
|
213
|
+
|
|
214
|
+
mat = this.D3.matrix.slice(0, 3); // True copy
|
|
215
|
+
mat.push([0].concat(n));
|
|
216
|
+
|
|
217
|
+
// 2D coordinates of point:
|
|
218
|
+
rhs = point.coords.usrCoords.concat([d]);
|
|
219
|
+
try {
|
|
220
|
+
// Prevent singularity in case elevation angle is zero
|
|
221
|
+
if (mat[2][3] === 1.0) {
|
|
222
|
+
mat[2][1] = mat[2][2] = Mat.eps * 0.001;
|
|
223
|
+
}
|
|
224
|
+
sol = Mat.Numerics.Gauss(mat, rhs);
|
|
225
|
+
} catch (err) {
|
|
226
|
+
sol = [0, NaN, NaN, NaN];
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return sol;
|
|
230
|
+
},
|
|
231
|
+
|
|
232
|
+
project3DToCube: function (c3d) {
|
|
233
|
+
var cube = this.D3.bbox3d;
|
|
234
|
+
if (c3d[1] < cube[0][0]) { c3d[1] = cube[0][0]; }
|
|
235
|
+
if (c3d[1] > cube[0][1]) { c3d[1] = cube[0][1]; }
|
|
236
|
+
if (c3d[2] < cube[1][0]) { c3d[2] = cube[1][0]; }
|
|
237
|
+
if (c3d[2] > cube[1][1]) { c3d[2] = cube[1][1]; }
|
|
238
|
+
if (c3d[3] < cube[2][0]) { c3d[3] = cube[2][0]; }
|
|
239
|
+
if (c3d[3] > cube[2][1]) { c3d[3] = cube[2][1]; }
|
|
240
|
+
|
|
241
|
+
return c3d;
|
|
242
|
+
},
|
|
243
|
+
|
|
244
|
+
intersectionLineCube: function (p, d, r) {
|
|
245
|
+
var rnew, i, r0, r1;
|
|
246
|
+
|
|
247
|
+
rnew = r;
|
|
248
|
+
for (i = 0; i < 3; i++) {
|
|
249
|
+
if (d[i] !== 0) {
|
|
250
|
+
r0 = (this.D3.bbox3d[i][0] - p[i]) / d[i];
|
|
251
|
+
r1 = (this.D3.bbox3d[i][1] - p[i]) / d[i];
|
|
252
|
+
if (r < 0) {
|
|
253
|
+
rnew = Math.max(rnew, Math.min(r0, r1));
|
|
254
|
+
} else {
|
|
255
|
+
rnew = Math.min(rnew, Math.max(r0, r1));
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
return rnew;
|
|
260
|
+
},
|
|
261
|
+
|
|
262
|
+
isInCube: function (q) {
|
|
263
|
+
return q[0] > this.D3.bbox3d[0][0] - Mat.eps && q[0] < this.D3.bbox3d[0][1] + Mat.eps &&
|
|
264
|
+
q[1] > this.D3.bbox3d[1][0] - Mat.eps && q[1] < this.D3.bbox3d[1][1] + Mat.eps &&
|
|
265
|
+
q[2] > this.D3.bbox3d[2][0] - Mat.eps && q[2] < this.D3.bbox3d[2][1] + Mat.eps;
|
|
266
|
+
},
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
*
|
|
270
|
+
* @param {*} plane1
|
|
271
|
+
* @param {*} plane2
|
|
272
|
+
* @param {*} d
|
|
273
|
+
* @returns Array of length 2 containing the coordinates of the defining points of
|
|
274
|
+
* of the intersection segment.
|
|
275
|
+
*/
|
|
276
|
+
intersectionPlanePlane: function(plane1, plane2, d) {
|
|
277
|
+
var ret = [[], []],
|
|
278
|
+
p, dir, r, q;
|
|
279
|
+
|
|
280
|
+
d = d || plane2.D3.d;
|
|
281
|
+
|
|
282
|
+
p = Mat.Geometry.meet3Planes(plane1.D3.normal, plane1.D3.d, plane2.D3.normal, d,
|
|
283
|
+
Mat.crossProduct(plane1.D3.normal, plane2.D3.normal), 0);
|
|
284
|
+
dir = Mat.Geometry.meetPlanePlane(plane1.D3.dir1, plane1.D3.dir2, plane2.D3.dir1, plane2.D3.dir2);
|
|
285
|
+
r = this.intersectionLineCube(p, dir, Infinity);
|
|
286
|
+
q = Mat.axpy(r, dir, p);
|
|
287
|
+
if (this.isInCube(q)) {
|
|
288
|
+
ret[0] = q;
|
|
289
|
+
}
|
|
290
|
+
r = this.intersectionLineCube(p, dir, -Infinity);
|
|
291
|
+
q = Mat.axpy(r, dir, p);
|
|
292
|
+
if (this.isInCube(q) ) {
|
|
293
|
+
ret[1] = q;
|
|
294
|
+
}
|
|
295
|
+
return ret;
|
|
296
|
+
},
|
|
297
|
+
|
|
298
|
+
getMesh: function (X, Y, Z, interval_u, interval_v) {
|
|
299
|
+
var i_u, i_v, u, v, c2d,
|
|
300
|
+
delta_u, delta_v,
|
|
301
|
+
p = [0, 0, 0],
|
|
302
|
+
steps_u = interval_u[2],
|
|
303
|
+
steps_v = interval_v[2],
|
|
304
|
+
|
|
305
|
+
dataX = [],
|
|
306
|
+
dataY = [];
|
|
307
|
+
|
|
308
|
+
delta_u = (Type.evaluate(interval_u[1]) - Type.evaluate(interval_u[0])) / (steps_u);
|
|
309
|
+
delta_v = (Type.evaluate(interval_v[1]) - Type.evaluate(interval_v[0])) / (steps_v);
|
|
310
|
+
|
|
311
|
+
for (i_u = 0; i_u <= steps_u; i_u++) {
|
|
312
|
+
u = interval_u[0] + delta_u * i_u;
|
|
313
|
+
for (i_v = 0; i_v <= steps_v; i_v++) {
|
|
314
|
+
v = interval_v[0] + delta_v * i_v;
|
|
315
|
+
p[0] = X(u, v);
|
|
316
|
+
p[1] = Y(u, v);
|
|
317
|
+
p[2] = Z(u, v);
|
|
318
|
+
c2d = this.project3DTo2D(p);
|
|
319
|
+
dataX.push(c2d[1]);
|
|
320
|
+
dataY.push(c2d[2]);
|
|
321
|
+
}
|
|
322
|
+
dataX.push(NaN);
|
|
323
|
+
dataY.push(NaN);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
for (i_v = 0; i_v <= steps_v; i_v++) {
|
|
327
|
+
v = interval_v[0] + delta_v * i_v;
|
|
328
|
+
for (i_u = 0; i_u <= steps_u; i_u++) {
|
|
329
|
+
u = interval_u[0] + delta_u * i_u;
|
|
330
|
+
p[0] = X(u, v);
|
|
331
|
+
p[1] = Y(u, v);
|
|
332
|
+
p[2] = Z(u, v);
|
|
333
|
+
c2d = this.project3DTo2D(p);
|
|
334
|
+
dataX.push(c2d[1]);
|
|
335
|
+
dataY.push(c2d[2]);
|
|
336
|
+
}
|
|
337
|
+
dataX.push(NaN);
|
|
338
|
+
dataY.push(NaN);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
return [dataX, dataY];
|
|
342
|
+
},
|
|
343
|
+
|
|
344
|
+
animateAzimuth: function () {
|
|
345
|
+
var s = this.D3.az_slide._smin,
|
|
346
|
+
e = this.D3.az_slide._smax,
|
|
347
|
+
sdiff = e - s,
|
|
348
|
+
newVal = this.D3.az_slide.Value() + 0.1;
|
|
349
|
+
|
|
350
|
+
this.D3.az_slide.position = ((newVal - s) / sdiff);
|
|
351
|
+
if (this.D3.az_slide.position > 1) {
|
|
352
|
+
this.D3.az_slide.position = 0.0;
|
|
353
|
+
}
|
|
354
|
+
this.board.update();
|
|
355
|
+
|
|
356
|
+
this.timeoutAzimuth = setTimeout(function () { this.animateAzimuth(); }.bind(this), 200);
|
|
357
|
+
},
|
|
358
|
+
|
|
359
|
+
stopAzimuth: function () {
|
|
360
|
+
clearTimeout(this.timeoutAzimuth);
|
|
361
|
+
this.timeoutAzimuth = null;
|
|
362
|
+
}
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
*
|
|
367
|
+
* @param {*} board
|
|
368
|
+
* @param {*} parents
|
|
369
|
+
* @param {*} attributes
|
|
370
|
+
* @returns
|
|
371
|
+
*/
|
|
372
|
+
ThreeD.createView3D = function (board, parents, attributes) {
|
|
373
|
+
var view, frame, attr,
|
|
374
|
+
x, y, w, h,
|
|
375
|
+
coords = parents[0], // llft corner
|
|
376
|
+
size = parents[1]; // [w, h]
|
|
377
|
+
|
|
378
|
+
attr = Type.copyAttributes(attributes, board.options, 'view3d');
|
|
379
|
+
view = new ThreeD.View3D(board, parents, attr);
|
|
380
|
+
view.defaultAxes = view.create('axes3d', parents, attributes);
|
|
381
|
+
|
|
382
|
+
x = coords[0];
|
|
383
|
+
y = coords[1];
|
|
384
|
+
w = size[0];
|
|
385
|
+
h = size[1];
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* Frame around the view object
|
|
389
|
+
*/
|
|
390
|
+
if (false) {
|
|
391
|
+
frame = board.create('polygon', [
|
|
392
|
+
[coords[0], coords[1] + size[1]], // ulft
|
|
393
|
+
[coords[0], coords[1]], // llft
|
|
394
|
+
[coords[0] + size[0], coords[1]], // lrt
|
|
395
|
+
[coords[0] + size[0], coords[1] + size[1]], // urt
|
|
396
|
+
], {
|
|
397
|
+
fillColor: 'none',
|
|
398
|
+
highlightFillColor: 'none',
|
|
399
|
+
highlight: false,
|
|
400
|
+
vertices: {
|
|
401
|
+
fixed: true,
|
|
402
|
+
visible: false
|
|
403
|
+
},
|
|
404
|
+
borders: {
|
|
405
|
+
strokeColor: 'black',
|
|
406
|
+
highlight: false,
|
|
407
|
+
strokeWidth: 0.5,
|
|
408
|
+
dash: 4
|
|
409
|
+
}
|
|
410
|
+
});
|
|
411
|
+
//view.add(frame);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* Slider to adapt azimuth angle
|
|
416
|
+
*/
|
|
417
|
+
view.D3.az_slide = board.create('slider', [[x - 1, y - 2], [x + w + 1, y - 2], [0, 1.0, 2 * Math.PI]], {
|
|
418
|
+
style: 6, name: 'az',
|
|
419
|
+
point1: { frozen: true },
|
|
420
|
+
point2: { frozen: true }
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
* Slider to adapt elevation angle
|
|
425
|
+
*/
|
|
426
|
+
view.D3.el_slide = board.create('slider', [[x - 1, y], [x - 1, y + h], [0, 0.30, Math.PI / 2]], {
|
|
427
|
+
style: 6, name: 'el',
|
|
428
|
+
point1: { frozen: true },
|
|
429
|
+
point2: { frozen: true }
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
view.board.highlightInfobox = function (x, y, el) {
|
|
433
|
+
var d;
|
|
434
|
+
|
|
435
|
+
if (Type.exists(el.D3)) {
|
|
436
|
+
d = Type.evaluate(el.visProp.infoboxdigits);
|
|
437
|
+
if (d === 'auto') {
|
|
438
|
+
view.board.highlightCustomInfobox('(' +
|
|
439
|
+
Type.autoDigits(el.D3.X()) + ' | ' +
|
|
440
|
+
Type.autoDigits(el.D3.Y()) + ' | ' +
|
|
441
|
+
Type.autoDigits(el.D3.Z()) + ')', el);
|
|
442
|
+
} else {
|
|
443
|
+
view.board.highlightCustomInfobox('(' +
|
|
444
|
+
Type.toFixed(el.D3.X(), d) + ' | ' +
|
|
445
|
+
Type.toFixed(el.D3.Y(), d) + ' | ' +
|
|
446
|
+
Type.toFixed(el.D3.Z(), d) + ')', el);
|
|
447
|
+
}
|
|
448
|
+
} else {
|
|
449
|
+
view.board.highlightCustomInfobox('(' + x + ', ' + y + ')', el);
|
|
450
|
+
}
|
|
451
|
+
};
|
|
452
|
+
|
|
453
|
+
return view;
|
|
454
|
+
};
|
|
455
|
+
JXG.registerElement('view3d', ThreeD.createView3D);
|
|
456
|
+
|
|
457
|
+
return ThreeD.View3D;
|
|
458
|
+
});
|
|
459
|
+
|
package/src/base/board.js
CHANGED
|
@@ -2417,10 +2417,14 @@ define([
|
|
|
2417
2417
|
}
|
|
2418
2418
|
}
|
|
2419
2419
|
|
|
2420
|
+
this.originMoveEnd();
|
|
2421
|
+
this.update();
|
|
2422
|
+
|
|
2420
2423
|
// selection
|
|
2421
2424
|
if (this.selectingMode) {
|
|
2422
2425
|
this._stopSelecting(evt);
|
|
2423
2426
|
this.triggerEventHandlers(['touchstopselecting', 'pointerstopselecting', 'stopselecting'], [evt]);
|
|
2427
|
+
this.stopSelectionMode();
|
|
2424
2428
|
} else {
|
|
2425
2429
|
for (i = this.downObjects.length - 1; i > -1; i--) {
|
|
2426
2430
|
found = false;
|
|
@@ -2431,32 +2435,30 @@ define([
|
|
|
2431
2435
|
}
|
|
2432
2436
|
if (!found) {
|
|
2433
2437
|
this.downObjects[i].triggerEventHandlers(['touchend', 'up', 'pointerup', 'MSPointerUp'], [evt]);
|
|
2434
|
-
this.downObjects[i].snapToGrid();
|
|
2435
|
-
this.downObjects[i].snapToPoints();
|
|
2438
|
+
// this.downObjects[i].snapToGrid();
|
|
2439
|
+
// this.downObjects[i].snapToPoints();
|
|
2436
2440
|
this.downObjects.splice(i, 1);
|
|
2437
2441
|
}
|
|
2438
2442
|
}
|
|
2439
2443
|
}
|
|
2440
2444
|
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
Env.removeEvent(this.document, 'pointerup', this.pointerUpListener, this);
|
|
2448
|
-
Env.removeEvent(this.document, 'pointercancel', this.pointerUpListener, this);
|
|
2449
|
-
}
|
|
2450
|
-
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);
|
|
2451
2451
|
}
|
|
2452
|
+
this.hasPointerUp = false;
|
|
2453
|
+
}
|
|
2452
2454
|
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2455
|
+
// this.dehighlightAll();
|
|
2456
|
+
// this.updateQuality = this.BOARD_QUALITY_HIGH;
|
|
2457
|
+
// this.mode = this.BOARD_MODE_NONE;
|
|
2458
|
+
|
|
2459
|
+
// this.originMoveEnd();
|
|
2460
|
+
// this.update();
|
|
2456
2461
|
|
|
2457
|
-
this.originMoveEnd();
|
|
2458
|
-
this.update();
|
|
2459
|
-
// }
|
|
2460
2462
|
// After one finger leaves the screen the gesture is stopped.
|
|
2461
2463
|
this._pointerClearTouches();
|
|
2462
2464
|
return true;
|
|
@@ -2799,6 +2801,7 @@ define([
|
|
|
2799
2801
|
if (this.selectingMode) {
|
|
2800
2802
|
this._stopSelecting(evt);
|
|
2801
2803
|
this.triggerEventHandlers(['touchstopselecting', 'stopselecting'], [evt]);
|
|
2804
|
+
this.stopSelectionMode();
|
|
2802
2805
|
} else if (evtTouches && evtTouches.length > 0) {
|
|
2803
2806
|
for (i = 0; i < this.touches.length; i++) {
|
|
2804
2807
|
tmpTouches[i] = this.touches[i];
|
|
@@ -2890,8 +2893,8 @@ define([
|
|
|
2890
2893
|
}
|
|
2891
2894
|
if (!found) {
|
|
2892
2895
|
this.downObjects[i].triggerEventHandlers(['touchup', 'up'], [evt]);
|
|
2893
|
-
this.downObjects[i].snapToGrid();
|
|
2894
|
-
this.downObjects[i].snapToPoints();
|
|
2896
|
+
// this.downObjects[i].snapToGrid();
|
|
2897
|
+
// this.downObjects[i].snapToPoints();
|
|
2895
2898
|
this.downObjects.splice(i, 1);
|
|
2896
2899
|
}
|
|
2897
2900
|
}
|
|
@@ -3054,11 +3057,11 @@ define([
|
|
|
3054
3057
|
// redraw with high precision
|
|
3055
3058
|
this.updateQuality = this.BOARD_QUALITY_HIGH;
|
|
3056
3059
|
|
|
3057
|
-
if (this.mouse && this.mouse.obj) {
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
}
|
|
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
|
+
// }
|
|
3062
3065
|
|
|
3063
3066
|
this.originMoveEnd();
|
|
3064
3067
|
this.dehighlightAll();
|
|
@@ -3068,6 +3071,7 @@ define([
|
|
|
3068
3071
|
if (this.selectingMode) {
|
|
3069
3072
|
this._stopSelecting(evt);
|
|
3070
3073
|
this.triggerEventHandlers(['mousestopselecting', 'stopselecting'], [evt]);
|
|
3074
|
+
this.stopSelectionMode();
|
|
3071
3075
|
} else {
|
|
3072
3076
|
for (i = 0; i < this.downObjects.length; i++) {
|
|
3073
3077
|
this.downObjects[i].triggerEventHandlers(['mouseup', 'up'], [evt]);
|
|
@@ -3248,7 +3252,7 @@ define([
|
|
|
3248
3252
|
|
|
3249
3253
|
this.update();
|
|
3250
3254
|
|
|
3251
|
-
if (done) {
|
|
3255
|
+
if (done && Type.exists(evt.preventDefault)) {
|
|
3252
3256
|
evt.preventDefault();
|
|
3253
3257
|
}
|
|
3254
3258
|
return true;
|
package/src/base/constants.js
CHANGED
|
@@ -198,8 +198,6 @@ define([
|
|
|
198
198
|
* @private
|
|
199
199
|
*/
|
|
200
200
|
updateCoords: function (fromParent) {
|
|
201
|
-
var i;
|
|
202
|
-
|
|
203
201
|
if (!this.needsUpdate) {
|
|
204
202
|
return this;
|
|
205
203
|
}
|
|
@@ -326,7 +324,6 @@ define([
|
|
|
326
324
|
doRound = true;
|
|
327
325
|
newPos = 0.0;
|
|
328
326
|
} else {
|
|
329
|
-
//this.coords.setCoordinates(Const.COORDS_BY_USER, Geometry.projectPointToLine(this, slide, this.board).usrCoords, false);
|
|
330
327
|
newCoords = Geometry.projectPointToLine(this, slide, this.board);
|
|
331
328
|
p1c = p1c.usrCoords.slice(0);
|
|
332
329
|
p2c = p2c.usrCoords.slice(0);
|
|
@@ -1833,7 +1830,7 @@ define([
|
|
|
1833
1830
|
if (direction < 0) {
|
|
1834
1831
|
alpha *= this.intervalCount / stepCount;
|
|
1835
1832
|
} else {
|
|
1836
|
-
alpha *= (stepCount - this.intervalCount);
|
|
1833
|
+
alpha *= (stepCount - this.intervalCount) / stepCount;
|
|
1837
1834
|
}
|
|
1838
1835
|
radius = this.slideObject.Radius();
|
|
1839
1836
|
|
package/src/base/element.js
CHANGED
|
@@ -1052,26 +1052,35 @@ define([
|
|
|
1052
1052
|
},
|
|
1053
1053
|
|
|
1054
1054
|
/**
|
|
1055
|
-
* Resolves
|
|
1056
|
-
* Writes the expanded
|
|
1057
|
-
* @param {Object}
|
|
1058
|
-
* @returns {Object} The given
|
|
1055
|
+
* Resolves attribute shortcuts like <tt>color</tt> and expands them, e.g. <tt>strokeColor</tt> and <tt>fillColor</tt>.
|
|
1056
|
+
* Writes the expanded attributes back to the given <tt>attributes</tt>.
|
|
1057
|
+
* @param {Object} attributes object
|
|
1058
|
+
* @returns {Object} The given attributes object with shortcuts expanded.
|
|
1059
|
+
* @private
|
|
1059
1060
|
*/
|
|
1060
|
-
resolveShortcuts: function (
|
|
1061
|
-
var key, i
|
|
1061
|
+
resolveShortcuts: function (attributes) {
|
|
1062
|
+
var key, i,
|
|
1063
|
+
j,
|
|
1064
|
+
subattr = ['traceattributes', 'traceAttributes'];
|
|
1062
1065
|
|
|
1063
1066
|
for (key in Options.shortcuts) {
|
|
1064
1067
|
if (Options.shortcuts.hasOwnProperty(key)) {
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1068
|
+
|
|
1069
|
+
if (Type.exists(attributes[key])) {
|
|
1070
|
+
for (i = 0; i < Options.shortcuts[key].length; i++) {
|
|
1071
|
+
if (!Type.exists(attributes[Options.shortcuts[key][i]])) {
|
|
1072
|
+
attributes[Options.shortcuts[key][i]] = attributes[key];
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
for (j = 0; j < subattr.length; j++) {
|
|
1077
|
+
if (Type.isObject(attributes[subattr[j]])) {
|
|
1078
|
+
attributes[subattr[j]] = this.resolveShortcuts(attributes[subattr[j]]);
|
|
1079
|
+
}
|
|
1069
1080
|
}
|
|
1070
1081
|
}
|
|
1071
|
-
}
|
|
1072
|
-
}
|
|
1073
1082
|
}
|
|
1074
|
-
return
|
|
1083
|
+
return attributes;
|
|
1075
1084
|
},
|
|
1076
1085
|
|
|
1077
1086
|
/**
|
|
@@ -324,7 +324,13 @@
|
|
|
324
324
|
* an SVG foreignObject container.
|
|
325
325
|
* <p>
|
|
326
326
|
* Instead of board.create('foreignobject') the shortcut board.create('fo') may be used.
|
|
327
|
-
*
|
|
327
|
+
*
|
|
328
|
+
* <p style="background-color:#dddddd; padding:10px"><b>NOTE:</b> In Safari up to version 15, a foreignObject does not obey the layer structure
|
|
329
|
+
* if it contains <video> or <iframe> tags, as well as elements which are
|
|
330
|
+
* positioned with <tt>position:absolute|relative|fixed</tt>. In this case, the foreignobject will be
|
|
331
|
+
* "above" the JSXGraph construction.
|
|
332
|
+
* </p>
|
|
333
|
+
*
|
|
328
334
|
* @pseudo
|
|
329
335
|
* @description
|
|
330
336
|
* @name ForeignObject
|
package/src/base/line.js
CHANGED
|
@@ -695,7 +695,7 @@ define([
|
|
|
695
695
|
if (this.parents.length < 3) { // Line through two points
|
|
696
696
|
this.point1.handleSnapToGrid(true, true);
|
|
697
697
|
this.point2.handleSnapToGrid(true, true);
|
|
698
|
-
|
|
698
|
+
} else if (Type.exists(pos)) { // Free line
|
|
699
699
|
sX = Type.evaluate(this.visProp.snapsizex);
|
|
700
700
|
sY = Type.evaluate(this.visProp.snapsizey);
|
|
701
701
|
|