UNPKG

svgedit

Version:

Powerful SVG-Editor for your browser

179 lines (165 loc) 5.22 kB
/** * @file ext-grid.js * * @license Apache-2.0 * * @copyright 2010 Redou Mine, 2010 Alexis Deveria * */ const name = 'grid' const loadExtensionTranslation = async function (svgEditor) { let translationModule const lang = svgEditor.configObj.pref('lang') try { translationModule = await import(`./locale/${lang}.js`) } catch (_error) { console.warn(`Missing translation (${lang}) for ${name} - using 'en'`) translationModule = await import('./locale/en.js') } svgEditor.i18next.addResourceBundle(lang, name, translationModule.default) } export default { name, async init () { const svgEditor = this await loadExtensionTranslation(svgEditor) const { svgCanvas } = svgEditor const { $id, $click, NS } = svgCanvas const svgdoc = $id('svgcanvas').ownerDocument const { assignAttributes } = svgCanvas const hcanvas = document.createElement('canvas') const canvBG = $id('canvasBackground') const units = svgCanvas.getTypeMap() // Assumes prior `init()` call on `units.js` module const intervals = [0.01, 0.1, 1, 10, 100, 1000] let showGrid = svgEditor.configObj.curConfig.showGrid || false hcanvas.style.display = 'none' svgEditor.$svgEditor.appendChild(hcanvas) const canvasGrid = svgdoc.createElementNS(NS.SVG, 'svg') assignAttributes(canvasGrid, { id: 'canvasGrid', width: '100%', height: '100%', x: 0, y: 0, overflow: 'visible', display: 'none' }) canvBG.appendChild(canvasGrid) const gridDefs = svgdoc.createElementNS(NS.SVG, 'defs') // grid-pattern const gridPattern = svgdoc.createElementNS(NS.SVG, 'pattern') assignAttributes(gridPattern, { id: 'gridpattern', patternUnits: 'userSpaceOnUse', x: 0, // -(value.strokeWidth / 2), // position for strokewidth y: 0, // -(value.strokeWidth / 2), // position for strokewidth width: 100, height: 100 }) const gridimg = svgdoc.createElementNS(NS.SVG, 'image') assignAttributes(gridimg, { x: 0, y: 0, width: 100, height: 100 }) gridPattern.append(gridimg) gridDefs.append(gridPattern) $id('canvasGrid').appendChild(gridDefs) // grid-box const gridBox = svgdoc.createElementNS(NS.SVG, 'rect') assignAttributes(gridBox, { width: '100%', height: '100%', x: 0, y: 0, 'stroke-width': 0, stroke: 'none', fill: 'url(#gridpattern)', style: 'pointer-events: none; display:visible;' }) $id('canvasGrid').appendChild(gridBox) /** * * @param {Float} zoom * @returns {void} */ const updateGrid = (zoom) => { // TODO: Try this with <line> elements, then compare performance difference const unit = units[svgEditor.configObj.curConfig.baseUnit] // 1 = 1px const uMulti = unit * zoom // Calculate the main number interval const rawM = 100 / uMulti let multi = 1 intervals.some((num) => { multi = num return rawM <= num }) const bigInt = multi * uMulti // Set the canvas size to the width of the container hcanvas.width = bigInt hcanvas.height = bigInt const ctx = hcanvas.getContext('2d') const curD = 0.5 const part = bigInt / 10 ctx.globalAlpha = 0.2 ctx.strokeStyle = svgEditor.configObj.curConfig.gridColor for (let i = 1; i < 10; i++) { const subD = Math.round(part * i) + 0.5 // const lineNum = (i % 2)?12:10; const lineNum = 0 ctx.moveTo(subD, bigInt) ctx.lineTo(subD, lineNum) ctx.moveTo(bigInt, subD) ctx.lineTo(lineNum, subD) } ctx.stroke() ctx.beginPath() ctx.globalAlpha = 0.5 ctx.moveTo(curD, bigInt) ctx.lineTo(curD, 0) ctx.moveTo(bigInt, curD) ctx.lineTo(0, curD) ctx.stroke() const datauri = hcanvas.toDataURL('image/png') gridimg.setAttribute('width', bigInt) gridimg.setAttribute('height', bigInt) gridimg.parentNode.setAttribute('width', bigInt) gridimg.parentNode.setAttribute('height', bigInt) svgCanvas.setHref(gridimg, datauri) } /** * * @returns {void} */ const gridUpdate = () => { if (showGrid) { updateGrid(svgCanvas.getZoom()) } $id('canvasGrid').style.display = (showGrid) ? 'block' : 'none' $id('view_grid').pressed = showGrid } return { name: svgEditor.i18next.t(`${name}:name`), zoomChanged (zoom) { if (showGrid) { updateGrid(zoom) } }, callback () { // Add the button and its handler(s) const buttonTemplate = document.createElement('template') const title = `${name}:buttons.0.title` buttonTemplate.innerHTML = ` <se-button id="view_grid" title="${title}" src="grid.svg"></se-button> ` $id('editor_panel').append(buttonTemplate.content.cloneNode(true)) $click($id('view_grid'), () => { svgEditor.configObj.curConfig.showGrid = showGrid = !showGrid gridUpdate() }) if (showGrid) { gridUpdate() } } } } }