/*
* CustomGrid.js
*/
import {
append as svgAppend,
attr as svgAttr,
create as svgCreate,
clear as svgClear
} from 'tiny-svg'
import { query } from 'min-dom'
import { quantize } from 'diagram-js/lib/features/grid-snapping/GridUtil'
import { getMid } from 'diagram-js/lib/layout/LayoutUtil'
const GRID_COLOR = '#ccc'
const LAYER_NAME = 'djs-grid'
const SPACING = 40
const GRID_DIMENSIONS = {
width: 100000,
height: 100000
}
const randomNumber = () => Math.trunc(Math.random() * 1000000)
class CustomGrid {
_canvas
_visible
_gfx
constructor(canvas, eventBus) {
this._canvas = canvas
this._visible = false
eventBus.on('diagram.init', () => this._init())
eventBus.on('gridSnapping.toggle', ({ active }) => {
this.toggle(active)
this._centerGridAroundViewbox()
})
eventBus.on('canvas.viewbox.changed', ({ viewbox }) => {
return this._centerGridAroundViewbox(viewbox)
})
}
_init() {
let defs = query('defs', this._canvas._svg)
if (!defs) {
defs = svgCreate('defs')
svgAppend(this._canvas._svg, defs)
}
const patternId = 'djs-grid-pattern-' + randomNumber()
/** Create Pattern */
const pattern = svgCreate('pattern', {
id: patternId,
width: SPACING,
height: SPACING,
patternUnits: 'userSpaceOnUse'
})
const path1 = svgCreate('path', {
d: 'M0 10h40M10 0v40M0 20h40M20 0v40M0 30h40M30 0v40',
stroke: GRID_COLOR,
fill: 'none',
opacity: 0.2
})
const path2 = svgCreate('path', {
d: 'M40 0H0v40',
stroke: GRID_COLOR,
fill: 'none'
})
svgAppend(pattern, path1)
svgAppend(pattern, path2)
svgAppend(defs, pattern)
/** Create Gfx */
this._gfx = svgCreate('rect', {
x: -(GRID_DIMENSIONS.width / 2),
y: -(GRID_DIMENSIONS.height / 2),
width: GRID_DIMENSIONS.width,
height: GRID_DIMENSIONS.height,
fill: `url(#${patternId})`
})
}
_centerGridAroundViewbox(viewbox) {
if (!viewbox) {
viewbox = this._canvas.viewbox()
}
const mid = getMid(viewbox)
svgAttr(this._gfx, {
x: -(GRID_DIMENSIONS.width / 2) + quantize(mid.x, SPACING),
y: -(GRID_DIMENSIONS.height / 2) + quantize(mid.y, SPACING)
})
}
isVisible() {
return this._visible
}
toggle(visible) {
if (typeof visible === 'undefined') {
visible = !this._visible
}
if (visible === this._visible) {
return
}
const parent = this._getParent()
if (visible) {
svgAppend(parent, this._gfx)
} else {
svgClear(parent)
}
this._visible = visible
}
_getParent() {
return this._canvas.getLayer(LAYER_NAME, -2)
}
}
CustomGrid.$inject = ['canvas', 'eventBus']
export default {
__init__: ['grid'],
grid: ['type', CustomGrid]
}