UNPKG

@antv/x6

Version:

JavaScript diagramming library that uses SVG and HTML for rendering

168 lines (145 loc) 4.16 kB
import { Dom } from '../../common' import { Point } from '../../geometry' import type { Edge, TerminalType } from '../../model/edge' import type { EdgeView } from '../../view/edge' import { ToolItem, type ToolItemOptions } from '../../view/tool' import type { SimpleAttrs } from '../attr' class Arrowhead extends ToolItem<EdgeView, Options> { public static defaults: Options = { ...ToolItem.getDefaults(), tagName: 'path', isSVGElement: true, events: { mousedown: 'onMouseDown', touchstart: 'onMouseDown', }, documentEvents: { mousemove: 'onMouseMove', touchmove: 'onMouseMove', mouseup: 'onMouseUp', touchend: 'onMouseUp', touchcancel: 'onMouseUp', }, } protected get type() { return this.options.type! } protected get ratio() { return this.options.ratio! } protected init() { if (this.options.attrs) { const { class: className, ...attrs } = this.options.attrs this.setAttrs(attrs, this.container) if (className) { Dom.addClass(this.container, className as string) } } } protected onRender() { Dom.addClass( this.container, this.prefixClassName(`edge-tool-${this.type}-arrowhead`), ) this.update() } update() { const ratio = this.ratio const edgeView = this.cellView as EdgeView const tangent = edgeView.getTangentAtRatio(ratio) const position = tangent ? tangent.start : edgeView.getPointAtRatio(ratio) const angle = (tangent && tangent.vector().vectorAngle(new Point(1, 0))) || 0 if (!position) { return this } const matrix = Dom.createSVGMatrix() .translate(position.x, position.y) .rotate(angle) Dom.transform(this.container as SVGElement, matrix, { absolute: true }) return this } protected onMouseDown(evt: Dom.MouseDownEvent) { if (this.guard(evt)) { return } evt.stopPropagation() evt.preventDefault() const edgeView = this.cellView as EdgeView if (edgeView.can('arrowheadMovable')) { edgeView.cell.startBatch('move-arrowhead', { ui: true, toolId: this.cid, }) const coords = this.graph.snapToGrid(evt.clientX, evt.clientY) const data = edgeView.prepareArrowheadDragging(this.type, { x: coords.x, y: coords.y, options: { ...this.options, toolId: this.cid, }, }) this.cellView.setEventData(evt, data) this.delegateDocumentEvents(this.options.documentEvents!, evt.data) edgeView.graph.view.undelegateEvents() this.container.style.pointerEvents = 'none' } this.focus() } protected onMouseMove(evt: Dom.MouseMoveEvent) { const e = this.normalizeEvent(evt) const coords = this.graph.snapToGrid(e.clientX, e.clientY) this.cellView.onMouseMove(e, coords.x, coords.y) this.update() } protected onMouseUp(evt: Dom.MouseUpEvent) { this.undelegateDocumentEvents() const e = this.normalizeEvent(evt) const edgeView = this.cellView const coords = this.graph.snapToGrid(e.clientX, e.clientY) edgeView.onMouseUp(e, coords.x, coords.y) this.graph.view.delegateEvents() this.blur() this.container.style.pointerEvents = '' edgeView.cell.stopBatch('move-arrowhead', { ui: true, toolId: this.cid, }) } } interface Options extends ToolItemOptions { attrs?: SimpleAttrs type?: TerminalType ratio?: number } export class SourceArrowhead extends Arrowhead { public static defaults: Options = { ...Arrowhead.getDefaults(), name: 'source-arrowhead', type: 'source', ratio: 0, attrs: { d: 'M 10 -8 -10 0 10 8 Z', fill: '#333', stroke: '#fff', 'stroke-width': 2, cursor: 'move', }, } } export class TargetArrowhead extends Arrowhead { public static defaults: Options = { ...Arrowhead.getDefaults(), name: 'target-arrowhead', type: 'target', ratio: 1, attrs: { d: 'M -10 -8 10 0 -10 8 Z', fill: '#333', stroke: '#fff', 'stroke-width': 2, cursor: 'move', }, } }