Skip to content

Commit

Permalink
fix: markerStartOffset/markerEndOffset of the path (#1808)
Browse files Browse the repository at this point in the history
* fix: `markerStartOffset` of the path in the svg renderer is drawn abnormally

* fix: `markerEndOffset` of the path in the svg/canvas renderer is drawn abnormally
  • Loading branch information
wang1212 authored Oct 31, 2024
1 parent fdb1819 commit 4aa12e8
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 135 deletions.
6 changes: 6 additions & 0 deletions .changeset/many-jeans-tan.md
Original file line number Diff line number Diff line change
@@ -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
61 changes: 61 additions & 0 deletions __tests__/demos/bugfix/1760.ts
Original file line number Diff line number Diff line change
@@ -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);
}
1 change: 1 addition & 0 deletions __tests__/demos/bugfix/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
5 changes: 5 additions & 0 deletions babel.config.mjs
Original file line number Diff line number Diff line change
@@ -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,
Expand Down
92 changes: 0 additions & 92 deletions demo/issues/issue-1760.html

This file was deleted.

41 changes: 17 additions & 24 deletions packages/g-lite/src/utils/path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
39 changes: 20 additions & 19 deletions packages/g-plugin-canvas-path-generator/src/paths/Path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,43 +48,44 @@ 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(
params[1],
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;
Expand Down

0 comments on commit 4aa12e8

Please sign in to comment.