123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- import getArcParams from './get-arc-params';
- import { isSamePoint } from './get-arc-params';
- import parsePath from './parse-path';
- // 点对称
- function toSymmetry(point, center) {
- return [center[0] + (center[0] - point[0]), center[1] + (center[1] - point[1])];
- }
- export default function getSegments(path) {
- path = parsePath(path);
- var segments = [];
- var currentPoint = null; // 当前图形
- var nextParams = null; // 下一节点的 path 参数
- var startMovePoint = null; // 开始 M 的点,可能会有多个
- var lastStartMovePointIndex = 0; // 最近一个开始点 M 的索引
- var count = path.length;
- for (var i = 0; i < count; i++) {
- var params = path[i];
- nextParams = path[i + 1];
- var command = params[0];
- // 数学定义上的参数,便于后面的计算
- var segment = {
- command: command,
- prePoint: currentPoint,
- params: params,
- startTangent: null,
- endTangent: null,
- };
- switch (command) {
- case 'M':
- startMovePoint = [params[1], params[2]];
- lastStartMovePointIndex = i;
- break;
- case 'A':
- var arcParams = getArcParams(currentPoint, params);
- segment['arcParams'] = arcParams;
- break;
- default:
- break;
- }
- if (command === 'Z') {
- // 有了 Z 后,当前节点从开始 M 的点开始
- currentPoint = startMovePoint;
- // 如果当前点的命令为 Z,相当于当前点为最近一个 M 点,则下一个点直接指向最近一个 M 点的下一个点
- nextParams = path[lastStartMovePointIndex + 1];
- }
- else {
- var len = params.length;
- currentPoint = [params[len - 2], params[len - 1]];
- }
- if (nextParams && nextParams[0] === 'Z') {
- // 如果下一个点的命令为 Z,则下一个点直接指向最近一个 M 点
- nextParams = path[lastStartMovePointIndex];
- if (segments[lastStartMovePointIndex]) {
- // 如果下一个点的命令为 Z,则最近一个 M 点的前一个点为当前点
- segments[lastStartMovePointIndex].prePoint = currentPoint;
- }
- }
- segment['currentPoint'] = currentPoint;
- // 如果当前点与最近一个 M 点相同,则最近一个 M 点的前一个点为当前点的前一个点
- if (segments[lastStartMovePointIndex] &&
- isSamePoint(currentPoint, segments[lastStartMovePointIndex].currentPoint)) {
- segments[lastStartMovePointIndex].prePoint = segment.prePoint;
- }
- var nextPoint = nextParams ? [nextParams[nextParams.length - 2], nextParams[nextParams.length - 1]] : null;
- segment['nextPoint'] = nextPoint;
- // Add startTangent and endTangent
- var prePoint = segment.prePoint;
- if (['L', 'H', 'V'].includes(command)) {
- segment.startTangent = [prePoint[0] - currentPoint[0], prePoint[1] - currentPoint[1]];
- segment.endTangent = [currentPoint[0] - prePoint[0], currentPoint[1] - prePoint[1]];
- }
- else if (command === 'Q') {
- // 二次贝塞尔曲线只有一个控制点
- var cp = [params[1], params[2]];
- // 二次贝塞尔曲线的终点为 currentPoint
- segment.startTangent = [prePoint[0] - cp[0], prePoint[1] - cp[1]];
- segment.endTangent = [currentPoint[0] - cp[0], currentPoint[1] - cp[1]];
- }
- else if (command === 'T') {
- var preSegment = segments[i - 1];
- var cp = toSymmetry(preSegment.currentPoint, prePoint);
- if (preSegment.command === 'Q') {
- segment.command = 'Q';
- segment.startTangent = [prePoint[0] - cp[0], prePoint[1] - cp[1]];
- segment.endTangent = [currentPoint[0] - cp[0], currentPoint[1] - cp[1]];
- }
- else {
- segment.command = 'TL';
- segment.startTangent = [prePoint[0] - currentPoint[0], prePoint[1] - currentPoint[1]];
- segment.endTangent = [currentPoint[0] - prePoint[0], currentPoint[1] - prePoint[1]];
- }
- }
- else if (command === 'C') {
- // 三次贝塞尔曲线有两个控制点
- var cp1 = [params[1], params[2]];
- var cp2 = [params[3], params[4]];
- segment.startTangent = [prePoint[0] - cp1[0], prePoint[1] - cp1[1]];
- segment.endTangent = [currentPoint[0] - cp2[0], currentPoint[1] - cp2[1]];
- // horizontal line, eg. ['C', 100, 100, 100, 100, 200, 200]
- if (segment.startTangent[0] === 0 && segment.startTangent[1] === 0) {
- segment.startTangent = [cp1[0] - cp2[0], cp1[1] - cp2[1]];
- }
- if (segment.endTangent[0] === 0 && segment.endTangent[1] === 0) {
- segment.endTangent = [cp2[0] - cp1[0], cp2[1] - cp1[1]];
- }
- }
- else if (command === 'S') {
- var preSegment = segments[i - 1];
- var cp1 = toSymmetry(preSegment.currentPoint, prePoint);
- var cp2 = [params[1], params[2]];
- if (preSegment.command === 'C') {
- segment.command = 'C'; // 将 S 命令变换为 C 命令
- segment.startTangent = [prePoint[0] - cp1[0], prePoint[1] - cp1[1]];
- segment.endTangent = [currentPoint[0] - cp2[0], currentPoint[1] - cp2[1]];
- }
- else {
- segment.command = 'SQ'; // 将 S 命令变换为 SQ 命令
- segment.startTangent = [prePoint[0] - cp2[0], prePoint[1] - cp2[1]];
- segment.endTangent = [currentPoint[0] - cp2[0], currentPoint[1] - cp2[1]];
- }
- }
- else if (command === 'A') {
- var d = 0.001;
- var _a = segment['arcParams'] || {}, _b = _a.cx, cx = _b === void 0 ? 0 : _b, _c = _a.cy, cy = _c === void 0 ? 0 : _c, _d = _a.rx, rx = _d === void 0 ? 0 : _d, _e = _a.ry, ry = _e === void 0 ? 0 : _e, _f = _a.sweepFlag, sweepFlag = _f === void 0 ? 0 : _f, _g = _a.startAngle, startAngle = _g === void 0 ? 0 : _g, _h = _a.endAngle, endAngle = _h === void 0 ? 0 : _h;
- if (sweepFlag === 0) {
- d *= -1;
- }
- var dx1 = rx * Math.cos(startAngle - d) + cx;
- var dy1 = ry * Math.sin(startAngle - d) + cy;
- segment.startTangent = [dx1 - startMovePoint[0], dy1 - startMovePoint[1]];
- var dx2 = rx * Math.cos(startAngle + endAngle + d) + cx;
- var dy2 = ry * Math.sin(startAngle + endAngle - d) + cy;
- segment.endTangent = [prePoint[0] - dx2, prePoint[1] - dy2];
- }
- segments.push(segment);
- }
- return segments;
- }
- //# sourceMappingURL=path-2-segments.js.map
|