UNPKG

@antv/x6

Version:

JavaScript diagramming library that uses SVG and HTML for rendering.

216 lines 7.84 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.drawArc = exports.arcToCurves = exports.drawPoints = exports.isValid = void 0; var point_1 = require("../point"); var regexSupportedData = new RegExp("^[\\s\\dLMCZz,.]*$"); function isValid(data) { if (typeof data !== 'string') { return false; } return regexSupportedData.test(data); } exports.isValid = isValid; /** * Returns the remainder of division of `n` by `m`. You should use this * instead of the built-in operation as the built-in operation does not * properly handle negative numbers. */ function mod(n, m) { return ((n % m) + m) % m; } function draw(points, round, initialMove, close, exclude) { var data = []; var end = points[points.length - 1]; var rounded = round != null && round > 0; var arcSize = round || 0; // Adds virtual waypoint in the center between start and end point if (close && rounded) { points = points.slice(); // eslint-disable-line var p0 = points[0]; var wp = new point_1.Point(end.x + (p0.x - end.x) / 2, end.y + (p0.y - end.y) / 2); points.splice(0, 0, wp); } var pt = points[0]; var i = 1; // Draws the line segments if (initialMove) { data.push('M', pt.x, pt.y); } else { data.push('L', pt.x, pt.y); } while (i < (close ? points.length : points.length - 1)) { var tmp = points[mod(i, points.length)]; var dx = pt.x - tmp.x; var dy = pt.y - tmp.y; if (rounded && (dx !== 0 || dy !== 0) && (exclude == null || exclude.indexOf(i - 1) < 0)) { // Draws a line from the last point to the current // point with a spacing of size off the current point // into direction of the last point var dist = Math.sqrt(dx * dx + dy * dy); var nx1 = (dx * Math.min(arcSize, dist / 2)) / dist; var ny1 = (dy * Math.min(arcSize, dist / 2)) / dist; var x1 = tmp.x + nx1; var y1 = tmp.y + ny1; data.push('L', x1, y1); // Draws a curve from the last point to the current // point with a spacing of size off the current point // into direction of the next point var next = points[mod(i + 1, points.length)]; // Uses next non-overlapping point while (i < points.length - 2 && Math.round(next.x - tmp.x) === 0 && Math.round(next.y - tmp.y) === 0) { next = points[mod(i + 2, points.length)]; i += 1; } dx = next.x - tmp.x; dy = next.y - tmp.y; dist = Math.max(1, Math.sqrt(dx * dx + dy * dy)); var nx2 = (dx * Math.min(arcSize, dist / 2)) / dist; var ny2 = (dy * Math.min(arcSize, dist / 2)) / dist; var x2 = tmp.x + nx2; var y2 = tmp.y + ny2; data.push('Q', tmp.x, tmp.y, x2, y2); tmp = new point_1.Point(x2, y2); } else { data.push('L', tmp.x, tmp.y); } pt = tmp; i += 1; } if (close) { data.push('Z'); } else { data.push('L', end.x, end.y); } return data.map(function (v) { return (typeof v === 'string' ? v : +v.toFixed(3)); }).join(' '); } function drawPoints(points, options) { if (options === void 0) { options = {}; } var pts = []; if (points && points.length) { points.forEach(function (p) { if (Array.isArray(p)) { pts.push({ x: p[0], y: p[1] }); } else { pts.push({ x: p.x, y: p.y }); } }); } return draw(pts, options.round, options.initialMove == null || options.initialMove, options.close, options.exclude); } exports.drawPoints = drawPoints; /** * Converts the given arc to a series of curves. */ function arcToCurves(x0, y0, r1, r2, angle, largeArcFlag, sweepFlag, x, y) { if (angle === void 0) { angle = 0; } if (largeArcFlag === void 0) { largeArcFlag = 0; } if (sweepFlag === void 0) { sweepFlag = 0; } if (r1 === 0 || r2 === 0) { return []; } x -= x0; // eslint-disable-line y -= y0; // eslint-disable-line r1 = Math.abs(r1); // eslint-disable-line r2 = Math.abs(r2); // eslint-disable-line var ctx = -x / 2; var cty = -y / 2; var cpsi = Math.cos((angle * Math.PI) / 180); var spsi = Math.sin((angle * Math.PI) / 180); var rxd = cpsi * ctx + spsi * cty; var ryd = -1 * spsi * ctx + cpsi * cty; var rxdd = rxd * rxd; var rydd = ryd * ryd; var r1x = r1 * r1; var r2y = r2 * r2; var lamda = rxdd / r1x + rydd / r2y; var sds; if (lamda > 1) { r1 = Math.sqrt(lamda) * r1; // eslint-disable-line r2 = Math.sqrt(lamda) * r2; // eslint-disable-line sds = 0; } else { var seif = 1; if (largeArcFlag === sweepFlag) { seif = -1; } sds = seif * Math.sqrt((r1x * r2y - r1x * rydd - r2y * rxdd) / (r1x * rydd + r2y * rxdd)); } var txd = (sds * r1 * ryd) / r2; var tyd = (-1 * sds * r2 * rxd) / r1; var tx = cpsi * txd - spsi * tyd + x / 2; var ty = spsi * txd + cpsi * tyd + y / 2; var rad = Math.atan2((ryd - tyd) / r2, (rxd - txd) / r1) - Math.atan2(0, 1); var s1 = rad >= 0 ? rad : 2 * Math.PI + rad; rad = Math.atan2((-ryd - tyd) / r2, (-rxd - txd) / r1) - Math.atan2((ryd - tyd) / r2, (rxd - txd) / r1); var dr = rad >= 0 ? rad : 2 * Math.PI + rad; if (sweepFlag === 0 && dr > 0) { dr -= 2 * Math.PI; } else if (sweepFlag !== 0 && dr < 0) { dr += 2 * Math.PI; } var sse = (dr * 2) / Math.PI; var seg = Math.ceil(sse < 0 ? -1 * sse : sse); var segr = dr / seg; var t = ((8 / 3) * Math.sin(segr / 4) * Math.sin(segr / 4)) / Math.sin(segr / 2); var cpsir1 = cpsi * r1; var cpsir2 = cpsi * r2; var spsir1 = spsi * r1; var spsir2 = spsi * r2; var mc = Math.cos(s1); var ms = Math.sin(s1); var x2 = -t * (cpsir1 * ms + spsir2 * mc); var y2 = -t * (spsir1 * ms - cpsir2 * mc); var x3 = 0; var y3 = 0; var result = []; for (var n = 0; n < seg; n += 1) { s1 += segr; mc = Math.cos(s1); ms = Math.sin(s1); x3 = cpsir1 * mc - spsir2 * ms + tx; y3 = spsir1 * mc + cpsir2 * ms + ty; var dx = -t * (cpsir1 * ms + spsir2 * mc); var dy = -t * (spsir1 * ms - cpsir2 * mc); // CurveTo updates x0, y0 so need to restore it var index = n * 6; result[index] = Number(x2 + x0); result[index + 1] = Number(y2 + y0); result[index + 2] = Number(x3 - dx + x0); result[index + 3] = Number(y3 - dy + y0); result[index + 4] = Number(x3 + x0); result[index + 5] = Number(y3 + y0); x2 = x3 + dx; y2 = y3 + dy; } return result.map(function (num) { return +num.toFixed(2); }); } exports.arcToCurves = arcToCurves; function drawArc(startX, startY, rx, ry, xAxisRotation, largeArcFlag, sweepFlag, stopX, stopY) { if (xAxisRotation === void 0) { xAxisRotation = 0; } if (largeArcFlag === void 0) { largeArcFlag = 0; } if (sweepFlag === void 0) { sweepFlag = 0; } var data = []; var points = arcToCurves(startX, startY, rx, ry, xAxisRotation, largeArcFlag, sweepFlag, stopX, stopY); if (points != null) { for (var i = 0, ii = points.length; i < ii; i += 6) { data.push('C', points[i], points[i + 1], points[i + 2], points[i + 3], points[i + 4], points[i + 5]); } } return data.join(' '); } exports.drawArc = drawArc; //# sourceMappingURL=util.js.map