@svgedit/svgcanvas 7.4.1 → 7.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/elem-get-set.js +86 -38
- package/core/event.js +53 -26
- package/core/history.js +57 -22
- package/core/sanitize.js +5 -4
- package/core/selected-elem.js +13 -7
- package/core/text-actions.js +39 -4
- package/core/undo.js +27 -10
- package/dist/svgcanvas.js +40089 -33447
- package/dist/svgcanvas.js.map +1 -1
- package/package.json +1 -1
- package/svgcanvas.js +3 -1
package/core/undo.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import * as draw from './draw.js'
|
|
8
8
|
import * as hstry from './history.js'
|
|
9
|
+
import { BBOX_AFFECTING_ATTRS } from './history.js'
|
|
9
10
|
import {
|
|
10
11
|
getRotationAngle, getBBox as utilsGetBBox, setHref, getStrokedBBoxDefaultVisible
|
|
11
12
|
} from './utilities.js'
|
|
@@ -204,7 +205,10 @@ export const changeSelectedAttributeNoUndoMethod = (attr, newValue, elems) => {
|
|
|
204
205
|
} else if (attr === '#href') {
|
|
205
206
|
setHref(elem, newValue)
|
|
206
207
|
} else if (newValue) {
|
|
207
|
-
|
|
208
|
+
// Number(), unlike parseFloat(), rejects a value with a trailing unit suffix
|
|
209
|
+
// (e.g. "10pt", "2px") instead of silently truncating it to a bare number.
|
|
210
|
+
const asNumber = Number(newValue)
|
|
211
|
+
elem.setAttribute(attr, Number.isNaN(asNumber) ? newValue : asNumber)
|
|
208
212
|
} else if (typeof newValue === 'number') {
|
|
209
213
|
elem.setAttribute(attr, newValue)
|
|
210
214
|
} else {
|
|
@@ -239,26 +243,39 @@ export const changeSelectedAttributeNoUndoMethod = (attr, newValue, elems) => {
|
|
|
239
243
|
svgCanvas.selectorManager.requestSelector(elem).resize()
|
|
240
244
|
}, 0)
|
|
241
245
|
}
|
|
242
|
-
//
|
|
243
|
-
//
|
|
246
|
+
// Only recalculate rotation center for attributes that change element geometry.
|
|
247
|
+
// Non-geometric attributes (stroke-width, fill, opacity, etc.) don't affect
|
|
248
|
+
// the bbox center, so the rotation is already correct and must not be touched.
|
|
249
|
+
// BBOX_AFFECTING_ATTRS is imported from history.js to keep the list in one place.
|
|
244
250
|
const angle = getRotationAngle(elem)
|
|
245
|
-
if (angle !== 0 && attr !== 'transform') {
|
|
251
|
+
if (angle !== 0 && attr !== 'transform' && BBOX_AFFECTING_ATTRS.has(attr)) {
|
|
246
252
|
const tlist = getTransformList(elem)
|
|
247
253
|
let n = tlist.numberOfItems
|
|
248
254
|
while (n--) {
|
|
249
255
|
const xform = tlist.getItem(n)
|
|
250
256
|
if (xform.type === 4) {
|
|
251
|
-
//
|
|
257
|
+
// Compute bbox BEFORE removing the rotation so we can bail out
|
|
258
|
+
// safely if getBBox returns nothing (avoids losing the rotation).
|
|
259
|
+
const box = utilsGetBBox(elem)
|
|
260
|
+
if (!box) break
|
|
261
|
+
|
|
252
262
|
tlist.removeItem(n)
|
|
253
263
|
|
|
254
|
-
|
|
264
|
+
// Transform bbox center through only the transforms that come
|
|
265
|
+
// AFTER the rotation in the list (not the pre-rotation transforms).
|
|
266
|
+
// After removeItem(n), what was at n+1 is now at n.
|
|
267
|
+
let centerMatrix
|
|
268
|
+
if (n < tlist.numberOfItems) {
|
|
269
|
+
centerMatrix = transformListToTransform(tlist, n, tlist.numberOfItems - 1).matrix
|
|
270
|
+
} else {
|
|
271
|
+
centerMatrix = svgCanvas.getSvgRoot().createSVGMatrix() // identity
|
|
272
|
+
}
|
|
255
273
|
const center = transformPoint(
|
|
256
|
-
box.x + box.width / 2, box.y + box.height / 2,
|
|
274
|
+
box.x + box.width / 2, box.y + box.height / 2, centerMatrix
|
|
257
275
|
)
|
|
258
|
-
|
|
259
|
-
const cy = center.y
|
|
276
|
+
|
|
260
277
|
const newrot = svgCanvas.getSvgRoot().createSVGTransform()
|
|
261
|
-
newrot.setRotate(angle,
|
|
278
|
+
newrot.setRotate(angle, center.x, center.y)
|
|
262
279
|
tlist.insertItemBefore(newrot, n)
|
|
263
280
|
break
|
|
264
281
|
}
|