@svgedit/svgcanvas 7.2.7 → 7.4.1
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/common/browser.js +104 -37
- package/common/logger.js +151 -0
- package/common/util.js +96 -155
- package/core/blur-event.js +106 -42
- package/core/clear.js +13 -3
- package/core/coords.js +214 -90
- package/core/copy-elem.js +27 -13
- package/core/dataStorage.js +84 -21
- package/core/draw.js +80 -40
- package/core/elem-get-set.js +161 -77
- package/core/event.js +143 -28
- package/core/history.js +50 -30
- package/core/historyrecording.js +4 -2
- package/core/json.js +54 -12
- package/core/layer.js +11 -17
- package/core/math.js +102 -23
- package/core/namespaces.js +5 -5
- package/core/paint.js +95 -24
- package/core/paste-elem.js +58 -19
- package/core/path-actions.js +812 -791
- package/core/path-method.js +236 -37
- package/core/path.js +45 -10
- package/core/recalculate.js +410 -15
- package/core/sanitize.js +46 -14
- package/core/select.js +44 -20
- package/core/selected-elem.js +146 -31
- package/core/selection.js +16 -6
- package/core/svg-exec.js +99 -27
- package/core/svgroot.js +1 -1
- package/core/text-actions.js +327 -306
- package/core/undo.js +20 -5
- package/core/units.js +8 -6
- package/core/utilities.js +282 -170
- package/dist/svgcanvas.js +31590 -53383
- package/dist/svgcanvas.js.map +1 -1
- package/package.json +55 -54
- package/publish.md +1 -6
- package/svgcanvas.d.ts +225 -0
- package/svgcanvas.js +9 -9
- package/vite.config.mjs +20 -0
- package/rollup.config.mjs +0 -38
package/core/path-method.js
CHANGED
|
@@ -16,6 +16,190 @@ import {
|
|
|
16
16
|
getElement
|
|
17
17
|
} from './utilities.js'
|
|
18
18
|
|
|
19
|
+
const TYPE_TO_CMD = {
|
|
20
|
+
1: 'Z',
|
|
21
|
+
2: 'M',
|
|
22
|
+
3: 'm',
|
|
23
|
+
4: 'L',
|
|
24
|
+
5: 'l',
|
|
25
|
+
6: 'C',
|
|
26
|
+
7: 'c',
|
|
27
|
+
8: 'Q',
|
|
28
|
+
9: 'q',
|
|
29
|
+
10: 'A',
|
|
30
|
+
11: 'a',
|
|
31
|
+
12: 'H',
|
|
32
|
+
13: 'h',
|
|
33
|
+
14: 'V',
|
|
34
|
+
15: 'v',
|
|
35
|
+
16: 'S',
|
|
36
|
+
17: 's',
|
|
37
|
+
18: 'T',
|
|
38
|
+
19: 't'
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const CMD_TO_TYPE = Object.fromEntries(
|
|
42
|
+
Object.entries(TYPE_TO_CMD).map(([k, v]) => [v, Number(k)])
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
class PathDataListShim {
|
|
46
|
+
constructor (elem) {
|
|
47
|
+
this.elem = elem
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
_getData () {
|
|
51
|
+
return this.elem.getPathData()
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
_setData (data) {
|
|
55
|
+
this.elem.setPathData(data)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
get numberOfItems () {
|
|
59
|
+
return this._getData().length
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
_entryToSeg (entry) {
|
|
63
|
+
const { type, values = [] } = entry
|
|
64
|
+
const cmd = CMD_TO_TYPE[type] || CMD_TO_TYPE[type?.toUpperCase?.()]
|
|
65
|
+
const seg = { pathSegType: cmd }
|
|
66
|
+
const U = String(type).toUpperCase()
|
|
67
|
+
switch (U) {
|
|
68
|
+
case 'H':
|
|
69
|
+
[seg.x] = values
|
|
70
|
+
break
|
|
71
|
+
case 'V':
|
|
72
|
+
[seg.y] = values
|
|
73
|
+
break
|
|
74
|
+
case 'M':
|
|
75
|
+
case 'L':
|
|
76
|
+
case 'T':
|
|
77
|
+
[seg.x, seg.y] = values
|
|
78
|
+
break
|
|
79
|
+
case 'S':
|
|
80
|
+
[seg.x2, seg.y2, seg.x, seg.y] = values
|
|
81
|
+
break
|
|
82
|
+
case 'C':
|
|
83
|
+
[seg.x1, seg.y1, seg.x2, seg.y2, seg.x, seg.y] = values
|
|
84
|
+
break
|
|
85
|
+
case 'Q':
|
|
86
|
+
[seg.x1, seg.y1, seg.x, seg.y] = values
|
|
87
|
+
break
|
|
88
|
+
case 'A':
|
|
89
|
+
[
|
|
90
|
+
seg.r1,
|
|
91
|
+
seg.r2,
|
|
92
|
+
seg.angle,
|
|
93
|
+
seg.largeArcFlag,
|
|
94
|
+
seg.sweepFlag,
|
|
95
|
+
seg.x,
|
|
96
|
+
seg.y
|
|
97
|
+
] = values
|
|
98
|
+
break
|
|
99
|
+
default:
|
|
100
|
+
break
|
|
101
|
+
}
|
|
102
|
+
return seg
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
_segToEntry (seg) {
|
|
106
|
+
const type = TYPE_TO_CMD[seg.pathSegType] || seg.type
|
|
107
|
+
if (!type) {
|
|
108
|
+
return { type: 'Z', values: [] }
|
|
109
|
+
}
|
|
110
|
+
const U = String(type).toUpperCase()
|
|
111
|
+
let values = []
|
|
112
|
+
switch (U) {
|
|
113
|
+
case 'H':
|
|
114
|
+
values = [seg.x]
|
|
115
|
+
break
|
|
116
|
+
case 'V':
|
|
117
|
+
values = [seg.y]
|
|
118
|
+
break
|
|
119
|
+
case 'M':
|
|
120
|
+
case 'L':
|
|
121
|
+
case 'T':
|
|
122
|
+
values = [seg.x, seg.y]
|
|
123
|
+
break
|
|
124
|
+
case 'S':
|
|
125
|
+
values = [seg.x2, seg.y2, seg.x, seg.y]
|
|
126
|
+
break
|
|
127
|
+
case 'C':
|
|
128
|
+
values = [seg.x1, seg.y1, seg.x2, seg.y2, seg.x, seg.y]
|
|
129
|
+
break
|
|
130
|
+
case 'Q':
|
|
131
|
+
values = [seg.x1, seg.y1, seg.x, seg.y]
|
|
132
|
+
break
|
|
133
|
+
case 'A':
|
|
134
|
+
values = [
|
|
135
|
+
seg.r1,
|
|
136
|
+
seg.r2,
|
|
137
|
+
seg.angle,
|
|
138
|
+
Number(seg.largeArcFlag),
|
|
139
|
+
Number(seg.sweepFlag),
|
|
140
|
+
seg.x,
|
|
141
|
+
seg.y
|
|
142
|
+
]
|
|
143
|
+
break
|
|
144
|
+
default:
|
|
145
|
+
values = []
|
|
146
|
+
}
|
|
147
|
+
return { type, values }
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
getItem (index) {
|
|
151
|
+
const entry = this._getData()[index]
|
|
152
|
+
return entry ? this._entryToSeg(entry) : null
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
replaceItem (seg, index) {
|
|
156
|
+
const data = this._getData()
|
|
157
|
+
data[index] = this._segToEntry(seg)
|
|
158
|
+
this._setData(data)
|
|
159
|
+
return seg
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
insertItemBefore (seg, index) {
|
|
163
|
+
const data = this._getData()
|
|
164
|
+
data.splice(index, 0, this._segToEntry(seg))
|
|
165
|
+
this._setData(data)
|
|
166
|
+
return seg
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
appendItem (seg) {
|
|
170
|
+
const data = this._getData()
|
|
171
|
+
data.push(this._segToEntry(seg))
|
|
172
|
+
this._setData(data)
|
|
173
|
+
return seg
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
removeItem (index) {
|
|
177
|
+
const data = this._getData()
|
|
178
|
+
data.splice(index, 1)
|
|
179
|
+
this._setData(data)
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
clear () {
|
|
183
|
+
this._setData([])
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (
|
|
188
|
+
typeof SVGPathElement !== 'undefined' &&
|
|
189
|
+
typeof SVGPathElement.prototype.getPathData === 'function' &&
|
|
190
|
+
typeof SVGPathElement.prototype.setPathData === 'function' &&
|
|
191
|
+
!('pathSegList' in SVGPathElement.prototype)
|
|
192
|
+
) {
|
|
193
|
+
Object.defineProperty(SVGPathElement.prototype, 'pathSegList', {
|
|
194
|
+
get () {
|
|
195
|
+
if (!this._pathSegListShim) {
|
|
196
|
+
this._pathSegListShim = new PathDataListShim(this)
|
|
197
|
+
}
|
|
198
|
+
return this._pathSegListShim
|
|
199
|
+
}
|
|
200
|
+
})
|
|
201
|
+
}
|
|
202
|
+
|
|
19
203
|
let svgCanvas = null
|
|
20
204
|
|
|
21
205
|
/**
|
|
@@ -36,7 +220,7 @@ export const init = (canvas) => {
|
|
|
36
220
|
* @returns {ArgumentsArray}
|
|
37
221
|
*/
|
|
38
222
|
/* eslint-enable max-len */
|
|
39
|
-
export const ptObjToArrMethod =
|
|
223
|
+
export const ptObjToArrMethod = (type, segItem) => {
|
|
40
224
|
const segData = svgCanvas.getSegData()
|
|
41
225
|
const props = segData[type]
|
|
42
226
|
return props.map((prop) => {
|
|
@@ -50,7 +234,7 @@ export const ptObjToArrMethod = function (type, segItem) {
|
|
|
50
234
|
* @param {module:math.XYObject} altPt
|
|
51
235
|
* @returns {module:math.XYObject}
|
|
52
236
|
*/
|
|
53
|
-
export const getGripPtMethod =
|
|
237
|
+
export const getGripPtMethod = (seg, altPt) => {
|
|
54
238
|
const { path: pth } = seg
|
|
55
239
|
let out = {
|
|
56
240
|
x: altPt ? altPt.x : seg.item.x,
|
|
@@ -73,7 +257,7 @@ export const getGripPtMethod = function (seg, altPt) {
|
|
|
73
257
|
* @param {module:path.Path} pth
|
|
74
258
|
* @returns {module:math.XYObject}
|
|
75
259
|
*/
|
|
76
|
-
export const getPointFromGripMethod =
|
|
260
|
+
export const getPointFromGripMethod = (pt, pth) => {
|
|
77
261
|
const out = {
|
|
78
262
|
x: pt.x,
|
|
79
263
|
y: pt.y
|
|
@@ -94,7 +278,7 @@ export const getPointFromGripMethod = function (pt, pth) {
|
|
|
94
278
|
* @function module:path.getGripContainer
|
|
95
279
|
* @returns {Element}
|
|
96
280
|
*/
|
|
97
|
-
export const getGripContainerMethod =
|
|
281
|
+
export const getGripContainerMethod = () => {
|
|
98
282
|
let c = getElement('pathpointgrip_container')
|
|
99
283
|
if (!c) {
|
|
100
284
|
const parentElement = getElement('selectorParentGroup')
|
|
@@ -113,16 +297,16 @@ export const getGripContainerMethod = function () {
|
|
|
113
297
|
* @param {Integer} y
|
|
114
298
|
* @returns {SVGCircleElement}
|
|
115
299
|
*/
|
|
116
|
-
export const addPointGripMethod =
|
|
300
|
+
export const addPointGripMethod = (index, x, y) => {
|
|
117
301
|
// create the container of all the point grips
|
|
118
302
|
const pointGripContainer = getGripContainerMethod()
|
|
119
303
|
|
|
120
|
-
let pointGrip = getElement(
|
|
304
|
+
let pointGrip = getElement(`pathpointgrip_${index}`)
|
|
121
305
|
// create it
|
|
122
306
|
if (!pointGrip) {
|
|
123
307
|
pointGrip = document.createElementNS(NS.SVG, 'circle')
|
|
124
308
|
const atts = {
|
|
125
|
-
id:
|
|
309
|
+
id: `pathpointgrip_${index}`,
|
|
126
310
|
display: 'none',
|
|
127
311
|
r: 4,
|
|
128
312
|
fill: '#0FF',
|
|
@@ -163,7 +347,7 @@ export const addPointGripMethod = function (index, x, y) {
|
|
|
163
347
|
* @param {string} id
|
|
164
348
|
* @returns {SVGCircleElement}
|
|
165
349
|
*/
|
|
166
|
-
export const addCtrlGripMethod =
|
|
350
|
+
export const addCtrlGripMethod = (id) => {
|
|
167
351
|
let pointGrip = getElement('ctrlpointgrip_' + id)
|
|
168
352
|
if (pointGrip) { return pointGrip }
|
|
169
353
|
|
|
@@ -191,7 +375,7 @@ export const addCtrlGripMethod = function (id) {
|
|
|
191
375
|
* @param {string} id
|
|
192
376
|
* @returns {SVGLineElement}
|
|
193
377
|
*/
|
|
194
|
-
export const getCtrlLineMethod =
|
|
378
|
+
export const getCtrlLineMethod = (id) => {
|
|
195
379
|
let ctrlLine = getElement('ctrlLine_' + id)
|
|
196
380
|
if (ctrlLine) { return ctrlLine }
|
|
197
381
|
|
|
@@ -211,7 +395,7 @@ export const getCtrlLineMethod = function (id) {
|
|
|
211
395
|
* @param {boolean} update
|
|
212
396
|
* @returns {SVGCircleElement}
|
|
213
397
|
*/
|
|
214
|
-
export const getPointGripMethod =
|
|
398
|
+
export const getPointGripMethod = (seg, update) => {
|
|
215
399
|
const { index } = seg
|
|
216
400
|
const pointGrip = addPointGripMethod(index)
|
|
217
401
|
|
|
@@ -231,7 +415,7 @@ export const getPointGripMethod = function (seg, update) {
|
|
|
231
415
|
* @param {Segment} seg
|
|
232
416
|
* @returns {PlainObject<string, SVGLineElement|SVGCircleElement>}
|
|
233
417
|
*/
|
|
234
|
-
export const getControlPointsMethod =
|
|
418
|
+
export const getControlPointsMethod = (seg) => {
|
|
235
419
|
const { item, index } = seg
|
|
236
420
|
if (!('x1' in item) || !('x2' in item)) { return null }
|
|
237
421
|
const cpt = {}
|
|
@@ -246,7 +430,7 @@ export const getControlPointsMethod = function (seg) {
|
|
|
246
430
|
for (let i = 1; i < 3; i++) {
|
|
247
431
|
const id = index + 'c' + i
|
|
248
432
|
|
|
249
|
-
const ctrlLine = cpt[
|
|
433
|
+
const ctrlLine = cpt[`c${i}_line`] = getCtrlLineMethod(id)
|
|
250
434
|
|
|
251
435
|
const pt = getGripPtMethod(seg, { x: item['x' + i], y: item['y' + i] })
|
|
252
436
|
const gpt = getGripPtMethod(seg, { x: segItems[i - 1].x, y: segItems[i - 1].y })
|
|
@@ -259,10 +443,10 @@ export const getControlPointsMethod = function (seg) {
|
|
|
259
443
|
display: 'inline'
|
|
260
444
|
})
|
|
261
445
|
|
|
262
|
-
cpt[
|
|
446
|
+
cpt[`c${i}_line`] = ctrlLine
|
|
263
447
|
|
|
264
448
|
// create it
|
|
265
|
-
const pointGrip = cpt[
|
|
449
|
+
const pointGrip = cpt[`c${i}`] = addCtrlGripMethod(id)
|
|
266
450
|
|
|
267
451
|
assignAttributes(pointGrip, {
|
|
268
452
|
cx: pt.x,
|
|
@@ -282,12 +466,29 @@ export const getControlPointsMethod = function (seg) {
|
|
|
282
466
|
* @param {SVGPathElement} elem
|
|
283
467
|
* @returns {void}
|
|
284
468
|
*/
|
|
285
|
-
export const replacePathSegMethod =
|
|
469
|
+
export const replacePathSegMethod = (type, index, pts, elem) => {
|
|
286
470
|
const path = svgCanvas.getPathObj()
|
|
287
471
|
const pth = elem || path.elem
|
|
288
472
|
const pathFuncs = svgCanvas.getPathFuncs()
|
|
289
473
|
const func = 'createSVGPathSeg' + pathFuncs[type]
|
|
290
|
-
const
|
|
474
|
+
const segData = svgCanvas.getSegData?.()
|
|
475
|
+
const props = segData?.[type] || segData?.[type - 1]
|
|
476
|
+
if (props && pts.length < props.length) {
|
|
477
|
+
const currentSeg = pth.pathSegList?.getItem?.(index)
|
|
478
|
+
if (currentSeg) {
|
|
479
|
+
pts = props.map((prop, i) => (pts[i] !== undefined ? pts[i] : currentSeg[prop]))
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
let seg
|
|
483
|
+
if (typeof pth[func] === 'function') {
|
|
484
|
+
seg = pth[func](...pts)
|
|
485
|
+
} else {
|
|
486
|
+
const safeProps = props || []
|
|
487
|
+
seg = { pathSegType: type }
|
|
488
|
+
safeProps.forEach((prop, i) => {
|
|
489
|
+
seg[prop] = pts[i]
|
|
490
|
+
})
|
|
491
|
+
}
|
|
291
492
|
|
|
292
493
|
pth.pathSegList.replaceItem(seg, index)
|
|
293
494
|
}
|
|
@@ -297,15 +498,15 @@ export const replacePathSegMethod = function (type, index, pts, elem) {
|
|
|
297
498
|
* @param {boolean} update
|
|
298
499
|
* @returns {SVGPathElement}
|
|
299
500
|
*/
|
|
300
|
-
export const getSegSelectorMethod =
|
|
501
|
+
export const getSegSelectorMethod = (seg, update) => {
|
|
301
502
|
const { index } = seg
|
|
302
|
-
let segLine = getElement(
|
|
503
|
+
let segLine = getElement(`segline_${index}`)
|
|
303
504
|
if (!segLine) {
|
|
304
505
|
const pointGripContainer = getGripContainerMethod()
|
|
305
506
|
// create segline
|
|
306
507
|
segLine = document.createElementNS(NS.SVG, 'path')
|
|
307
508
|
assignAttributes(segLine, {
|
|
308
|
-
id:
|
|
509
|
+
id: `segline_${index}`,
|
|
309
510
|
display: 'none',
|
|
310
511
|
fill: 'none',
|
|
311
512
|
stroke: '#0FF',
|
|
@@ -353,7 +554,7 @@ export class Segment {
|
|
|
353
554
|
this.item = item
|
|
354
555
|
this.type = item.pathSegType
|
|
355
556
|
|
|
356
|
-
this.ctrlpts =
|
|
557
|
+
this.ctrlpts = null
|
|
357
558
|
this.ptgrip = null
|
|
358
559
|
this.segsel = null
|
|
359
560
|
}
|
|
@@ -375,8 +576,8 @@ export class Segment {
|
|
|
375
576
|
* @returns {void}
|
|
376
577
|
*/
|
|
377
578
|
selectCtrls (y) {
|
|
378
|
-
document.getElementById(
|
|
379
|
-
document.getElementById(
|
|
579
|
+
document.getElementById(`ctrlpointgrip_${this.index}c1`)?.setAttribute('fill', y ? '#0FF' : '#EEE')
|
|
580
|
+
document.getElementById(`ctrlpointgrip_${this.index}c2`)?.setAttribute('fill', y ? '#0FF' : '#EEE')
|
|
380
581
|
}
|
|
381
582
|
|
|
382
583
|
/**
|
|
@@ -450,27 +651,25 @@ export class Segment {
|
|
|
450
651
|
move (dx, dy) {
|
|
451
652
|
const { item } = this
|
|
452
653
|
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
654
|
+
item.x += dx
|
|
655
|
+
item.y += dy
|
|
656
|
+
|
|
657
|
+
// `x2/y2` are the control point attached to this node (when present)
|
|
658
|
+
if ('x2' in item) { item.x2 += dx }
|
|
659
|
+
if ('y2' in item) { item.y2 += dy }
|
|
459
660
|
|
|
460
661
|
replacePathSegMethod(
|
|
461
662
|
this.type,
|
|
462
663
|
this.index,
|
|
463
|
-
|
|
464
|
-
this.type === 10 ? ptObjToArrMethod(this.type, item) : curPts
|
|
664
|
+
ptObjToArrMethod(this.type, item)
|
|
465
665
|
)
|
|
466
666
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
replacePathSegMethod(this.next.type, this.next.index, nextPts)
|
|
667
|
+
const next = this.next?.item
|
|
668
|
+
// `x1/y1` are the control point attached to this node on the next segment (when present)
|
|
669
|
+
if (next && 'x1' in next && 'y1' in next) {
|
|
670
|
+
next.x1 += dx
|
|
671
|
+
next.y1 += dy
|
|
672
|
+
replacePathSegMethod(this.next.type, this.next.index, ptObjToArrMethod(this.next.type, next))
|
|
474
673
|
}
|
|
475
674
|
|
|
476
675
|
if (this.mate) {
|
package/core/path.js
CHANGED
|
@@ -236,6 +236,7 @@ export const init = (canvas) => {
|
|
|
236
236
|
svgCanvas.getPointFromGrip = getPointFromGripMethod
|
|
237
237
|
svgCanvas.setLinkControlPoints = setLinkControlPoints
|
|
238
238
|
svgCanvas.reorientGrads = reorientGrads
|
|
239
|
+
svgCanvas.recalcRotatedPath = recalcRotatedPath
|
|
239
240
|
svgCanvas.getSegData = () => { return segData }
|
|
240
241
|
svgCanvas.getUIStrings = () => { return uiStrings }
|
|
241
242
|
svgCanvas.getPathObj = () => { return path }
|
|
@@ -466,14 +467,17 @@ const getRotVals = (x, y) => {
|
|
|
466
467
|
* @returns {void}
|
|
467
468
|
*/
|
|
468
469
|
export const recalcRotatedPath = () => {
|
|
469
|
-
const currentPath = path
|
|
470
|
+
const currentPath = path?.elem
|
|
471
|
+
if (!currentPath) { return }
|
|
470
472
|
angle = getRotationAngle(currentPath, true)
|
|
471
473
|
if (!angle) { return }
|
|
472
474
|
// selectedBBoxes[0] = path.oldbbox;
|
|
473
475
|
const oldbox = path.oldbbox // selectedBBoxes[0],
|
|
476
|
+
if (!oldbox) { return }
|
|
474
477
|
oldcx = oldbox.x + oldbox.width / 2
|
|
475
478
|
oldcy = oldbox.y + oldbox.height / 2
|
|
476
479
|
const box = getBBox(currentPath)
|
|
480
|
+
if (!box) { return }
|
|
477
481
|
newcx = box.x + box.width / 2
|
|
478
482
|
newcy = box.y + box.height / 2
|
|
479
483
|
|
|
@@ -487,6 +491,7 @@ export const recalcRotatedPath = () => {
|
|
|
487
491
|
newcy = r * Math.sin(theta) + oldcy
|
|
488
492
|
|
|
489
493
|
const list = currentPath.pathSegList
|
|
494
|
+
if (!list) { return }
|
|
490
495
|
|
|
491
496
|
let i = list.numberOfItems
|
|
492
497
|
while (i) {
|
|
@@ -495,13 +500,33 @@ export const recalcRotatedPath = () => {
|
|
|
495
500
|
const type = seg.pathSegType
|
|
496
501
|
if (type === 1) { continue }
|
|
497
502
|
|
|
498
|
-
const
|
|
499
|
-
|
|
500
|
-
|
|
503
|
+
const props = segData[type]
|
|
504
|
+
if (!props) { continue }
|
|
505
|
+
|
|
506
|
+
const newVals = {}
|
|
507
|
+
if (seg.x !== null && seg.x !== undefined && seg.y !== null && seg.y !== undefined) {
|
|
508
|
+
const rvals = getRotVals(seg.x, seg.y)
|
|
509
|
+
newVals.x = rvals.x
|
|
510
|
+
newVals.y = rvals.y
|
|
511
|
+
}
|
|
512
|
+
if (seg.x1 !== null && seg.x1 !== undefined && seg.y1 !== null && seg.y1 !== undefined) {
|
|
501
513
|
const cVals1 = getRotVals(seg.x1, seg.y1)
|
|
514
|
+
newVals.x1 = cVals1.x
|
|
515
|
+
newVals.y1 = cVals1.y
|
|
516
|
+
}
|
|
517
|
+
if (seg.x2 !== null && seg.x2 !== undefined && seg.y2 !== null && seg.y2 !== undefined) {
|
|
502
518
|
const cVals2 = getRotVals(seg.x2, seg.y2)
|
|
503
|
-
|
|
519
|
+
newVals.x2 = cVals2.x
|
|
520
|
+
newVals.y2 = cVals2.y
|
|
504
521
|
}
|
|
522
|
+
|
|
523
|
+
const points = props.map((prop) => {
|
|
524
|
+
if (Object.prototype.hasOwnProperty.call(newVals, prop)) {
|
|
525
|
+
return newVals[prop]
|
|
526
|
+
}
|
|
527
|
+
const val = seg[prop]
|
|
528
|
+
return val === null || val === undefined ? 0 : val
|
|
529
|
+
})
|
|
505
530
|
replacePathSeg(type, i, points)
|
|
506
531
|
} // loop for each point
|
|
507
532
|
|
|
@@ -512,8 +537,18 @@ export const recalcRotatedPath = () => {
|
|
|
512
537
|
// now we must set the new transform to be rotated around the new center
|
|
513
538
|
const Rnc = svgCanvas.getSvgRoot().createSVGTransform()
|
|
514
539
|
const tlist = getTransformList(currentPath)
|
|
540
|
+
if (!tlist) { return }
|
|
515
541
|
Rnc.setRotate((angle * 180.0 / Math.PI), newcx, newcy)
|
|
516
|
-
tlist.
|
|
542
|
+
if (tlist.numberOfItems) {
|
|
543
|
+
if (typeof tlist.replaceItem === 'function') {
|
|
544
|
+
tlist.replaceItem(Rnc, 0)
|
|
545
|
+
} else {
|
|
546
|
+
tlist.removeItem(0)
|
|
547
|
+
tlist.insertItemBefore(Rnc, 0)
|
|
548
|
+
}
|
|
549
|
+
} else {
|
|
550
|
+
tlist.appendItem(Rnc)
|
|
551
|
+
}
|
|
517
552
|
}
|
|
518
553
|
|
|
519
554
|
// ====================================
|
|
@@ -571,7 +606,7 @@ export const reorientGrads = (elem, m) => {
|
|
|
571
606
|
}
|
|
572
607
|
newgrad.id = svgCanvas.getNextId()
|
|
573
608
|
findDefs().append(newgrad)
|
|
574
|
-
elem.setAttribute(type,
|
|
609
|
+
elem.setAttribute(type, `url(#${newgrad.id})`)
|
|
575
610
|
}
|
|
576
611
|
}
|
|
577
612
|
}
|
|
@@ -618,7 +653,7 @@ export const convertPath = (pth, toRel) => {
|
|
|
618
653
|
switch (type) {
|
|
619
654
|
case 1: // z,Z closepath (Z/z)
|
|
620
655
|
d += 'z'
|
|
621
|
-
if (lastM
|
|
656
|
+
if (lastM) {
|
|
622
657
|
curx = lastM[0]
|
|
623
658
|
cury = lastM[1]
|
|
624
659
|
}
|
|
@@ -765,10 +800,10 @@ const pathDSegment = (letter, points, morePoints, lastPoint) => {
|
|
|
765
800
|
})
|
|
766
801
|
let segment = letter + points.join(' ')
|
|
767
802
|
if (morePoints) {
|
|
768
|
-
segment +=
|
|
803
|
+
segment += ` ${morePoints.join(' ')}`
|
|
769
804
|
}
|
|
770
805
|
if (lastPoint) {
|
|
771
|
-
segment +=
|
|
806
|
+
segment += ` ${shortFloat(lastPoint)}`
|
|
772
807
|
}
|
|
773
808
|
return segment
|
|
774
809
|
}
|