UNPKG

@antv/x6

Version:

JavaScript diagramming library that uses SVG and HTML for rendering.

333 lines 11.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.transformRectangle = exports.transformPolyline = exports.transformLine = exports.transformPoint = exports.matrixToTranslation = exports.matrixToRotation = exports.matrixToScale = exports.decomposeMatrix = exports.parseTransformString = exports.matrixToTransformString = exports.transformStringToMatrix = exports.createSVGTransform = exports.createSVGMatrix = exports.createSVGPoint = void 0; var geometry_1 = require("../../geometry"); var elem_1 = require("./elem"); var svgDocument = (0, elem_1.createSvgElement)('svg'); var transformRegex = /(\w+)\(([^,)]+),?([^)]+)?\)/gi; var transformSeparatorRegex = /[ ,]+/; var transformationListRegex = /^(\w+)\((.*)\)/; /** * Returns a SVG point object initialized with the `x` and `y` coordinates. * @see https://developer.mozilla.org/en/docs/Web/API/SVGPoint */ function createSVGPoint(x, y) { var p = svgDocument.createSVGPoint(); p.x = x; p.y = y; return p; } exports.createSVGPoint = createSVGPoint; /** * Returns the SVG transformation matrix initialized with the given matrix. * * The given matrix is an object of the form: * { * a: number * b: number * c: number * d: number * e: number * f: number * } * * @see https://developer.mozilla.org/en/docs/Web/API/SVGMatrix */ function createSVGMatrix(matrix) { var mat = svgDocument.createSVGMatrix(); if (matrix != null) { var source = matrix; var target = mat; // eslint-disable-next-line for (var key in source) { target[key] = source[key]; } } return mat; } exports.createSVGMatrix = createSVGMatrix; /** * Returns a SVG transform object. * @see https://developer.mozilla.org/en/docs/Web/API/SVGTransform */ function createSVGTransform(matrix) { if (matrix != null) { if (!(matrix instanceof DOMMatrix)) { matrix = createSVGMatrix(matrix); // eslint-disable-line } return svgDocument.createSVGTransformFromMatrix(matrix); } return svgDocument.createSVGTransform(); } exports.createSVGTransform = createSVGTransform; /** * Returns the SVG transformation matrix built from the `transformString`. * * E.g. 'translate(10,10) scale(2,2)' will result in matrix: * `{ a: 2, b: 0, c: 0, d: 2, e: 10, f: 10}` */ function transformStringToMatrix(transform) { var mat = createSVGMatrix(); var matches = transform != null && transform.match(transformRegex); if (!matches) { return mat; } for (var i = 0, n = matches.length; i < n; i += 1) { var transformationString = matches[i]; var transformationMatch = transformationString.match(transformationListRegex); if (transformationMatch) { var sx = void 0; var sy = void 0; var tx = void 0; var ty = void 0; var angle = void 0; var ctm = createSVGMatrix(); var args = transformationMatch[2].split(transformSeparatorRegex); switch (transformationMatch[1].toLowerCase()) { case 'scale': sx = parseFloat(args[0]); sy = args[1] === undefined ? sx : parseFloat(args[1]); ctm = ctm.scaleNonUniform(sx, sy); break; case 'translate': tx = parseFloat(args[0]); ty = parseFloat(args[1]); ctm = ctm.translate(tx, ty); break; case 'rotate': angle = parseFloat(args[0]); tx = parseFloat(args[1]) || 0; ty = parseFloat(args[2]) || 0; if (tx !== 0 || ty !== 0) { ctm = ctm.translate(tx, ty).rotate(angle).translate(-tx, -ty); } else { ctm = ctm.rotate(angle); } break; case 'skewx': angle = parseFloat(args[0]); ctm = ctm.skewX(angle); break; case 'skewy': angle = parseFloat(args[0]); ctm = ctm.skewY(angle); break; case 'matrix': ctm.a = parseFloat(args[0]); ctm.b = parseFloat(args[1]); ctm.c = parseFloat(args[2]); ctm.d = parseFloat(args[3]); ctm.e = parseFloat(args[4]); ctm.f = parseFloat(args[5]); break; default: continue; } mat = mat.multiply(ctm); } } return mat; } exports.transformStringToMatrix = transformStringToMatrix; function matrixToTransformString(matrix) { var m = matrix || {}; var a = m.a != null ? m.a : 1; var b = m.b != null ? m.b : 0; var c = m.c != null ? m.c : 0; var d = m.d != null ? m.d : 1; var e = m.e != null ? m.e : 0; var f = m.f != null ? m.f : 0; return "matrix(" + a + "," + b + "," + c + "," + d + "," + e + "," + f + ")"; } exports.matrixToTransformString = matrixToTransformString; function parseTransformString(transform) { var translation; var rotation; var scale; if (transform) { var separator = transformSeparatorRegex; // Allow reading transform string with a single matrix if (transform.trim().indexOf('matrix') >= 0) { var matrix = transformStringToMatrix(transform); var decomposedMatrix = decomposeMatrix(matrix); translation = [decomposedMatrix.translateX, decomposedMatrix.translateY]; rotation = [decomposedMatrix.rotation]; scale = [decomposedMatrix.scaleX, decomposedMatrix.scaleY]; var transformations = []; if (translation[0] !== 0 || translation[1] !== 0) { transformations.push("translate(" + translation.join(',') + ")"); } if (scale[0] !== 1 || scale[1] !== 1) { transformations.push("scale(" + scale.join(',') + ")"); } if (rotation[0] !== 0) { transformations.push("rotate(" + rotation[0] + ")"); } transform = transformations.join(' '); // eslint-disable-line } else { var translateMatch = transform.match(/translate\((.*?)\)/); if (translateMatch) { translation = translateMatch[1].split(separator); } var rotateMatch = transform.match(/rotate\((.*?)\)/); if (rotateMatch) { rotation = rotateMatch[1].split(separator); } var scaleMatch = transform.match(/scale\((.*?)\)/); if (scaleMatch) { scale = scaleMatch[1].split(separator); } } } var sx = scale && scale[0] ? parseFloat(scale[0]) : 1; return { raw: transform || '', translation: { tx: translation && translation[0] ? parseInt(translation[0], 10) : 0, ty: translation && translation[1] ? parseInt(translation[1], 10) : 0, }, rotation: { angle: rotation && rotation[0] ? parseInt(rotation[0], 10) : 0, cx: rotation && rotation[1] ? parseInt(rotation[1], 10) : undefined, cy: rotation && rotation[2] ? parseInt(rotation[2], 10) : undefined, }, scale: { sx: sx, sy: scale && scale[1] ? parseFloat(scale[1]) : sx, }, }; } exports.parseTransformString = parseTransformString; function deltaTransformPoint(matrix, point) { var dx = point.x * matrix.a + point.y * matrix.c + 0; var dy = point.x * matrix.b + point.y * matrix.d + 0; return { x: dx, y: dy }; } /** * Decomposes the SVG transformation matrix into separate transformations. * * Returns an object of the form: * { * translateX: number * translateY: number * scaleX: number * scaleY: number * skewX: number * skewY: number * rotation: number * } * * @see https://developer.mozilla.org/en/docs/Web/API/SVGMatrix */ function decomposeMatrix(matrix) { // @see https://gist.github.com/2052247 var px = deltaTransformPoint(matrix, { x: 0, y: 1 }); var py = deltaTransformPoint(matrix, { x: 1, y: 0 }); var skewX = (180 / Math.PI) * Math.atan2(px.y, px.x) - 90; var skewY = (180 / Math.PI) * Math.atan2(py.y, py.x); return { skewX: skewX, skewY: skewY, translateX: matrix.e, translateY: matrix.f, scaleX: Math.sqrt(matrix.a * matrix.a + matrix.b * matrix.b), scaleY: Math.sqrt(matrix.c * matrix.c + matrix.d * matrix.d), rotation: skewX, }; } exports.decomposeMatrix = decomposeMatrix; function matrixToScale(matrix) { var a; var b; var c; var d; if (matrix) { a = matrix.a == null ? 1 : matrix.a; d = matrix.d == null ? 1 : matrix.d; b = matrix.b; c = matrix.c; } else { a = d = 1; } return { sx: b ? Math.sqrt(a * a + b * b) : a, sy: c ? Math.sqrt(c * c + d * d) : d, }; } exports.matrixToScale = matrixToScale; function matrixToRotation(matrix) { var p = { x: 0, y: 1 }; if (matrix) { p = deltaTransformPoint(matrix, p); } return { angle: geometry_1.Angle.normalize(geometry_1.Angle.toDeg(Math.atan2(p.y, p.x)) - 90), }; } exports.matrixToRotation = matrixToRotation; function matrixToTranslation(matrix) { return { tx: (matrix && matrix.e) || 0, ty: (matrix && matrix.f) || 0, }; } exports.matrixToTranslation = matrixToTranslation; /** * Transforms point by an SVG transformation represented by `matrix`. */ function transformPoint(point, matrix) { var ret = createSVGPoint(point.x, point.y).matrixTransform(matrix); return new geometry_1.Point(ret.x, ret.y); } exports.transformPoint = transformPoint; /** * Transforms line by an SVG transformation represented by `matrix`. */ function transformLine(line, matrix) { return new geometry_1.Line(transformPoint(line.start, matrix), transformPoint(line.end, matrix)); } exports.transformLine = transformLine; /** * Transforms polyline by an SVG transformation represented by `matrix`. */ function transformPolyline(polyline, matrix) { var points = polyline instanceof geometry_1.Polyline ? polyline.points : polyline; if (!Array.isArray(points)) { points = []; } return new geometry_1.Polyline(points.map(function (p) { return transformPoint(p, matrix); })); } exports.transformPolyline = transformPolyline; function transformRectangle(rect, matrix) { var p = svgDocument.createSVGPoint(); p.x = rect.x; p.y = rect.y; var corner1 = p.matrixTransform(matrix); p.x = rect.x + rect.width; p.y = rect.y; var corner2 = p.matrixTransform(matrix); p.x = rect.x + rect.width; p.y = rect.y + rect.height; var corner3 = p.matrixTransform(matrix); p.x = rect.x; p.y = rect.y + rect.height; var corner4 = p.matrixTransform(matrix); var minX = Math.min(corner1.x, corner2.x, corner3.x, corner4.x); var maxX = Math.max(corner1.x, corner2.x, corner3.x, corner4.x); var minY = Math.min(corner1.y, corner2.y, corner3.y, corner4.y); var maxY = Math.max(corner1.y, corner2.y, corner3.y, corner4.y); return new geometry_1.Rectangle(minX, minY, maxX - minX, maxY - minY); } exports.transformRectangle = transformRectangle; //# sourceMappingURL=matrix.js.map