88 lines
2.2 KiB
JavaScript
88 lines
2.2 KiB
JavaScript
import { G, getWindow } from '@svgdotjs/svg.js'
|
|
import { getMoseDownFunc, transformPoint } from './utils'
|
|
|
|
export class PointSelectHandler {
|
|
constructor(el) {
|
|
this.el = el
|
|
el.remember('_pointSelectHandler', this)
|
|
this.selection = new G()
|
|
this.order = ['lt', 't', 'rt', 'r', 'rb', 'b', 'lb', 'l', 'rot']
|
|
this.mutationHandler = this.mutationHandler.bind(this)
|
|
|
|
const win = getWindow()
|
|
this.observer = new win.MutationObserver(this.mutationHandler)
|
|
}
|
|
|
|
init(options) {
|
|
this.createHandle = options.createHandle || this.createHandleFn
|
|
this.updateHandle = options.updateHandle || this.updateHandleFn
|
|
|
|
// mount group
|
|
this.el.root().put(this.selection)
|
|
|
|
this.updatePoints()
|
|
this.createSelection()
|
|
this.createPointHandles()
|
|
this.updatePointHandles()
|
|
this.observer.observe(this.el.node, { attributes: true })
|
|
}
|
|
|
|
active(val, options) {
|
|
// Disable selection
|
|
if (!val) {
|
|
this.selection.clear().remove()
|
|
this.observer.disconnect()
|
|
return
|
|
}
|
|
|
|
// Enable selection
|
|
this.init(options)
|
|
}
|
|
|
|
createSelection() {
|
|
this.selection.polygon(this.points).addClass('svg_select_shape_pointSelect')
|
|
}
|
|
|
|
updateSelection() {
|
|
this.selection.get(0).plot(this.points)
|
|
}
|
|
|
|
createPointHandles() {
|
|
this.points.forEach((p, index, arr) => {
|
|
this.createHandle.call(this, this.selection, p, index, arr)
|
|
|
|
this.selection
|
|
.get(index + 1)
|
|
.addClass('svg_select_handle_point')
|
|
.on('mousedown.selection touchstart.selection', getMoseDownFunc('point', this.el, this.points, index))
|
|
})
|
|
}
|
|
|
|
createHandleFn(group) {
|
|
group.circle(5)
|
|
}
|
|
|
|
updateHandleFn(shape, point) {
|
|
shape.center(point[0], point[1])
|
|
}
|
|
|
|
updatePointHandles() {
|
|
this.points.forEach((p, index, arr) => {
|
|
this.updateHandle.call(this, this.selection.get(index + 1), p, index, arr)
|
|
})
|
|
}
|
|
|
|
// gets new bounding box points and transform them into the elements space
|
|
updatePoints() {
|
|
const fromShapeToUiMatrix = this.el.parent().screenCTM().inverseO().multiplyO(this.el.screenCTM())
|
|
this.points = this.el.array().map((p) => transformPoint(p, fromShapeToUiMatrix))
|
|
}
|
|
|
|
mutationHandler() {
|
|
this.updatePoints()
|
|
|
|
this.updateSelection()
|
|
this.updatePointHandles()
|
|
}
|
|
}
|