From 3410ece268ca08e21fa4d9f5011c1250251b9fd9 Mon Sep 17 00:00:00 2001 From: JFH <20402845+jfhenon@users.noreply.github.com> Date: Sat, 1 Jan 2022 14:17:29 -0300 Subject: [PATCH] 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. --- src/svgcanvas/recalculate.js | 125 +---------------------------------- src/svgcanvas/svgcanvas.js | 2 +- 2 files changed, 4 insertions(+), 123 deletions(-) diff --git a/src/svgcanvas/recalculate.js b/src/svgcanvas/recalculate.js index 343f9a36..e218e920 100644 --- a/src/svgcanvas/recalculate.js +++ b/src/svgcanvas/recalculate.js @@ -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 = []; diff --git a/src/svgcanvas/svgcanvas.js b/src/svgcanvas/svgcanvas.js index ad78176a..03d8896b 100644 --- a/src/svgcanvas/svgcanvas.js +++ b/src/svgcanvas/svgcanvas.js @@ -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 }