You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
349 lines
13 KiB
349 lines
13 KiB
/*!
|
|
* @antv/g-plugin-canvas-path-generator
|
|
* @description A G plugin of path generator with Canvas2D API
|
|
* @version 2.1.22
|
|
* @date 7/30/2025, 1:35:25 PM
|
|
* @author AntVis
|
|
* @docs https://g.antv.antgroup.com/
|
|
*/
|
|
'use strict';
|
|
|
|
var _defineProperty = require('@babel/runtime/helpers/defineProperty');
|
|
var _classCallCheck = require('@babel/runtime/helpers/classCallCheck');
|
|
var _createClass = require('@babel/runtime/helpers/createClass');
|
|
var _callSuper = require('@babel/runtime/helpers/callSuper');
|
|
var _inherits = require('@babel/runtime/helpers/inherits');
|
|
var gLite = require('@antv/g-lite');
|
|
var _slicedToArray = require('@babel/runtime/helpers/slicedToArray');
|
|
var util = require('@antv/util');
|
|
|
|
function generatePath$6(context, parsedStyle) {
|
|
var _parsedStyle$cx = parsedStyle.cx,
|
|
cx = _parsedStyle$cx === void 0 ? 0 : _parsedStyle$cx,
|
|
_parsedStyle$cy = parsedStyle.cy,
|
|
cy = _parsedStyle$cy === void 0 ? 0 : _parsedStyle$cy,
|
|
r = parsedStyle.r;
|
|
context.arc(cx, cy, r, 0, Math.PI * 2, false);
|
|
}
|
|
|
|
function generatePath$5(context, parsedStyle) {
|
|
var _parsedStyle$cx = parsedStyle.cx,
|
|
cx = _parsedStyle$cx === void 0 ? 0 : _parsedStyle$cx,
|
|
_parsedStyle$cy = parsedStyle.cy,
|
|
cy = _parsedStyle$cy === void 0 ? 0 : _parsedStyle$cy,
|
|
rx = parsedStyle.rx,
|
|
ry = parsedStyle.ry;
|
|
|
|
// @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/ellipse
|
|
if (context.ellipse) {
|
|
context.ellipse(cx, cy, rx, ry, 0, 0, Math.PI * 2, false);
|
|
} else {
|
|
// 如果不支持,则使用圆来绘制,进行变形
|
|
var r = rx > ry ? rx : ry;
|
|
var scaleX = rx > ry ? 1 : rx / ry;
|
|
var scaleY = rx > ry ? ry / rx : 1;
|
|
context.save();
|
|
context.scale(scaleX, scaleY);
|
|
context.arc(cx, cy, r, 0, Math.PI * 2);
|
|
}
|
|
}
|
|
|
|
function generatePath$4(context, parsedStyle) {
|
|
var x1 = parsedStyle.x1,
|
|
y1 = parsedStyle.y1,
|
|
x2 = parsedStyle.x2,
|
|
y2 = parsedStyle.y2,
|
|
markerStart = parsedStyle.markerStart,
|
|
markerEnd = parsedStyle.markerEnd,
|
|
markerStartOffset = parsedStyle.markerStartOffset,
|
|
markerEndOffset = parsedStyle.markerEndOffset;
|
|
var startOffsetX = 0;
|
|
var startOffsetY = 0;
|
|
var endOffsetX = 0;
|
|
var endOffsetY = 0;
|
|
var rad = 0;
|
|
var x;
|
|
var y;
|
|
if (markerStart && gLite.isDisplayObject(markerStart) && markerStartOffset) {
|
|
x = x2 - x1;
|
|
y = y2 - y1;
|
|
rad = Math.atan2(y, x);
|
|
startOffsetX = Math.cos(rad) * (markerStartOffset || 0);
|
|
startOffsetY = Math.sin(rad) * (markerStartOffset || 0);
|
|
}
|
|
if (markerEnd && gLite.isDisplayObject(markerEnd) && markerEndOffset) {
|
|
x = x1 - x2;
|
|
y = y1 - y2;
|
|
rad = Math.atan2(y, x);
|
|
endOffsetX = Math.cos(rad) * (markerEndOffset || 0);
|
|
endOffsetY = Math.sin(rad) * (markerEndOffset || 0);
|
|
}
|
|
context.moveTo(x1 + startOffsetX, y1 + startOffsetY);
|
|
context.lineTo(x2 + endOffsetX, y2 + endOffsetY);
|
|
}
|
|
|
|
function generatePath$3(context, parsedStyle) {
|
|
var markerStart = parsedStyle.markerStart,
|
|
markerEnd = parsedStyle.markerEnd,
|
|
markerStartOffset = parsedStyle.markerStartOffset,
|
|
markerEndOffset = parsedStyle.markerEndOffset;
|
|
var _parsedStyle$d = parsedStyle.d,
|
|
absolutePath = _parsedStyle$d.absolutePath,
|
|
segments = _parsedStyle$d.segments;
|
|
var startOffsetX = 0;
|
|
var startOffsetY = 0;
|
|
var endOffsetX = 0;
|
|
var endOffsetY = 0;
|
|
var rad = 0;
|
|
var x;
|
|
var y;
|
|
if (markerStart && gLite.isDisplayObject(markerStart) && markerStartOffset) {
|
|
var _getStartTangent = markerStart.parentNode.getStartTangent(),
|
|
_getStartTangent2 = _slicedToArray(_getStartTangent, 2),
|
|
p1 = _getStartTangent2[0],
|
|
p2 = _getStartTangent2[1];
|
|
x = p1[0] - p2[0];
|
|
y = p1[1] - p2[1];
|
|
rad = Math.atan2(y, x);
|
|
startOffsetX = Math.cos(rad) * (markerStartOffset || 0);
|
|
startOffsetY = Math.sin(rad) * (markerStartOffset || 0);
|
|
}
|
|
if (markerEnd && gLite.isDisplayObject(markerEnd) && markerEndOffset) {
|
|
var _getEndTangent = markerEnd.parentNode.getEndTangent(),
|
|
_getEndTangent2 = _slicedToArray(_getEndTangent, 2),
|
|
_p = _getEndTangent2[0],
|
|
_p2 = _getEndTangent2[1];
|
|
x = _p[0] - _p2[0];
|
|
y = _p[1] - _p2[1];
|
|
rad = Math.atan2(y, x);
|
|
endOffsetX = Math.cos(rad) * (markerEndOffset || 0);
|
|
endOffsetY = Math.sin(rad) * (markerEndOffset || 0);
|
|
}
|
|
for (var i = 0; i < absolutePath.length; i++) {
|
|
var params = absolutePath[i];
|
|
var command = params[0];
|
|
var nextSegment = absolutePath[i + 1];
|
|
var useStartOffset = i === 0 && (startOffsetX !== 0 || startOffsetY !== 0);
|
|
var useEndOffset = (i === absolutePath.length - 1 || nextSegment && (nextSegment[0] === 'M' || nextSegment[0] === 'Z')) && endOffsetX !== 0 && endOffsetY !== 0;
|
|
var _ref = useStartOffset ? [startOffsetX, startOffsetY] : [0, 0],
|
|
_ref2 = _slicedToArray(_ref, 2),
|
|
startOffsetXTemp = _ref2[0],
|
|
startOffsetYTemp = _ref2[1];
|
|
var _ref3 = useEndOffset ? [endOffsetX, endOffsetY] : [0, 0],
|
|
_ref4 = _slicedToArray(_ref3, 2),
|
|
endOffsetXTemp = _ref4[0],
|
|
endOffsetYTemp = _ref4[1];
|
|
switch (command) {
|
|
case 'M':
|
|
// Use start marker offset
|
|
context.moveTo(params[1] + startOffsetXTemp, params[2] + startOffsetYTemp);
|
|
break;
|
|
case 'L':
|
|
context.lineTo(params[1] + endOffsetXTemp, params[2] + endOffsetYTemp);
|
|
break;
|
|
case 'Q':
|
|
context.quadraticCurveTo(params[1], params[2], params[3] + endOffsetXTemp, params[4] + endOffsetYTemp);
|
|
break;
|
|
case 'C':
|
|
context.bezierCurveTo(params[1], params[2], params[3], params[4], params[5] + endOffsetXTemp, params[6] + endOffsetYTemp);
|
|
break;
|
|
case 'A':
|
|
{
|
|
// FIXME startOffset / endOffset
|
|
var arcParams = segments[i].arcParams;
|
|
var cx = arcParams.cx,
|
|
cy = arcParams.cy,
|
|
rx = arcParams.rx,
|
|
ry = arcParams.ry,
|
|
startAngle = arcParams.startAngle,
|
|
endAngle = arcParams.endAngle,
|
|
xRotation = arcParams.xRotation,
|
|
sweepFlag = arcParams.sweepFlag;
|
|
// @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/ellipse
|
|
if (context.ellipse) {
|
|
context.ellipse(cx, cy, rx, ry, xRotation, startAngle, endAngle, !!(1 - sweepFlag));
|
|
} else {
|
|
// @see https://stackoverflow.com/a/47494351
|
|
var r = rx > ry ? rx : ry;
|
|
var scaleX = rx > ry ? 1 : rx / ry;
|
|
var scaleY = rx > ry ? ry / rx : 1;
|
|
context.translate(cx, cy);
|
|
context.rotate(xRotation);
|
|
context.scale(scaleX, scaleY);
|
|
context.arc(0, 0, r, startAngle, endAngle, !!(1 - sweepFlag));
|
|
context.scale(1 / scaleX, 1 / scaleY);
|
|
context.rotate(-xRotation);
|
|
context.translate(-cx, -cy);
|
|
}
|
|
if (useEndOffset) {
|
|
context.lineTo(params[6] + endOffsetX, params[7] + endOffsetY);
|
|
}
|
|
break;
|
|
}
|
|
case 'Z':
|
|
context.closePath();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
function generatePath$2(context, parsedStyle) {
|
|
var markerStart = parsedStyle.markerStart,
|
|
markerEnd = parsedStyle.markerEnd,
|
|
markerStartOffset = parsedStyle.markerStartOffset,
|
|
markerEndOffset = parsedStyle.markerEndOffset;
|
|
var points = parsedStyle.points.points;
|
|
var length = points.length;
|
|
var x1 = points[0][0];
|
|
var y1 = points[0][1];
|
|
var x2 = points[length - 1][0];
|
|
var y2 = points[length - 1][1];
|
|
var startOffsetX = 0;
|
|
var startOffsetY = 0;
|
|
var endOffsetX = 0;
|
|
var endOffsetY = 0;
|
|
var rad = 0;
|
|
var x;
|
|
var y;
|
|
if (markerStart && gLite.isDisplayObject(markerStart) && markerStartOffset) {
|
|
x = points[1][0] - points[0][0];
|
|
y = points[1][1] - points[0][1];
|
|
rad = Math.atan2(y, x);
|
|
startOffsetX = Math.cos(rad) * (markerStartOffset || 0);
|
|
startOffsetY = Math.sin(rad) * (markerStartOffset || 0);
|
|
}
|
|
if (markerEnd && gLite.isDisplayObject(markerEnd) && markerEndOffset) {
|
|
x = points[length - 1][0] - points[0][0];
|
|
y = points[length - 1][1] - points[0][1];
|
|
rad = Math.atan2(y, x);
|
|
endOffsetX = Math.cos(rad) * (markerEndOffset || 0);
|
|
endOffsetY = Math.sin(rad) * (markerEndOffset || 0);
|
|
}
|
|
context.moveTo(x1 + (startOffsetX || endOffsetX), y1 + (startOffsetY || endOffsetY));
|
|
for (var i = 1; i < length - 1; i++) {
|
|
var point = points[i];
|
|
context.lineTo(point[0], point[1]);
|
|
}
|
|
context.lineTo(x2, y2);
|
|
}
|
|
|
|
function generatePath$1(context, parsedStyle) {
|
|
var markerStart = parsedStyle.markerStart,
|
|
markerEnd = parsedStyle.markerEnd,
|
|
markerStartOffset = parsedStyle.markerStartOffset,
|
|
markerEndOffset = parsedStyle.markerEndOffset;
|
|
var points = parsedStyle.points.points;
|
|
var length = points.length;
|
|
var x1 = points[0][0];
|
|
var y1 = points[0][1];
|
|
var x2 = points[length - 1][0];
|
|
var y2 = points[length - 1][1];
|
|
var startOffsetX = 0;
|
|
var startOffsetY = 0;
|
|
var endOffsetX = 0;
|
|
var endOffsetY = 0;
|
|
var rad = 0;
|
|
var x;
|
|
var y;
|
|
if (markerStart && gLite.isDisplayObject(markerStart) && markerStartOffset) {
|
|
x = points[1][0] - points[0][0];
|
|
y = points[1][1] - points[0][1];
|
|
rad = Math.atan2(y, x);
|
|
startOffsetX = Math.cos(rad) * (markerStartOffset || 0);
|
|
startOffsetY = Math.sin(rad) * (markerStartOffset || 0);
|
|
}
|
|
if (markerEnd && gLite.isDisplayObject(markerEnd) && markerEndOffset) {
|
|
x = points[length - 2][0] - points[length - 1][0];
|
|
y = points[length - 2][1] - points[length - 1][1];
|
|
rad = Math.atan2(y, x);
|
|
endOffsetX = Math.cos(rad) * (markerEndOffset || 0);
|
|
endOffsetY = Math.sin(rad) * (markerEndOffset || 0);
|
|
}
|
|
context.moveTo(x1 + startOffsetX, y1 + startOffsetY);
|
|
for (var i = 1; i < length - 1; i++) {
|
|
var point = points[i];
|
|
context.lineTo(point[0], point[1]);
|
|
}
|
|
context.lineTo(x2 + endOffsetX, y2 + endOffsetY);
|
|
}
|
|
|
|
function generatePath(context, parsedStyle) {
|
|
var _parsedStyle$x = parsedStyle.x,
|
|
x = _parsedStyle$x === void 0 ? 0 : _parsedStyle$x,
|
|
_parsedStyle$y = parsedStyle.y,
|
|
y = _parsedStyle$y === void 0 ? 0 : _parsedStyle$y,
|
|
radius = parsedStyle.radius,
|
|
width = parsedStyle.width,
|
|
height = parsedStyle.height;
|
|
var w = width;
|
|
var h = height;
|
|
var hasRadius = radius && radius.some(function (r) {
|
|
return r !== 0;
|
|
});
|
|
if (!hasRadius) {
|
|
// Canvas support negative width/height of rect
|
|
context.rect(x, y, w, h);
|
|
} else {
|
|
var signX = width > 0 ? 1 : -1;
|
|
var signY = height > 0 ? 1 : -1;
|
|
var sweepFlag = signX + signY === 0;
|
|
var _radius$map = radius.map(function (r) {
|
|
return util.clamp(r, 0, Math.min(Math.abs(w) / 2, Math.abs(h) / 2));
|
|
}),
|
|
_radius$map2 = _slicedToArray(_radius$map, 4),
|
|
tlr = _radius$map2[0],
|
|
trr = _radius$map2[1],
|
|
brr = _radius$map2[2],
|
|
blr = _radius$map2[3];
|
|
context.moveTo(signX * tlr + x, y);
|
|
context.lineTo(w - signX * trr + x, y);
|
|
if (trr !== 0) {
|
|
context.arc(w - signX * trr + x, signY * trr + y, trr, -signY * Math.PI / 2, signX > 0 ? 0 : Math.PI, sweepFlag);
|
|
}
|
|
context.lineTo(w + x, h - signY * brr + y);
|
|
if (brr !== 0) {
|
|
context.arc(w - signX * brr + x, h - signY * brr + y, brr, signX > 0 ? 0 : Math.PI, signY > 0 ? Math.PI / 2 : 1.5 * Math.PI, sweepFlag);
|
|
}
|
|
context.lineTo(signX * blr + x, h + y);
|
|
if (blr !== 0) {
|
|
context.arc(signX * blr + x, h - signY * blr + y, blr, signY > 0 ? Math.PI / 2 : -Math.PI / 2, signX > 0 ? Math.PI : 0, sweepFlag);
|
|
}
|
|
context.lineTo(x, signY * tlr + y);
|
|
if (tlr !== 0) {
|
|
context.arc(signX * tlr + x, signY * tlr + y, tlr, signX > 0 ? Math.PI : 0, signY > 0 ? Math.PI * 1.5 : Math.PI / 2, sweepFlag);
|
|
}
|
|
}
|
|
}
|
|
|
|
var Plugin = /*#__PURE__*/function (_AbstractRendererPlug) {
|
|
function Plugin() {
|
|
var _this;
|
|
_classCallCheck(this, Plugin);
|
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
args[_key] = arguments[_key];
|
|
}
|
|
_this = _callSuper(this, Plugin, [].concat(args));
|
|
_this.name = 'canvas-path-generator';
|
|
return _this;
|
|
}
|
|
_inherits(Plugin, _AbstractRendererPlug);
|
|
return _createClass(Plugin, [{
|
|
key: "init",
|
|
value: function init() {
|
|
var _pathGeneratorFactory;
|
|
var pathGeneratorFactory = (_pathGeneratorFactory = {}, _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_pathGeneratorFactory, gLite.Shape.CIRCLE, generatePath$6), gLite.Shape.ELLIPSE, generatePath$5), gLite.Shape.RECT, generatePath), gLite.Shape.LINE, generatePath$4), gLite.Shape.POLYLINE, generatePath$1), gLite.Shape.POLYGON, generatePath$2), gLite.Shape.PATH, generatePath$3), gLite.Shape.TEXT, undefined), gLite.Shape.GROUP, undefined), gLite.Shape.IMAGE, undefined), _defineProperty(_defineProperty(_defineProperty(_pathGeneratorFactory, gLite.Shape.HTML, undefined), gLite.Shape.MESH, undefined), gLite.Shape.FRAGMENT, undefined));
|
|
|
|
// @ts-ignore
|
|
this.context.pathGeneratorFactory = pathGeneratorFactory;
|
|
}
|
|
}, {
|
|
key: "destroy",
|
|
value: function destroy() {
|
|
// @ts-ignore
|
|
delete this.context.pathGeneratorFactory;
|
|
}
|
|
}]);
|
|
}(gLite.AbstractRendererPlugin);
|
|
|
|
exports.Plugin = Plugin;
|
|
//# sourceMappingURL=index.js.map
|
|
|