Skip to content

Commit

Permalink
feat: add induction area option for Anchor
Browse files Browse the repository at this point in the history
  • Loading branch information
bubkoo committed Dec 13, 2019
1 parent 0ee98a6 commit 5f0783e
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 44 deletions.
71 changes: 29 additions & 42 deletions packages/x6/src/handler/anchor/handler.ts
Expand Up @@ -10,12 +10,13 @@ import { DomEvent, MouseEventEx, Disposable } from '../../common'
import { getAnchorOptions, createAnchorHighlightShape } from './option'

export class AnchorHandler extends BaseHandler {
inductionSize: number
currentState: State | null
currentPoint: Point | null
currentArea: Rectangle | null
currentAnchor: Anchor | null

protected icons: Shape[] | null
protected knobs: Shape[] | null
protected points: Point[] | null
protected anchors: Anchor[] | null
protected highlight: Shape | null
Expand All @@ -25,6 +26,9 @@ export class AnchorHandler extends BaseHandler {

constructor(graph: Graph) {
super(graph)

this.inductionSize = graph.options.anchor.inductionSize

this.resetHandler = () => {
if (
this.currentState != null &&
Expand Down Expand Up @@ -57,7 +61,7 @@ export class AnchorHandler extends BaseHandler {
if (
this.currentState != null &&
this.anchors != null &&
this.icons != null &&
this.knobs != null &&
this.points != null
) {
const state = this.graph.view.getState(this.currentState.cell)!
Expand All @@ -68,9 +72,9 @@ export class AnchorHandler extends BaseHandler {
const anchor = this.anchors[i]
const point = this.graph.view.getConnectionPoint(state, anchor)!

this.redrawAnchor(state, anchor, point, this.icons[i])
this.redrawAnchor(state, anchor, point, this.knobs[i])
this.points[i] = point
this.currentArea.add(this.icons[i].bounds)
this.currentArea.add(this.knobs[i].bounds)
}
}
}
Expand Down Expand Up @@ -203,17 +207,13 @@ export class AnchorHandler extends BaseHandler {
)
}

const graphX = e.getGraphX()
const graphY = e.getGraphY()
const tol = this.getTolerance(e)
const x = currentPoint != null ? currentPoint.x : e.getGraphX()
const y = currentPoint != null ? currentPoint.y : e.getGraphY()
const x = currentPoint != null ? currentPoint.x : graphX
const y = currentPoint != null ? currentPoint.y : graphY
const grid = new Rectangle(x - tol, y - tol, 2 * tol, 2 * tol)
const mouse = new Rectangle(
e.getGraphX() - tol,
e.getGraphY() - tol,
2 * tol,
2 * tol,
)

const mouse = new Rectangle(graphX - tol, graphY - tol, 2 * tol, 2 * tol)
const state = this.graph.view.getState(this.getCell(e, currentPoint))

// Keeps focus icons visible while over node bounds and
Expand All @@ -237,40 +237,32 @@ export class AnchorHandler extends BaseHandler {

// highlight hovering anchor
if (
this.icons != null &&
this.knobs != null &&
this.points != null &&
this.anchors != null &&
(state == null || this.currentState === state)
) {
// console.log('highlight hovering anchor')
let bounds: Rectangle | null = null
let minDist: number | null = null

const cx = mouse.getCenterX()
const cy = mouse.getCenterY()

for (let i = 0, ii = this.icons.length; i < ii; i += 1) {
const dx = cx - this.icons[i].bounds.getCenterX()
const dy = cy - this.icons[i].bounds.getCenterY()
for (let i = 0, ii = this.knobs.length; i < ii; i += 1) {
const dx = graphX - this.knobs[i].bounds.getCenterX()
const dy = graphY - this.knobs[i].bounds.getCenterY()
const dis = dx * dx + dy * dy

// console.log(dx, dy, dis)
if (
(this.intersects(this.icons[i], mouse, isSource, existingEdge) ||
(currentPoint != null &&
this.intersects(
this.icons[i],
grid,
isSource,
existingEdge,
))) &&
(Math.sqrt(dis) < this.inductionSize ||
this.intersects(this.knobs[i], mouse) ||
(currentPoint != null && this.intersects(this.knobs[i], grid))) &&
(minDist == null || dis < minDist)
) {
this.currentPoint = this.points[i]
this.currentAnchor = this.anchors[i]
minDist = dis
bounds = this.icons[i].bounds.clone()
bounds = this.knobs[i].bounds.clone()

if (this.highlight == null) {
// lazy
this.highlight = this.createHighlightShape(state)
}
}
Expand Down Expand Up @@ -301,14 +293,14 @@ export class AnchorHandler extends BaseHandler {

this.destroyIcons()

this.icons = []
this.knobs = []
this.points = []

for (let i = 0, ii = this.anchors.length; i < ii; i += 1) {
const c = this.anchors[i]
const p = this.graph.view.getConnectionPoint(state, c)!
const icon = this.redrawAnchor(state, c, p)
this.icons.push(icon)
this.knobs.push(icon)
this.points.push(p)
this.currentArea.add(icon.bounds)
}
Expand All @@ -334,19 +326,14 @@ export class AnchorHandler extends BaseHandler {
return shape
}

protected intersects(
icon: Shape,
mouse: Rectangle,
isSource: boolean,
existingEdge: boolean,
) {
protected intersects(icon: Shape, mouse: Rectangle) {
return icon.bounds.isIntersectWith(mouse)
}

protected destroyIcons() {
if (this.icons != null) {
this.icons.forEach(i => i.dispose())
this.icons = null
if (this.knobs != null) {
this.knobs.forEach(i => i.dispose())
this.knobs = null
this.points = null
}
}
Expand Down
5 changes: 3 additions & 2 deletions packages/x6/src/handler/anchor/option.ts
Expand Up @@ -13,6 +13,7 @@ import {
} from '../../option'

export interface AnchorOptions {
inductionSize: number
/**
* The image for fixed connection points.
*/
Expand All @@ -30,7 +31,7 @@ export interface GetAnchorOptionsArgs {

export function getAnchorOptions(args: GetAnchorOptionsArgs) {
const { graph } = args
const options = graph.options.anchor as AnchorOptions
const options = graph.options.anchor
return {
image: drill(options.image, args.graph, args),
cursor: drill(options.cursor, args.graph, args),
Expand Down Expand Up @@ -58,7 +59,7 @@ export function createAnchorHighlightShape(
args: CreateAnchorHighlightShapeArgs,
) {
const { graph } = args
const opts = graph.options.anchorHighlight as AnchorHighlightOptions
const opts = graph.options.anchorHighlight
const raw = drill(opts.shape, graph, args)
const ctor = Shape.getShape(raw) || EllipseShape
const shape = new ctor() as Shape
Expand Down
1 change: 1 addition & 0 deletions packages/x6/src/option/preset.ts
Expand Up @@ -295,6 +295,7 @@ export const preset: FullOptions = {
anchor: {
image: images.cross,
cursor: globals.defaultCursorPointer,
inductionSize: 20,
},

anchorHighlight: {
Expand Down

0 comments on commit 5f0783e

Please sign in to comment.