@svgedit/svgcanvas 7.2.6 → 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/CHANGES.md +6 -0
- 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 +51 -31
- 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 +100 -23
- 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 +438 -24
- package/core/sanitize.js +71 -34
- package/core/select.js +44 -20
- package/core/selected-elem.js +146 -31
- package/core/selection.js +16 -6
- package/core/svg-exec.js +103 -29
- 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 +316 -203
- package/dist/svgcanvas.js +31616 -53281
- 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/elem-get-set.js
CHANGED
|
@@ -122,25 +122,36 @@ const setGroupTitleMethod = (val) => {
|
|
|
122
122
|
const selectedElements = svgCanvas.getSelectedElements()
|
|
123
123
|
const dataStorage = svgCanvas.getDataStorage()
|
|
124
124
|
let elem = selectedElements[0]
|
|
125
|
+
if (!elem) { return }
|
|
125
126
|
if (dataStorage.has(elem, 'gsvg')) {
|
|
126
127
|
elem = dataStorage.get(elem, 'gsvg')
|
|
128
|
+
} else if (dataStorage.has(elem, 'symbol')) {
|
|
129
|
+
elem = dataStorage.get(elem, 'symbol')
|
|
127
130
|
}
|
|
128
|
-
|
|
129
|
-
const ts = elem.querySelectorAll('title')
|
|
131
|
+
if (!elem) { return }
|
|
130
132
|
|
|
131
133
|
const batchCmd = new BatchCommand('Set Label')
|
|
132
134
|
|
|
133
|
-
let title
|
|
135
|
+
let title = null
|
|
136
|
+
for (const child of elem.childNodes) {
|
|
137
|
+
if (child.nodeName === 'title') {
|
|
138
|
+
title = child
|
|
139
|
+
break
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
134
143
|
if (val.length === 0) {
|
|
144
|
+
if (!title) { return }
|
|
135
145
|
// Remove title element
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
} else if (
|
|
146
|
+
const { nextSibling } = title
|
|
147
|
+
title.remove()
|
|
148
|
+
batchCmd.addSubCommand(new RemoveElementCommand(title, nextSibling, elem))
|
|
149
|
+
} else if (title) {
|
|
140
150
|
// Change title contents
|
|
141
|
-
|
|
142
|
-
|
|
151
|
+
const oldText = title.textContent
|
|
152
|
+
if (oldText === val) { return }
|
|
143
153
|
title.textContent = val
|
|
154
|
+
batchCmd.addSubCommand(new ChangeElementCommand(title, { '#text': oldText }))
|
|
144
155
|
} else {
|
|
145
156
|
// Add title element
|
|
146
157
|
title = svgCanvas.getDOMDocument().createElementNS(NS.SVG, 'title')
|
|
@@ -149,7 +160,9 @@ const setGroupTitleMethod = (val) => {
|
|
|
149
160
|
batchCmd.addSubCommand(new InsertElementCommand(title))
|
|
150
161
|
}
|
|
151
162
|
|
|
152
|
-
|
|
163
|
+
if (!batchCmd.isEmpty()) {
|
|
164
|
+
svgCanvas.addCommandToHistory(batchCmd)
|
|
165
|
+
}
|
|
153
166
|
}
|
|
154
167
|
|
|
155
168
|
/**
|
|
@@ -160,33 +173,44 @@ const setGroupTitleMethod = (val) => {
|
|
|
160
173
|
* @returns {void}
|
|
161
174
|
*/
|
|
162
175
|
const setDocumentTitleMethod = (newTitle) => {
|
|
163
|
-
const {
|
|
164
|
-
|
|
165
|
-
|
|
176
|
+
const {
|
|
177
|
+
InsertElementCommand, RemoveElementCommand,
|
|
178
|
+
ChangeElementCommand, BatchCommand
|
|
179
|
+
} = svgCanvas.history
|
|
180
|
+
const svgContent = svgCanvas.getSvgContent()
|
|
166
181
|
|
|
167
182
|
const batchCmd = new BatchCommand('Change Image Title')
|
|
168
183
|
|
|
169
|
-
|
|
184
|
+
/** @type {Element|null} */
|
|
185
|
+
let docTitle = null
|
|
186
|
+
for (const child of svgContent.childNodes) {
|
|
170
187
|
if (child.nodeName === 'title') {
|
|
171
188
|
docTitle = child
|
|
172
|
-
oldTitle = docTitle.textContent
|
|
173
189
|
break
|
|
174
190
|
}
|
|
175
191
|
}
|
|
192
|
+
|
|
176
193
|
if (!docTitle) {
|
|
194
|
+
if (!newTitle.length) { return }
|
|
177
195
|
docTitle = svgCanvas.getDOMDocument().createElementNS(NS.SVG, 'title')
|
|
178
|
-
svgCanvas.getSvgContent().insertBefore(docTitle, svgCanvas.getSvgContent().firstChild)
|
|
179
|
-
// svgContent.firstChild.before(docTitle); // Ok to replace above with this?
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
if (newTitle.length) {
|
|
183
196
|
docTitle.textContent = newTitle
|
|
197
|
+
svgContent.insertBefore(docTitle, svgContent.firstChild)
|
|
198
|
+
batchCmd.addSubCommand(new InsertElementCommand(docTitle))
|
|
199
|
+
} else if (newTitle.length) {
|
|
200
|
+
const oldTitle = docTitle.textContent
|
|
201
|
+
if (oldTitle === newTitle) { return }
|
|
202
|
+
docTitle.textContent = newTitle
|
|
203
|
+
batchCmd.addSubCommand(new ChangeElementCommand(docTitle, { '#text': oldTitle }))
|
|
184
204
|
} else {
|
|
185
205
|
// No title given, so element is not necessary
|
|
206
|
+
const { nextSibling } = docTitle
|
|
186
207
|
docTitle.remove()
|
|
208
|
+
batchCmd.addSubCommand(new RemoveElementCommand(docTitle, nextSibling, svgContent))
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (!batchCmd.isEmpty()) {
|
|
212
|
+
svgCanvas.addCommandToHistory(batchCmd)
|
|
187
213
|
}
|
|
188
|
-
batchCmd.addSubCommand(new ChangeElementCommand(docTitle, { '#text': oldTitle }))
|
|
189
|
-
svgCanvas.addCommandToHistory(batchCmd)
|
|
190
214
|
}
|
|
191
215
|
|
|
192
216
|
/**
|
|
@@ -201,7 +225,6 @@ const setDocumentTitleMethod = (newTitle) => {
|
|
|
201
225
|
*/
|
|
202
226
|
const setResolutionMethod = (x, y) => {
|
|
203
227
|
const { ChangeElementCommand, BatchCommand } = svgCanvas.history
|
|
204
|
-
const zoom = svgCanvas.getZoom()
|
|
205
228
|
const res = svgCanvas.getResolution()
|
|
206
229
|
const { w, h } = res
|
|
207
230
|
let batchCmd
|
|
@@ -220,8 +243,10 @@ const setResolutionMethod = (x, y) => {
|
|
|
220
243
|
dy.push(bbox.y * -1)
|
|
221
244
|
})
|
|
222
245
|
|
|
223
|
-
const cmd = svgCanvas.moveSelectedElements(dx, dy,
|
|
224
|
-
|
|
246
|
+
const cmd = svgCanvas.moveSelectedElements(dx, dy, false)
|
|
247
|
+
if (cmd) {
|
|
248
|
+
batchCmd.addSubCommand(cmd)
|
|
249
|
+
}
|
|
225
250
|
svgCanvas.clearSelection()
|
|
226
251
|
|
|
227
252
|
x = Math.round(bbox.width)
|
|
@@ -230,26 +255,25 @@ const setResolutionMethod = (x, y) => {
|
|
|
230
255
|
return false
|
|
231
256
|
}
|
|
232
257
|
}
|
|
233
|
-
|
|
258
|
+
const newW = convertToNum('width', x)
|
|
259
|
+
const newH = convertToNum('height', y)
|
|
260
|
+
if (newW !== w || newH !== h) {
|
|
234
261
|
if (!batchCmd) {
|
|
235
262
|
batchCmd = new BatchCommand('Change Image Dimensions')
|
|
236
263
|
}
|
|
264
|
+
const svgContent = svgCanvas.getSvgContent()
|
|
265
|
+
const oldViewBox = svgContent.getAttribute('viewBox')
|
|
237
266
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
svgCanvas.getSvgContent().setAttribute('width', x)
|
|
242
|
-
svgCanvas.getSvgContent().setAttribute('height', y)
|
|
267
|
+
svgContent.setAttribute('width', newW)
|
|
268
|
+
svgContent.setAttribute('height', newH)
|
|
243
269
|
|
|
244
|
-
svgCanvas.contentW =
|
|
245
|
-
svgCanvas.contentH =
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
svgCanvas.getSvgContent().setAttribute('viewBox', [0, 0, x / zoom, y / zoom].join(' '))
|
|
249
|
-
batchCmd.addSubCommand(new ChangeElementCommand(svgCanvas.getSvgContent(), { viewBox: ['0 0', w, h].join(' ') }))
|
|
270
|
+
svgCanvas.contentW = newW
|
|
271
|
+
svgCanvas.contentH = newH
|
|
272
|
+
svgContent.setAttribute('viewBox', [0, 0, newW, newH].join(' '))
|
|
273
|
+
batchCmd.addSubCommand(new ChangeElementCommand(svgContent, { width: w, height: h, viewBox: oldViewBox }))
|
|
250
274
|
|
|
251
275
|
svgCanvas.addCommandToHistory(batchCmd)
|
|
252
|
-
svgCanvas.call('changed', [
|
|
276
|
+
svgCanvas.call('changed', [svgContent])
|
|
253
277
|
}
|
|
254
278
|
return true
|
|
255
279
|
}
|
|
@@ -286,20 +310,36 @@ const setBBoxZoomMethod = (val, editorW, editorH) => {
|
|
|
286
310
|
let spacer = 0.85
|
|
287
311
|
let bb
|
|
288
312
|
const calcZoom = (bb) => {
|
|
289
|
-
if (!bb) { return
|
|
313
|
+
if (!bb) { return undefined }
|
|
314
|
+
if (!Number.isFinite(editorW) || !Number.isFinite(editorH) || editorW <= 0 || editorH <= 0) {
|
|
315
|
+
return undefined
|
|
316
|
+
}
|
|
317
|
+
if (!Number.isFinite(bb.width) || !Number.isFinite(bb.height) || bb.width <= 0 || bb.height <= 0) {
|
|
318
|
+
return undefined
|
|
319
|
+
}
|
|
290
320
|
const wZoom = Math.round((editorW / bb.width) * 100 * spacer) / 100
|
|
291
321
|
const hZoom = Math.round((editorH / bb.height) * 100 * spacer) / 100
|
|
292
322
|
const zoom = Math.min(wZoom, hZoom)
|
|
323
|
+
if (!Number.isFinite(zoom) || zoom <= 0) {
|
|
324
|
+
return undefined
|
|
325
|
+
}
|
|
293
326
|
svgCanvas.setZoom(zoom)
|
|
294
327
|
return { zoom, bbox: bb }
|
|
295
328
|
}
|
|
296
329
|
|
|
297
|
-
if (typeof val === 'object') {
|
|
330
|
+
if (val && typeof val === 'object') {
|
|
298
331
|
bb = val
|
|
299
332
|
if (bb.width === 0 || bb.height === 0) {
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
333
|
+
let newzoom = zoom
|
|
334
|
+
if (Number.isFinite(bb.zoom) && bb.zoom > 0) {
|
|
335
|
+
newzoom = bb.zoom
|
|
336
|
+
} else if (Number.isFinite(bb.factor) && bb.factor > 0) {
|
|
337
|
+
newzoom = zoom * bb.factor
|
|
338
|
+
}
|
|
339
|
+
if (Number.isFinite(newzoom) && newzoom > 0) {
|
|
340
|
+
svgCanvas.setZoom(newzoom)
|
|
341
|
+
}
|
|
342
|
+
return { zoom: newzoom, bbox: bb }
|
|
303
343
|
}
|
|
304
344
|
return calcZoom(bb)
|
|
305
345
|
}
|
|
@@ -307,12 +347,7 @@ const setBBoxZoomMethod = (val, editorW, editorH) => {
|
|
|
307
347
|
switch (val) {
|
|
308
348
|
case 'selection': {
|
|
309
349
|
if (!selectedElements[0]) { return undefined }
|
|
310
|
-
const selectedElems = selectedElements.
|
|
311
|
-
if (n) {
|
|
312
|
-
return n
|
|
313
|
-
}
|
|
314
|
-
return undefined
|
|
315
|
-
})
|
|
350
|
+
const selectedElems = selectedElements.filter(Boolean)
|
|
316
351
|
bb = getStrokedBBoxDefaultVisible(selectedElems)
|
|
317
352
|
break
|
|
318
353
|
} case 'canvas': {
|
|
@@ -340,13 +375,22 @@ const setBBoxZoomMethod = (val, editorW, editorH) => {
|
|
|
340
375
|
* @returns {void}
|
|
341
376
|
*/
|
|
342
377
|
const setZoomMethod = (zoomLevel) => {
|
|
378
|
+
if (!Number.isFinite(zoomLevel) || zoomLevel <= 0) {
|
|
379
|
+
return
|
|
380
|
+
}
|
|
343
381
|
const selectedElements = svgCanvas.getSelectedElements()
|
|
344
382
|
const res = svgCanvas.getResolution()
|
|
345
|
-
|
|
383
|
+
const w = res.w / zoomLevel
|
|
384
|
+
const h = res.h / zoomLevel
|
|
385
|
+
if (!Number.isFinite(w) || !Number.isFinite(h) || w <= 0 || h <= 0) {
|
|
386
|
+
return
|
|
387
|
+
}
|
|
388
|
+
svgCanvas.getSvgContent().setAttribute('viewBox', `0 0 ${w} ${h}`)
|
|
346
389
|
svgCanvas.setZoom(zoomLevel)
|
|
347
390
|
selectedElements.forEach((elem) => {
|
|
348
391
|
if (!elem) { return }
|
|
349
|
-
svgCanvas.selectorManager.requestSelector(elem)
|
|
392
|
+
const selector = svgCanvas.selectorManager.requestSelector(elem)
|
|
393
|
+
selector && selector.resize()
|
|
350
394
|
})
|
|
351
395
|
svgCanvas.pathActions.zoomChange()
|
|
352
396
|
svgCanvas.runExtensions('zoomChanged', zoomLevel)
|
|
@@ -364,7 +408,7 @@ const setZoomMethod = (zoomLevel) => {
|
|
|
364
408
|
const setColorMethod = (type, val, preventUndo) => {
|
|
365
409
|
const selectedElements = svgCanvas.getSelectedElements()
|
|
366
410
|
svgCanvas.setCurShape(type, val)
|
|
367
|
-
svgCanvas.setCurProperties(type
|
|
411
|
+
svgCanvas.setCurProperties(`${type}_paint`, { type: 'solidColor' })
|
|
368
412
|
const elems = []
|
|
369
413
|
/**
|
|
370
414
|
*
|
|
@@ -408,10 +452,11 @@ const setColorMethod = (type, val, preventUndo) => {
|
|
|
408
452
|
* @returns {void}
|
|
409
453
|
*/
|
|
410
454
|
const setGradientMethod = (type) => {
|
|
411
|
-
if (!svgCanvas.getCurProperties(type
|
|
412
|
-
svgCanvas.getCurProperties(type
|
|
455
|
+
if (!svgCanvas.getCurProperties(`${type}_paint`) ||
|
|
456
|
+
svgCanvas.getCurProperties(`${type}_paint`).type === 'solidColor') { return }
|
|
413
457
|
const canvas = svgCanvas
|
|
414
458
|
let grad = canvas[type + 'Grad']
|
|
459
|
+
if (!grad) { return }
|
|
415
460
|
// find out if there is a duplicate gradient already in the defs
|
|
416
461
|
const duplicateGrad = findDuplicateGradient(grad)
|
|
417
462
|
const defs = findDefs()
|
|
@@ -425,7 +470,7 @@ const setGradientMethod = (type) => {
|
|
|
425
470
|
} else { // use existing gradient
|
|
426
471
|
grad = duplicateGrad
|
|
427
472
|
}
|
|
428
|
-
svgCanvas.setColor(type,
|
|
473
|
+
svgCanvas.setColor(type, `url(#${grad.id})`)
|
|
429
474
|
}
|
|
430
475
|
|
|
431
476
|
/**
|
|
@@ -435,12 +480,21 @@ const setGradientMethod = (type) => {
|
|
|
435
480
|
* @returns {SVGGradientElement} The existing gradient if found, `null` if not
|
|
436
481
|
*/
|
|
437
482
|
const findDuplicateGradient = (grad) => {
|
|
483
|
+
if (!grad) {
|
|
484
|
+
return null
|
|
485
|
+
}
|
|
486
|
+
if (!['linearGradient', 'radialGradient'].includes(grad.tagName)) {
|
|
487
|
+
return null
|
|
488
|
+
}
|
|
438
489
|
const defs = findDefs()
|
|
439
490
|
const existingGrads = defs.querySelectorAll('linearGradient, radialGradient')
|
|
440
491
|
let i = existingGrads.length
|
|
441
492
|
const radAttrs = ['r', 'cx', 'cy', 'fx', 'fy']
|
|
442
493
|
while (i--) {
|
|
443
494
|
const og = existingGrads[i]
|
|
495
|
+
if (og.tagName !== grad.tagName) {
|
|
496
|
+
continue
|
|
497
|
+
}
|
|
444
498
|
if (grad.tagName === 'linearGradient') {
|
|
445
499
|
if (grad.getAttribute('x1') !== og.getAttribute('x1') ||
|
|
446
500
|
grad.getAttribute('y1') !== og.getAttribute('y1') ||
|
|
@@ -514,10 +568,10 @@ const setPaintMethod = (type, paint) => {
|
|
|
514
568
|
svgCanvas.setPaintOpacity(type, p.alpha / 100, true)
|
|
515
569
|
|
|
516
570
|
// now set the current paint object
|
|
517
|
-
svgCanvas.setCurProperties(type
|
|
571
|
+
svgCanvas.setCurProperties(`${type}_paint`, p)
|
|
518
572
|
switch (p.type) {
|
|
519
573
|
case 'solidColor':
|
|
520
|
-
svgCanvas.setColor(type, p.solidColor !== 'none' ?
|
|
574
|
+
svgCanvas.setColor(type, p.solidColor !== 'none' ? `#${p.solidColor}` : 'none')
|
|
521
575
|
break
|
|
522
576
|
case 'linearGradient':
|
|
523
577
|
case 'radialGradient':
|
|
@@ -653,7 +707,7 @@ const addTextDecorationMethod = (value) => {
|
|
|
653
707
|
// Add the new text decoration value if it did not exist
|
|
654
708
|
if (!oldValue.includes(value)) {
|
|
655
709
|
batchCmd.addSubCommand(new ChangeElementCommand(elem, { 'text-decoration': oldValue }))
|
|
656
|
-
svgCanvas.changeSelectedAttributeNoUndo('text-decoration',
|
|
710
|
+
svgCanvas.changeSelectedAttributeNoUndo('text-decoration', `${oldValue} ${value}`.trim(), [elem])
|
|
657
711
|
}
|
|
658
712
|
})
|
|
659
713
|
if (!batchCmd.isEmpty()) {
|
|
@@ -892,32 +946,48 @@ const setImageURLMethod = (val) => {
|
|
|
892
946
|
const setsize = (!attrs.width || !attrs.height)
|
|
893
947
|
|
|
894
948
|
const curHref = getHref(elem)
|
|
949
|
+
const hrefChanged = curHref !== val
|
|
895
950
|
|
|
896
951
|
// Do nothing if no URL change or size change
|
|
897
|
-
if (
|
|
952
|
+
if (!hrefChanged && !setsize) {
|
|
898
953
|
return
|
|
899
954
|
}
|
|
900
955
|
|
|
901
956
|
const batchCmd = new BatchCommand('Change Image URL')
|
|
902
957
|
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
958
|
+
if (hrefChanged) {
|
|
959
|
+
setHref(elem, val)
|
|
960
|
+
batchCmd.addSubCommand(new ChangeElementCommand(elem, {
|
|
961
|
+
'#href': curHref
|
|
962
|
+
}))
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
let finalized = false
|
|
966
|
+
const finalize = () => {
|
|
967
|
+
if (finalized) { return }
|
|
968
|
+
finalized = true
|
|
969
|
+
if (batchCmd.isEmpty()) { return }
|
|
970
|
+
svgCanvas.addCommandToHistory(batchCmd)
|
|
971
|
+
svgCanvas.call('changed', [elem])
|
|
972
|
+
}
|
|
973
|
+
|
|
907
974
|
const img = new Image()
|
|
908
|
-
img.onload =
|
|
975
|
+
img.onload = () => {
|
|
909
976
|
const changes = {
|
|
910
977
|
width: elem.getAttribute('width'),
|
|
911
978
|
height: elem.getAttribute('height')
|
|
912
979
|
}
|
|
913
|
-
elem.setAttribute('width',
|
|
914
|
-
elem.setAttribute('height',
|
|
980
|
+
elem.setAttribute('width', img.width)
|
|
981
|
+
elem.setAttribute('height', img.height)
|
|
915
982
|
|
|
916
|
-
svgCanvas.selectorManager.requestSelector(elem)
|
|
983
|
+
const selector = svgCanvas.selectorManager.requestSelector(elem)
|
|
984
|
+
selector && selector.resize()
|
|
917
985
|
|
|
918
986
|
batchCmd.addSubCommand(new ChangeElementCommand(elem, changes))
|
|
919
|
-
|
|
920
|
-
|
|
987
|
+
finalize()
|
|
988
|
+
}
|
|
989
|
+
img.onerror = () => {
|
|
990
|
+
finalize()
|
|
921
991
|
}
|
|
922
992
|
img.src = val
|
|
923
993
|
}
|
|
@@ -969,15 +1039,27 @@ const setRectRadiusMethod = (val) => {
|
|
|
969
1039
|
const { ChangeElementCommand } = svgCanvas.history
|
|
970
1040
|
const selectedElements = svgCanvas.getSelectedElements()
|
|
971
1041
|
const selected = selectedElements[0]
|
|
972
|
-
if (selected?.tagName
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
svgCanvas.addCommandToHistory(new ChangeElementCommand(selected, { rx: r, ry: r }, 'Radius'))
|
|
978
|
-
svgCanvas.call('changed', [selected])
|
|
979
|
-
}
|
|
1042
|
+
if (selected?.tagName !== 'rect') { return }
|
|
1043
|
+
|
|
1044
|
+
const radius = Number(val)
|
|
1045
|
+
if (!Number.isFinite(radius) || radius < 0) {
|
|
1046
|
+
return
|
|
980
1047
|
}
|
|
1048
|
+
|
|
1049
|
+
const oldRx = selected.getAttribute('rx')
|
|
1050
|
+
const oldRy = selected.getAttribute('ry')
|
|
1051
|
+
const currentRx = Number(oldRx)
|
|
1052
|
+
const currentRy = Number(oldRy)
|
|
1053
|
+
const hasCurrentRx = oldRx !== null && Number.isFinite(currentRx)
|
|
1054
|
+
const hasCurrentRy = oldRy !== null && Number.isFinite(currentRy)
|
|
1055
|
+
const already = (radius === 0 && oldRx === null && oldRy === null) ||
|
|
1056
|
+
(hasCurrentRx && hasCurrentRy && currentRx === radius && currentRy === radius)
|
|
1057
|
+
if (already) { return }
|
|
1058
|
+
|
|
1059
|
+
selected.setAttribute('rx', radius)
|
|
1060
|
+
selected.setAttribute('ry', radius)
|
|
1061
|
+
svgCanvas.addCommandToHistory(new ChangeElementCommand(selected, { rx: oldRx, ry: oldRy }, 'Radius'))
|
|
1062
|
+
svgCanvas.call('changed', [selected])
|
|
981
1063
|
}
|
|
982
1064
|
|
|
983
1065
|
/**
|
|
@@ -1021,7 +1103,9 @@ const setSegTypeMethod = (newType) => {
|
|
|
1021
1103
|
*/
|
|
1022
1104
|
const setBackgroundMethod = (color, url) => {
|
|
1023
1105
|
const bg = getElement('canvasBackground')
|
|
1106
|
+
if (!bg) { return }
|
|
1024
1107
|
const border = bg.querySelector('rect')
|
|
1108
|
+
if (!border) { return }
|
|
1025
1109
|
let bgImg = getElement('background_image')
|
|
1026
1110
|
let bgPattern = getElement('background_pattern')
|
|
1027
1111
|
border.setAttribute('fill', color === 'chessboard' ? '#fff' : color)
|