svgedit/packages/svgcanvas/blur-event.js

157 lines
4.3 KiB
JavaScript

/**
* Tools for blur event.
* @module blur
* @license MIT
* @copyright 2011 Jeff Schiller
*/
let svgCanvas = null
/**
* @function module:blur.init
* @param {module:blur.blurContext} blurContext
* @returns {void}
*/
export const init = (canvas) => {
svgCanvas = canvas
}
/**
* Sets the `stdDeviation` blur value on the selected element without being undoable.
* @function module:svgcanvas.SvgCanvas#setBlurNoUndo
* @param {Float} val - The new `stdDeviation` value
* @returns {void}
*/
export const setBlurNoUndo = function (val) {
const selectedElements = svgCanvas.getSelectedElements()
if (!svgCanvas.getFilter()) {
svgCanvas.setBlur(val)
return
}
if (val === 0) {
// Don't change the StdDev, as that will hide the element.
// Instead, just remove the value for "filter"
svgCanvas.changeSelectedAttributeNoUndo('filter', '')
svgCanvas.setFilterHidden(true)
} else {
const elem = selectedElements[0]
if (svgCanvas.getFilterHidden()) {
svgCanvas.changeSelectedAttributeNoUndo('filter', 'url(#' + elem.id + '_blur)')
}
const filter = svgCanvas.getFilter()
svgCanvas.changeSelectedAttributeNoUndo('stdDeviation', val, [filter.firstChild])
svgCanvas.setBlurOffsets(filter, val)
}
}
/**
*
* @returns {void}
*/
function finishChange () {
const bCmd = svgCanvas.undoMgr.finishUndoableChange()
svgCanvas.getCurCommand().addSubCommand(bCmd)
svgCanvas.addCommandToHistory(svgCanvas.getCurCommand())
svgCanvas.setCurCommand(null)
svgCanvas.setFilter(null)
}
/**
* Sets the `x`, `y`, `width`, `height` values of the filter element in order to
* make the blur not be clipped. Removes them if not neeeded.
* @function module:svgcanvas.SvgCanvas#setBlurOffsets
* @param {Element} filterElem - The filter DOM element to update
* @param {Float} stdDev - The standard deviation value on which to base the offset size
* @returns {void}
*/
export const setBlurOffsets = function (filterElem, stdDev) {
if (stdDev > 3) {
// TODO: Create algorithm here where size is based on expected blur
svgCanvas.assignAttributes(filterElem, {
x: '-50%',
y: '-50%',
width: '200%',
height: '200%'
}, 100)
} else {
filterElem.removeAttribute('x')
filterElem.removeAttribute('y')
filterElem.removeAttribute('width')
filterElem.removeAttribute('height')
}
}
/**
* Adds/updates the blur filter to the selected element.
* @function module:svgcanvas.SvgCanvas#setBlur
* @param {Float} val - Float with the new `stdDeviation` blur value
* @param {boolean} complete - Whether or not the action should be completed (to add to the undo manager)
* @returns {void}
*/
export const setBlur = function (val, complete) {
const {
InsertElementCommand, ChangeElementCommand, BatchCommand
} = svgCanvas.history
const selectedElements = svgCanvas.getSelectedElements()
if (svgCanvas.getCurCommand()) {
finishChange()
return
}
// Looks for associated blur, creates one if not found
const elem = selectedElements[0]
const elemId = elem.id
svgCanvas.setFilter(svgCanvas.getElement(elemId + '_blur'))
val -= 0
const batchCmd = new BatchCommand()
// Blur found!
if (svgCanvas.getFilter()) {
if (val === 0) {
svgCanvas.setFilter(null)
}
} else {
// Not found, so create
const newblur = svgCanvas.addSVGElementsFromJson({
element: 'feGaussianBlur',
attr: {
in: 'SourceGraphic',
stdDeviation: val
}
})
svgCanvas.setFilter(svgCanvas.addSVGElementsFromJson({
element: 'filter',
attr: {
id: elemId + '_blur'
}
}))
svgCanvas.getFilter().append(newblur)
svgCanvas.findDefs().append(svgCanvas.getFilter())
batchCmd.addSubCommand(new InsertElementCommand(svgCanvas.getFilter()))
}
const changes = { filter: elem.getAttribute('filter') }
if (val === 0) {
elem.removeAttribute('filter')
batchCmd.addSubCommand(new ChangeElementCommand(elem, changes))
return
}
svgCanvas.changeSelectedAttribute('filter', 'url(#' + elemId + '_blur)')
batchCmd.addSubCommand(new ChangeElementCommand(elem, changes))
svgCanvas.setBlurOffsets(svgCanvas.getFilter(), val)
const filter = svgCanvas.getFilter()
svgCanvas.setCurCommand(batchCmd)
svgCanvas.undoMgr.beginUndoableChange('stdDeviation', [filter ? filter.firstChild : null])
if (complete) {
svgCanvas.setBlurNoUndo(val)
finishChange()
}
}