using consolidate() to simplify transformations

this has the effect to create a matrix transform so this avoid mixing the translation transform cause by the move with existing transformations on the object.
master
JFH 2022-01-01 14:17:29 -03:00
parent 82fab95988
commit 3410ece268
2 changed files with 4 additions and 123 deletions

View File

@ -10,7 +10,7 @@ import { getRotationAngle, getHref, getBBox, getRefElem } from './utilities.js'
import { BatchCommand, ChangeElementCommand } from './history.js'
import { remapElement } from './coords.js'
import {
isIdentity, matrixMultiply, transformPoint, transformListToTransform,
matrixMultiply, transformPoint, transformListToTransform,
hasMatrixTransform
} from './math.js'
import {
@ -19,28 +19,6 @@ import {
let svgCanvas
/**
* @interface module:recalculate.EditorContext
*/
/**
* @function module:recalculate.EditorContext#getSvgRoot
* @returns {SVGSVGElement} The root DOM element
*/
/**
* @function module:recalculate.EditorContext#getStartTransform
* @returns {string}
*/
/**
* @function module:recalculate.EditorContext#setStartTransform
* @param {string} transform
* @returns {void}
*/
/**
* @function module:recalculate.init
* @param {module:recalculate.EditorContext} editorContext
* @returns {void}
*/
export const init = (canvas) => {
svgCanvas = canvas
}
@ -76,96 +54,15 @@ export const recalculateDimensions = (selected) => {
const svgroot = svgCanvas.getSvgRoot()
const dataStorage = svgCanvas.getDataStorage()
const tlist = selected.transform?.baseVal
// remove any unnecessary transforms
if (tlist && tlist.numberOfItems > 0) {
let k = tlist.numberOfItems
const noi = k
while (k--) {
const xform = tlist.getItem(k)
if (xform.type === 0) {
tlist.removeItem(k)
// remove identity matrices
} else if (xform.type === 1) {
if (isIdentity(xform.matrix)) {
if (noi === 1) {
// Overcome Chrome bug (though only when noi is 1) with
// `removeItem` preventing `removeAttribute` from
// subsequently working
// See https://bugs.chromium.org/p/chromium/issues/detail?id=843901
selected.removeAttribute('transform')
return null
}
tlist.removeItem(k)
}
// remove zero-degree rotations
} else if (xform.type === 4 && xform.angle === 0) {
tlist.removeItem(k)
}
}
// End here if all it has is a rotation
if (tlist.numberOfItems === 1 &&
getRotationAngle(selected)) { return null }
}
// if this element had no transforms, we are done
if (!tlist || tlist.numberOfItems === 0) {
// Chrome apparently had a bug that requires clearing the attribute first.
selected.setAttribute('transform', '')
// However, this still next line currently doesn't work at all in Chrome
selected.removeAttribute('transform')
// selected.transform.baseVal.clear(); // Didn't help for Chrome bug
return null
}
// TODO: Make this work for more than 2
if (tlist) {
let mxs = []
let k = tlist.numberOfItems
while (k--) {
const xform = tlist.getItem(k)
if (xform.type === 1) {
mxs.push([xform.matrix, k])
} else if (mxs.length) {
mxs = []
}
}
if (mxs.length === 2) {
const mNew = svgroot.createSVGTransformFromMatrix(matrixMultiply(mxs[1][0], mxs[0][0]))
tlist.removeItem(mxs[0][1])
tlist.removeItem(mxs[1][1])
tlist.insertItemBefore(mNew, mxs[1][1])
}
// consolidate transforms using standard SVG
tlist.consolidate()
// combine matrix + translate
k = tlist.numberOfItems
if (k >= 2 && tlist.getItem(k - 2).type === 1 && tlist.getItem(k - 1).type === 2) {
const mt = svgroot.createSVGTransform()
const m = matrixMultiply(
tlist.getItem(k - 2).matrix,
tlist.getItem(k - 1).matrix
)
mt.setMatrix(m)
tlist.removeItem(k - 2)
tlist.removeItem(k - 2)
tlist.appendItem(mt)
}
}
// If it still has a single [M] or [R][M], return null too (prevents BatchCommand from being returned).
switch (selected.tagName) {
// Ignore these elements, as they can absorb the [M]
case 'line':
case 'polyline':
case 'polygon':
case 'path':
break
default:
if ((tlist.numberOfItems === 1 && tlist.getItem(0).type === 1) ||
(tlist.numberOfItems === 2 && tlist.getItem(0).type === 1 && tlist.getItem(0).type === 4)) {
return null
}
}
// Grouped SVG element
const gsvg = (dataStorage.has(selected, 'gsvg')) ? dataStorage.get(selected, 'gsvg') : undefined
// we know we have some transforms, so set up return variable
@ -305,22 +202,6 @@ export const recalculateDimensions = (selected) => {
const m = transformListToTransform(childTlist).matrix
// Convert a matrix to a scale if applicable
// if (hasMatrixTransform(childTlist) && childTlist.numberOfItems == 1) {
// if (m.b==0 && m.c==0 && m.e==0 && m.f==0) {
// childTlist.removeItem(0);
// const translateOrigin = svgroot.createSVGTransform(),
// scale = svgroot.createSVGTransform(),
// translateBack = svgroot.createSVGTransform();
// translateOrigin.setTranslate(0, 0);
// scale.setScale(m.a, m.d);
// translateBack.setTranslate(0, 0);
// childTlist.appendItem(translateBack);
// childTlist.appendItem(scale);
// childTlist.appendItem(translateOrigin);
// }
// }
const angle = getRotationAngle(child)
oldStartTransform = svgCanvas.getStartTransform()
// const childxforms = [];

View File

@ -301,7 +301,7 @@ class SvgCanvas {
getSelectedElements () { return this.selectedElements }
setSelectedElements (key, value) { this.selectedElements[key] = value }
setEmptySelectedElements () { this.selectedElements = [] }
getSvgRoot () { return this.svgroot }
getSvgRoot () { return this.svgroot } // @returns {SVGSVGElement} The root DOM element
getDOMDocument () { return this.svgdoc }
getDOMContainer () { return this.container }
getCurConfig () { return this.curConfig }