UNPKG

mathpix-markdown-it

Version:

Mathpix-markdown-it is an open source implementation of the mathpix-markdown spec written in Typescript. It relies on the following open source libraries: MathJax v3 (to render math with SVGs), markdown-it (for standard Markdown parsing)

630 lines 30.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var MathHelper_1 = require("./MathHelper"); var UtilityFunctions_1 = require("./UtilityFunctions"); var Line_1 = require("./Line"); var Vector2_1 = require("./Vector2"); var Atom_1 = require("./Atom"); var SvgWrapper = /** @class */ (function () { function SvgWrapper(themeManager, target, options) { if (typeof target === 'string' || target instanceof String) { this.svg = document.getElementById(target.toString()); } else { this.svg = target; } this.opts = options; this.gradientId = 0; // maintain a list of line elements and their corresponding gradients // maintain a list of vertex elements this.paths = []; this.vertices = []; this.gradients = []; // maintain the offset for drawing purposes this.offsetX = 0.0; this.offsetY = 0.0; // maintain the dimensions this.drawingWidth = 0; this.drawingHeight = 0; this.halfBondThickness = this.opts.bondThickness / 2.0; // for managing color schemes this.themeManager = themeManager; // create the mask this.maskElements = []; var mask = document.createElementNS('http://www.w3.org/2000/svg', 'rect'); mask.setAttributeNS(null, 'x', '0'); mask.setAttributeNS(null, 'y', '0'); mask.setAttributeNS(null, 'width', '100%'); mask.setAttributeNS(null, 'height', '100%'); mask.setAttributeNS(null, 'fill', 'white'); this.maskElements.push(mask); // clear the svg element while (this.svg.firstChild) { this.svg.removeChild(this.svg.firstChild); } } SvgWrapper.prototype.constructSvg = function () { var e_1, _a, e_2, _b, e_3, _c, e_4, _d; // TODO: add the defs element to put gradients in var elementClassName = this.opts.id ? 'element-' + this.opts.id : 'element'; var subClassName = this.opts.id ? 'sub-' + this.opts.id : 'sub'; var defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs'), masks = document.createElementNS('http://www.w3.org/2000/svg', 'mask'), style = document.createElementNS('http://www.w3.org/2000/svg', 'style'), paths = document.createElementNS('http://www.w3.org/2000/svg', 'g'), vertices = document.createElementNS('http://www.w3.org/2000/svg', 'g'), pathChildNodes = this.paths; // give the mask an id if (this.opts.id) { masks.setAttributeNS(null, 'id', 'text-mask-' + this.opts.id); } else { masks.setAttributeNS(null, 'id', 'text-mask'); } // create the css styles style.appendChild(document.createTextNode("\n .".concat(elementClassName, " {\n font: ").concat(this.opts.fontSizeLargePx ? this.opts.fontSizeLargePx + 'px' : this.opts.fontSizeLarge + 'pt', " Helvetica, Arial, sans-serif;\n alignment-baseline: 'middle';\n }\n .").concat(subClassName, " {\n font: ").concat(this.opts.fontSizeSmallPx ? this.opts.fontSizeSmallPx + 'px' : this.opts.fontSizeSmall + 'pt', " Helvetica, Arial, sans-serif;\n }\n "))); try { for (var pathChildNodes_1 = tslib_1.__values(pathChildNodes), pathChildNodes_1_1 = pathChildNodes_1.next(); !pathChildNodes_1_1.done; pathChildNodes_1_1 = pathChildNodes_1.next()) { var path = pathChildNodes_1_1.value; paths.appendChild(path); } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (pathChildNodes_1_1 && !pathChildNodes_1_1.done && (_a = pathChildNodes_1.return)) _a.call(pathChildNodes_1); } finally { if (e_1) throw e_1.error; } } try { for (var _e = tslib_1.__values(this.vertices), _f = _e.next(); !_f.done; _f = _e.next()) { var vertex = _f.value; vertices.appendChild(vertex); } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (_f && !_f.done && (_b = _e.return)) _b.call(_e); } finally { if (e_2) throw e_2.error; } } try { for (var _g = tslib_1.__values(this.maskElements), _h = _g.next(); !_h.done; _h = _g.next()) { var mask = _h.value; masks.appendChild(mask); } } catch (e_3_1) { e_3 = { error: e_3_1 }; } finally { try { if (_h && !_h.done && (_c = _g.return)) _c.call(_g); } finally { if (e_3) throw e_3.error; } } try { for (var _j = tslib_1.__values(this.gradients), _k = _j.next(); !_k.done; _k = _j.next()) { var gradient = _k.value; defs.appendChild(gradient); } } catch (e_4_1) { e_4 = { error: e_4_1 }; } finally { try { if (_k && !_k.done && (_d = _j.return)) _d.call(_j); } finally { if (e_4) throw e_4.error; } } if (this.opts.id) { paths.setAttributeNS(null, 'mask', "url(#text-mask-".concat(this.opts.id, ")")); } else { paths.setAttributeNS(null, 'mask', 'url(#text-mask)'); } if (this.svg) { this.svg.appendChild(defs); this.svg.appendChild(masks); this.svg.appendChild(style); this.svg.appendChild(paths); this.svg.appendChild(vertices); return this.svg; } else { var container = document.createElementNS('http://www.w3.org/2000/svg', 'g'); container.appendChild(defs); container.appendChild(masks); container.appendChild(style); container.appendChild(paths); container.appendChild(vertices); return container; } }; /** * Create a linear gradient to apply to a line * * @param {Line} line the line to apply the gradiation to. */ SvgWrapper.prototype.createGradient = function (line) { // create the gradient and add it var gradient = document.createElementNS('http://www.w3.org/2000/svg', 'linearGradient'), gradientUrl = "line-".concat(this.gradientId++), l = line.getLeftVector(), r = line.getRightVector(), fromX = l.x + this.offsetX, fromY = l.y + this.offsetY, toX = r.x + this.offsetX, toY = r.y + this.offsetY; if (this.opts.id) { gradientUrl = "line-".concat(this.opts.id, "-").concat(this.gradientId++); } gradient.setAttributeNS(null, 'id', gradientUrl); gradient.setAttributeNS(null, 'gradientUnits', 'userSpaceOnUse'); gradient.setAttributeNS(null, 'x1', fromX); gradient.setAttributeNS(null, 'y1', fromY); gradient.setAttributeNS(null, 'x2', toX); gradient.setAttributeNS(null, 'y2', toY); var firstColor = this.opts.disableGradient ? this.themeManager.getColor(this.themeManager.getColor('C')) : this.themeManager.getColor(line.getLeftElement()) || this.themeManager.getColor('C'); var secondColor = this.opts.disableGradient ? this.themeManager.getColor(this.themeManager.getColor('C')) : this.themeManager.getColor(line.getRightElement() || this.themeManager.getColor('C')); var firstStop = document.createElementNS('http://www.w3.org/2000/svg', 'stop'); firstStop.setAttributeNS(null, 'stop-color', firstColor); firstStop.setAttributeNS(null, 'offset', '20%'); var secondStop = document.createElementNS('http://www.w3.org/2000/svg', 'stop'); secondStop.setAttributeNS(null, 'stop-color', secondColor); secondStop.setAttributeNS(null, 'offset', '100%'); gradient.appendChild(firstStop); gradient.appendChild(secondStop); this.gradients.push(gradient); return gradientUrl; }; /** * Create a tspan element for sub or super scripts that styles the text * appropriately as one of those text types. * * @param {String} text the actual text * @param {String} shift the type of text, either 'sub', or 'super' */ SvgWrapper.prototype.createSubSuperScripts = function (text, shift) { var subClassName = this.opts.id ? 'sub-' + this.opts.id : 'sub'; var elem = document.createElementNS('http://www.w3.org/2000/svg', 'tspan'); elem.setAttributeNS(null, 'baseline-shift', shift); elem.appendChild(document.createTextNode(text)); elem.setAttributeNS(null, 'class', subClassName); return elem; }; /** * Determine drawing dimensiosn based on vertex positions. * * @param {Vertex[]} vertices An array of vertices containing the vertices associated with the current molecule. */ SvgWrapper.prototype.determineDimensions = function (vertices) { // Figure out the final size of the image var maxX = -Number.MAX_VALUE; var maxY = -Number.MAX_VALUE; var minX = Number.MAX_VALUE; var minY = Number.MAX_VALUE; for (var i = 0; i < vertices.length; i++) { if (!vertices[i].value.isDrawn) { continue; } var p = vertices[i].position; if (maxX < p.x) maxX = p.x; if (maxY < p.y) maxY = p.y; if (minX > p.x) minX = p.x; if (minY > p.y) minY = p.y; } // Add padding var padding = this.opts.padding; maxX += padding * 4; maxY += padding * 2; minX -= padding * 4; minY -= padding * 2; this.drawingWidth = maxX - minX; this.drawingHeight = maxY - minY; // let scaleX = this.svg.clientWidth // ? this.svg.clientWidth / this.drawingWidth // : this.opts.width / this.drawingWidth; // let scaleY = this.svg.clientHeight // ? this.svg.clientHeight / this.drawingHeight // : this.opts.height / this.drawingHeight; // let scale = (scaleX < scaleY) ? scaleX : scaleY; var viewBoxDim = Math.round(this.drawingWidth > this.drawingHeight ? this.drawingWidth : this.drawingHeight); // this.svg.setAttributeNS(null, 'viewBox', `0 0 ${viewBoxDim} ${viewBoxDim}`); this.svg.setAttributeNS(null, 'viewBox', "0 0 ".concat(viewBoxDim, " ").concat(this.drawingHeight)); this.offsetX = -minX; this.offsetY = -minY; // Center // if (scaleX < scaleY) { // if (this.svg.clientHeight ) { // this.offsetY += this.svg.clientHeight / (2.0 * scale) - this.drawingHeight / 2.0; // } else { // this.offsetY += this.opts.height / (2.0 * scale) - this.drawingHeight / 2.0; // } // } else { // if (this.svg.clientWidth) { // this.offsetX += this.svg.clientWidth / (2.0 * scale) - this.drawingWidth / 2.0; // } else { // this.offsetX += this.opts.width / (2.0 * scale) - this.drawingWidth / 2.0; // } // // } }; /** * Draw an svg ellipse as a ball. * * @param {Number} x The x position of the text. * @param {Number} y The y position of the text. * @param {String} elementName The name of the element (single-letter). */ SvgWrapper.prototype.drawBall = function (x, y, elementName) { var ball = document.createElementNS('http://www.w3.org/2000/svg', 'circle'); ball.setAttributeNS(null, 'cx', x + this.offsetX); ball.setAttributeNS(null, 'cy', y + this.offsetY); ball.setAttributeNS(null, 'r', (this.opts.bondLength / 4.5).toString()); ball.setAttributeNS(null, 'fill', this.themeManager.getColor(elementName)); this.vertices.push(ball); }; /** * Draw a dashed wedge on the canvas. * * @param {Line} line A line. */ SvgWrapper.prototype.drawDashedWedge = function (line) { if (isNaN(line.from.x) || isNaN(line.from.y) || isNaN(line.to.x) || isNaN(line.to.y)) { return; } var // offsetX = this.offsetX, // offsetY = this.offsetY, l = line.getLeftVector().clone(), r = line.getRightVector().clone(), normals = Vector2_1.default.normals(l, r); normals[0].normalize(); normals[1].normalize(); var isRightChiralCenter = line.getRightChiral(), start, end; if (isRightChiralCenter) { start = r; end = l; } else { start = l; end = r; } var dir = Vector2_1.default.subtract(end, start).normalize(), length = line.getLength(), step = 1.25 / (length / (this.opts.bondThickness * 3.0)); // changed = false; var gradient = this.createGradient(line); for (var t = 0.0; t < 1.0; t += step) { var to = Vector2_1.default.multiplyScalar(dir, t * length), startDash = Vector2_1.default.add(start, to), width = 1.5 * t, dashOffset = Vector2_1.default.multiplyScalar(normals[0], width); startDash.subtract(dashOffset); var endDash = startDash.clone(); endDash.add(Vector2_1.default.multiplyScalar(dashOffset, 2.0)); this.drawLine(new Line_1.default(startDash, endDash), null, gradient); } }; /** * Draws a debug dot at a given coordinate and adds text. * * @param {Number} x The x coordinate. * @param {Number} y The y coordindate. * @param {String} [debugText=''] A string. * @param {String} [color='#f00'] A color in hex form. */ SvgWrapper.prototype.drawDebugPoint = function (x, y, debugText, color) { if (debugText === void 0) { debugText = ''; } if (color === void 0) { color = '#f00'; } var point = document.createElementNS('http://www.w3.org/2000/svg', 'circle'); point.setAttributeNS(null, 'cx', x + this.offsetX); point.setAttributeNS(null, 'cy', y + this.offsetY); point.setAttributeNS(null, 'r', '2'); point.setAttributeNS(null, 'fill', '#f00'); this.vertices.push(point); this.drawDebugText(x, y, debugText); }; /** * Draws a debug text message at a given position * * @param {Number} x The x coordinate. * @param {Number} y The y coordinate. * @param {String} text The debug text. */ SvgWrapper.prototype.drawDebugText = function (x, y, text) { var color = this.opts.disableColors ? this.themeManager.getColor('C') : '#ff0000'; var textElem = document.createElementNS('http://www.w3.org/2000/svg', 'text'); textElem.setAttributeNS(null, 'x', x + this.offsetX); textElem.setAttributeNS(null, 'y', y + this.offsetY); textElem.setAttributeNS(null, 'class', 'debug'); textElem.setAttributeNS(null, 'fill', color); textElem.setAttributeNS(null, 'style', "\n font: 5px Droid Sans, sans-serif;\n "); textElem.appendChild(document.createTextNode(text)); this.vertices.push(textElem); }; /** * Draws a line. * * @param {Line} line A line. * @param {Boolean} dashed defaults to false. * @param {String} gradient gradient url. Defaults to null. */ SvgWrapper.prototype.drawLine = function (line, dashed, gradient) { if (dashed === void 0) { dashed = false; } if (gradient === void 0) { gradient = null; } var // opts = this.opts, stylesArr = [ ['stroke-linecap', 'round'], ['stroke-dasharray', dashed ? '5, 5' : 'none'], ['stroke-width', this.opts.bondThickness], ], l = line.getLeftVector(), r = line.getRightVector(), fromX = l.x + this.offsetX, fromY = l.y + this.offsetY, toX = r.x + this.offsetX, toY = r.y + this.offsetY; var styles = stylesArr.map(function (sub) { return sub.join(':'); }).join(';'), lineElem = document.createElementNS('http://www.w3.org/2000/svg', 'line'); lineElem.setAttributeNS(null, 'x1', fromX); lineElem.setAttributeNS(null, 'y1', fromY); lineElem.setAttributeNS(null, 'x2', toX); lineElem.setAttributeNS(null, 'y2', toY); lineElem.setAttributeNS(null, 'style', styles); this.paths.push(lineElem); if (gradient == null) { // gradient = this.createGradient(line, fromX, fromY, toX, toY); gradient = this.createGradient(line); } lineElem.setAttributeNS(null, 'stroke', "url('#".concat(gradient, "')")); }; /** * Draw a point. * * @param {Number} x The x position of the point. * @param {Number} y The y position of the point. * @param {String} elementName The name of the element (single-letter). */ SvgWrapper.prototype.drawPoint = function (x, y, elementName) { // let ctx = this.ctx; var offsetX = this.offsetX; var offsetY = this.offsetY; // first create a mask var mask = document.createElementNS('http://www.w3.org/2000/svg', 'circle'); mask.setAttributeNS(null, 'cx', x + offsetX); mask.setAttributeNS(null, 'cy', y + offsetY); mask.setAttributeNS(null, 'r', '1.5'); mask.setAttributeNS(null, 'fill', 'black'); this.maskElements.push(mask); // now create the point var point = document.createElementNS('http://www.w3.org/2000/svg', 'circle'); point.setAttributeNS(null, 'cx', x + offsetX); point.setAttributeNS(null, 'cy', y + offsetY); point.setAttributeNS(null, 'r', '0.75'); point.setAttributeNS(null, 'fill', this.themeManager.getColor(elementName)); this.vertices.push(point); }; /** * Draw a text to the canvas. * * @param {Number} x The x position of the text. * @param {Number} y The y position of the text. * @param {String} elementName The name of the element (single-letter). * @param {Number} hydrogens The number of hydrogen atoms. * @param {String} direction The direction of the text in relation to the associated vertex. * @param {Boolean} isTerminal A boolean indicating whether or not the vertex is terminal. * @param {Number} charge The charge of the atom. * @param {Number} isotope The isotope number. * @param {Object} attachedPseudoElement A map with containing information for pseudo elements or concatinated elements. The key is comprised of the element symbol and the hydrogen count. * @param {String} attachedPseudoElement.element The element symbol. * @param {Number} attachedPseudoElement.count The number of occurences that match the key. * @param {Number} attachedPseudoElement.hyrogenCount The number of hydrogens attached to each atom matching the key. */ SvgWrapper.prototype.drawText = function (x, y, elementName, hydrogens, direction, isTerminal, charge, isotope, attachedPseudoElement, isCentre) { if (attachedPseudoElement === void 0) { attachedPseudoElement = {}; } var dFont = this.opts.fontSizeLarge / 2; var coeffWidth = (0, Atom_1.getAtomCoefficientForWidth)(elementName); var radius = dFont + dFont / this.opts.dCircle; radius += (direction === 'down' || direction === 'up') && coeffWidth !== -1 ? direction === 'down' ? dFont / (2 * coeffWidth) : dFont / coeffWidth : 0; var elementClassName = this.opts.id ? 'element-' + this.opts.id : 'element'; var offsetX = this.offsetX, offsetY = this.offsetY, pos = { x: x + offsetX, y: y + offsetY, }, textElem = document.createElementNS('http://www.w3.org/2000/svg', 'text'), writingMode = 'horizontal-tb', letterSpacing = 'normal', textOrientation = 'mixed', textDirection = 'direction: ltr;', xShift = -dFont, yShift = dFont; var writingModeOld = this.opts.supportSvg1 ? 'rl-tb' : ''; var textOrientationOld = ''; var mask = document.createElementNS('http://www.w3.org/2000/svg', 'circle'); mask.setAttributeNS(null, 'cx', pos.x); mask.setAttributeNS(null, 'cy', pos.y); mask.setAttributeNS(null, 'r', (radius).toString()); mask.setAttributeNS(null, 'fill', 'black'); this.maskElements.push(mask); // determine writing mode if (/up|down/.test(direction) && !isTerminal) { writingMode = 'vertical-rl'; textOrientation = 'upright'; writingModeOld = this.opts.supportSvg1 ? 'tb' : ''; textOrientationOld = 'glyph-orientation-vertical: 0;'; // Need for Arora and Safari letterSpacing = '-1px'; } if (direction === 'down' && (!isTerminal || isCentre || elementName.length === 2)) { xShift = 0; if (elementName.length === 2) { yShift = dFont; } else { yShift = -dFont - dFont / 2; } } else if (direction === 'up' && !isTerminal) { xShift = 0; if (isCentre && elementName.length === 2) { yShift = dFont; } else { if (elementName.length === 2) { yShift = dFont; } else { yShift += dFont / 2; } } } else if (direction === 'left') { xShift = dFont; } else if (direction === 'right') { if (isCentre && elementName.length === 2) { xShift -= dFont / 2; } else { xShift += dFont / 4; } } if (direction === 'left' || (direction === 'up' && !isTerminal)) { textDirection = 'direction: rtl; unicode-bidi: bidi-override;'; } // now the text element textElem.setAttributeNS(null, 'x', pos.x + xShift); textElem.setAttributeNS(null, 'y', pos.y + yShift); textElem.setAttributeNS(null, 'class', elementClassName); textElem.setAttributeNS(null, 'fill', this.themeManager.getColor(elementName)); var style = ['text-anchor: start;']; if (this.opts.supportSvg1 && writingModeOld) { style.push("writing-mode: ".concat(writingModeOld, ";")); } if (textOrientationOld) { style.push(textOrientationOld); } style.push("writing-mode: ".concat(writingMode, ";")); style.push("text-orientation: ".concat(textOrientation, ";")); style.push("letter-spacing: ".concat(letterSpacing, ";")); style.push(textDirection); textElem.setAttributeNS(null, 'style', style.join(' ')); var textNode = document.createElementNS('http://www.w3.org/2000/svg', 'tspan'); // special case for element names that are 2 letters if (elementName.length > 1) { var textAnchor = /up|down/.test(direction) ? 'middle' : 'start'; textNode.setAttributeNS(null, 'style', "\n unicode-bidi: plaintext;\n writing-mode: lr-tb;\n letter-spacing: normal;\n text-anchor: ".concat(textAnchor, ";\n ")); } var isAdded = false; if (this.opts.supportSvg1 && hydrogens === 1 && (direction === 'left' || (direction === 'up' && !isTerminal))) { if (direction === 'up' && !isTerminal) { textNode.appendChild(document.createTextNode('H' + elementName)); } else { textNode.appendChild(document.createTextNode(elementName + 'H')); } isAdded = true; } else { textNode.appendChild(document.createTextNode(elementName)); } textElem.appendChild(textNode); // Charge if (charge) { var chargeElem = this.createSubSuperScripts((0, UtilityFunctions_1.getChargeText)(charge), 'super'); textNode.appendChild(chargeElem); } // let isotopeText = '0'; if (isotope > 0) { var isotopeElem = this.createSubSuperScripts(isotope.toString(), 'super'); textNode.appendChild(isotopeElem); } // TODO: Better handle exceptions // Exception for nitro (draw nitro as NO2 instead of N+O-O) if (charge === 1 && elementName === 'N' && attachedPseudoElement.hasOwnProperty('0O') && attachedPseudoElement.hasOwnProperty('0O-1')) { attachedPseudoElement = { '0O': { element: 'O', count: 2, hydrogenCount: 0, previousElement: 'C', charge: '' } }; charge = 0; } if (!isAdded && hydrogens > 0) { var hydrogenElem = document.createElementNS('http://www.w3.org/2000/svg', 'tspan'); hydrogenElem.setAttributeNS(null, 'style', 'unicode-bidi: plaintext;'); hydrogenElem.appendChild(document.createTextNode('H')); textElem.appendChild(hydrogenElem); if (hydrogens > 1) { var hydrogenCountElem = this.createSubSuperScripts(hydrogens, 'sub'); hydrogenElem.appendChild(hydrogenCountElem); } } for (var key in attachedPseudoElement) { if (!attachedPseudoElement.hasOwnProperty(key)) { continue; } var element = attachedPseudoElement[key].element, elementCount = attachedPseudoElement[key].count, hydrogenCount = attachedPseudoElement[key].hydrogenCount, elementCharge = attachedPseudoElement[key].charge, pseudoElementElem = document.createElementNS('http://www.w3.org/2000/svg', 'tspan'); pseudoElementElem.setAttributeNS(null, 'style', 'unicode-bidi: plaintext;'); pseudoElementElem.appendChild(document.createTextNode(element)); pseudoElementElem.setAttributeNS(null, 'fill', this.themeManager.getColor(element)); if (elementCharge !== 0) { var elementChargeElem = this.createSubSuperScripts((0, UtilityFunctions_1.getChargeText)(elementCharge), 'super'); pseudoElementElem.appendChild(elementChargeElem); } if (hydrogenCount > 0) { var pseudoHydrogenElem = document.createElementNS('http://www.w3.org/2000/svg', 'tspan'); pseudoHydrogenElem.setAttributeNS(null, 'style', 'unicode-bidi: plaintext;'); pseudoHydrogenElem.appendChild(document.createTextNode('H')); pseudoElementElem.appendChild(pseudoHydrogenElem); if (hydrogenCount > 1) { var hydrogenCountElem = this.createSubSuperScripts(hydrogenCount, 'sub'); pseudoHydrogenElem.appendChild(hydrogenCountElem); } } if (elementCount > 1) { var elementCountElem = this.createSubSuperScripts(elementCount, 'sub'); pseudoElementElem.appendChild(elementCountElem); } textElem.appendChild(pseudoElementElem); } this.vertices.push(textElem); }; /** * @param {Line} line the line object to create the wedge from */ SvgWrapper.prototype.drawWedge = function (line) { var offsetX = this.offsetX, offsetY = this.offsetY, l = line.getLeftVector().clone(), r = line.getRightVector().clone(); l.x += offsetX; l.y += offsetY; r.x += offsetX; r.y += offsetY; var normals = Vector2_1.default.normals(l, r); normals[0].normalize(); normals[1].normalize(); var isRightChiralCenter = line.getRightChiral(); var start = l, end = r; if (isRightChiralCenter) { start = r; end = l; } var t = Vector2_1.default.add(start, Vector2_1.default.multiplyScalar(normals[0], this.halfBondThickness)), u = Vector2_1.default.add(end, Vector2_1.default.multiplyScalar(normals[0], 1.5 + this.halfBondThickness)), v = Vector2_1.default.add(end, Vector2_1.default.multiplyScalar(normals[1], 1.5 + this.halfBondThickness)), w = Vector2_1.default.add(start, Vector2_1.default.multiplyScalar(normals[1], this.halfBondThickness)); var polygon = document.createElementNS('http://www.w3.org/2000/svg', 'polygon'), // gradient = this.createGradient(line, l.x, l.y, r.x, r.y); gradient = this.createGradient(line); polygon.setAttributeNS(null, 'points', "".concat(t.x, ",").concat(t.y, " ").concat(u.x, ",").concat(u.y, " ").concat(v.x, ",").concat(v.y, " ").concat(w.x, ",").concat(w.y)); polygon.setAttributeNS(null, 'fill', "url('#".concat(gradient, "')")); this.paths.push(polygon); }; /** * Draws a ring inside a provided ring, indicating aromaticity. * * @param {Ring} ring A ring. */ SvgWrapper.prototype.drawAromaticityRing = function (ring) { var ball = document.createElementNS('http://www.w3.org/2000/svg', 'circle'); var radius = MathHelper_1.default.apothemFromSideLength(this.opts.bondLength, ring.getSize()); ball.setAttributeNS(null, 'cx', ring.center.x + this.offsetX); ball.setAttributeNS(null, 'cy', ring.center.y + this.offsetY); ball.setAttributeNS(null, 'r', (radius - this.opts.bondSpacing).toString()); ball.setAttributeNS(null, 'stroke', this.themeManager.getColor('C')); ball.setAttributeNS(null, 'stroke-width', this.opts.bondThickness); ball.setAttributeNS(null, 'fill', 'transparent'); this.vertices.push(ball); }; return SvgWrapper; }()); exports.default = SvgWrapper; //# sourceMappingURL=SvgWrapper.js.map