1 /*global JXG:true, define: true*/
  2 
  3 import JXG from "./jxg.js";
  4 import Options from "./options.js";
  5 
  6 JXG.extend(Options, {
  7     // infobox: {
  8     //     // strokeColor: 'black',
  9     //     // useKatex: false,
 10     //     // useMathjax: false
 11     // },
 12 
 13     axes3d: {
 14         /**#@+
 15          * @visprop
 16          */
 17 
 18         /**
 19          * Position of the main axes in a View3D element. Possible values are
 20          * 'center', 'border' or 'none'. This attribute is immutable, i.e.
 21          * can not be changed during the lifetime of the construction.
 22          *
 23          * @type String
 24          * @name View3D#axesPosition
 25          * @default 'center'
 26          */
 27         axesPosition: "center", // Possible values: 'center', 'border', 'none'
 28 
 29         // Main axes
 30         /**
 31          * Attributes of the centered 3D x-axis.
 32          *
 33          * @type Line3D
 34          * @name View3D#xAxis
 35          * @see View3D#axesPosition
 36          */
 37         xAxis: {
 38             visible: true,
 39             layer: 12,
 40             point2: { name: "x" },
 41             strokeColor: JXG.palette.red
 42         },
 43 
 44         /**
 45          * Attributes of the centered 3D y-axis.
 46          *
 47          * @type Line3D
 48          * @name View3D#yAxis
 49          * @see View3D#axesPosition
 50          */
 51         yAxis: {
 52             visible: true,
 53             layer: 12,
 54             point2: { name: "y" },
 55             strokeColor: JXG.palette.green
 56         },
 57 
 58         /**
 59          * Attributes of the centered 3D z-axis.
 60          *
 61          * @type Line3D
 62          * @name View3D#zAxis
 63          * @see View3D#axesPosition
 64          */
 65         zAxis: {
 66             visible: true,
 67             layer: 12,
 68             point2: { name: "z" },
 69             strokeColor: JXG.palette.blue
 70         },
 71 
 72         /**
 73          * Attributes of the 3D x-axis at the border.
 74          *
 75          * @type Line3D
 76          * @name View3D#xAxisBorder
 77          * @see View3D#axesPosition
 78          * @default <pre>{
 79          *   name: 'x',
 80          *   withLabel: false,
 81          *   label: {
 82          *       position: '50% left',
 83          *       offset: [30, 0],
 84          *       fontsize: 15
 85          *   },
 86          *   strokeWidth: 1,
 87          *   lastArrow: false,
 88          *   ticks3d: {
 89          *       label: {
 90          *           anchorX: 'middle',
 91          *           anchorY: 'middle'
 92          *       }
 93          *   }
 94          *}
 95          *</pre>
 96          */
 97         xAxisBorder: {
 98             name: 'x',
 99             visible: 'ìnherit',
100             withLabel: false,
101             label: {
102                 position: '50% left',
103                 offset: [30, 0],
104                 fontsize: 15
105             },
106             strokeWidth: 1,
107             lastArrow: false,
108             ticks3d: {
109                 visible: 'ìnherit',
110                 label: {
111                     anchorX: 'middle',
112                     anchorY: 'middle'
113                 }
114 
115             }
116         },
117 
118         /**
119          * Attributes of the 3D y-axis at the border.
120          *
121          * @type Line3D
122          * @name View3D#yAxisBorder
123          * @see View3D#axesPosition
124          * @default <pre>{
125          *   name: 'x',
126          *   withLabel: false,
127          *   label: {
128          *       position: '50% right',
129          *       offset: [0, -30],
130          *       fontsize: 15
131          *   },
132          *   strokeWidth: 1,
133          *   lastArrow: false,
134          *   ticks3d: {
135          *       label: {
136          *           anchorX: 'middle',
137          *       }
138          *   }
139          *}
140          *</pre>
141          */
142         yAxisBorder: {
143             name: 'y',
144             visible: 'ìnherit',
145             withLabel: false,
146             label: {
147                 position: '50% right',
148                 offset: [0, -30],
149                 fontsize: 15
150             },
151             strokeWidth: 1,
152             lastArrow: false,
153             ticks3d: {
154                 visible: 'ìnherit',
155                 label: {
156                     anchorX: 'middle'
157                 }
158             }
159         },
160 
161         /**
162          * Attributes of the 3D z-axis at the border.
163          *
164          * @type Line3D
165          * @name View3D#zAxisBorder
166          * @see View3D#axesPosition
167          * @default <pre>{
168          *   name: 'z',
169          *   withLabel: false,
170          *   label: {
171          *       position: '50% right',
172          *       offset: [30, 0],
173          *       fontsize: 15
174          *   },
175          *   strokeWidth: 1,
176          *   lastArrow: false,
177          *   ticks3d: {
178          *       label: {
179          *           anchorX: 'middle',
180          *           anchorY: 'middle'
181          *       }
182          *   }
183          *}
184          *</pre>
185          */
186         zAxisBorder: {
187             name: 'z',
188             visible: 'ìnherit',
189             withLabel: false,
190             label: {
191                 position: '50% right',
192                 offset: [30, 0],
193                 fontsize: 15
194             },
195             strokeWidth: 1,
196             lastArrow: false,
197             ticks3d: {
198                 visible: 'ìnherit',
199                 label: {
200                     anchorX: 'middle',
201                     anchorY: 'middle'
202                 }
203             }
204         },
205 
206         // Planes
207         /**
208          * Attributes of the 3D plane orthogonal to the x-axis at the "rear" of the cube.
209          * @type Plane3D
210          * @name View3D#xPlaneRear
211          */
212         xPlaneRear: {
213             visible: true,
214             layer: 0,
215             strokeWidth: 1,
216             strokeColor: '#dddddd',
217             fillColor: '#dddddd',
218             mesh3d: { layer: 1 },
219 
220             stepsU: 10,
221             stepsV: 10,
222             tiling: 'rectangle',
223             polyhedron: {
224                 visible: 'inherit',
225                 strokeWidth: 0.5,
226                 shader: {
227                     enabled: true,
228                     fixed: true,
229                     type: 'zIndex',
230                     hue: 0,
231                     saturation: 0,
232                     minlightness: 65,
233                     maxLightness: 98
234                 }
235             }
236         },
237 
238         /**
239          * Attributes of the 3D plane orthogonal to the y-axis at the "rear" of the cube.
240          * @type Plane3D
241          * @name View3D#yPlaneRear
242          */
243         yPlaneRear: {
244             visible: true,
245             strokeWidth: 1,
246             strokeColor: '#dddddd',
247             fillColor: '#dddddd',
248             layer: 0,
249             mesh3d: { layer: 1 },
250 
251             stepsU: 10,
252             stepsV: 10,
253             tiling: 'rectangle',
254             polyhedron: {
255                 visible: 'inherit',
256                 strokeWidth: 0.5,
257                 shader: {
258                     enabled: true,
259                     fixed: true,
260                     type: 'zIndex',
261                     hue: 0,
262                     saturation: 0,
263                     minlightness: 65,
264                     maxLightness: 98
265                 }
266             }
267         },
268 
269         /**
270          * Attributes of the 3D plane orthogonal to the z-axis at the "rear" of the cube.
271          * @type Plane3D
272          * @name View3D#zPlaneRear
273          */
274         zPlaneRear: {
275             visible: true,
276             strokeWidth: 1,
277             strokeColor: '#dddddd',
278             fillColor: '#dddddd',
279             layer: 0,
280             mesh3d: { layer: 1 },
281 
282             stepsU: 10,
283             stepsV: 10,
284             tiling: 'rectangle',
285             polyhedron: {
286                 visible: 'inherit',
287                 strokeWidth: 0.5,
288                 shader: {
289                     enabled: true,
290                     fixed: true,
291                     type: 'zIndex',
292                     hue: 0,
293                     saturation: 0,
294                     minlightness: 65,
295                     maxLightness: 98
296                 }
297             }
298         },
299 
300         /**
301          * Attributes of the 3D plane orthogonal to the x-axis at the "front" of the cube.
302          * @type Plane3D
303          * @name View3D#xPlaneFront
304          */
305         xPlaneFront: {
306             visible: false,
307             strokeWidth: 1,
308             strokeColor: '#dddddd',
309             fillColor: '#dddddd',
310             layer: 0,
311             mesh3d: { layer: 1 },
312 
313             stepsU: 10,
314             stepsV: 10,
315             tiling: 'rectangle',
316             polyhedron: {
317                 visible: 'inherit',
318                 strokeWidth: 0.5,
319                 shader: {
320                     enabled: true,
321                     fixed: true,
322                     type: 'zIndex',
323                     hue: 0,
324                     saturation: 0,
325                     minlightness: 65,
326                     maxLightness: 98
327                 }
328             }
329         },
330         /**
331          * Attributes of the 3D plane orthogonal to the y-axis at the "front" of the cube.
332          * @type Plane3D
333          * @name View3D#yPlaneFront
334          */
335         yPlaneFront: {
336             visible: false,
337             strokeWidth: 1,
338             strokeColor: '#dddddd',
339             fillColor: '#dddddd',
340             layer: 0,
341             mesh3d: { layer: 1 },
342 
343             stepsU: 10,
344             stepsV: 10,
345             tiling: 'rectangle',
346             polyhedron: {
347                 visible: 'inherit',
348                 strokeWidth: 0.5,
349                 shader: {
350                     enabled: true,
351                     fixed: true,
352                     type: 'zIndex',
353                     hue: 0,
354                     saturation: 0,
355                     minlightness: 65,
356                     maxLightness: 98
357                 }
358             }
359         },
360         /**
361          * Attributes of the 3D plane orthogonal to the z-axis at the "front" of the cube.
362          * @type Plane3D
363          * @name View3D#zPlaneFront
364          */
365         zPlaneFront: {
366             visible: false,
367             strokeWidth: 1,
368             strokeColor: '#dddddd',
369             fillColor: '#dddddd',
370             layer: 0,
371             mesh3d: { layer: 1 },
372 
373             stepsU: 10,
374             stepsV: 10,
375             tiling: 'rectangle',
376             polyhedron: {
377                 visible: 'inherit',
378                 strokeWidth: 0.5,
379                 shader: {
380                     enabled: true,
381                     fixed: true,
382                     type: 'zIndex',
383                     hue: 0,
384                     saturation: 0,
385                     minlightness: 65,
386                     maxLightness: 98
387                 }
388             }
389         },
390 
391         // Axes on the planes
392         /**
393          * Attributes of the 3D y-axis on the 3D plane orthogonal to the x-axis at the "rear" of the cube.
394          * @type Plane3D
395          * @name View3D#xPlaneRearYAxis
396          */
397         xPlaneRearYAxis: {
398             visible: 'inherit',
399             strokeColor: "#aaaaaa",
400             strokeWidth: 1.2,
401             layer: 12
402         },
403         /**
404          * Attributes of the 3D z-axis on the 3D plane orthogonal to the x-axis at the "rear" of the cube.
405          * @type Plane3D
406          * @name View3D#xPlaneRearZAxis
407          */
408         xPlaneRearZAxis: {
409             visible: 'inherit',
410             strokeColor: "#888888",
411             strokeWidth: 1.2,
412             layer: 12
413         },
414         /**
415          * Attributes of the 3D y-axis on the 3D plane orthogonal to the x-axis at the "front" of the cube.
416          * @type Plane3D
417          * @name View3D#xPlaneFrontYAxis
418          */
419         xPlaneFrontYAxis: {
420             visible: 'inherit',
421             strokeColor: "#888888",
422             strokeWidth: 1.2,
423             layer: 12
424         },
425         /**
426          * Attributes of the 3D z-axis on the 3D plane orthogonal to the x-axis at the "front" of the cube.
427          * @type Plane3D
428          * @name View3D#xPlaneFrontZAxis
429          */
430         xPlaneFrontZAxis: {
431             visible: 'inherit',
432             strokeColor: "#888888",
433             strokeWidth: 1.2,
434             layer: 12
435         },
436         /**
437          * Attributes of the 3D x-axis on the 3D plane orthogonal to the y-axis at the "rear" of the cube.
438          * @type Plane3D
439          * @name View3D#yPlaneRearXAxis
440          */
441         yPlaneRearXAxis: {
442             visible: 'inherit',
443             strokeColor: "#888888",
444             strokeWidth: 1.2,
445             layer: 12
446         },
447         /**
448          * Attributes of the 3D z-axis on the 3D plane orthogonal to the y-axis at the "rear" of the cube.
449          * @type Plane3D
450          * @name View3D#yPlaneRearZAxis
451          */
452         yPlaneRearZAxis: {
453             visible: 'inherit',
454             strokeColor: "#888888",
455             strokeWidth: 1.2,
456             layer: 12
457         },
458         /**
459          * Attributes of the 3D x-axis on the 3D plane orthogonal to the y-axis at the "front" of the cube.
460          * @type Plane3D
461          * @name View3D#yPlaneFrontXAxis
462          */
463         yPlaneFrontXAxis: {
464             visible: 'inherit',
465             strokeColor: "#888888",
466             strokeWidth: 1.2,
467             layer: 12
468         },
469         /**
470          * Attributes of the 3D z-axis on the 3D plane orthogonal to the y-axis at the "front" of the cube.
471          * @type Plane3D
472          * @name View3D#yPlaneFrontZAxis
473          */
474         yPlaneFrontZAxis: {
475             visible: 'inherit',
476             strokeColor: "#888888",
477             strokeWidth: 1.2,
478             layer: 12
479         },
480 
481         /**
482          * Attributes of the 3D x-axis on the 3D plane orthogonal to the z-axis at the "rear" of the cube.
483          * @type Plane3D
484          * @name View3D#zPlaneRearXAxis
485          */
486         zPlaneRearXAxis: {
487             visible: 'inherit',
488             strokeColor: "#888888",
489             strokeWidth: 1.2,
490             layer: 12
491         },
492         /**
493          * Attributes of the 3D y-axis on the 3D plane orthogonal to the z-axis at the "rear" of the cube.
494          * @type Plane3D
495          * @name View3D#zPlaneRearYAxis
496          */
497         zPlaneRearYAxis: {
498             visible: 'inherit',
499             strokeColor: "#888888",
500             strokeWidth: 1.2,
501             layer: 12
502         },
503         /**
504          * Attributes of the 3D x-axis on the 3D plane orthogonal to the z-axis at the "front" of the cube.
505          * @type Plane3D
506          * @name View3D#zPlaneFrontXAxis
507          */
508         zPlaneFrontXAxis: {
509             visible: 'inherit',
510             strokeColor: "#888888",
511             strokeWidth: 1.2,
512             layer: 12
513         },
514         /**
515          * Attributes of the 3D y-axis on the 3D plane orthogonal to the z-axis at the "front" of the cube.
516          * @type Plane3D
517          * @name View3D#zPlaneFrontYAxis
518          */
519         zPlaneFrontYAxis: {
520             visible: 'inherit',
521             strokeColor: "#888888",
522             strokeWidth: 1.2,
523             layer: 12
524         }
525 
526         /**#@-*/
527     },
528 
529     axis3d: {
530         highlight: false,
531         fixed: true,
532         strokeColor: "black",
533         strokeWidth: 1,
534         lastArrow: true,
535         tabindex: null,
536 
537         point1: { visible: false, name: "", withLabel: false },
538         point2: { visible: false, name: "", withLabel: false, label: { visible: true } }
539     },
540 
541     circle3d: {
542 
543         layer: 12,
544         point: { visible: false, name: "" },
545         needsRegularUpdate: true
546 
547     },
548 
549     curve3d: {
550         /**#@+
551          * @visprop
552          */
553 
554         layer: 12,
555         highlight: false,
556         tabindex: -1,
557         strokeWidth: 1,
558         numberPointsHigh: 200,
559         needsRegularUpdate: true
560 
561         /**#@-*/
562     },
563 
564     face3d: {
565         /**#@+
566          * @visprop
567          */
568 
569         transitionProperties: [],
570         layer: 12,
571         highlight: false,
572         tabindex: null,
573         strokeWidth: 1,
574         fillColor: JXG.palette.yellow,
575         fillOpacity: 0.4,
576         needsRegularUpdate: true,
577 
578         /**
579          * Shading of faces. For this, the HSL color scheme is used.
580          * Two types are possible: either by 'angle' or by 'zIndex'.
581          * By default (i.e. type:'angle'), the angle between the camera axis and the normal of the
582          * face determines the lightness value of the HSL color. Otherwise, the
583          * zIndex of the face determines the lightness value of the HSL color.
584          * <p>
585          * Note that shading needs a lot of computing resources, in particular for
586          * SVG rendering. Setting `renderer:'canvas'` will allow to rotate the viewport
587          * much faster.
588          *
589          * @type Object
590          * @name Face3D#shader
591          * @see View3D#depthOrder
592          * @default <pre>shader: {
593          *   enabled: false,
594          *   fixed: true,    // If false, update shading during rotation of viewport
595          *   type: 'angle',  // 'angle', otherwise zIndex
596          *   hue: 60,        // yellow
597          *   saturation: 90,
598          *   minLightness: 30,
599          *   maxLightness: 90,
600          *
601          *   light: {
602          *       type: 1,// 1: lighting==camera,
603          *               // 2: Fixed: angle(light, object),
604          *               // 3: Fixed: angle(light, camera) (default)
605          *       az: -45, // TODO use radians, ignored for type==1
606          *       el: 20,  // TODO use radians, ignored for type==1
607          *       bank: 0, // TODO use radians, ignored for type==1, type==3
608          *       dir: -1  // -1, 0 (use abs), 1: Default: -1
609          *   }
610          * }</pre>
611          *
612          * @example
613          *         var view = board.create(
614          *             'view3d',
615          *             [[-5, -3], [8, 8],
616          *             [[-3, 3], [-3, 3], [-3, 3]]],
617          *             {
618          *                 projection: 'central',
619          *                 trackball: { enabled: true },
620          *                 depthOrder: {
621          *                     enabled: true
622          *                 },
623          *                 xPlaneRear: { visible: false },
624          *                 yPlaneRear: { visible: false },
625          *                 zPlaneRear: { fillOpacity: 0.2, visible: true }
626          *             }
627          *         );
628          *
629          *         let rho = 1.6180339887;
630          *         let vertexList = [
631          *             [0, -1, -rho], [0, +1, -rho], [0, -1, rho], [0, +1, rho],
632          *             [1, rho, 0], [-1, rho, 0], [1, -rho, 0], [-1, -rho, 0],
633          *             [-rho, 0, 1], [-rho, 0, -1], [rho, 0, 1], [rho, 0, -1]
634          *         ];
635          *         let faceArray = [
636          *             [4, 1, 11],
637          *             [11, 1, 0],
638          *             [6, 11, 0],
639          *             [0, 1, 9],
640          *             [11, 10, 4],
641          *             [9, 1, 5],
642          *             [8, 9, 5],
643          *             [5, 3, 8],
644          *             [6, 10, 11],
645          *             [2, 3, 10],
646          *             [2, 10, 6],
647          *             [8, 3, 2],
648          *             [3, 4, 10],
649          *             [7, 8, 2],
650          *             [9, 8, 7],
651          *             [0, 9, 7],
652          *             [4, 3, 5],
653          *             [5, 1, 4],
654          *             [0, 7, 6],
655          *             [7, 2, 6]
656          *         ];
657          *         var ico = view.create('polyhedron3d', [vertexList, faceArray], {
658          *             fillColorArray: [],
659          *             fillOpacity: 1,
660          *             strokeWidth: 0.1,
661          *             layer: 12,
662          *             shader: {
663          *                 enabled: true,
664          *                 type: 'angle',
665          *                 hue: 0,
666          *                 saturation: 90,
667          *                 minlightness: 60,
668          *                 maxLightness: 80
669          *             }
670          *         });
671          *
672          * </pre><div id="JXGbf32b040-affb-4e03-a05b-abfe953f614d" class="jxgbox" style="width: 300px; height: 300px;"></div>
673          * <script type="text/javascript">
674          *     (function() {
675          *         var board = JXG.JSXGraph.initBoard('JXGbf32b040-affb-4e03-a05b-abfe953f614d',
676          *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false,
677          *                pan: {enabled: false}, zoom: {enabled: false}});
678          *             var view = board.create(
679          *                 'view3d',
680          *                 [[-5, -3], [8, 8],
681          *                 [[-3, 3], [-3, 3], [-3, 3]]],
682          *                 {
683          *                     projection: 'central',
684          *                     trackball: { enabled: true },
685          *                     depthOrder: {
686          *                         enabled: true
687          *                     },
688          *                     xPlaneRear: { visible: false },
689          *                     yPlaneRear: { visible: false },
690          *                     zPlaneRear: { fillOpacity: 0.2, visible: true }
691          *                 }
692          *             );
693          *
694          *             let rho = 1.6180339887;
695          *             let vertexList = [
696          *                 [0, -1, -rho], [0, +1, -rho], [0, -1, rho], [0, +1, rho],
697          *                 [1, rho, 0], [-1, rho, 0], [1, -rho, 0], [-1, -rho, 0],
698          *                 [-rho, 0, 1], [-rho, 0, -1], [rho, 0, 1], [rho, 0, -1]
699          *             ];
700          *             let faceArray = [
701          *                 [4, 1, 11],
702          *                 [11, 1, 0],
703          *                 [6, 11, 0],
704          *                 [0, 1, 9],
705          *                 [11, 10, 4],
706          *                 [9, 1, 5],
707          *                 [8, 9, 5],
708          *                 [5, 3, 8],
709          *                 [6, 10, 11],
710          *                 [2, 3, 10],
711          *                 [2, 10, 6],
712          *                 [8, 3, 2],
713          *                 [3, 4, 10],
714          *                 [7, 8, 2],
715          *                 [9, 8, 7],
716          *                 [0, 9, 7],
717          *                 [4, 3, 5],
718          *                 [5, 1, 4],
719          *                 [0, 7, 6],
720          *                 [7, 2, 6]
721          *             ];
722          *             var ico = view.create('polyhedron3d', [vertexList, faceArray], {
723          *                 fillColorArray: [],
724          *                 fillOpacity: 1,
725          *                 strokeWidth: 0.1,
726          *                 layer: 12,
727          *                 shader: {
728          *                     enabled: true,
729          *                     type: 'angle',
730          *                     hue: 0,
731          *                     saturation: 90,
732          *                     minlightness: 60,
733          *                     maxLightness: 80
734          *                 }
735          *             });
736          *
737          *     })();
738          *
739          * </script><pre>
740          *
741          */
742         shader: {
743             enabled: false,
744             fixed: true,    // If false, update shading during rotation of viewport
745             type: 'angle',  // 'angle', otherwise zIndex
746             hue: 60,        // yellow
747             saturation: 90,
748             minLightness: 30,
749             maxLightness: 90,
750 
751             light: {
752                 type: 1,// 1: lighting==camera,
753                         // 2: Fixed: angle(light, object),
754                         // 3: Fixed: angle(light, camera) (default)
755                 az: -45, // TODO use radians, ignored for type==1
756                 el: 20,  // TODO use radians, ignored for type==1
757                 bank: 0, // TODO use radians, ignored for type==1, type==3
758                 dir: -1  // -1, 0 (use abs), 1: Default: -1
759             }
760         }
761 
762         /**#@-*/
763     },
764 
765     intersectionline3d: {
766         point1: { visible: false, name: "" }, // Used in point/point
767         point2: { visible: false, name: "" }
768     },
769 
770     line3d: {
771         /**#@+
772          * @visprop
773          */
774 
775         layer: 12,
776         strokeWidth: 1,
777         strokeColor: "black",
778         fixed: true,
779         tabindex: null,
780         // gradient: "linear",
781         // gradientSecondColor: "#ffffff",
782         needsRegularUpdate: true,
783 
784         /**
785          * Attributes of the defining point in case the line is defined by [point, vector, [range]]
786          * @type Point3D
787          * @name Line3D#point
788          * @default <pre>visible: false, name: ""</pre>
789          */
790         point: { visible: false, name: "" }, // Used in cases of point/direction/range
791 
792         /**
793          * Attributes of the first point in case the line is defined by [point, point].
794          * @type Point3D
795          * @name Line3D#point1
796          * @default <pre>visible: false, name: ""</pre>
797          */
798         point1: { visible: false, name: "" }, // Used in point/point
799 
800         /**
801          * Attributes of the second point in case the line is defined by [point, point].
802          * @type Point3D
803          * @name Line3D#point2
804          * @default <pre>visible: false, name: ""</pre>
805          */
806         point2: { visible: false, name: "" },
807 
808         /**
809          * If the 3D line is defined by two points and if this attribute is true,
810          * the 3D line stretches infinitely in direction of its first point.
811          * Otherwise it ends at point1.
812          *
813          * @name Line3D#straightFirst
814          * @see Line3D#straightLast
815          * @type Boolean
816          * @default false
817          */
818         straightFirst: false,
819 
820 
821         /**
822          * If the 3D line is defined by two points and if this attribute is true,
823          * the 3D line stretches infinitely in direction of its second point.
824          * Otherwise it ends at point2.
825          *
826          * @name Line3D#straightLast
827          * @see Line3D#straightFirst
828          * @type Boolean
829          * @default false
830          */
831         straightLast: false
832 
833         /**#@-*/
834     },
835 
836     mesh3d: {
837         /**#@+
838          * @visprop
839          */
840 
841         layer: 12,
842         strokeWidth: 1,
843         strokeColor: "#9a9a9a",
844         strokeOpacity: 0.6,
845         highlight: false,
846         tabindex: null,
847         needsRegularUpdate: true,
848 
849         /**
850          * Step width of the mesh in the direction of the first spanning vector.
851          * @type {Number}
852          * @name Mesh3D#stepWidthU
853          * @default 1
854          *
855          */
856         stepWidthU: 1,
857 
858         /**
859          * Step width of the mesh in the direction of the second spanning vector.
860          *
861          * @type {Number}
862          * @name Mesh3D#stepWidthV
863          * @default 1
864          *
865          */
866         stepWidthV: 1
867 
868         /**#@-*/
869     },
870 
871     plane3d: {
872         /**#@+
873          * @visprop
874          */
875 
876         layer: 12,
877         strokeWidth: 1,
878         strokeColor: "black",
879         strokeOpacity: 1,
880         highlight: false,
881         tabindex: null,
882         needsRegularUpdate: true,
883         visible: true,
884 
885         gradient: "linear",
886         gradientSecondColor: "#ffffff",
887         gradientAngle: Math.PI,
888         fillColor: "#bbbbbb",
889         fillOpacity: 0.3,
890 
891         type: 'shader', // 'wireframe', 'shader', 'colormap', 'colorarray'
892         tiling: 'rectangle', // 'triangle', 'rectangle'
893 
894         /**
895          * Optional 3D mesh of a finite plane.
896          * It is not available if the plane is infinite (at initialization time) in any direction.
897          *
898          * @type Mesh3D
899          * @name Plane3D#mesh3d
900          * @default see {@link Mesh3D}
901          */
902         mesh3d: {
903             visible: 'inherit'
904         },
905 
906         stepsU: 6,
907         stepsV: 6,
908         polyhedron: {
909             layer: 12,
910             visible: 'inherit',
911             strokeWidth: 0.4,
912             strokeOpacity: 0.7,
913             strokeColor: '#cccccc',
914             fillOpacity: 0.30,
915             // fillColorArray: ['none', '#e7e7e7']
916             fillColorArray: ['#e7e7e7']
917         },
918 
919         /**
920          * If the second parameter and the third parameter are given as arrays or functions and threePoints:true
921          * then the second and third parameter are interpreted as point coordinates and not as directions, i.e.
922          * the plane is defined by three points.
923          *
924          * @name Plane3D#threePoints
925          * @type Boolean
926          * @default false
927          */
928         threePoints: false,
929 
930         /**
931          * Attributes of the defining point in case the plane is defined by [point, direction1, direction2, [range1, [range2]]].
932          * @type Point3D
933          * @name Plane3D#point
934          * @default <pre>visible: false, name: "", fixed: true</pre>
935          */
936         point: { visible: false, name: "", fixed: true },
937 
938         /**
939          * Attributes of the first point in case the plane is defined by [point, point, point].
940          * @type Point3D
941          * @name Plane3D#point1
942          * @default <pre>visible: false, name: ""</pre>
943          */
944         point1: { visible: false, name: "" }, // Used in point/point/point
945 
946         /**
947          * Attributes of the second point in case the plane is defined by [point, point, point].
948          * @type Point3D
949          * @name Plane3D#point2
950          * @default <pre>visible: false, name: ""</pre>
951          */
952         point2: { visible: false, name: "" }, // Used in point/point/point
953 
954         /**
955          * Attributes of the third point in case the plane is defined by [point, point, point].
956          * @type Point3D
957          * @name Plane3D#point3
958          * @default <pre>visible: false, name: ""</pre>
959          */
960         point3: { visible: false, name: "" } // Used in point/point/point
961 
962         /**#@-*/
963     },
964 
965     point3d: {
966         layer: 13,
967         infoboxDigits: "auto",
968         strokeWidth: 0,
969         gradient: "radial",
970         gradientSecondColor: "#555555",
971         fillColor: "yellow",
972         highlightStrokeColor: "#555555",
973         gradientFX: 0.7,
974         gradientFY: 0.3,
975         needsRegularUpdate: true,
976 
977         /**
978          * If the point is bound to another  element ("glides" on that element)
979          * and if the bound reaches the boundary, the point may start cyclically
980          * at the ozher side of the boundary - like one expects from a glider on a sphere.
981          * For this, set cyclic to true.
982          * @type Boolean
983          * @name Point3D#cyclic
984          * @default false
985          */
986         cyclic: false
987     },
988 
989     polygon3d: {
990         /**#@+
991          * @visprop
992          */
993 
994         layer: 12,
995         highlight: false,
996         tabindex: -1,
997         strokeWidth: 1,
998         fillColor: 'none',
999         needsRegularUpdate: true
1000 
1001 
1002         /**#@-*/
1003     },
1004 
1005     polyhedron3d: {
1006         /**#@+
1007          * @visprop
1008          */
1009 
1010         /**
1011          * Color array to define fill colors of faces cyclically.
1012          * Alternatively, the fill color can be defined for each face individually.
1013          *
1014          * @type Array
1015          * @name Polyhedron3D#fillColorArray
1016          * @default ['white', 'black']
1017          */
1018         fillColorArray: ['white', 'black'],
1019 
1020         needsRegularUpdate: true
1021 
1022         /**#@-*/
1023     },
1024 
1025     sphere3d: {
1026         /**#@+
1027          * @visprop
1028          */
1029 
1030         layer: 12,
1031         highlight: false,
1032 
1033         strokeWidth: 1,
1034         strokeColor: '#00ff80',
1035         fillColor: 'white',
1036         gradient: 'radial',
1037         gradientSecondColor: '#00ff80',
1038         gradientFX: 0.7,
1039         gradientFY: 0.3,
1040         fillOpacity: 0.4,
1041         needsRegularUpdate: true
1042 
1043         /**#@-*/
1044     },
1045 
1046     surface3d: {
1047         /**#@+
1048          * @visprop
1049          */
1050 
1051         visible: true,
1052         layer: 12,
1053         highlight: false,
1054         tabindex: -1,
1055 
1056         /**
1057          * Description of how the mesh is visualized. Possible values are 'wireframe', 'rectangle', 'triangle'.
1058          * In case of `tiling:'wireframe'`, a rectangular mesh is displayed, the number of steps is determined by
1059          * the attributes `stepsU` and `stepsV`. Further, the attributes `strokeWidth` and `strokeColor`, ...
1060          * determine the style of the mesh.
1061          * <p>
1062          * In case of `tiling:'triangle'` or `tiling:'rectangle'` a polyhedron3d element is displayed, using the
1063          * attributes `stepsU` and `stepsV`. In case of `triangle`, equilateral triangles are created if stepsV==0.
1064          * <p>
1065          * All other attributes of the polyhedron3d have to be set inside of `polyhedron`, including `strokeWidth`
1066          * and `strokeColor`. The wireframe settings for these attributes are ignored.
1067          * <p>
1068          * At the time being (v1.13+), this attribute is immutable.
1069          *
1070          * @type String
1071          * @name ParametricSurface3D#tiling
1072          * @default 'wireframe'
1073          * @see ParametricSurface3D#polyhedron
1074          *
1075          * @example
1076          *
1077          * var view = board.create('view3d',
1078          *     [
1079          *         [-6, -3], [8, 8],
1080          *         [[-5, 5], [-5, 5], [-5, 5]]
1081          *     ],
1082          *     {
1083          *         xPlaneRear: {visible: false},
1084          *         yPlaneRear: {visible: false},
1085          *     });
1086          *
1087          * // Function F to be plotted
1088          * var F = (x, y) => Math.cos(x * y / 4);
1089          *
1090          * // 3D surface
1091          * var c = view.create('functiongraph3d', [
1092          *     F,
1093          *     [-5, 5],
1094          *     [-5, 5],
1095          * ], {
1096          *     strokeWidth: 0.5,
1097          *     stepsU: 70,
1098          *     stepsV: 70,
1099          *     tiling:'wireframe'
1100          * });
1101          *
1102          * </pre><div id="JXG87646dd4-9fe5-4c21-8734-089abc612515" class="jxgbox" style="width: 500px; height: 500px;"></div>
1103          * <script type="text/javascript">
1104          *     (function() {
1105          *         var board = JXG.JSXGraph.initBoard('JXG87646dd4-9fe5-4c21-8734-089abc612515',
1106          *             {boundingbox: [-8, 8, 8,-8], axis: false, pan: {enabled: false}, showcopyright: false, shownavigation: false});
1107          *     var box = [-5, 5];
1108          *     var view = board.create('view3d',
1109          *         [
1110          *             [-6, -3], [8, 8],
1111          *             [box, box, box]
1112          *         ],
1113          *         {
1114          *             xPlaneRear: {visible: false},
1115          *             yPlaneRear: {visible: false},
1116          *         });
1117          *
1118          *     // Function F to be plotted
1119          *     var F = (x, y) => Math.cos(x * y / 4);
1120          *
1121          *     // 3D surface
1122          *     var c = view.create('functiongraph3d', [
1123          *         F,
1124          *         box,
1125          *         box
1126          *     ], {
1127          *         strokeWidth: 0.5,
1128          *         stepsU: 50,
1129          *         stepsV: 50,
1130          *         tiling: 'wireframe'
1131          *     });
1132          *     })();
1133          *
1134          * </script><pre>
1135          *
1136          * @example
1137          *
1138          * var view = board.create('view3d',
1139          *     [
1140          *         [-6, -3], [8, 8],
1141          *         [[-5, 5], [-5, 5], [-5, 5]]
1142          *     ],
1143          *     {
1144          *         xPlaneRear: {visible: false},
1145          *         yPlaneRear: {visible: false},
1146          *     });
1147          *
1148          * // Function F to be plotted
1149          * var F = (x, y) => Math.cos(x * y / 4);
1150          *
1151          * // 3D surface
1152          * var c = view.create('functiongraph3d', [
1153          *     F,
1154          *     [-5, 5],
1155          *     [-5, 5],
1156          * ], {
1157          *     stepsU: 15,
1158          *     stepsV: 15,
1159          *     tiling:'triangle'
1160          * });
1161          *
1162          * </pre><div id="JXG6591ae99-1319-4cd7-b035-465484ad27d2" class="jxgbox" style="width: 500px; height: 500px;"></div>
1163          * <script type="text/javascript">
1164          *     (function() {
1165          *         var board = JXG.JSXGraph.initBoard('JXG6591ae99-1319-4cd7-b035-465484ad27d2',
1166          *             {boundingbox: [-8, 8, 8,-8], axis: false, pan: {enabled: false}, showcopyright: false, shownavigation: false});
1167          *     var box = [-5, 5];
1168          *     var view = board.create('view3d',
1169          *         [
1170          *             [-6, -3], [8, 8],
1171          *             [box, box, box]
1172          *         ],
1173          *         {
1174          *             xPlaneRear: {visible: false},
1175          *             yPlaneRear: {visible: false},
1176          *         });
1177          *
1178          *     // Function F to be plotted
1179          *     var F = (x, y) => Math.cos(x * y / 4);
1180          *
1181          *     // 3D surface
1182          *     var c = view.create('functiongraph3d', [
1183          *         F,
1184          *         box,
1185          *         box
1186          *     ], {
1187          *         stepsU: 15,
1188          *         stepsV: 15,
1189          *         tiling: 'triangle'
1190          *     });
1191          *     })();
1192          *
1193          * </script><pre>
1194          *
1195          * @example
1196          *
1197          * var view = board.create('view3d',
1198          *     [
1199          *         [-6, -3], [8, 8],
1200          *         [[-5, 5], [-5, 5], [-5, 5]]
1201          *     ],
1202          *     {
1203          *         xPlaneRear: {visible: false},
1204          *         yPlaneRear: {visible: false},
1205          *     });
1206          *
1207          * // Function F to be plotted
1208          * var F = (x, y) => Math.cos(x * y / 4);
1209          *
1210          * // 3D surface
1211          * var c = view.create('functiongraph3d', [
1212          *     F,
1213          *     [-5, 5],
1214          *     [-5, 5],
1215          * ], {
1216          *     stepsU: 15,
1217          *     stepsV: 15,
1218          *     tiling: 'rectangle'
1219          * });
1220          *
1221          * </pre><div id="JXG6bebc69d-95fd-4923-9689-29461bb21471" class="jxgbox" style="width: 500px; height: 500px;"></div>
1222          * <script type="text/javascript">
1223          *     (function() {
1224          *         var board = JXG.JSXGraph.initBoard('JXG6bebc69d-95fd-4923-9689-29461bb21471',
1225          *             {boundingbox: [-8, 8, 8,-8], axis: false, pan: {enabled: false}, showcopyright: false, shownavigation: false});
1226          *     var box = [-5, 5];
1227          *     var view = board.create('view3d',
1228          *         [
1229          *             [-6, -3], [8, 8],
1230          *             [box, box, box]
1231          *         ],
1232          *         {
1233          *             xPlaneRear: {visible: false},
1234          *             yPlaneRear: {visible: false},
1235          *         });
1236          *
1237          *     // Function F to be plotted
1238          *     var F = (x, y) => Math.cos(x * y / 4);
1239          *
1240          *     // 3D surface
1241          *     var c = view.create('functiongraph3d', [
1242          *         F,
1243          *         box,
1244          *         box
1245          *     ], {
1246          *         stepsU: 15,
1247          *         stepsV: 15,
1248          *         tiling: 'rectangle'
1249          *     });
1250          *     })();
1251          *
1252          * </script><pre>
1253          */
1254         type: 'wireframe', // 'colormap', 'shader', 'colorarray'
1255         tiling: 'rectangle', // 'triangle'
1256 
1257         // Wireframe
1258         strokeWidth: 0.75,
1259         // --- end wireframe
1260 
1261         /**
1262          * HSV color range for colormap. Supply lower bound [z_min, hue_min] on z-value and corresponding hue value, as well
1263          * as upper bound [z_max, hue_max] on z-value and corresponding hue value. Further, give constant values for
1264          * "saturation" and "value" of HSV.
1265          *
1266          * @type {object}
1267          * @name ParametricSurface3D#colormap
1268          * @default <pre>{
1269          *   min: [-5, 190],
1270          *   max: [5, 0],
1271          *   s: 0.9,
1272          *   v: 0.9
1273          * }</pre>
1274          */
1275         colormap: {
1276             min: [-5, 190],
1277             max: [5, 0],
1278             s: 0.9,
1279             v: 0.9
1280         },
1281 
1282         /**
1283          * Attributes for the polyhedron3d in case `style='triangle'` or `style='rectangle'`.
1284          * Specifications are e.g.
1285          * <ul>
1286          *  <li>strokewidth: 0
1287          *  <li>fillColorArray: ['white', JXG.palette.blue]
1288          * </ul>
1289          * @type {object}
1290          * @name ParametricSurface3D#polyhedron
1291          * @default <pre>{strokewidth: 0, fillColorArray: ['white', 'black'] }</pre>
1292          * @see ParametricSurface3D#style
1293          *
1294          * @example
1295          * var F = (x, y) => Math.cos(x * y / 4);
1296          *
1297          * var view = board.create('view3d', [
1298          *    [-6, -3], [8, 8],
1299          *    [[-5, 5], [-5, 5], [-5, 5]]
1300          *  ], {
1301          *    xPlaneRear: {visible: false},
1302          *    yPlaneRear: {visible: false},
1303          *    depthOrder: {enabled: true}
1304          *  });
1305          *
1306          * // 3D surface
1307          * var c = view.create('functiongraph3d', [F, [-5, 5], [-5, 5]], {
1308          *    strokeWidth: 1, // ignored
1309          *    stepsU: 10,
1310          *    stepsV: 10,
1311          *    tiling: 'triangle',
1312          *    polyhedron: {
1313          *        strokeWidth: 0, // has priority
1314          *        fillOpacity: 0.9,
1315          *        shader: {
1316          *            enabled: true,
1317          *            hue: 20,
1318          *            saturation: 90,
1319          *            minlightness: 50,
1320          *            maxLightness: 80
1321          *        }
1322          *    }
1323          * });
1324          *
1325          * </pre><div id="JXG8123a727-adef-4c10-83e6-d4f5e2203f68" class="jxgbox" style="width: 300px; height: 300px;"></div>
1326          * <script type="text/javascript">
1327          *     (function() {
1328          *         var board = JXG.JSXGraph.initBoard('JXG8123a727-adef-4c10-83e6-d4f5e2203f68',
1329          *             {boundingbox: [-8, 8, 8,-8], axis: false, pan: {enabled: false}, showcopyright: false, shownavigation: false});
1330          *
1331          *     var F = (x, y) => Math.cos(x * y / 4);
1332          *     var box = [-5, 5];
1333          *     var view = board.create('view3d',
1334          *      [
1335          *      [-6, -3], [8, 8],
1336          *      [box, box, box]
1337          *            ],
1338          *             {
1339          *               xPlaneRear: {visible: false},
1340          *               yPlaneRear: {visible: false},
1341          *               depthOrder: {enabled: true}
1342          *     });
1343          *
1344          *     // 3D surface
1345          *     var c = view.create('functiongraph3d', [F, box, box], {
1346          *       strokeWidth: 0.5,
1347          *       stepsU: 10,
1348          *       stepsV: 10,
1349          *       tiling: 'triangle',
1350          *       polyhedron: {
1351          *           strokeWidth: 0,
1352          *           fillOpacity: 0.9,
1353          *           shader: {
1354          *               enabled: true,
1355          *               hue: 20,
1356          *               saturation: 90,
1357          *               minlightness: 50,
1358          *               maxLightness: 80
1359          *           }
1360          *       }
1361          *     });
1362          *
1363          *     })();
1364          *
1365          * </script><pre>
1366          *
1367          * @example
1368          *
1369          * var view = board.create('view3d',
1370          *     [
1371          *         [-6, -3], [8, 8],
1372          *         [[-5, 5], [-5, 5], [-5, 5]]
1373          *     ], {
1374          *         xPlaneRear: {visible: false},
1375          *         yPlaneRear: {visible: false}
1376          *     });
1377          *
1378          * // Function F to be plotted
1379          * var F = (x, y) => y - x;
1380          *
1381          * // 3D surface
1382          * var c = view.create('functiongraph3d', [F, [-5, 5], [-5, 5]], {
1383          *     stepsU: 9,
1384          *     stepsV: 9,
1385          *     tiling: 'rectangle'
1386          * });
1387          *
1388          * </pre><div id="JXG87646dd4-9fe5-4c21-8734-089abc612519" class="jxgbox" style="width: 500px; height: 500px;"></div>
1389          * <script type="text/javascript">
1390          *     (function() {
1391          *         var board = JXG.JSXGraph.initBoard('JXG87646dd4-9fe5-4c21-8734-089abc612519',
1392          *             {boundingbox: [-8, 8, 8,-8], axis: false, pan: {enabled: false}, showcopyright: false, shownavigation: false});
1393          *     var box = [-5, 5];
1394          *     var view = board.create('view3d',
1395          *         [
1396          *             [-6, -3], [8, 8],
1397          *             [box, box, box]
1398          *         ], {
1399          *             xPlaneRear: {visible: false},
1400          *             yPlaneRear: {visible: false}
1401          *         });
1402          *
1403          *     // Function F to be plotted
1404          *     var F = (x, y) => y - x;
1405          *
1406          *     // 3D surface
1407          *     var c = view.create('functiongraph3d', [F, box, box], {
1408          *         stepsU: 9,
1409          *         stepsV: 9,
1410          *         tiling: 'rectangle'
1411          *     });
1412          *     })();
1413          * </script><pre>
1414          */
1415         polyhedron: {
1416             visible: 'inherit',
1417             strokeWidth: 0.1,
1418             fillOpacity: 0.8,
1419             fillColorArray: ['white', JXG.palette.blue],
1420             shader: {
1421                 enabled: false,
1422                 fixed: true,
1423                 hue: 60,     // yellow
1424                 saturation: 90,
1425                 minLightness: 55,
1426                 maxLightness: 90,
1427 
1428                 light: {
1429                     dir: -1
1430                 }
1431             }
1432         },
1433 
1434         /**
1435          * Number of intervals the mesh is divided into in direction of parameter u.
1436          * If stepsU = 0 and type is 'wireframe' a 3D wireframe plot in one direction is created.
1437          * @type Number
1438          * @name ParametricSurface3D#stepsU
1439          */
1440         stepsU: 30,
1441 
1442         /**
1443          * Number of intervals the mesh is divided into in direction of parameter v.
1444          * If stepsV = 0 and type is 'wireframe' a 3D wireframe plot in one direction is created.
1445          * @type Number
1446          * @name ParametricSurface3D#stepsV
1447          */
1448         stepsV: 30,
1449 
1450         needsRegularUpdate: true
1451 
1452         /**#@-*/
1453     },
1454 
1455     text3d: {
1456         /**#@+
1457          * @visprop
1458          */
1459 
1460         withLabel: false,
1461         needsRegularUpdate: true
1462 
1463         /**#@-*/
1464     },
1465 
1466     ticks3d: {
1467         /**#@+
1468          * @visprop
1469          */
1470 
1471         visible: true,
1472 
1473         ticksDistance: 1,
1474         majorHeight: 10,
1475         minorTicks: 0,
1476         tickEndings: [0, 1],
1477         drawLabels: true,
1478         needsRegularUpdate: true,
1479 
1480         label: {
1481             visible: true,
1482             withLabel: false
1483         }
1484 
1485         /**#@-*/
1486     },
1487 
1488     vectorfield3d: {
1489         /**#@+
1490          * @visprop
1491          */
1492 
1493         /**
1494          * Scaling factor of the vectors. This in contrast to slope fields, where this attribute sets the vector to the given length.
1495          * @name scale
1496          * @memberOf Vectorfield3D.prototype
1497          * @type {Number|Function}
1498          * @see Slopefield.scale
1499          * @default 1
1500          */
1501         scale: 1,
1502 
1503         /**
1504          * Customize arrow heads of vectors. Be careful! If enabled this will slow down the performance.
1505          * Fields are:
1506          * <ul>
1507          *  <li> enabled: Boolean
1508          *  <li> size: length of the arrow head legs (in pixel)
1509          *  <li> angle: angle of the arrow head legs In radians.
1510          * </ul>
1511          * @name arrowhead
1512          * @memberOf Vectorfield3D.prototype
1513          * @type {Object}
1514          * @default <tt>{enabled: true, size: 5, angle: Math.PI * 0.125}</tt>
1515          */
1516         arrowhead: {
1517             enabled: true,
1518             size: 5,
1519             angle: Math.PI * 0.125
1520         },
1521         needsRegularUpdate: true
1522 
1523         /**#@-*/
1524     },
1525 
1526     view3d: {
1527         /**#@+
1528          * @visprop
1529          */
1530 
1531         needsRegularUpdate: true,
1532 
1533         /**
1534          * When this attribute is enabled, elements closer to the screen are drawn
1535          * over elements further from the screen within the 3D layer. This affects
1536          * all elements which are in one of the layer specified in the sub-attribute 'layers'.
1537          * <p>
1538          * For each layer this depth ordering is done independently.
1539          * Sub-attributes:
1540          *      <ul>
1541          *          <li><tt>enabled</tt>: false/true
1542          *          <li><tt>layers</tt>: [12, 13]
1543          *      </ul>
1544          *
1545          * @name View3D#depthOrder
1546          * @type Object
1547          * @default <pre>{
1548          *   enabled: false,
1549          *   layers: [12, 13]
1550          * }
1551          * </pre>
1552          */
1553         depthOrder: {
1554             enabled: true,
1555             layers: [12, 13]
1556         },
1557 
1558         /**
1559          * Choose the projection type to be used: `parallel` or `central`.
1560          * <ul>
1561          * <li> `parallel` is parallel projection, also called orthographic projection
1562          * <li> `central` is central projection, also called perspective projection
1563          * </ul>
1564          *
1565          *
1566          * @name View3D#projection
1567          * @type String
1568          * @default 'parallel'
1569          * @example
1570          *         var bound = [-5, 5];
1571          *         var view = board.create('view3d',
1572          *             [[-6, -3], [8, 8],
1573          *             [bound, bound, bound]],
1574          *             {
1575          *                 projection: 'parallel'
1576          *             });
1577          *
1578          * </pre><div id="JXG80d81b13-c604-4841-bdf6-62996440088a" class="jxgbox" style="width: 300px; height: 300px;"></div>
1579          * <script type="text/javascript">
1580          *     (function() {
1581          *         var board = JXG.JSXGraph.initBoard('JXG80d81b13-c604-4841-bdf6-62996440088a',
1582          *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});
1583          *             var bound = [-5, 5];
1584          *             var view = board.create('view3d',
1585          *                 [[-6, -3], [8, 8],
1586          *                 [bound, bound, bound]],
1587          *                 {
1588          *                     projection: 'parallel'
1589          *                 });
1590          *
1591          *     })();
1592          *
1593          * </script><pre>
1594          *
1595          * @example
1596          *         var bound = [-5, 5];
1597          *         var view = board.create('view3d',
1598          *             [[-6, -3], [8, 8],
1599          *             [bound, bound, bound]],
1600          *             {
1601          *                 projection: 'central'
1602          *             });
1603          *
1604          * </pre><div id="JXGdb7b7c99-631c-41d0-99bf-c0a8d0138218" class="jxgbox" style="width: 300px; height: 300px;"></div>
1605          * <script type="text/javascript">
1606          *     (function() {
1607          *         var board = JXG.JSXGraph.initBoard('JXGdb7b7c99-631c-41d0-99bf-c0a8d0138218',
1608          *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});
1609          *             var bound = [-5, 5];
1610          *             var view = board.create('view3d',
1611          *                 [[-6, -3], [8, 8],
1612          *                 [bound, bound, bound]],
1613          *                 {
1614          *                     projection: 'central'
1615          *                 });
1616          *     })();
1617          *
1618          * </script><pre>
1619          *
1620          */
1621         projection: 'parallel',
1622 
1623         /**
1624          * Allow vertical dragging of objects, i.e. in direction of the z-axis.
1625          * Subobjects are
1626          * <ul>
1627          *  <li>enabled: true
1628          *  <li>key: 'shift'
1629          * </ul>
1630          * <p>
1631          * Possible values for attribute <i>key</i>: 'shift' or 'ctrl'.
1632          *
1633          * @name View3D#verticalDrag
1634          * @type Object
1635          * @default <tt>{enabled: true, key: 'shift'}</tt>
1636          */
1637         verticalDrag: {
1638             enabled: true,
1639             key: 'shift'
1640         },
1641 
1642         /**
1643          * Specify the user handling of the azimuth.
1644          * <ul>
1645          *  <li><tt>pointer</tt> sub-attributes:
1646          *      <ul>
1647          *          <li><tt>enabled</tt>: Boolean that specifies whether pointer navigation is allowed by azimuth.
1648          *          <li><tt>speed</tt>: Number indicating how many passes the range of the az_slider makes when the cursor crosses the entire board once in the horizontal direction.
1649          *          <li><tt>outside</tt>: Boolean that specifies whether the pointer navigation is continued when the cursor leaves the board.
1650          *          <li><tt>button</tt>: Which button of the pointer should be used? (<tt>'-1'</tt> (=no button), <tt>'0'</tt> or <tt>'2'</tt>)
1651          *          <li><tt>key</tt>: Should an additional key be pressed? (<tt>'none'</tt>, <tt>'shift'</tt> or <tt>'ctrl'</tt>)
1652          *      </ul>
1653          *  <li><tt>keyboard</tt> sub-attributes:
1654          *      <ul>
1655          *          <li><tt>enabled</tt>: Boolean that specifies whether the keyboard (left/right arrow keys) can be used to navigate the board.
1656          *          <li><tt>step</tt>: Size of the step per keystroke.
1657          *          <li><tt>key</tt>: Should an additional key be pressed? (<tt>'none'</tt>, <tt>'shift'</tt> or <tt>'ctrl'</tt>)
1658          *      </ul>
1659          *  <li><tt>continuous</tt>: Boolean that specifies whether the az_slider starts again from the beginning when its end is reached.
1660          *  <li><tt>slider</tt> attributes of the az_slider ({@link Slider}) with additional
1661          *      <ul>
1662          *          <li><tt>min</tt>: Minimum value.
1663          *          <li><tt>max</tt>: Maximum value.
1664          *          <li><tt>start</tt>: Start value.
1665          *      </ul>
1666          *      'min' and 'max' are used only if trackball is not enabled.
1667          *     Additionally, the attributes 'slider.point1.pos' and 'slider.point2.pos' control the position of the slider. Possible
1668          *     values are 'auto' or an array [x, y] of length 2 for the position in user coordinates (or a function returning such an array).
1669          * </ul>
1670          *
1671          * @name View3D#az
1672          * @type Object
1673          * @default <pre>{
1674          *      pointer: {enabled: true, speed: 1, outside: true, button: -1, key: 'none'},
1675          *      keyboard: {enabled: true, step: 10, key: 'ctrl'},
1676          *      continuous: true,
1677          *      slider: {
1678          *          visible: true,
1679          *          style: 6,
1680          *          point1: {
1681          *              pos: 'auto',
1682          *              frozen: false
1683          *          },
1684          *          point2: {
1685          *              pos: 'auto',
1686          *              frozen: false
1687          *          },
1688          *          min: 0,
1689          *          max: 2 * Math.PI,
1690          *          start: 1.0
1691          *      },
1692          * }</pre>
1693          *
1694          * @example
1695          *     var bound = [-4, 6];
1696          *     var view = board.create('view3d',
1697          *         [[-4, -3], [8, 8],
1698          *         [bound, bound, bound]],
1699          *         {
1700          *             projection: 'parallel',
1701          *             az: {
1702          *                 slider: {visible: true, start: 0.75 * Math.PI}
1703          *             }
1704          *         });
1705          *
1706          * </pre><div id="JXG4c381f21-f043-4419-941d-75f384c026d0" class="jxgbox" style="width: 300px; height: 300px;"></div>
1707          * <script type="text/javascript">
1708          *     (function() {
1709          *         var board = JXG.JSXGraph.initBoard('JXG4c381f21-f043-4419-941d-75f384c026d0',
1710          *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});
1711          *         var bound = [-4, 6];
1712          *         var view = board.create('view3d',
1713          *             [[-4, -3], [8, 8],
1714          *             [bound, bound, bound]],
1715          *             {
1716          *                 projection: 'parallel',
1717          *                 az: {
1718          *                     slider: {visible: true, start: 0.75 * Math.PI}
1719          *                 }
1720          *             });
1721          *
1722          *     })();
1723          *
1724          * </script><pre>
1725          *
1726          */
1727         az: {
1728             pointer: {
1729                 enabled: true,
1730                 speed: 1,
1731                 outside: true,
1732                 button: -1,
1733                 key: 'none'
1734             },
1735             keyboard: {
1736                 enabled: true,
1737                 step: 10,
1738                 key: 'ctrl'
1739             },
1740             continuous: true,
1741             slider: {
1742                 visible: 'inherit',
1743                 style: 6,
1744                 point1: {
1745                     pos: 'auto',
1746                     frozen: false
1747                 },
1748                 point2: {
1749                     pos: 'auto',
1750                     frozen: false
1751                 },
1752                 min: 0,
1753                 max: 2 * Math.PI,
1754                 start: 1.0
1755             }
1756         },
1757 
1758         /**
1759          * Specify the user handling of the elevation.
1760          * <ul>
1761          *  <li><tt>pointer</tt> sub-attributes:
1762          *      <ul>
1763          *          <li><tt>enabled</tt>: Boolean that specifies whether pointer navigation is allowed by elevation.
1764          *          <li><tt>speed</tt>: Number indicating how many passes the range of the el_slider makes when the cursor crosses the entire board once in the horizontal direction.
1765          *          <li><tt>outside</tt>: Boolean that specifies whether the pointer navigation is continued when the cursor leaves the board.
1766          *          <li><tt>button</tt>: Which button of the pointer should be used? (<tt>'-1'</tt> (=no button), <tt>'0'</tt> or <tt>'2'</tt>)
1767          *          <li><tt>key</tt>: Should an additional key be pressed? (<tt>'none'</tt>, <tt>'shift'</tt> or <tt>'ctrl'</tt>)
1768          *      </ul>
1769          *  <li><tt>keyboard</tt> sub-attributes:
1770          *      <ul>
1771          *          <li><tt>enabled</tt>: Boolean that specifies whether the keyboard (up/down arrow keys) can be used to navigate the board.
1772          *          <li><tt>step</tt>: Size of the step per keystroke.
1773          *          <li><tt>key</tt>: Should an additional key be pressed? (<tt>'none'</tt>, <tt>'shift'</tt> or <tt>'ctrl'</tt>)
1774          *      </ul>
1775          *  <li><tt>continuous</tt>: Boolean that specifies whether the el_slider starts again from the beginning when its end is reached.
1776          *  <li><tt>slider</tt> attributes of the el_slider ({@link Slider}) with additional
1777          *      <ul>
1778          *          <li><tt>min</tt>: Minimum value.
1779          *          <li><tt>max</tt>: Maximum value.
1780          *          <li><tt>start</tt>: Start value.
1781          *      </ul>
1782          *     'min' and 'max' are used only if trackball is not enabled.
1783          *     Additionally, the attributes 'slider.point1.pos' and 'slider.point2.pos' control the position of the slider. Possible
1784          *     values are 'auto' or an array [x, y] of length 2 for the position in user coordinates (or a function returning such an array).
1785          * </ul>
1786          *
1787          * @name View3D#el
1788          * @type Object
1789          * @default <pre>{
1790          *      pointer: {enabled: true, speed: 1, outside: true, button: -1, key: 'none'},
1791          *      keyboard: {enabled: true, step: 10, key: 'ctrl'},
1792          *      continuous: true,
1793          *      slider: {
1794          *          visible: true,
1795          *          style: 6,
1796          *          point1: {
1797          *              pos: 'auto',
1798          *              frozen: false
1799          *          },
1800          *          point2: {
1801          *              pos: 'auto',
1802          *              frozen: false
1803          *          },
1804          *          min: 0,
1805          *          max: 2 * Math.PI,
1806          *          start: 0.3
1807          *      },
1808          * }<pre>
1809          * @example
1810          *     var bound = [-4, 6];
1811          *     var view = board.create('view3d',
1812          *         [[-4, -3], [8, 8],
1813          *         [bound, bound, bound]],
1814          *         {
1815          *             projection: 'parallel',
1816          *             el: {
1817          *                 slider: {visible: true}
1818          *             }
1819          *         });
1820          *
1821          * </pre><div id="JXG8926f733-c42e-466b-853c-74feb795e879" class="jxgbox" style="width: 300px; height: 300px;"></div>
1822          * <script type="text/javascript">
1823          *     (function() {
1824          *         var board = JXG.JSXGraph.initBoard('JXG8926f733-c42e-466b-853c-74feb795e879',
1825          *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});
1826          *         var bound = [-4, 6];
1827          *         var view = board.create('view3d',
1828          *             [[-4, -3], [8, 8],
1829          *             [bound, bound, bound]],
1830          *             {
1831          *                 projection: 'parallel',
1832          *                 el: {
1833          *                     slider: {visible: true}
1834          *                 }
1835          *             });
1836          *
1837          *     })();
1838          *
1839          * </script><pre>
1840          *
1841          */
1842         el: {
1843             pointer: {
1844                 enabled: true,
1845                 speed: 1,
1846                 outside: true,
1847                 button: -1,
1848                 key: 'none'
1849             },
1850             keyboard: {
1851                 enabled: true,
1852                 step: 10,
1853                 key: 'ctrl'
1854             },
1855             continuous: true,
1856             slider: {
1857                 visible: 'inherit',
1858                 style: 6,
1859                 point1: {
1860                     frozen: false,
1861                     pos: 'auto'
1862                 },
1863                 point2: {
1864                     frozen: false,
1865                     pos: 'auto'
1866                 },
1867                 min: 0,
1868                 max: 2 * Math.PI,
1869                 start: 0.3
1870             }
1871         },
1872 
1873         /**
1874          * Specify the user handling of the bank angle.
1875          * <ul>
1876          *  <li><tt>pointer</tt> sub-attributes:
1877          *      <ul>
1878          *          <li><tt>enabled</tt>: Boolean that specifies whether pointer navigation is allowed by elevation.
1879          *          <li><tt>speed</tt>: Number indicating how many passes the range of the el_slider makes when the cursor crosses the entire board once in the horizontal direction.
1880          *          <li><tt>outside</tt>: Boolean that specifies whether the pointer navigation is continued when the cursor leaves the board.
1881          *          <li><tt>button</tt>: Which button of the pointer should be used? (<tt>'-1'</tt> (=no button), <tt>'0'</tt> or <tt>'2'</tt>)
1882          *          <li><tt>key</tt>: Should an additional key be pressed? (<tt>'none'</tt>, <tt>'shift'</tt> or <tt>'ctrl'</tt>)
1883          *      </ul>
1884          *  <li><tt>keyboard</tt> sub-attributes:
1885          *      <ul>
1886          *          <li><tt>enabled</tt>: Boolean that specifies whether the keyboard ('<', '>' keys) can be used to navigate the board.
1887          *          <li><tt>step</tt>: Size of the step per keystroke.
1888          *          <li><tt>key</tt>: Should an additional key be pressed? (<tt>'none'</tt>, <tt>'shift'</tt> or <tt>'ctrl'</tt>)
1889          *      </ul>
1890          *  <li><tt>continuous</tt>: Boolean that specifies whether the el_slider starts again from the beginning when its end is reached.
1891          *  <li><tt>slider</tt> attributes of the el_slider ({@link Slider}) with additional
1892          *      <ul>
1893          *          <li><tt>min</tt>: Minimum value.
1894          *          <li><tt>max</tt>: Maximum value.
1895          *          <li><tt>start</tt>: Start value.
1896          *      </ul>
1897          *      'min' and 'max' are used only if trackball is not enabled.
1898          *     Additionally, the attributes 'slider.point1.pos' and 'slider.point2.pos' control the position of the slider. Possible
1899          *     values are 'auto' or an array [x, y] of length 2 for the position in user coordinates (or a function returning such an array).
1900          * </ul>
1901          *
1902          * @name View3D#bank
1903          * @type Object
1904          * @default <pre>{
1905          *      pointer: {enabled: true, speed: 1, outside: true, button: -1, key: 'none'},
1906          *      keyboard: {enabled: true, step: 10, key: 'ctrl'},
1907          *      continuous: true,
1908          *      slider: {
1909          *          visible: true,
1910          *          style: 6,
1911          *          point1: {
1912          *              pos: 'auto',
1913          *              frozen: false
1914          *          },
1915          *          point2: {
1916          *              pos: 'auto',
1917          *              frozen: false
1918          *          },
1919          *          min: 0,
1920          *          max: 2 * Math.PI,
1921          *          start: 0.3
1922          *      },
1923          * }<pre>
1924          * @example
1925          *     var bound = [-4, 6];
1926          *     var view = board.create('view3d',
1927          *         [[-4, -3], [8, 8],
1928          *         [bound, bound, bound]],
1929          *         {
1930          *             projection: 'parallel',
1931          *             bank: {
1932          *                 slider: {visible: true}
1933          *             }
1934          *         });
1935          *
1936          * </pre><div id="JXGb67811ea-c1e3-4d1e-b13c-3537b3436f6c" class="jxgbox" style="width: 300px; height: 300px;"></div>
1937          * <script type="text/javascript">
1938          *     (function() {
1939          *         var board = JXG.JSXGraph.initBoard('JXGb67811ea-c1e3-4d1e-b13c-3537b3436f6c',
1940          *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});
1941          *         var bound = [-4, 6];
1942          *         var view = board.create('view3d',
1943          *             [[-4, -3], [8, 8],
1944          *             [bound, bound, bound]],
1945          *             {
1946          *                 projection: 'parallel',
1947          *                 bank: {
1948          *                     slider: {visible: true}
1949          *                 }
1950          *             });
1951          *
1952          *     })();
1953          *
1954          * </script><pre>
1955          *
1956          */
1957         bank: {
1958             pointer: {
1959                 enabled: true,
1960                 speed: 0.08,
1961                 outside: true,
1962                 button: -1,
1963                 key: 'none'
1964             },
1965             keyboard: {
1966                 enabled: true,
1967                 step: 10,
1968                 key: 'ctrl'
1969             },
1970             continuous: true,
1971             slider: {
1972                 visible: 'inherit',
1973                 style: 6,
1974                 point1: {
1975                     frozen: false,
1976                     pos: 'auto'
1977                 },
1978                 point2: {
1979                     frozen: false,
1980                     pos: 'auto'
1981                 },
1982                 min: -Math.PI,
1983                 max:  Math.PI,
1984                 start: 0.0
1985             }
1986         },
1987 
1988         /**
1989          * Enable user handling by a virtual trackball that allows to move the 3D scene
1990          * with 3 degrees of freedom. If not enabled, direct user dragging (i.e. in the JSXGraph board, not manipulating the sliders) will only have
1991          * two degrees of freedom. This means, the z-axis will always be projected to a vertical 2D line.
1992          * <p>
1993          * Sub-attributes:
1994          *      <ul>
1995          *          <li><tt>enabled</tt>: Boolean that specifies whether pointer navigation is allowed by elevation.
1996          *          <li><tt>outside</tt>: Boolean that specifies whether the pointer navigation is continued when the cursor leaves the board.
1997          *          <li><tt>button</tt>: Which button of the pointer should be used? (<tt>'-1'</tt> (=no button), <tt>'0'</tt> or <tt>'2'</tt>)
1998          *          <li><tt>key</tt>: Should an additional key be pressed? (<tt>'none'</tt>, <tt>'shift'</tt> or <tt>'ctrl'</tt>)
1999          *      </ul>
2000          *
2001          * @name View3D#trackball
2002          * @type Object
2003          * @default <pre>{
2004          *   enabled: false,
2005          *   outside: true,
2006          *   button: -1,
2007          *   key: 'none'
2008          * }
2009          * </pre>
2010          */
2011         trackball: {
2012             enabled: false,
2013             outside: true,
2014             button: -1,
2015             key: 'none'
2016         },
2017 
2018         /**
2019          * Distance of the camera to the center of the view.
2020          * If set to 'auto', r will be calculated automatically.
2021          *
2022          * @type {Number|String}
2023          * @default 'auto'
2024          */
2025         r: 'auto',
2026 
2027         /**
2028          * Field of View defines the angle of view (in radians) of the camera, determining how much of the scene is captured within the frame.
2029          *
2030          * @type Number
2031          * @default 2/5*Math.PI
2032          */
2033         fov: 1 / 5 * 2 * Math.PI,
2034 
2035         /**
2036          * Fixed values for the view, which can be changed using keyboard keys `picture-up` and `picture-down`.
2037          * Array of the form: [[el0, az0, r0], [el1, az1, r1, ...[eln, azn, rn]]
2038          *
2039          * @name View3D#values
2040          * @type Array
2041          * @default <tt>{[[0, 1.57], [0.78, 0.62], [0, 0], [5.49, 0.62], [4.71, 0], [3.93, 0.62], [3.14, 0], [2.36, 0.62], [1.57, 1.57]]}<tt>
2042          */
2043         values: [
2044             [0, 1.57],
2045             [0.78, 0.62],
2046             [0, 0],
2047             [5.49, 0.62],
2048             [4.71, 0],
2049             [3.93, 0.62],
2050             [3.14, 0],
2051             [2.36, 0.62],
2052             [1.57, 1.57]
2053         ],
2054 
2055         infobox: {
2056             // strokeColor: '#888888',
2057             strokeColor: '#000000',
2058             fontSize: 16,
2059             useKatex: false,
2060             useMathjax: false,
2061             intl: {
2062                 enabled: true,
2063                 options: {
2064                     minimumFractionDigits: 2,
2065                     maximumFractionDigits: 3
2066                 }
2067             }
2068         },
2069 
2070         /**
2071          * @class
2072          * @ignore
2073          */
2074         _currentView: -1
2075 
2076         /**#@-*/
2077     }
2078 });
2079 
2080 export default JXG.Options;
2081