1 /* 2 Copyright 2008-2023 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 <https://www.gnu.org/licenses/> 27 and <https://opensource.org/licenses/MIT/>. 28 */ 29 /*global JXG:true, define: true*/ 30 31 import JXG from "../jxg"; 32 import Type from "../utils/type"; 33 34 /** 35 * Constructs a new GeometryElement3D object. 36 * @class This is the basic class for 3D geometry elements like Point3D and Line3D. 37 * @constructor 38 * @param {string} elType 39 * @borrows JXG.EventEmitter#on as this.on 40 * @borrows JXG.EventEmitter#off as this.off 41 * @borrows JXG.EventEmitter#triggerEventHandlers as this.triggerEventHandlers 42 * @borrows JXG.EventEmitter#eventHandlers as this.eventHandlers 43 */ 44 JXG.GeometryElement3D = function (view, elType) { 45 this.elType = elType; 46 this.id = this.board.setId(this, elType); 47 48 /** 49 * Pointer to the view3D in which the element is constructed 50 * @type JXG.View3D 51 * @private 52 */ 53 this.view = view; 54 55 /** 56 * Link to the 2D element(s) used to visualize the 3D element 57 * in a view. In case, there are several 2D elements, it is an array. 58 * 59 * @type JXG.GeometryElement,Array 60 * @private 61 * 62 * @example 63 * p.element2D; 64 */ 65 this.element2D = null; 66 67 /** 68 * If this property exists (and is true) the element is a 3D element. 69 * 70 * @type Boolean 71 * @private 72 */ 73 this.is3D = true; 74 75 this.view.objects[this.id] = this; 76 77 if (this.name !== "") { 78 this.view.elementsByName[this.name] = this; 79 } 80 }; 81 82 JXG.extend(JXG.GeometryElement3D.prototype, { 83 84 setAttr2D: function(attr3D) { 85 var attr2D = attr3D; 86 87 attr2D.name = this.name; 88 89 return attr2D; 90 }, 91 92 // Documented in element.js 93 setAttribute: function(attr) { 94 var i, key, value, arg, pair, 95 attributes = {}; 96 97 // Normalize the user input 98 for (i = 0; i < arguments.length; i++) { 99 arg = arguments[i]; 100 if (Type.isString(arg)) { 101 // pairRaw is string of the form 'key:value' 102 pair = arg.split(":"); 103 attributes[Type.trim(pair[0])] = Type.trim(pair[1]); 104 } else if (!Type.isArray(arg)) { 105 // pairRaw consists of objects of the form {key1:value1,key2:value2,...} 106 JXG.extend(attributes, arg); 107 } else { 108 // pairRaw consists of array [key,value] 109 attributes[arg[0]] = arg[1]; 110 } 111 } 112 113 for (i in attributes) { 114 if (attributes.hasOwnProperty(i)) { 115 key = i.replace(/\s+/g, "").toLowerCase(); 116 value = attributes[i]; 117 switch (key) { 118 case "numberpointshigh": 119 case "stepsu": 120 case "stepsv": 121 if (Type.exists(this.visProp[key]) && 122 (!JXG.Validator[key] || 123 (JXG.Validator[key] && JXG.Validator[key](value)) || 124 (JXG.Validator[key] && 125 Type.isFunction(value) && 126 JXG.Validator[key](value()))) 127 ) { 128 value = 129 value.toLowerCase && value.toLowerCase() === "false" 130 ? false 131 : value; 132 this._set(key, value); 133 } 134 break; 135 default: 136 if (Type.exists(this.element2D)) { 137 this.element2D.setAttribute(attributes); 138 } 139 } 140 } 141 } 142 }, 143 144 // Documented in element.js 145 getAttribute: function(key) { 146 var result; 147 key = key.toLowerCase(); 148 149 switch (key) { 150 case "numberpointshigh": 151 case "stepsu": 152 case "stepsv": 153 result = this.visProp[key]; 154 break; 155 default: 156 if (Type.exists(this.element2D)) { 157 result = this.element2D.getAttribute(key); 158 } 159 break; 160 } 161 162 return result; 163 }, 164 165 // Documented in element.js 166 getAttributes: function() { 167 var attr = {}, 168 i, key, 169 attr3D = ['numberpointshigh', 'stepsu', 'stepsv'], 170 le = attr3D.length; 171 172 if (Type.exists(this.element2D)) { 173 attr = Type.merge(this.element2D.getAttributes()); 174 } 175 176 for (i = 0; i < le; i++) { 177 key = attr3D[i]; 178 if (Type.exists(this.visProp[key])) { 179 attr[key] = this.visProp[key]; 180 } 181 } 182 183 return attr; 184 } 185 186 }); 187 188 export default JXG.GeometryElement3D; 189