123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280 |
- import { Dom, FunctionExt } from '@antv/x6-common';
- import { Point } from '@antv/x6-geometry';
- import { ToolsView } from '../../view/tool';
- import * as Util from './util';
- class Anchor extends ToolsView.ToolItem {
- get type() {
- return this.options.type;
- }
- onRender() {
- Dom.addClass(this.container, this.prefixClassName(`edge-tool-${this.type}-anchor`));
- this.toggleArea(false);
- this.update();
- }
- update() {
- const type = this.type;
- const edgeView = this.cellView;
- const terminalView = edgeView.getTerminalView(type);
- if (terminalView) {
- this.updateAnchor();
- this.updateArea();
- this.container.style.display = '';
- }
- else {
- this.container.style.display = 'none';
- }
- return this;
- }
- updateAnchor() {
- const childNodes = this.childNodes;
- if (!childNodes) {
- return;
- }
- const anchorNode = childNodes.anchor;
- if (!anchorNode) {
- return;
- }
- const type = this.type;
- const edgeView = this.cellView;
- const options = this.options;
- const position = edgeView.getTerminalAnchor(type);
- const customAnchor = edgeView.cell.prop([type, 'anchor']);
- anchorNode.setAttribute('transform', `translate(${position.x}, ${position.y})`);
- const anchorAttrs = customAnchor
- ? options.customAnchorAttrs
- : options.defaultAnchorAttrs;
- if (anchorAttrs) {
- Object.keys(anchorAttrs).forEach((attrName) => {
- anchorNode.setAttribute(attrName, anchorAttrs[attrName]);
- });
- }
- }
- updateArea() {
- const childNodes = this.childNodes;
- if (!childNodes) {
- return;
- }
- const areaNode = childNodes.area;
- if (!areaNode) {
- return;
- }
- const type = this.type;
- const edgeView = this.cellView;
- const terminalView = edgeView.getTerminalView(type);
- if (terminalView) {
- const terminalCell = terminalView.cell;
- const magnet = edgeView.getTerminalMagnet(type);
- let padding = this.options.areaPadding || 0;
- if (!Number.isFinite(padding)) {
- padding = 0;
- }
- let bbox;
- let angle;
- let center;
- if (terminalView.isEdgeElement(magnet)) {
- bbox = terminalView.getBBox();
- angle = 0;
- center = bbox.getCenter();
- }
- else {
- bbox = terminalView.getUnrotatedBBoxOfElement(magnet);
- angle = terminalCell.getAngle();
- center = bbox.getCenter();
- if (angle) {
- center.rotate(-angle, terminalCell.getBBox().getCenter());
- }
- }
- bbox.inflate(padding);
- Dom.attr(areaNode, {
- x: -bbox.width / 2,
- y: -bbox.height / 2,
- width: bbox.width,
- height: bbox.height,
- transform: `translate(${center.x}, ${center.y}) rotate(${angle})`,
- });
- }
- }
- toggleArea(visible) {
- if (this.childNodes) {
- const elem = this.childNodes.area;
- if (elem) {
- elem.style.display = visible ? '' : 'none';
- }
- }
- }
- onMouseDown(evt) {
- if (this.guard(evt)) {
- return;
- }
- evt.stopPropagation();
- evt.preventDefault();
- this.graph.view.undelegateEvents();
- if (this.options.documentEvents) {
- this.delegateDocumentEvents(this.options.documentEvents);
- }
- this.focus();
- this.toggleArea(this.options.restrictArea);
- this.cell.startBatch('move-anchor', {
- ui: true,
- toolId: this.cid,
- });
- }
- resetAnchor(anchor) {
- const type = this.type;
- const cell = this.cell;
- if (anchor) {
- cell.prop([type, 'anchor'], anchor, {
- rewrite: true,
- ui: true,
- toolId: this.cid,
- });
- }
- else {
- cell.removeProp([type, 'anchor'], {
- ui: true,
- toolId: this.cid,
- });
- }
- }
- onMouseMove(evt) {
- const terminalType = this.type;
- const edgeView = this.cellView;
- const terminalView = edgeView.getTerminalView(terminalType);
- if (terminalView == null) {
- return;
- }
- const e = this.normalizeEvent(evt);
- const terminalCell = terminalView.cell;
- const terminalMagnet = edgeView.getTerminalMagnet(terminalType);
- let coords = this.graph.coord.clientToLocalPoint(e.clientX, e.clientY);
- const snapFn = this.options.snap;
- if (typeof snapFn === 'function') {
- const tmp = FunctionExt.call(snapFn, edgeView, coords, terminalView, terminalMagnet, terminalType, edgeView, this);
- coords = Point.create(tmp);
- }
- if (this.options.restrictArea) {
- if (terminalView.isEdgeElement(terminalMagnet)) {
- const pointAtConnection = terminalView.getClosestPoint(coords);
- if (pointAtConnection) {
- coords = pointAtConnection;
- }
- }
- else {
- const bbox = terminalView.getUnrotatedBBoxOfElement(terminalMagnet);
- const angle = terminalCell.getAngle();
- const origin = terminalCell.getBBox().getCenter();
- const rotatedCoords = coords.clone().rotate(angle, origin);
- if (!bbox.containsPoint(rotatedCoords)) {
- coords = bbox
- .getNearestPointToPoint(rotatedCoords)
- .rotate(-angle, origin);
- }
- }
- }
- let anchor;
- const anchorFn = this.options.anchor;
- if (typeof anchorFn === 'function') {
- anchor = FunctionExt.call(anchorFn, edgeView, coords, terminalView, terminalMagnet, terminalType, edgeView, this);
- }
- this.resetAnchor(anchor);
- this.update();
- }
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
- onMouseUp(evt) {
- this.graph.view.delegateEvents();
- this.undelegateDocumentEvents();
- this.blur();
- this.toggleArea(false);
- const edgeView = this.cellView;
- if (this.options.removeRedundancies) {
- edgeView.removeRedundantLinearVertices({ ui: true, toolId: this.cid });
- }
- this.cell.stopBatch('move-anchor', { ui: true, toolId: this.cid });
- }
- onDblClick() {
- const anchor = this.options.resetAnchor;
- if (anchor) {
- this.resetAnchor(anchor === true ? undefined : anchor);
- }
- this.update();
- }
- }
- (function (Anchor) {
- Anchor.config({
- tagName: 'g',
- markup: [
- {
- tagName: 'circle',
- selector: 'anchor',
- attrs: {
- cursor: 'pointer',
- },
- },
- {
- tagName: 'rect',
- selector: 'area',
- attrs: {
- 'pointer-events': 'none',
- fill: 'none',
- stroke: '#33334F',
- 'stroke-dasharray': '2,4',
- rx: 5,
- ry: 5,
- },
- },
- ],
- events: {
- mousedown: 'onMouseDown',
- touchstart: 'onMouseDown',
- dblclick: 'onDblClick',
- },
- documentEvents: {
- mousemove: 'onMouseMove',
- touchmove: 'onMouseMove',
- mouseup: 'onMouseUp',
- touchend: 'onMouseUp',
- touchcancel: 'onMouseUp',
- },
- customAnchorAttrs: {
- 'stroke-width': 4,
- stroke: '#33334F',
- fill: '#FFFFFF',
- r: 5,
- },
- defaultAnchorAttrs: {
- 'stroke-width': 2,
- stroke: '#FFFFFF',
- fill: '#33334F',
- r: 6,
- },
- areaPadding: 6,
- snapRadius: 10,
- resetAnchor: true,
- restrictArea: true,
- removeRedundancies: true,
- anchor: Util.getAnchor,
- snap(pos, terminalView, terminalMagnet, terminalType, edgeView, toolView) {
- const snapRadius = toolView.options.snapRadius || 0;
- const isSource = terminalType === 'source';
- const refIndex = isSource ? 0 : -1;
- const ref = this.cell.getVertexAt(refIndex) ||
- this.getTerminalAnchor(isSource ? 'target' : 'source');
- if (ref) {
- if (Math.abs(ref.x - pos.x) < snapRadius)
- pos.x = ref.x;
- if (Math.abs(ref.y - pos.y) < snapRadius)
- pos.y = ref.y;
- }
- return pos;
- },
- });
- })(Anchor || (Anchor = {}));
- export const SourceAnchor = Anchor.define({
- name: 'source-anchor',
- type: 'source',
- });
- export const TargetAnchor = Anchor.define({
- name: 'target-anchor',
- type: 'target',
- });
- //# sourceMappingURL=anchor.js.map
|