AutorÃa | Ultima modificación | Ver Log |
{"version":3,"file":"shapes.min.js","sources":["../src/shapes.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/* eslint max-depth: [\"error\", 8] */\n\n/**\n * Library of classes for handling simple shapes.\n *\n * These classes can represent shapes, let you alter them, can go to and from a string\n * representation, and can give you an SVG repre
sentation.\n *\n * @module qtype_ddmarker/shapes\n * @copyright 2018 The Open University\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\ndefine(function() {\n\n \"use strict\";\n\n /**\n * A point, with x and y coordinates.\n *\n * @param {int} x centre X.\n * @param {int} y centre Y.\n * @constructor\n */\n function Point(x, y) {\n this.x = x;\n this.y = y;\n }\n\n /**\n * Standard toString method.\n * @returns {string} \"x;y\";\n */\n Point.prototype.toString = function() {\n return this.x + ',' + this.y;\n };\n\n /**\n * Move a point\n * @param {int} dx x offset\n * @param {int} dy y offset\n */\n Point.prototype.move = function(dx, dy) {\n this.x += dx;\n this.y += dy;\n };\n\n /**\n * Return a new point that is a certain position relative to this one.\n *\n * @param {(int|Point)} offsetX if a point, offset by this points coordinates, else a
nd int x offset.\n * @param {int} [offsetY] used if offsetX is an int, the corresponding y offset.\n * @return {Point} the new point.\n */\n Point.prototype.offset = function(offsetX, offsetY) {\n if (offsetX instanceof Point) {\n offsetY = offsetX.y;\n offsetX = offsetX.x;\n }\n return new Point(this.x + offsetX, this.y + offsetY);\n };\n\n /**\n * Make a point from the string representation.\n *\n * @param {String} coordinates \"x,y\".\n * @return {Point} the point. Throws an exception if input is not valid.\n */\n Point.parse = function(coordinates) {\n var bits = coordinates.split(',');\n if (bits.length !== 2) {\n throw new Error(coordinates + ' is not a valid point');\n }\n return new Point(Math.round(bits[0]), Math.round(bits[1]));\n };\n\n\n /**\n * Shape constructor. Abstract class to represent the different types of drop zone shapes.\n *\n * @param {String}
[label] name of this area.\n * @param {int} [x] centre X.\n * @param {int} [y] centre Y.\n * @constructor\n */\n function Shape(label, x, y) {\n this.label = label;\n this.centre = new Point(x || 0, y || 0);\n }\n\n /**\n * Get the type of shape.\n *\n * @return {String} 'circle', 'rectangle' or 'polygon';\n */\n Shape.prototype.getType = function() {\n throw new Error('Not implemented.');\n };\n\n /**\n * Get the string representation of this shape.\n *\n * @return {String} coordinates as they need to be typed into the form.\n */\n Shape.prototype.getCoordinates = function() {\n throw new Error('Not implemented.');\n };\n\n /**\n * Update the shape from the string representation.\n *\n * @param {String} coordinates in the form returned by getCoordinates.\n * @param {number} ratio Ratio to scale.\n * @return {boolean} true if the string could be parsed and the shape updated, else false.
\n */\n Shape.prototype.parse = function(coordinates, ratio) {\n void (coordinates, ratio);\n throw new Error('Not implemented.');\n };\n\n /**\n * Move the entire shape by this offset.\n *\n * @param {int} dx x offset.\n * @param {int} dy y offset.\n * @param {int} maxX ensure that after editing, the shape lies between 0 and maxX on the x-axis.\n * @param {int} maxY ensure that after editing, the shape lies between 0 and maxX on the y-axis.\n */\n Shape.prototype.move = function(dx, dy, maxX, maxY) {\n void (maxY);\n };\n\n /**\n * Move one of the edit handles by this offset.\n *\n * @param {int} handleIndex which handle was moved.\n * @param {int} dx x offset.\n * @param {int} dy y offset.\n * @param {int} maxX ensure that after editing, the shape lies between 0 and maxX on the x-axis.\n * @param {int} maxY ensure that after editing, the shape lies between 0 and maxX on the y-axis.\n */\n Shape.prototy
pe.edit = function(handleIndex, dx, dy, maxX, maxY) {\n void (maxY);\n };\n\n /**\n * Update the properties of this shape after a sequence of edits.\n *\n * For example make sure the circle radius is positive, of the polygon centre is centred.\n */\n Shape.prototype.normalizeShape = function() {\n void (1); // To make CiBoT happy.\n };\n\n /**\n * Get the string representation of this shape.\n *\n * @param {SVGElement} svg the SVG graphic to add this shape to.\n * @return {SVGElement} SVG representation of this shape.\n */\n Shape.prototype.makeSvg = function(svg) {\n void (svg);\n throw new Error('Not implemented.');\n };\n\n /**\n * Update the SVG representation of this shape.\n *\n * @param {SVGElement} svgEl the SVG representation of this shape.\n */\n Shape.prototype.updateSvg = function(svgEl) {\n void (svgEl);\n };\n\n /**\n * Make a circle similar to this shape.\n *\n *
@return {Circle} a circle that is about the same size and position as this shape.\n */\n Shape.prototype.makeSimilarCircle = function() {\n throw new Error('Not implemented.');\n };\n\n /**\n * Make a rectangle similar to this shape.\n *\n * @return {Rectangle} a rectangle that is about the same size and position as this shape.\n */\n Shape.prototype.makeSimilarRectangle = function() {\n throw new Error('Not implemented.');\n };\n\n /**\n * Make a polygon similar to this shape.\n *\n * @return {Polygon} a polygon that is about the same size and position as this shape.\n */\n Shape.prototype.makeSimilarPolygon = function() {\n throw new Error('Not implemented.');\n };\n\n /**\n * Get the handles that should be offered to edit this shape, or null if not appropriate.\n *\n * @return {Object[]} with properties moveHandle {Point} and editHandles {Point[]}\n */\n Shape.prototype.getHandlePositions = function() {\
n return null;\n };\n\n\n /**\n * A shape that is a circle.\n *\n * @param {String} label name of this area.\n * @param {int} [x] centre X.\n * @param {int} [y] centre Y.\n * @param {int} [radius] radius.\n * @constructor\n */\n function Circle(label, x, y, radius) {\n x = x || 15;\n y = y || 15;\n Shape.call(this, label, x, y);\n this.radius = radius || 15;\n }\n Circle.prototype = new Shape();\n\n Circle.prototype.getType = function() {\n return 'circle';\n };\n\n Circle.prototype.getCoordinates = function() {\n return this.centre + ';' + Math.abs(this.radius);\n };\n\n Circle.prototype.makeSvg = function(svg) {\n var svgEl = createSvgShapeGroup(svg, 'circle');\n this.updateSvg(svgEl);\n return svgEl;\n };\n\n Circle.prototype.updateSvg = function(svgEl) {\n svgEl.childNodes[0].setAttribute('cx', this.centre.x);\n svgEl.childNodes[0].setAttribute('cy', this
.centre.y);\n svgEl.childNodes[0].setAttribute('r', Math.abs(this.radius));\n svgEl.childNodes[1].setAttribute('x', this.centre.x);\n svgEl.childNodes[1].setAttribute('y', this.centre.y + 15);\n svgEl.childNodes[1].textContent = this.label;\n };\n\n Circle.prototype.parse = function(coordinates, ratio) {\n if (!coordinates.match(/^\\d+(\\.\\d+)?,\\d+(\\.\\d+)?;\\d+(\\.\\d+)?$/)) {\n return false;\n }\n\n var bits = coordinates.split(';');\n this.centre = Point.parse(bits[0]);\n this.centre.x = this.centre.x * parseFloat(ratio);\n this.centre.y = this.centre.y * parseFloat(ratio);\n this.radius = Math.round(bits[1]) * parseFloat(ratio);\n return true;\n };\n\n Circle.prototype.move = function(dx, dy, maxX, maxY) {\n this.centre.move(dx, dy);\n if (this.centre.x < this.radius) {\n this.centre.x = this.radius;\n }\n if (this.centre.x > maxX - this.radius) {\n
this.centre.x = maxX - this.radius;\n }\n if (this.centre.y < this.radius) {\n this.centre.y = this.radius;\n }\n if (this.centre.y > maxY - this.radius) {\n this.centre.y = maxY - this.radius;\n }\n };\n\n Circle.prototype.edit = function(handleIndex, dx, dy, maxX, maxY) {\n this.radius += dx;\n var limit = Math.min(this.centre.x, this.centre.y, maxX - this.centre.x, maxY - this.centre.y);\n if (this.radius > limit) {\n this.radius = limit;\n }\n if (this.radius < -limit) {\n this.radius = -limit;\n }\n };\n\n /**\n * Update the properties of this shape after a sequence of edits.\n *\n * For example make sure the circle radius is positive, of the polygon centre is centred.\n */\n Circle.prototype.normalizeShape = function() {\n this.radius = Math.abs(this.radius);\n };\n\n Circle.prototype.makeSimilarRectangle = function() {\n return n
ew Rectangle(this.label,\n this.centre.x - this.radius, this.centre.y - this.radius,\n this.radius * 2, this.radius * 2);\n };\n\n Circle.prototype.makeSimilarPolygon = function() {\n // We make a similar square, so if you go to and from Rectangle afterwards, it is loss-less.\n return new Polygon(this.label, [\n this.centre.offset(-this.radius, -this.radius), this.centre.offset(-this.radius, this.radius),\n this.centre.offset(this.radius, this.radius), this.centre.offset(this.radius, -this.radius)]);\n };\n\n Circle.prototype.getHandlePositions = function() {\n return {\n moveHandle: this.centre,\n editHandles: [this.centre.offset(this.radius, 0)]\n };\n };\n\n\n /**\n * A shape that is a rectangle.\n *\n * @param {String} label name of this area.\n * @param {int} [x] top left X.\n * @param {int} [y] top left Y.\n * @param {int} [width] width.\n * @param
{int} [height] height.\n * @constructor\n */\n function Rectangle(label, x, y, width, height) {\n Shape.call(this, label, x, y);\n this.width = width || 30;\n this.height = height || 30;\n }\n Rectangle.prototype = new Shape();\n\n Rectangle.prototype.getType = function() {\n return 'rectangle';\n };\n\n Rectangle.prototype.getCoordinates = function() {\n return this.centre + ';' + this.width + ',' + this.height;\n };\n\n Rectangle.prototype.makeSvg = function(svg) {\n var svgEl = createSvgShapeGroup(svg, 'rect');\n this.updateSvg(svgEl);\n return svgEl;\n };\n\n Rectangle.prototype.updateSvg = function(svgEl) {\n if (this.width >= 0) {\n svgEl.childNodes[0].setAttribute('x', this.centre.x);\n svgEl.childNodes[0].setAttribute('width', this.width);\n } else {\n svgEl.childNodes[0].setAttribute('x', this.centre.x + this.width);\n svgEl.childNodes[0].setAttribut
e('width', -this.width);\n }\n if (this.height >= 0) {\n svgEl.childNodes[0].setAttribute('y', this.centre.y);\n svgEl.childNodes[0].setAttribute('height', this.height);\n } else {\n svgEl.childNodes[0].setAttribute('y', this.centre.y + this.height);\n svgEl.childNodes[0].setAttribute('height', -this.height);\n }\n\n svgEl.childNodes[1].setAttribute('x', this.centre.x + this.width / 2);\n svgEl.childNodes[1].setAttribute('y', this.centre.y + this.height / 2 + 15);\n svgEl.childNodes[1].textContent = this.label;\n };\n\n Rectangle.prototype.parse = function(coordinates, ratio) {\n if (!coordinates.match(/^\\d+(\\.\\d+)?,\\d+(\\.\\d+)?;\\d+(\\.\\d+)?,\\d+(\\.\\d+)?$/)) {\n return false;\n }\n\n var bits = coordinates.split(';');\n this.centre = Point.parse(bits[0]);\n this.centre.x = this.centre.x * parseFloat(ratio);\n this.centre.y = this.centre.y * parseFloa
t(ratio);\n var size = Point.parse(bits[1]);\n this.width = size.x * parseFloat(ratio);\n this.height = size.y * parseFloat(ratio);\n return true;\n };\n\n Rectangle.prototype.move = function(dx, dy, maxX, maxY) {\n this.centre.move(dx, dy);\n if (this.centre.x < 0) {\n this.centre.x = 0;\n }\n if (this.centre.x > maxX - this.width) {\n this.centre.x = maxX - this.width;\n }\n if (this.centre.y < 0) {\n this.centre.y = 0;\n }\n if (this.centre.y > maxY - this.height) {\n this.centre.y = maxY - this.height;\n }\n };\n\n Rectangle.prototype.edit = function(handleIndex, dx, dy, maxX, maxY) {\n this.width += dx;\n this.height += dy;\n if (this.width < -this.centre.x) {\n this.width = -this.centre.x;\n }\n if (this.width > maxX - this.centre.x) {\n this.width = maxX - this.centre.x;\n }\n if (this.h
eight < -this.centre.y) {\n this.height = -this.centre.y;\n }\n if (this.height > maxY - this.centre.y) {\n this.height = maxY - this.centre.y;\n }\n };\n\n /**\n * Update the properties of this shape after a sequence of edits.\n *\n * For example make sure the circle radius is positive, of the polygon centre is centred.\n */\n Rectangle.prototype.normalizeShape = function() {\n if (this.width < 0) {\n this.centre.x += this.width;\n this.width = -this.width;\n }\n if (this.height < 0) {\n this.centre.y += this.height;\n this.height = -this.height;\n }\n };\n\n Rectangle.prototype.makeSimilarCircle = function() {\n return new Circle(this.label,\n Math.round(this.centre.x + this.width / 2),\n Math.round(this.centre.y + this.height / 2),\n Math.round((this.width + this.height) / 4));\n };\n\n Rectangle.prototyp
e.makeSimilarPolygon = function() {\n return new Polygon(this.label, [\n this.centre, this.centre.offset(0, this.height),\n this.centre.offset(this.width, this.height), this.centre.offset(this.width, 0)]);\n };\n\n Rectangle.prototype.getHandlePositions = function() {\n return {\n moveHandle: this.centre.offset(this.width / 2, this.height / 2),\n editHandles: [this.centre.offset(this.width, this.height)]\n };\n };\n\n\n /**\n * A shape that is a polygon.\n *\n * @param {String} label name of this area.\n * @param {Point[]} [points] position of the vertices relative to (centreX, centreY).\n * each object in the array should have two\n * @constructor\n */\n function Polygon(label, points) {\n Shape.call(this, label, 0, 0);\n this.points = points ? points.slice() : [new Point(10, 10), new Point(40, 10), new Point(10, 40)];\n this.normalizeShape();\n this.ratio = 1;\n }\
n Polygon.prototype = new Shape();\n\n Polygon.prototype.getType = function() {\n return 'polygon';\n };\n\n Polygon.prototype.getCoordinates = function() {\n var coordinates = '';\n for (var i = 0; i < this.points.length; i++) {\n coordinates += this.centre.offset(this.points[i]) + ';';\n }\n return coordinates.slice(0, coordinates.length - 1); // Strip off the last ';'.\n };\n\n Polygon.prototype.makeSvg = function(svg) {\n var svgEl = createSvgShapeGroup(svg, 'polygon');\n this.updateSvg(svgEl);\n return svgEl;\n };\n\n Polygon.prototype.updateSvg = function(svgEl) {\n svgEl.childNodes[0].setAttribute('points', this.getCoordinates().replace(/[,;]/g, ' '));\n svgEl.childNodes[0].setAttribute('transform', 'scale(' + parseFloat(this.ratio) + ')');\n svgEl.childNodes[1].setAttribute('x', this.centre.x);\n svgEl.childNodes[1].setAttribute('y', this.centre.y + 15);\n svgEl.childNodes[1].
textContent = this.label;\n };\n\n Polygon.prototype.parse = function(coordinates, ratio) {\n if (!coordinates.match(/^\\d+(\\.\\d+)?,\\d+(\\.\\d+)?(?:;\\d+(\\.\\d+)?,\\d+(\\.\\d+)?)*$/)) {\n return false;\n }\n\n var bits = coordinates.split(';');\n var points = [];\n for (var i = 0; i < bits.length; i++) {\n points.push(Point.parse(bits[i]));\n }\n\n this.points = points;\n this.centre.x = 0;\n this.centre.y = 0;\n this.ratio = ratio;\n this.normalizeShape();\n\n return true;\n };\n\n Polygon.prototype.move = function(dx, dy, maxX, maxY) {\n this.centre.move(dx, dy);\n var bbXMin = maxX,\n bbXMax = 0,\n bbYMin = maxY,\n bbYMax = 0;\n // Computer centre.\n for (var i = 0; i < this.points.length; i++) {\n bbXMin = Math.min(bbXMin, this.points[i].x);\n bbXMax = Math.max(bbXMax, this.points[i].x);\n bb
YMin = Math.min(bbYMin, this.points[i].y);\n bbYMax = Math.max(bbYMax, this.points[i].y);\n }\n if (this.centre.x < -bbXMin) {\n this.centre.x = -bbXMin;\n }\n if (this.centre.x > maxX - bbXMax) {\n this.centre.x = maxX - bbXMax;\n }\n if (this.centre.y < -bbYMin) {\n this.centre.y = -bbYMin;\n }\n if (this.centre.y > maxY - bbYMax) {\n this.centre.y = maxY - bbYMax;\n }\n };\n\n Polygon.prototype.edit = function(handleIndex, dx, dy, maxX, maxY) {\n this.points[handleIndex].move(dx, dy);\n if (this.points[handleIndex].x < -this.centre.x) {\n this.points[handleIndex].x = -this.centre.x;\n }\n if (this.points[handleIndex].x > maxX - this.centre.x) {\n this.points[handleIndex].x = maxX - this.centre.x;\n }\n if (this.points[handleIndex].y < -this.centre.y) {\n this.points[handleIndex].y = -this.centre.y;\n }\
n if (this.points[handleIndex].y > maxY - this.centre.y) {\n this.points[handleIndex].y = maxY - this.centre.y;\n }\n };\n\n /**\n * Add a new point after the given point, with the same co-ordinates.\n *\n * This does not automatically normalise.\n *\n * @param {int} pointIndex the index of the vertex after which to insert this new one.\n */\n Polygon.prototype.addNewPointAfter = function(pointIndex) {\n this.points.splice(pointIndex, 0,\n new Point(this.points[pointIndex].x, this.points[pointIndex].y));\n };\n\n Polygon.prototype.normalizeShape = function() {\n var i,\n x = 0,\n y = 0;\n\n if (this.points.length === 0) {\n return;\n }\n\n // Computer centre.\n for (i = 0; i < this.points.length; i++) {\n x += this.points[i].x;\n y += this.points[i].y;\n }\n x = Math.round(x / this.points.length);\n y = Math.round(
y / this.points.length);\n\n if (x === 0 && y === 0) {\n return;\n }\n\n for (i = 0; i < this.points.length; i++) {\n this.points[i].move(-x, -y);\n }\n this.centre.move(x, y);\n };\n\n Polygon.prototype.makeSimilarCircle = function() {\n return this.makeSimilarRectangle().makeSimilarCircle();\n };\n\n Polygon.prototype.makeSimilarRectangle = function() {\n var p,\n minX = 0,\n maxX = 0,\n minY = 0,\n maxY = 0;\n for (var i = 0; i < this.points.length; i++) {\n p = this.points[i];\n minX = Math.min(minX, p.x);\n maxX = Math.max(maxX, p.x);\n minY = Math.min(minY, p.y);\n maxY = Math.max(maxY, p.y);\n }\n return new Rectangle(this.label,\n this.centre.x + minX, this.centre.y + minY,\n Math.max(maxX - minX, 10), Math.max(maxY - minY, 10));\n };\n\n Polygon.prototype.getHandle
Positions = function() {\n var editHandles = [];\n for (var i = 0; i < this.points.length; i++) {\n editHandles.push(this.points[i].offset(this.centre.x, this.centre.y));\n }\n\n this.centre.x = this.centre.x * parseFloat(this.ratio);\n this.centre.y = this.centre.y * parseFloat(this.ratio);\n\n return {\n moveHandle: this.centre,\n editHandles: editHandles\n };\n };\n\n\n /**\n * Not a shape (null object pattern).\n *\n * @param {String} label name of this area.\n * @constructor\n */\n function NullShape(label) {\n Shape.call(this, label);\n }\n NullShape.prototype = new Shape();\n\n NullShape.prototype.getType = function() {\n return 'null';\n };\n\n NullShape.prototype.getCoordinates = function() {\n return '';\n };\n\n NullShape.prototype.makeSvg = function(svg) {\n void (svg);\n return null;\n };\n\n NullShape.prototype.updateSvg = f
unction(svgEl) {\n void (svgEl);\n };\n\n NullShape.prototype.parse = function(coordinates) {\n void (coordinates);\n return false;\n };\n\n NullShape.prototype.makeSimilarCircle = function() {\n return new Circle(this.label);\n };\n\n NullShape.prototype.makeSimilarRectangle = function() {\n return new Rectangle(this.label);\n };\n\n NullShape.prototype.makeSimilarPolygon = function() {\n return new Polygon(this.label);\n };\n\n\n /**\n * Make a new SVG DOM element as a child of svg.\n *\n * @param {SVGElement} svg the parent node.\n * @param {String} tagName the tag name.\n * @return {SVGElement} the newly created node.\n */\n function createSvgElement(svg, tagName) {\n var svgEl = svg.ownerDocument.createElementNS('http://www.w3.org/2000/svg', tagName);\n svg.appendChild(svgEl);\n return svgEl;\n }\n\n /**\n * Make a group SVG DOM elements containing a shape of the given type a
s first child,\n * and a text label as the second child.\n *\n * @param {SVGElement} svg the parent node.\n * @param {String} tagName the tag name.\n * @return {SVGElement} the newly created g element.\n */\n function createSvgShapeGroup(svg, tagName) {\n var svgEl = createSvgElement(svg, 'g');\n createSvgElement(svgEl, tagName).setAttribute('class', 'shape');\n createSvgElement(svgEl, 'text').setAttribute('class', 'shapeLabel');\n return svgEl;\n }\n\n /**\n * @alias module:qtype_ddmarker/shapes\n */\n return {\n /**\n * A point, with x and y coordinates.\n *\n * @param {int} x centre X.\n * @param {int} y centre Y.\n * @constructor\n */\n Point: Point,\n\n /**\n * A point, with x and y coordinates.\n *\n * @param {int} x centre X.\n * @param {int} y centre Y.\n * @constructor\n */\n Shape: Shape,\n\n /**\n
* A shape that is a circle.\n *\n * @param {String} label name of this area.\n * @param {int} [x] centre X.\n * @param {int} [y] centre Y.\n * @param {int} [radius] radius.\n * @constructor\n */\n Circle: Circle,\n\n /**\n * A shape that is a rectangle.\n *\n * @param {String} label name of this area.\n * @param {int} [x] top left X.\n * @param {int} [y] top left Y.\n * @param {int} [width] width.\n * @param {int} [height] height.\n * @constructor\n */\n Rectangle: Rectangle,\n\n /**\n * A shape that is a polygon.\n *\n * @param {String} label name of this area.\n * @param {Point[]} [points] position of the vertices relative to (centreX, centreY).\n * each object in the array should have two\n * @constructor\n */\n Polygon: Polygon,\n\n /**\n * Not a shape (null obj
ect pattern).\n *\n * @param {String} label name of this area.\n * @constructor\n */\n NullShape: NullShape,\n\n /**\n * Make a new SVG DOM element as a child of svg.\n *\n * @param {SVGElement} svg the parent node.\n * @param {String} tagName the tag name.\n * @return {SVGElement} the newly created node.\n */\n createSvgElement: createSvgElement,\n\n /**\n * Make a shape of the given type.\n *\n * @param {String} shapeType\n * @param {String} label\n * @return {Shape} the requested shape.\n */\n make: function(shapeType, label) {\n switch (shapeType) {\n case 'circle':\n return new Circle(label);\n case 'rectangle':\n return new Rectangle(label);\n case 'polygon':\n return new Polygon(label);\n default:\n
return new NullShape(label);\n }\n },\n\n /**\n * Make a shape of the given type that is similar to the shape of the original type.\n *\n * @param {String} shapeType the new type of shape to make\n * @param {Shape} shape the shape to copy\n * @return {Shape} the similar shape of a different type.\n */\n getSimilar: function(shapeType, shape) {\n if (shapeType === shape.getType()) {\n return shape;\n }\n switch (shapeType) {\n case 'circle':\n return shape.makeSimilarCircle();\n case 'rectangle':\n return shape.makeSimilarRectangle();\n case 'polygon':\n return shape.makeSimilarPolygon();\n default:\n return new NullShape(shape.label);\n }\n }\n };\n});\n"],"names":["define","Point","x","y","Shape","label","centre","Circle","r
adius","call","this","Rectangle","width","height","Polygon","points","slice","normalizeShape","ratio","NullShape","createSvgElement","svg","tagName","svgEl","ownerDocument","createElementNS","appendChild","createSvgShapeGroup","setAttribute","prototype","toString","move","dx","dy","offset","offsetX","offsetY","parse","coordinates","bits","split","length","Error","Math","round","getType","getCoordinates","maxX","maxY","edit","handleIndex","makeSvg","updateSvg","makeSimilarCircle","makeSimilarRectangle","makeSimilarPolygon","getHandlePositions","abs","childNodes","textContent","match","parseFloat","limit","min","moveHandle","editHandles","size","i","replace","push","bbXMin","bbXMax","bbYMin","bbYMax","max","addNewPointAfter","pointIndex","splice","p","minX","minY","make","shapeType","getSimilar","shape"],"mappings":"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"}