diff --git a/.changeset/many-jeans-tan.md b/.changeset/many-jeans-tan.md
new file mode 100644
index 000000000..5dac58d1c
--- /dev/null
+++ b/.changeset/many-jeans-tan.md
@@ -0,0 +1,6 @@
+---
+'@antv/g-lite': patch
+'@antv/g-plugin-canvas-path-generator': patch
+---
+
+fix: `markerStartOffset`/`markerEndOffset` of the path in the svg/canvas renderer is drawn abnormally
diff --git a/__tests__/demos/bugfix/1760.ts b/__tests__/demos/bugfix/1760.ts
new file mode 100644
index 000000000..ea0ba6512
--- /dev/null
+++ b/__tests__/demos/bugfix/1760.ts
@@ -0,0 +1,61 @@
+import { Canvas, Path, Line } from '@antv/g';
+
+/**
+ * @see https://github.com/antvis/G/issues/1760
+ * @see https://github.com/antvis/G/issues/1790
+ * @see https://github.com/antvis/G/pull/1808
+ */
+export async function issue_1760(context: { canvas: Canvas }) {
+ const { canvas } = context;
+ await canvas.ready;
+
+ const arrowMarker = new Path({
+ style: {
+ d: 'M 10,10 L -10,0 L 10,-10 Z',
+ stroke: '#1890FF',
+ transformOrigin: 'center',
+ },
+ });
+ const arrowMarker1 = new Path({
+ style: {
+ d: 'M 10,10 L -10,0 L 10,-10 Z',
+ stroke: '#ff90FF',
+ transformOrigin: 'center',
+ },
+ });
+
+ const path = new Path({
+ style: {
+ lineWidth: 1,
+ stroke: '#54BECC',
+ // d: 'M 0,40 L 100,100',
+ // d: 'M 10,100 L 100,100',
+ d: 'M 10,100 Q 100,100 150,150',
+ // d: 'M 10,100 C 100,100 150,150 180,200',
+ // d: 'M 10,100 A 30 50 0 0 1 162.55 162.45',
+ // d: 'M 10,100 A 30 50 0 0 0 162.55 162.45',
+ markerStart: arrowMarker,
+ markerStartOffset: 30,
+ markerEnd: arrowMarker1,
+ markerEndOffset: 30,
+ },
+ });
+
+ const line = new Line({
+ style: {
+ x1: 10,
+ y1: 150,
+ x2: 100,
+ y2: 150,
+ lineWidth: 1,
+ stroke: '#54BECC',
+ markerStart: arrowMarker,
+ markerStartOffset: 30,
+ markerEnd: arrowMarker,
+ markerEndOffset: 30,
+ },
+ });
+
+ canvas.appendChild(path);
+ canvas.appendChild(line);
+}
diff --git a/__tests__/demos/bugfix/index.ts b/__tests__/demos/bugfix/index.ts
index f48122b8c..96e15b67c 100644
--- a/__tests__/demos/bugfix/index.ts
+++ b/__tests__/demos/bugfix/index.ts
@@ -7,3 +7,4 @@ export { shadowroot_offset } from './1677';
export { gradient_text } from './1572';
export { zoom } from './1667';
export { test_pick } from './1747';
+export { issue_1760 } from './1760';
diff --git a/babel.config.mjs b/babel.config.mjs
index 025ea934b..f22b25d61 100644
--- a/babel.config.mjs
+++ b/babel.config.mjs
@@ -1,6 +1,11 @@
// See https://babeljs.io/docs/en/configuration
export default {
+ /**
+ * @see https://babeljs.io/docs/options#targets
+ * default is es5
+ */
+ // targets: '',
assumptions: {
privateFieldsAsProperties: true,
setPublicClassFields: true,
diff --git a/demo/issues/issue-1760.html b/demo/issues/issue-1760.html
deleted file mode 100644
index 4b4a1006f..000000000
--- a/demo/issues/issue-1760.html
+++ /dev/null
@@ -1,92 +0,0 @@
-
-
-
-
-
- issue-1760
-
-
-
-
-
-
-
-
-
-
diff --git a/packages/g-lite/src/utils/path.ts b/packages/g-lite/src/utils/path.ts
index ec204cb80..e5df1195d 100644
--- a/packages/g-lite/src/utils/path.ts
+++ b/packages/g-lite/src/utils/path.ts
@@ -959,41 +959,34 @@ export function translatePathToString(
(nextSegment[0] === 'M' || nextSegment[0] === 'Z'))) &&
endOffsetX !== 0 &&
endOffsetY !== 0;
+ const [startOffsetXTemp, startOffsetYTemp] = useStartOffset
+ ? [startOffsetX, startOffsetY]
+ : [0, 0];
+ const [endOffsetXTemp, endOffsetYTemp] = useEndOffset
+ ? [endOffsetX, endOffsetY]
+ : [0, 0];
switch (command) {
case 'M':
- // Use start marker offset
- if (useStartOffset) {
- return `M ${params[1] + startOffsetX},${
- params[2] + startOffsetY
- } L ${params[1]},${params[2]}`;
- }
- return `M ${params[1]},${params[2]}`;
+ return `M ${params[1] + startOffsetXTemp},${params[2] + startOffsetYTemp}`;
case 'L':
- return `L ${params[1] + (useEndOffset ? endOffsetX : 0)},${
- params[2] + (useEndOffset ? endOffsetY : 0)
+ return `L ${params[1] + endOffsetXTemp},${
+ params[2] + endOffsetYTemp
}`;
+
case 'Q':
- return `Q ${params[1]} ${params[2]},${params[3]} ${params[4]}${
- useEndOffset
- ? ` L ${params[3] + endOffsetX},${params[4] + endOffsetY}`
- : ''
- }`;
+ return `Q ${params[1]} ${params[2]},${params[3] + endOffsetXTemp} ${params[4] + endOffsetYTemp}`;
+
case 'C':
- return `C ${params[1]} ${params[2]},${params[3]} ${params[4]},${params[5]} ${params[6]}${
- useEndOffset
- ? ` L ${params[5] + endOffsetX},${params[6] + endOffsetY}`
- : ''
- }`;
+ return `C ${params[1]} ${params[2]},${params[3]} ${params[4]},${params[5] + endOffsetXTemp} ${params[6] + endOffsetYTemp}`;
+
case 'A':
- return `A ${params[1]} ${params[2]} ${params[3]} ${params[4]} ${params[5]} ${params[6]} ${params[7]}${
- useEndOffset
- ? ` L ${params[6] + endOffsetX},${params[7] + endOffsetY}`
- : ''
- }`;
+ return `A ${params[1]} ${params[2]} ${params[3]} ${params[4]} ${params[5]} ${params[6] + endOffsetXTemp} ${params[7] + endOffsetYTemp}`;
+
case 'Z':
return 'Z';
+
default:
return null;
}
diff --git a/packages/g-plugin-canvas-path-generator/src/paths/Path.ts b/packages/g-plugin-canvas-path-generator/src/paths/Path.ts
index a5800a62c..2c9898d2f 100644
--- a/packages/g-plugin-canvas-path-generator/src/paths/Path.ts
+++ b/packages/g-plugin-canvas-path-generator/src/paths/Path.ts
@@ -48,28 +48,31 @@ export function generatePath(
(nextSegment && (nextSegment[0] === 'M' || nextSegment[0] === 'Z'))) &&
endOffsetX !== 0 &&
endOffsetY !== 0;
+ const [startOffsetXTemp, startOffsetYTemp] = useStartOffset
+ ? [startOffsetX, startOffsetY]
+ : [0, 0];
+ const [endOffsetXTemp, endOffsetYTemp] = useEndOffset
+ ? [endOffsetX, endOffsetY]
+ : [0, 0];
switch (command) {
case 'M':
// Use start marker offset
- if (useStartOffset) {
- context.moveTo(params[1] + startOffsetX, params[2] + startOffsetY);
- } else {
- context.moveTo(params[1], params[2]);
- }
+ context.moveTo(
+ params[1] + startOffsetXTemp,
+ params[2] + startOffsetYTemp,
+ );
break;
case 'L':
- if (useEndOffset) {
- context.lineTo(params[1] + endOffsetX, params[2] + endOffsetY);
- } else {
- context.lineTo(params[1], params[2]);
- }
+ context.lineTo(params[1] + endOffsetXTemp, params[2] + endOffsetYTemp);
break;
case 'Q':
- context.quadraticCurveTo(params[1], params[2], params[3], params[4]);
- if (useEndOffset) {
- context.lineTo(params[3] + endOffsetX, params[4] + endOffsetY);
- }
+ context.quadraticCurveTo(
+ params[1],
+ params[2],
+ params[3] + endOffsetXTemp,
+ params[4] + endOffsetYTemp,
+ );
break;
case 'C':
context.bezierCurveTo(
@@ -77,14 +80,12 @@ export function generatePath(
params[2],
params[3],
params[4],
- params[5],
- params[6],
+ params[5] + endOffsetXTemp,
+ params[6] + endOffsetYTemp,
);
- if (useEndOffset) {
- context.lineTo(params[5] + endOffsetX, params[6] + endOffsetY);
- }
break;
case 'A': {
+ // FIXME startOffset / endOffset
const { arcParams } = segments[i];
const { cx, cy, rx, ry, startAngle, endAngle, xRotation, sweepFlag } =
arcParams;