@svgedit/svgcanvas 7.2.1 → 7.2.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/CHANGES.md ADDED
@@ -0,0 +1,8 @@
1
+ # svgcanvas CHANGES
2
+
3
+ ## 7.2.1
4
+ - npm packages ugrade
5
+ - bug fixes
6
+
7
+ ## previous history
8
+ - See svgedit changes.md
package/core/coords.js CHANGED
@@ -8,7 +8,7 @@ import {
8
8
  snapToGrid, assignAttributes, getBBox, getRefElem, findDefs
9
9
  } from './utilities.js'
10
10
  import {
11
- transformPoint, transformListToTransform, matrixMultiply, transformBox
11
+ transformPoint, transformListToTransform, matrixMultiply, transformBox, getTransformList
12
12
  } from './math.js'
13
13
 
14
14
  // this is how we map paths to our preferred relative segment types
@@ -98,7 +98,7 @@ export const remapElement = (selected, changes, m) => {
98
98
  changes.y = Number.parseFloat(changes.y) + tNew.f
99
99
  } else {
100
100
  // we just absorb all matrices into the element and don't do any remapping
101
- const chlist = selected.transform.baseVal
101
+ const chlist = getTransformList(selected)
102
102
  const mt = svgCanvas.getSvgRoot().createSVGTransform()
103
103
  mt.setMatrix(matrixMultiply(transformListToTransform(chlist).matrix, m))
104
104
  chlist.clear()
@@ -115,7 +115,7 @@ export const remapElement = (selected, changes, m) => {
115
115
  // Allow images to be inverted (give them matrix when flipped)
116
116
  if (elName === 'image' && (m.a < 0 || m.d < 0)) {
117
117
  // Convert to matrix
118
- const chlist = selected.transform.baseVal
118
+ const chlist = getTransformList(selected)
119
119
  const mt = svgCanvas.getSvgRoot().createSVGTransform()
120
120
  mt.setMatrix(matrixMultiply(transformListToTransform(chlist).matrix, m))
121
121
  chlist.clear()
@@ -526,6 +526,7 @@ const setPaintMethod = (type, paint) => {
526
526
  break
527
527
  }
528
528
  }
529
+
529
530
  /**
530
531
  * Sets the stroke width for the current selected elements.
531
532
  * When attempting to set a line's width to 0, this changes it to 1 instead.
@@ -599,54 +600,41 @@ const setStrokeAttrMethod = (attr, val) => {
599
600
  svgCanvas.call('changed', selectedElements)
600
601
  }
601
602
  }
603
+
602
604
  /**
603
- * Check whether selected element is bold or not.
604
- * @function module:svgcanvas.SvgCanvas#getBold
605
- * @returns {boolean} Indicates whether or not element is bold
606
- */
605
+ * Check if all selected text elements are in bold.
606
+ * @function module:svgcanvas.SvgCanvas#getBold
607
+ * @returns {boolean} `true` if all selected elements are bold, `false` otherwise.
608
+ */
607
609
  const getBoldMethod = () => {
608
610
  const selectedElements = svgCanvas.getSelectedElements()
609
- // should only have one element selected
610
- const selected = selectedElements[0]
611
- if (selected?.tagName === 'text' &&
612
- !selectedElements[1]) {
613
- return (selected.getAttribute('font-weight') === 'bold')
614
- }
615
- return false
611
+ const textElements = selectedElements.filter(el => el?.tagName === 'text')
612
+ return textElements.every(el => el.getAttribute('font-weight') === 'bold')
616
613
  }
617
614
 
618
615
  /**
619
- * Make the selected element bold or normal.
620
- * @function module:svgcanvas.SvgCanvas#setBold
621
- * @param {boolean} b - Indicates bold (`true`) or normal (`false`)
622
- * @returns {void}
623
- */
616
+ * Make the selected element(s) bold or normal.
617
+ * @function module:svgcanvas.SvgCanvas#setBold
618
+ * @param {boolean} b - Indicates bold (`true`) or normal (`false`)
619
+ * @returns {void}
620
+ */
624
621
  const setBoldMethod = (b) => {
625
622
  const selectedElements = svgCanvas.getSelectedElements()
626
- const selected = selectedElements[0]
627
- if (selected?.tagName === 'text' &&
628
- !selectedElements[1]) {
629
- svgCanvas.changeSelectedAttribute('font-weight', b ? 'bold' : 'normal')
630
- }
631
- if (!selectedElements[0].textContent) {
623
+ const textElements = selectedElements.filter(el => el?.tagName === 'text')
624
+ svgCanvas.changeSelectedAttribute('font-weight', b ? 'bold' : 'normal', textElements)
625
+ if (!textElements.some(el => el.textContent)) {
632
626
  svgCanvas.textActions.setCursor()
633
627
  }
634
628
  }
635
629
 
636
630
  /**
637
- * Check whether selected element has the given text decoration value or not.
638
- * @returns {boolean} Indicates whether or not element has the text decoration value
631
+ * Check if all selected text elements have the given text decoration value or not.
632
+ * @returns {boolean} Indicates whether or not elements have the text decoration value
639
633
  */
640
634
  const hasTextDecorationMethod = (value) => {
641
635
  const selectedElements = svgCanvas.getSelectedElements()
642
- const selected = selectedElements[0]
643
-
644
- if (selected?.tagName === 'text' && !selectedElements[1]) {
645
- const attribute = selected.getAttribute('text-decoration') || ''
646
- return attribute.includes(value)
647
- }
648
-
649
- return false
636
+ const textElements = selectedElements.filter(el => el?.tagName === 'text')
637
+ return textElements.every(el => (el.getAttribute('text-decoration') || '').includes(value))
650
638
  }
651
639
 
652
640
  /**
@@ -655,13 +643,24 @@ const hasTextDecorationMethod = (value) => {
655
643
  * @returns {void}
656
644
  */
657
645
  const addTextDecorationMethod = (value) => {
646
+ const { ChangeElementCommand, BatchCommand } = svgCanvas.history
658
647
  const selectedElements = svgCanvas.getSelectedElements()
659
- const selected = selectedElements[0]
660
- if (selected?.tagName === 'text' && !selectedElements[1]) {
661
- const oldValue = selected.getAttribute('text-decoration') || ''
662
- svgCanvas.changeSelectedAttribute('text-decoration', (oldValue + ' ' + value).trim())
648
+ const textElements = selectedElements.filter(el => el?.tagName === 'text')
649
+
650
+ const batchCmd = new BatchCommand()
651
+ textElements.forEach(elem => {
652
+ const oldValue = elem.getAttribute('text-decoration') || ''
653
+ // Add the new text decoration value if it did not exist
654
+ if (!oldValue.includes(value)) {
655
+ batchCmd.addSubCommand(new ChangeElementCommand(elem, { 'text-decoration': oldValue }))
656
+ svgCanvas.changeSelectedAttributeNoUndo('text-decoration', (oldValue + ' ' + value).trim(), [elem])
657
+ }
658
+ })
659
+ if (!batchCmd.isEmpty()) {
660
+ svgCanvas.undoMgr.addCommandToHistory(batchCmd)
663
661
  }
664
- if (selectedElements.length > 0 && !selectedElements[0].textContent) {
662
+
663
+ if (!textElements.some(el => el.textContent)) {
665
664
  svgCanvas.textActions.setCursor()
666
665
  }
667
666
  }
@@ -672,44 +671,47 @@ const addTextDecorationMethod = (value) => {
672
671
  * @returns {void}
673
672
  */
674
673
  const removeTextDecorationMethod = (value) => {
674
+ const { ChangeElementCommand, BatchCommand } = svgCanvas.history
675
675
  const selectedElements = svgCanvas.getSelectedElements()
676
- const selected = selectedElements[0]
677
- if (selected?.tagName === 'text' && !selectedElements[1]) {
678
- const actualValues = selected.getAttribute('text-decoration') || ''
679
- svgCanvas.changeSelectedAttribute('text-decoration', actualValues.replace(value, '').trim())
676
+ const textElements = selectedElements.filter(el => el?.tagName === 'text')
677
+
678
+ const batchCmd = new BatchCommand()
679
+ textElements.forEach(elem => {
680
+ const actualValues = elem.getAttribute('text-decoration') || ''
681
+ batchCmd.addSubCommand(new ChangeElementCommand(elem, { 'text-decoration': actualValues }))
682
+ svgCanvas.changeSelectedAttributeNoUndo('text-decoration', actualValues.replace(value, '').trim(), [elem])
683
+ })
684
+ if (!batchCmd.isEmpty()) {
685
+ svgCanvas.undoMgr.addCommandToHistory(batchCmd)
680
686
  }
681
- if (selectedElements.length > 0 && !selectedElements[0].textContent) {
687
+
688
+ if (!textElements.some(el => el.textContent)) {
682
689
  svgCanvas.textActions.setCursor()
683
690
  }
684
691
  }
685
692
 
686
693
  /**
687
- * Check whether selected element is in italics or not.
688
- * @function module:svgcanvas.SvgCanvas#getItalic
689
- * @returns {boolean} Indicates whether or not element is italic
690
- */
694
+ * Check if all selected elements have an italic font style.
695
+ * @function module:svgcanvas.SvgCanvas#getItalic
696
+ * @returns {boolean} `true` if all selected elements are in italics, `false` otherwise.
697
+ */
691
698
  const getItalicMethod = () => {
692
699
  const selectedElements = svgCanvas.getSelectedElements()
693
- const selected = selectedElements[0]
694
- if (selected?.tagName === 'text' && !selectedElements[1]) {
695
- return (selected.getAttribute('font-style') === 'italic')
696
- }
697
- return false
700
+ const textElements = selectedElements.filter(el => el?.tagName === 'text')
701
+ return textElements.every(el => el.getAttribute('font-style') === 'italic')
698
702
  }
699
703
 
700
704
  /**
701
- * Make the selected element italic or normal.
702
- * @function module:svgcanvas.SvgCanvas#setItalic
703
- * @param {boolean} i - Indicates italic (`true`) or normal (`false`)
704
- * @returns {void}
705
- */
705
+ * Make the selected element(s) italic or normal.
706
+ * @function module:svgcanvas.SvgCanvas#setItalic
707
+ * @param {boolean} i - Indicates italic (`true`) or normal (`false`)
708
+ * @returns {void}
709
+ */
706
710
  const setItalicMethod = (i) => {
707
711
  const selectedElements = svgCanvas.getSelectedElements()
708
- const selected = selectedElements[0]
709
- if (selected?.tagName === 'text' && !selectedElements[1]) {
710
- svgCanvas.changeSelectedAttribute('font-style', i ? 'italic' : 'normal')
711
- }
712
- if (!selectedElements[0].textContent) {
712
+ const textElements = selectedElements.filter(el => el?.tagName === 'text')
713
+ svgCanvas.changeSelectedAttribute('font-style', i ? 'italic' : 'normal', textElements)
714
+ if (!textElements.some(el => el.textContent)) {
713
715
  svgCanvas.textActions.setCursor()
714
716
  }
715
717
  }
@@ -721,13 +723,8 @@ const setItalicMethod = (i) => {
721
723
  */
722
724
  const setTextAnchorMethod = (value) => {
723
725
  const selectedElements = svgCanvas.getSelectedElements()
724
- const selected = selectedElements[0]
725
- if (selected?.tagName === 'text' && !selectedElements[1]) {
726
- svgCanvas.changeSelectedAttribute('text-anchor', value)
727
- }
728
- if (selectedElements.length > 0 && !selectedElements[0].textContent) {
729
- svgCanvas.textActions.setCursor()
730
- }
726
+ const textElements = selectedElements.filter(el => el?.tagName === 'text')
727
+ svgCanvas.changeSelectedAttribute('text-anchor', value, textElements)
731
728
  }
732
729
 
733
730
  /**
@@ -737,11 +734,9 @@ const setTextAnchorMethod = (value) => {
737
734
  */
738
735
  const setLetterSpacingMethod = (value) => {
739
736
  const selectedElements = svgCanvas.getSelectedElements()
740
- const selected = selectedElements[0]
741
- if (selected?.tagName === 'text' && !selectedElements[1]) {
742
- svgCanvas.changeSelectedAttribute('letter-spacing', value)
743
- }
744
- if (selectedElements.length > 0 && !selectedElements[0].textContent) {
737
+ const textElements = selectedElements.filter(el => el?.tagName === 'text')
738
+ svgCanvas.changeSelectedAttribute('letter-spacing', value, textElements)
739
+ if (!textElements.some(el => el.textContent)) {
745
740
  svgCanvas.textActions.setCursor()
746
741
  }
747
742
  }
@@ -753,11 +748,9 @@ const setLetterSpacingMethod = (value) => {
753
748
  */
754
749
  const setWordSpacingMethod = (value) => {
755
750
  const selectedElements = svgCanvas.getSelectedElements()
756
- const selected = selectedElements[0]
757
- if (selected?.tagName === 'text' && !selectedElements[1]) {
758
- svgCanvas.changeSelectedAttribute('word-spacing', value)
759
- }
760
- if (selectedElements.length > 0 && !selectedElements[0].textContent) {
751
+ const textElements = selectedElements.filter(el => el?.tagName === 'text')
752
+ svgCanvas.changeSelectedAttribute('word-spacing', value, textElements)
753
+ if (!textElements.some(el => el.textContent)) {
761
754
  svgCanvas.textActions.setCursor()
762
755
  }
763
756
  }
@@ -769,11 +762,9 @@ const setWordSpacingMethod = (value) => {
769
762
  */
770
763
  const setTextLengthMethod = (value) => {
771
764
  const selectedElements = svgCanvas.getSelectedElements()
772
- const selected = selectedElements[0]
773
- if (selected?.tagName === 'text' && !selectedElements[1]) {
774
- svgCanvas.changeSelectedAttribute('textLength', value)
775
- }
776
- if (selectedElements.length > 0 && !selectedElements[0].textContent) {
765
+ const textElements = selectedElements.filter(el => el?.tagName === 'text')
766
+ svgCanvas.changeSelectedAttribute('textLength', value, textElements)
767
+ if (!textElements.some(el => el.textContent)) {
777
768
  svgCanvas.textActions.setCursor()
778
769
  }
779
770
  }
@@ -785,11 +776,9 @@ const setTextLengthMethod = (value) => {
785
776
  */
786
777
  const setLengthAdjustMethod = (value) => {
787
778
  const selectedElements = svgCanvas.getSelectedElements()
788
- const selected = selectedElements[0]
789
- if (selected?.tagName === 'text' && !selectedElements[1]) {
790
- svgCanvas.changeSelectedAttribute('lengthAdjust', value)
791
- }
792
- if (selectedElements.length > 0 && !selectedElements[0].textContent) {
779
+ const textElements = selectedElements.filter(el => el?.tagName === 'text')
780
+ svgCanvas.changeSelectedAttribute('lengthAdjust', value, textElements)
781
+ if (!textElements.some(el => el.textContent)) {
793
782
  svgCanvas.textActions.setCursor()
794
783
  }
795
784
  }
@@ -810,9 +799,10 @@ const getFontFamilyMethod = () => {
810
799
  */
811
800
  const setFontFamilyMethod = (val) => {
812
801
  const selectedElements = svgCanvas.getSelectedElements()
802
+ const textElements = selectedElements.filter(el => el?.tagName === 'text')
813
803
  svgCanvas.setCurText('font_family', val)
814
- svgCanvas.changeSelectedAttribute('font-family', val)
815
- if (!selectedElements[0]?.textContent) {
804
+ svgCanvas.changeSelectedAttribute('font-family', val, textElements)
805
+ if (!textElements.some(el => el.textContent)) {
816
806
  svgCanvas.textActions.setCursor()
817
807
  }
818
808
  }
package/core/event.js CHANGED
@@ -12,7 +12,7 @@ import {
12
12
  convertAttrs
13
13
  } from './units.js'
14
14
  import {
15
- transformPoint, hasMatrixTransform, getMatrix, snapToAngle
15
+ transformPoint, hasMatrixTransform, getMatrix, snapToAngle, getTransformList
16
16
  } from './math.js'
17
17
  import * as draw from './draw.js'
18
18
  import * as pathModule from './path.js'
@@ -83,7 +83,7 @@ const getBsplinePoint = (t) => {
83
83
  const updateTransformList = (svgRoot, element, dx, dy) => {
84
84
  const xform = svgRoot.createSVGTransform()
85
85
  xform.setTranslate(dx, dy)
86
- const tlist = element.transform?.baseVal
86
+ const tlist = getTransformList(element)
87
87
  if (tlist.numberOfItems) {
88
88
  const firstItem = tlist.getItem(0)
89
89
  if (firstItem.type === 2) { // SVG_TRANSFORM_TRANSLATE = 2
@@ -221,7 +221,7 @@ const mouseMoveEvent = (evt) => {
221
221
  // we track the resize bounding box and translate/scale the selected element
222
222
  // while the mouse is down, when mouse goes up, we use this to recalculate
223
223
  // the shape's coordinates
224
- tlist = selected.transform.baseVal
224
+ tlist = getTransformList(selected)
225
225
  const hasMatrix = hasMatrixTransform(tlist)
226
226
  box = hasMatrix ? svgCanvas.getInitBbox() : getBBox(selected)
227
227
  let left = box.x
@@ -1026,7 +1026,7 @@ const mouseDownEvent = (evt) => {
1026
1026
 
1027
1027
  svgCanvas.setStartTransform(mouseTarget.getAttribute('transform'))
1028
1028
 
1029
- const tlist = mouseTarget.transform.baseVal
1029
+ const tlist = getTransformList(mouseTarget)
1030
1030
  // consolidate transforms using standard SVG but keep the transformation used for the move/scale
1031
1031
  if (tlist.numberOfItems > 1) {
1032
1032
  const firstTransform = tlist.getItem(0)
@@ -1060,7 +1060,7 @@ const mouseDownEvent = (evt) => {
1060
1060
  // a transform to use for its translate
1061
1061
  for (const selectedElement of selectedElements) {
1062
1062
  if (!selectedElement) { continue }
1063
- const slist = selectedElement.transform?.baseVal
1063
+ const slist = getTransformList(selectedElement)
1064
1064
  if (slist.numberOfItems) {
1065
1065
  slist.insertItemBefore(svgRoot.createSVGTransform(), 0)
1066
1066
  } else {
package/core/math.js CHANGED
@@ -7,17 +7,17 @@
7
7
  */
8
8
 
9
9
  /**
10
- * @typedef {PlainObject} module:math.AngleCoord45
11
- * @property {Float} x - The angle-snapped x value
12
- * @property {Float} y - The angle-snapped y value
13
- * @property {Integer} a - The angle at which to snap
14
- */
10
+ * @typedef {PlainObject} module:math.AngleCoord45
11
+ * @property {Float} x - The angle-snapped x value
12
+ * @property {Float} y - The angle-snapped y value
13
+ * @property {Integer} a - The angle at which to snap
14
+ */
15
15
 
16
16
  /**
17
- * @typedef {PlainObject} module:math.XYObject
18
- * @property {Float} x
19
- * @property {Float} y
20
- */
17
+ * @typedef {PlainObject} module:math.XYObject
18
+ * @property {Float} x
19
+ * @property {Float} y
20
+ */
21
21
 
22
22
  import { NS } from './namespaces.js'
23
23
 
@@ -35,20 +35,35 @@ const svg = document.createElementNS(NS.SVG, 'svg')
35
35
  * @param {Float} y - Float representing the y coordinate
36
36
  * @param {SVGMatrix} m - Matrix object to transform the point with
37
37
  * @returns {module:math.XYObject} An x, y object representing the transformed point
38
- */
38
+ */
39
39
  export const transformPoint = function (x, y, m) {
40
40
  return { x: m.a * x + m.c * y + m.e, y: m.b * x + m.d * y + m.f }
41
41
  }
42
42
 
43
+ export const getTransformList = (elem) => {
44
+ if (elem.transform) {
45
+ return elem.transform?.baseVal
46
+ }
47
+ if (elem.gradientTransform) {
48
+ return elem.gradientTransform?.baseVal
49
+ }
50
+ if (elem.patternTransform) {
51
+ return elem.patternTransform?.baseVal
52
+ }
53
+ console.warn('no transform list found - check browser version', elem)
54
+ }
55
+
43
56
  /**
44
57
  * Helper function to check if the matrix performs no actual transform
45
58
  * (i.e. exists for identity purposes).
46
59
  * @function module:math.isIdentity
47
60
  * @param {SVGMatrix} m - The matrix object to check
48
61
  * @returns {boolean} Indicates whether or not the matrix is 1,0,0,1,0,0
49
- */
62
+ */
50
63
  export const isIdentity = function (m) {
51
- return (m.a === 1 && m.b === 0 && m.c === 0 && m.d === 1 && m.e === 0 && m.f === 0)
64
+ return (
65
+ m.a === 1 && m.b === 0 && m.c === 0 && m.d === 1 && m.e === 0 && m.f === 0
66
+ )
52
67
  }
53
68
 
54
69
  /**
@@ -57,18 +72,30 @@ export const isIdentity = function (m) {
57
72
  * @function module:math.matrixMultiply
58
73
  * @param {...SVGMatrix} args - Matrix objects to multiply
59
74
  * @returns {SVGMatrix} The matrix object resulting from the calculation
60
- */
75
+ */
61
76
  export const matrixMultiply = function (...args) {
62
77
  const m = args.reduceRight((prev, m1) => {
63
78
  return m1.multiply(prev)
64
79
  })
65
80
 
66
- if (Math.abs(m.a) < NEAR_ZERO) { m.a = 0 }
67
- if (Math.abs(m.b) < NEAR_ZERO) { m.b = 0 }
68
- if (Math.abs(m.c) < NEAR_ZERO) { m.c = 0 }
69
- if (Math.abs(m.d) < NEAR_ZERO) { m.d = 0 }
70
- if (Math.abs(m.e) < NEAR_ZERO) { m.e = 0 }
71
- if (Math.abs(m.f) < NEAR_ZERO) { m.f = 0 }
81
+ if (Math.abs(m.a) < NEAR_ZERO) {
82
+ m.a = 0
83
+ }
84
+ if (Math.abs(m.b) < NEAR_ZERO) {
85
+ m.b = 0
86
+ }
87
+ if (Math.abs(m.c) < NEAR_ZERO) {
88
+ m.c = 0
89
+ }
90
+ if (Math.abs(m.d) < NEAR_ZERO) {
91
+ m.d = 0
92
+ }
93
+ if (Math.abs(m.e) < NEAR_ZERO) {
94
+ m.e = 0
95
+ }
96
+ if (Math.abs(m.f) < NEAR_ZERO) {
97
+ m.f = 0
98
+ }
72
99
 
73
100
  return m
74
101
  }
@@ -78,29 +105,33 @@ export const matrixMultiply = function (...args) {
78
105
  * @function module:math.hasMatrixTransform
79
106
  * @param {SVGTransformList} [tlist] - The transformlist to check
80
107
  * @returns {boolean} Whether or not a matrix transform was found
81
- */
108
+ */
82
109
  export const hasMatrixTransform = function (tlist) {
83
- if (!tlist) { return false }
110
+ if (!tlist) {
111
+ return false
112
+ }
84
113
  let num = tlist.numberOfItems
85
114
  while (num--) {
86
115
  const xform = tlist.getItem(num)
87
- if (xform.type === 1 && !isIdentity(xform.matrix)) { return true }
116
+ if (xform.type === 1 && !isIdentity(xform.matrix)) {
117
+ return true
118
+ }
88
119
  }
89
120
  return false
90
121
  }
91
122
 
92
123
  /**
93
- * @typedef {PlainObject} module:math.TransformedBox An object with the following values
94
- * @property {module:math.XYObject} tl - The top left coordinate
95
- * @property {module:math.XYObject} tr - The top right coordinate
96
- * @property {module:math.XYObject} bl - The bottom left coordinate
97
- * @property {module:math.XYObject} br - The bottom right coordinate
98
- * @property {PlainObject} aabox - Object with the following values:
99
- * @property {Float} aabox.x - Float with the axis-aligned x coordinate
100
- * @property {Float} aabox.y - Float with the axis-aligned y coordinate
101
- * @property {Float} aabox.width - Float with the axis-aligned width coordinate
102
- * @property {Float} aabox.height - Float with the axis-aligned height coordinate
103
- */
124
+ * @typedef {PlainObject} module:math.TransformedBox An object with the following values
125
+ * @property {module:math.XYObject} tl - The top left coordinate
126
+ * @property {module:math.XYObject} tr - The top right coordinate
127
+ * @property {module:math.XYObject} bl - The bottom left coordinate
128
+ * @property {module:math.XYObject} br - The bottom right coordinate
129
+ * @property {PlainObject} aabox - Object with the following values:
130
+ * @property {Float} aabox.x - Float with the axis-aligned x coordinate
131
+ * @property {Float} aabox.y - Float with the axis-aligned y coordinate
132
+ * @property {Float} aabox.width - Float with the axis-aligned width coordinate
133
+ * @property {Float} aabox.height - Float with the axis-aligned height coordinate
134
+ */
104
135
 
105
136
  /**
106
137
  * Transforms a rectangle based on the given matrix.
@@ -111,12 +142,12 @@ export const hasMatrixTransform = function (tlist) {
111
142
  * @param {Float} h - Float with the box height
112
143
  * @param {SVGMatrix} m - Matrix object to transform the box by
113
144
  * @returns {module:math.TransformedBox}
114
- */
145
+ */
115
146
  export const transformBox = function (l, t, w, h, m) {
116
147
  const tl = transformPoint(l, t, m)
117
- const tr = transformPoint((l + w), t, m)
118
- const bl = transformPoint(l, (t + h), m)
119
- const br = transformPoint((l + w), (t + h), m)
148
+ const tr = transformPoint(l + w, t, m)
149
+ const bl = transformPoint(l, t + h, m)
150
+ const br = transformPoint(l + w, t + h, m)
120
151
 
121
152
  const minx = Math.min(tl.x, tr.x, bl.x, br.x)
122
153
  const maxx = Math.max(tl.x, tr.x, bl.x, br.x)
@@ -131,8 +162,8 @@ export const transformBox = function (l, t, w, h, m) {
131
162
  aabox: {
132
163
  x: minx,
133
164
  y: miny,
134
- width: (maxx - minx),
135
- height: (maxy - miny)
165
+ width: maxx - minx,
166
+ height: maxy - miny
136
167
  }
137
168
  }
138
169
  }
@@ -148,23 +179,28 @@ export const transformBox = function (l, t, w, h, m) {
148
179
  * @param {Integer} [max] - Optional integer indicating end transform position;
149
180
  * defaults to one less than the tlist's `numberOfItems`
150
181
  * @returns {SVGTransform} A single matrix transform object
151
- */
182
+ */
152
183
  export const transformListToTransform = function (tlist, min, max) {
153
184
  if (!tlist) {
154
185
  // Or should tlist = null have been prevented before this?
155
186
  return svg.createSVGTransformFromMatrix(svg.createSVGMatrix())
156
187
  }
157
188
  min = min || 0
158
- max = max || (tlist.numberOfItems - 1)
189
+ max = max || tlist.numberOfItems - 1
159
190
  min = Number.parseInt(min)
160
191
  max = Number.parseInt(max)
161
- if (min > max) { const temp = max; max = min; min = temp }
192
+ if (min > max) {
193
+ const temp = max
194
+ max = min
195
+ min = temp
196
+ }
162
197
  let m = svg.createSVGMatrix()
163
198
  for (let i = min; i <= max; ++i) {
164
199
  // if our indices are out of range, just use a harmless identity matrix
165
- const mtom = (i >= 0 && i < tlist.numberOfItems
166
- ? tlist.getItem(i).matrix
167
- : svg.createSVGMatrix())
200
+ const mtom =
201
+ i >= 0 && i < tlist.numberOfItems
202
+ ? tlist.getItem(i).matrix
203
+ : svg.createSVGMatrix()
168
204
  m = matrixMultiply(m, mtom)
169
205
  }
170
206
  return svg.createSVGTransformFromMatrix(m)
@@ -175,9 +211,9 @@ export const transformListToTransform = function (tlist, min, max) {
175
211
  * @function module:math.getMatrix
176
212
  * @param {Element} elem - The DOM element to check
177
213
  * @returns {SVGMatrix} The matrix object associated with the element's transformlist
178
- */
214
+ */
179
215
  export const getMatrix = (elem) => {
180
- const tlist = elem.transform.baseVal
216
+ const tlist = getTransformList(elem)
181
217
  return transformListToTransform(tlist).matrix
182
218
  }
183
219
 
@@ -190,7 +226,7 @@ export const getMatrix = (elem) => {
190
226
  * @param {Integer} x2 - Second coordinate's x value
191
227
  * @param {Integer} y2 - Second coordinate's y value
192
228
  * @returns {module:math.AngleCoord45}
193
- */
229
+ */
194
230
  export const snapToAngle = (x1, y1, x2, y2) => {
195
231
  const snap = Math.PI / 4 // 45 degrees
196
232
  const dx = x2 - x1
@@ -214,8 +250,10 @@ export const snapToAngle = (x1, y1, x2, y2) => {
214
250
  * @returns {boolean} True if rectangles intersect
215
251
  */
216
252
  export const rectsIntersect = (r1, r2) => {
217
- return r2.x < (r1.x + r1.width) &&
218
- (r2.x + r2.width) > r1.x &&
219
- r2.y < (r1.y + r1.height) &&
220
- (r2.y + r2.height) > r1.y
253
+ return (
254
+ r2.x < r1.x + r1.width &&
255
+ r2.x + r2.width > r1.x &&
256
+ r2.y < r1.y + r1.height &&
257
+ r2.y + r2.height > r1.y
258
+ )
221
259
  }
@@ -11,7 +11,7 @@ import { shortFloat } from './units.js'
11
11
  import { ChangeElementCommand, BatchCommand } from './history.js'
12
12
  import {
13
13
  transformPoint, snapToAngle, rectsIntersect,
14
- transformListToTransform
14
+ transformListToTransform, getTransformList
15
15
  } from './math.js'
16
16
  import {
17
17
  assignAttributes, getElement, getRotationAngle, snapToGrid,
@@ -876,7 +876,7 @@ export const pathActionsMethod = (function () {
876
876
  */
877
877
  resetOrientation (pth) {
878
878
  if (pth?.nodeName !== 'path') { return false }
879
- const tlist = pth.transform.baseVal
879
+ const tlist = getTransformList(pth)
880
880
  const m = transformListToTransform(tlist).matrix
881
881
  tlist.clear()
882
882
  pth.removeAttribute('transform')
package/core/path.js CHANGED
@@ -7,7 +7,7 @@
7
7
  */
8
8
 
9
9
  import { shortFloat } from './units.js'
10
- import { transformPoint } from './math.js'
10
+ import { transformPoint, getTransformList } from './math.js'
11
11
  import {
12
12
  getRotationAngle, getBBox,
13
13
  getRefElem, findDefs,
@@ -511,7 +511,7 @@ export const recalcRotatedPath = () => {
511
511
 
512
512
  // now we must set the new transform to be rotated around the new center
513
513
  const Rnc = svgCanvas.getSvgRoot().createSVGTransform()
514
- const tlist = currentPath.transform.baseVal
514
+ const tlist = getTransformList(currentPath)
515
515
  Rnc.setRotate((angle * 180.0 / Math.PI), newcx, newcy)
516
516
  tlist.replaceItem(Rnc, 0)
517
517
  }