1 /* 2 Copyright 2008-2023 3 Matthias Ehmann, 4 Michael Gerhaeuser, 5 Carsten Miller, 6 Bianca Valentin, 7 Alfred Wassermann, 8 Peter Wilfahrt 9 10 This file is part of JSXGraph. 11 12 JSXGraph is free software dual licensed under the GNU LGPL or MIT License. 13 14 You can redistribute it and/or modify it under the terms of the 15 16 * GNU Lesser General Public License as published by 17 the Free Software Foundation, either version 3 of the License, or 18 (at your option) any later version 19 OR 20 * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT 21 22 JSXGraph is distributed in the hope that it will be useful, 23 but WITHOUT ANY WARRANTY; without even the implied warranty of 24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25 GNU Lesser General Public License for more details. 26 27 You should have received a copy of the GNU Lesser General Public License and 28 the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/> 29 and <https://opensource.org/licenses/MIT/>. 30 */ 31 32 /*global JXG: true, define: true*/ 33 /*jslint nomen: true, plusplus: true*/ 34 35 /** 36 * @fileoverview Geometry objects for measurements are defined in this file. This file stores all 37 * style and functional properties that are required to use a tape measure on 38 * a board. 39 */ 40 41 import JXG from "../jxg"; 42 import Type from "../utils/type"; 43 import GeometryElement from "../base/element"; 44 45 /** 46 * @class A tape measure can be used to measure distances between points. 47 * @pseudo 48 * @description 49 * @name Tapemeasure 50 * @augments Segment 51 * @constructor 52 * @type JXG.Segment 53 * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown. 54 * @param {Array_Array} start,end, The two arrays give the initial position where the tape measure 55 * is drawn on the board. 56 * @example 57 * // Create a tape measure 58 * var p1 = board.create('point', [0,0]); 59 * var p2 = board.create('point', [1,1]); 60 * var p3 = board.create('point', [3,1]); 61 * var tape = board.create('tapemeasure', [[1, 2], [4, 2]], {name:'dist'}); 62 * </pre><div class="jxgbox" id="JXG6d9a2cda-22fe-4cd1-9d94-34283b1bdc01" style="width: 200px; height: 200px;"></div> 63 * <script type="text/javascript"> 64 * (function () { 65 * var board = JXG.JSXGraph.initBoard('JXG6d9a2cda-22fe-4cd1-9d94-34283b1bdc01', {boundingbox: [-1, 5, 5, -1], axis: true, showcopyright: false, shownavigation: false}); 66 * var p1 = board.create('point', [0,0]); 67 * var p2 = board.create('point', [1,1]); 68 * var p3 = board.create('point', [3,1]); 69 * var tape = board.create('tapemeasure', [[1, 2], [4, 2]], {name:'dist'} ); 70 * })(); 71 * </script><pre> 72 */ 73 JXG.createTapemeasure = function (board, parents, attributes) { 74 var pos0, pos1, attr, withTicks, withText, digits, li, p1, p2, n, ti; 75 76 pos0 = parents[0]; 77 pos1 = parents[1]; 78 79 // start point 80 attr = Type.copyAttributes(attributes, board.options, "tapemeasure", "point1"); 81 p1 = board.create("point", pos0, attr); 82 83 // end point 84 attr = Type.copyAttributes(attributes, board.options, "tapemeasure", "point2"); 85 p2 = board.create("point", pos1, attr); 86 87 p1.setAttribute({ ignoredSnapToPoints: [p2] }); 88 p2.setAttribute({ ignoredSnapToPoints: [p1] }); 89 90 // tape measure line 91 attr = Type.copyAttributes(attributes, board.options, "tapemeasure"); 92 withTicks = attr.withticks; 93 withText = attr.withlabel; 94 digits = attr.digits; 95 96 if (digits === 2 && attr.precision !== 2) { 97 // Backward compatibility 98 digits = attr.precision; 99 } 100 101 // Below, we will replace the label by the measurement function. 102 if (withText) { 103 attr.withlabel = true; 104 } 105 li = board.create("segment", [p1, p2], attr); 106 // p1, p2 are already added to li.inherits 107 108 if (withText) { 109 if (attributes.name && attributes.name !== "") { 110 n = attributes.name + " = "; 111 } else { 112 n = ""; 113 } 114 li.label.setText(function () { 115 var digits = Type.evaluate(li.label.visProp.digits); 116 117 if (li.label.useLocale()) { 118 return n + li.label.formatNumberLocale(p1.Dist(p2), digits); 119 } 120 return n + Type.toFixed(p1.Dist(p2), digits); 121 }); 122 } 123 124 if (withTicks) { 125 attr = Type.copyAttributes(attributes, board.options, "tapemeasure", "ticks"); 126 //ticks = 2; 127 ti = board.create("ticks", [li, 0.1], attr); 128 li.inherits.push(ti); 129 } 130 131 // override the segments's remove method to ensure the removal of all elements 132 /** @ignore */ 133 li.remove = function () { 134 if (withTicks) { 135 li.removeTicks(ti); 136 } 137 138 board.removeObject(p2); 139 board.removeObject(p1); 140 141 GeometryElement.prototype.remove.call(this); 142 }; 143 144 /** 145 * Returns the length of the tape measure. 146 * @name Value 147 * @memberOf Tapemeasure.prototype 148 * @function 149 * @returns {Number} length of tape measure. 150 */ 151 li.Value = function () { 152 return p1.Dist(p2); 153 }; 154 155 p1.dump = false; 156 p2.dump = false; 157 158 li.elType = "tapemeasure"; 159 li.getParents = function () { 160 return [ 161 [p1.X(), p1.Y()], 162 [p2.X(), p2.Y()] 163 ]; 164 }; 165 166 li.subs = { 167 point1: p1, 168 point2: p2 169 }; 170 171 if (withTicks) { 172 ti.dump = false; 173 } 174 175 li.methodMap = JXG.deepCopy(li.methodMap, { 176 Value: "Value" 177 }); 178 179 li.prepareUpdate().update(); 180 if (!board.isSuspendedUpdate) { 181 li.updateVisibility().updateRenderer(); 182 // The point updates are necessary in case of snapToGrid==true 183 li.point1.updateVisibility().updateRenderer(); 184 li.point2.updateVisibility().updateRenderer(); 185 } 186 187 return li; 188 }; 189 190 JXG.registerElement("tapemeasure", JXG.createTapemeasure); 191 192 // export default { 193 // createTapemeasure: JXG.createTapemeasure 194 // }; 195