Skip to content

Commit

Permalink
feat: create anchor with native shapes
Browse files Browse the repository at this point in the history
default use ellipse as an anchor shape

fix #39
  • Loading branch information
bubkoo committed Dec 13, 2019
1 parent 16bcfd2 commit af58546
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 39 deletions.
49 changes: 22 additions & 27 deletions packages/x6/src/handler/anchor/handler.ts
Expand Up @@ -3,11 +3,11 @@ import { Graph } from '../../graph'
import { View } from '../../core/view'
import { Model } from '../../core/model'
import { State } from '../../core/state'
import { Shape, ImageShape } from '../../shape'
import { Shape } from '../../shape'
import { BaseHandler } from '../handler-base'
import { Rectangle, Point, Anchor } from '../../struct'
import { DomEvent, MouseEventEx, Disposable } from '../../common'
import { getAnchorOptions, createAnchorHighlightShape } from './option'
import { createAnchorShape, createAnchorHighlightShape } from './option'

export class AnchorHandler extends BaseHandler {
inductiveSize: number
Expand Down Expand Up @@ -88,38 +88,33 @@ export class AnchorHandler extends BaseHandler {
point: Point,
icon?: Shape,
) {
const { image, cursor, className } = getAnchorOptions({
anchor,
point,
graph: this.graph,
cell: state.cell,
})

const bounds = new Rectangle(
Math.round(point.x - image.width / 2),
Math.round(point.y - image.height / 2),
image.width,
image.height,
)
// const { image, cursor, className } = getAnchorOptions({
// anchor,
// point,
// graph: this.graph,
// cell: state.cell,
// })

if (icon == null) {
const img = new ImageShape(bounds, image.src)
img.dialect = 'svg'
img.preserveImageAspect = false
img.init(this.graph.view.getDecoratorPane())
util.toBack(img.elem)
// tslint:disable-next-line
icon = createAnchorShape({
anchor,
point,
graph: this.graph,
cell: state.cell,
})
// const img = new ImageShape(bounds, image.src)
// img.dialect = 'svg'
// img.preserveImageAspect = false
icon.init(this.graph.view.getDecoratorPane())
util.toBack(icon.elem)

icon = img // tslint:disable-line
const getState = () => this.currentState || state
MouseEventEx.redirectMouseEvents(icon.elem, this.graph, getState)
}

util.applyClassName(icon, this.graph.prefixCls, 'anchor', className)

icon.image = image.src
icon.bounds = bounds
icon.cursor = cursor

icon.bounds.x = point.x - icon.bounds.width / 2
icon.bounds.y = point.y - icon.bounds.height / 2
icon.redraw()

return icon
Expand Down
60 changes: 51 additions & 9 deletions packages/x6/src/handler/anchor/option.ts
@@ -1,7 +1,7 @@
import { Cell } from '../../core/cell'
import { Graph } from '../../graph'
import { Shape, EllipseShape } from '../../shape'
import { Image, Anchor, Point } from '../../struct'
import { Shape, EllipseShape, ImageShape } from '../../shape'
import { Image, Anchor, Point, Rectangle } from '../../struct'
import {
drill,
BaseStyle,
Expand All @@ -12,7 +12,7 @@ import {
applyManualStyle,
} from '../../option'

export interface AnchorOptions {
export interface AnchorOptions extends BaseStyle<ApplyAnchortyleArgs> {
/**
* Specifies the inductive area size.
*
Expand All @@ -25,12 +25,22 @@ export interface AnchorOptions {
* Default is `true`.
*/
adsorbNearestTarget: boolean
/**
* The image for fixed connection points.
*/
image: OptionItem<GetAnchorOptionsArgs, Image>
cursor: OptionItem<GetAnchorOptionsArgs, string>
className?: OptionItem<GetAnchorOptionsArgs, string>

image?: OptionItem<CreateAnchorShapeArgs, Image>
shape: OptionItem<CreateAnchorShapeArgs, string>
size: OptionItem<CreateAnchorShapeArgs, number>
cursor: OptionItem<ApplyAnchortyleArgs, string>
}

export interface CreateAnchorShapeArgs {
graph: Graph
cell: Cell
anchor: Anchor
point: Point
}

export interface ApplyAnchortyleArgs extends CreateAnchorShapeArgs {
shape: Shape
}

export interface GetAnchorOptionsArgs {
Expand All @@ -50,6 +60,38 @@ export function getAnchorOptions(args: GetAnchorOptionsArgs) {
}
}

export function createAnchorShape(args: CreateAnchorShapeArgs) {
const { graph } = args
const options = graph.options.anchor
const image = drill(options.image, args.graph, args)

let shape: Shape
if (image) {
const bounds = new Rectangle(0, 0, image.width, image.height)
const img = new ImageShape(bounds, image.src)
img.preserveImageAspect = false
shape = img
} else {
const shapeName = drill(options.shape, graph, args)
const size = drill(options.size, graph, args)
const ctor = Shape.getShape(shapeName) || EllipseShape

shape = new ctor() as Shape
shape.bounds = new Rectangle(0, 0, size, size)
applyBaseStyle({ ...args, shape }, options)
}

const newArgs = { ...args, shape }
applyClassName(newArgs, options, 'anchor')
applyCursorStyle(newArgs, options)
applyManualStyle(newArgs, options)

return shape
}

// anchor highlight
// ----

export interface AnchorHighlightOptions
extends BaseStyle<ApplyAnchorHighlightShapeStyleArgs> {
shape: OptionItem<CreateAnchorHighlightShapeArgs, string>
Expand Down
13 changes: 10 additions & 3 deletions packages/x6/src/option/preset.ts
Expand Up @@ -293,9 +293,16 @@ export const preset: FullOptions = {
},

anchor: {
image: images.cross,
// image: images.cross,
shape: 'ellipse',
size: 6,
opacity: 0.8,
fill: '#fff',
stroke: globals.defaultPrimaryColor,
strokeWidth: 2,
dashed: false,
cursor: globals.defaultCursorPointer,
inductiveSize: 20,
inductiveSize: 24,
adsorbNearestTarget: true,
},

Expand All @@ -305,7 +312,7 @@ export const preset: FullOptions = {
opacity: 0.3,
fill: 'none',
stroke: globals.defaultValidColor,
strokeWidth: 10,
strokeWidth: 16,
dashed: false,
},

Expand Down

0 comments on commit af58546

Please sign in to comment.