mirror of
https://gitee.com/antv/g6.git
synced 2024-11-29 18:28:19 +08:00
fix(elements): fix incorrect ports position when rotate node
This commit is contained in:
parent
36411e5882
commit
bae52457be
29
packages/g6/__tests__/bugs/element-port-rotate.spec.ts
Normal file
29
packages/g6/__tests__/bugs/element-port-rotate.spec.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import { createGraph } from '@@/utils';
|
||||
|
||||
describe('element port rotate', () => {
|
||||
it('default', async () => {
|
||||
const graph = createGraph({
|
||||
data: {
|
||||
nodes: [{ id: 'node-1', style: { x: 100, y: 100 } }],
|
||||
},
|
||||
node: {
|
||||
type: 'rect',
|
||||
style: {
|
||||
size: [50, 150],
|
||||
port: true,
|
||||
portR: 3,
|
||||
ports: [
|
||||
{ key: 'port-1', placement: [0, 0.15] },
|
||||
{ key: 'port-2', placement: 'left' },
|
||||
{ key: 'port-3', placement: [0, 0.85] },
|
||||
],
|
||||
transform: 'rotate(45deg)',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await graph.draw();
|
||||
|
||||
await expect(graph).toMatchSnapshot(__filename);
|
||||
});
|
||||
});
|
@ -0,0 +1,23 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" style="background: transparent; position: absolute; outline: none;" color-interpolation-filters="sRGB" tabindex="1">
|
||||
<defs/>
|
||||
<g >
|
||||
<g fill="none">
|
||||
<g fill="none">
|
||||
<g fill="none" x="100" y="100" transform="matrix(0.707107,0.707107,-0.707107,0.707107,100,100)">
|
||||
<g>
|
||||
<path fill="rgba(23,131,255,1)" d="M -25,-75 l 50,0 l 0,150 l-50 0 z" class="key" stroke-width="0" stroke="rgba(0,0,0,1)" width="50" height="150" x="-25" y="-75"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1,-25,-52.500000)">
|
||||
<circle fill="rgba(23,131,255,1)" class="port-port-1" stroke-width="1" stroke="rgba(0,0,0,1)" stroke-opacity="0.65" r="3"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1,-25,0)">
|
||||
<circle fill="rgba(23,131,255,1)" class="port-port-2" stroke-width="1" stroke="rgba(0,0,0,1)" stroke-opacity="0.65" r="3"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1,-25,52.500000)">
|
||||
<circle fill="rgba(23,131,255,1)" class="port-port-3" stroke-width="1" stroke="rgba(0,0,0,1)" stroke-opacity="0.65" r="3"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
@ -1,6 +1,7 @@
|
||||
import type { BaseStyleProps, CircleStyleProps, DisplayObject, DisplayObjectConfig, Group } from '@antv/g';
|
||||
import { Circle as GCircle } from '@antv/g';
|
||||
import type { CategoricalPalette } from '../../palettes/types';
|
||||
import type { RuntimeContext } from '../../runtime/types';
|
||||
import type { NodeData } from '../../spec';
|
||||
import type {
|
||||
BaseElementStyleProps,
|
||||
@ -24,6 +25,7 @@ import { omitStyleProps, subObject, subStyleProps } from '../../utils/prefix';
|
||||
import { parseSize } from '../../utils/size';
|
||||
import { mergeOptions } from '../../utils/style';
|
||||
import { getWordWrapWidthByBox } from '../../utils/text';
|
||||
import { setVisibility } from '../../utils/visibility';
|
||||
import { BaseElement } from '../base-element';
|
||||
import { effect } from '../effect';
|
||||
import type { BadgeStyleProps, IconStyleProps, LabelStyleProps } from '../shapes';
|
||||
@ -328,8 +330,8 @@ export abstract class BaseNode<S extends BaseNodeStyleProps = BaseNodeStyleProps
|
||||
|
||||
protected getPortXY(attributes: Required<S>, style: NodePortStyleProps): Point {
|
||||
const { placement = 'left' } = style;
|
||||
const bounds = this.getShape('key').getLocalBounds();
|
||||
return getPortXYByPlacement(bounds, placement as PortPlacement);
|
||||
const keyShape = this.getShape('key');
|
||||
return getPortXYByPlacement(getBoundsInOffscreen(this.context, keyShape), placement as PortPlacement);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -385,6 +387,7 @@ export abstract class BaseNode<S extends BaseNodeStyleProps = BaseNodeStyleProps
|
||||
@effect((self, attributes) => self.getPortsStyle(attributes))
|
||||
protected drawPortShapes(attributes: Required<S>, container: Group): void {
|
||||
const portsStyle = this.getPortsStyle(attributes);
|
||||
|
||||
Object.keys(portsStyle).forEach((key) => {
|
||||
this.upsert(`port-${key}`, GCircle, portsStyle[key] as CircleStyleProps, container);
|
||||
});
|
||||
@ -429,3 +432,25 @@ export abstract class BaseNode<S extends BaseNodeStyleProps = BaseNodeStyleProps
|
||||
this.drawLabelShape(this.parsedAttributes, this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param context
|
||||
* @param shape
|
||||
*/
|
||||
function getBoundsInOffscreen(context: RuntimeContext, shape: DisplayObject) {
|
||||
if (!context) return shape.getLocalBounds();
|
||||
|
||||
// 将主图形靠背至全局空间,避免受到父级 transform 的影响
|
||||
// 合理的操作应该是靠背至离屏画布,但目前 G 有点问题
|
||||
// Move the main graphic to the global space to avoid being affected by the parent transform
|
||||
// The reasonable operation should be moved to the off-screen canvas, but there is a problem with G at present
|
||||
const canvas = context.canvas.getLayer();
|
||||
const substitute = shape.cloneNode();
|
||||
setVisibility(substitute, 'hidden');
|
||||
canvas.appendChild(substitute);
|
||||
const bounds = substitute.getLocalBounds();
|
||||
canvas.removeChild(substitute);
|
||||
|
||||
return bounds;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user