@svgedit/svgcanvas 7.2.3 → 7.2.4
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 +4 -0
- package/core/coords.js +203 -99
- package/core/draw.js +129 -56
- package/core/event.js +1 -0
- package/core/math.js +138 -154
- package/core/recalculate.js +232 -613
- package/core/sanitize.js +3 -3
- package/core/selected-elem.js +1 -1
- package/core/selection.js +1 -1
- package/core/svg-exec.js +163 -140
- package/core/text-actions.js +160 -129
- package/dist/svgcanvas.js +20310 -19109
- package/dist/svgcanvas.js.map +1 -1
- package/package.json +1 -1
- package/svgcanvas.js +1 -1
package/core/text-actions.js
CHANGED
|
@@ -6,33 +6,31 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { NS } from './namespaces.js'
|
|
9
|
+
import { transformPoint, getMatrix } from './math.js'
|
|
9
10
|
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
assignAttributes, getElement, getBBox as utilsGetBBox
|
|
11
|
+
assignAttributes,
|
|
12
|
+
getElement,
|
|
13
|
+
getBBox as utilsGetBBox
|
|
14
14
|
} from './utilities.js'
|
|
15
|
-
import {
|
|
16
|
-
supportsGoodTextCharPos
|
|
17
|
-
} from '../common/browser.js'
|
|
15
|
+
import { supportsGoodTextCharPos } from '../common/browser.js'
|
|
18
16
|
|
|
19
17
|
let svgCanvas = null
|
|
20
18
|
|
|
21
19
|
/**
|
|
22
|
-
* @function module:text-actions.init
|
|
23
|
-
* @param {module:text-actions.svgCanvas} textActionsContext
|
|
24
|
-
* @returns {void}
|
|
25
|
-
*/
|
|
26
|
-
export const init =
|
|
20
|
+
* @function module:text-actions.init
|
|
21
|
+
* @param {module:text-actions.svgCanvas} textActionsContext
|
|
22
|
+
* @returns {void}
|
|
23
|
+
*/
|
|
24
|
+
export const init = canvas => {
|
|
27
25
|
svgCanvas = canvas
|
|
28
26
|
}
|
|
29
27
|
|
|
30
28
|
/**
|
|
31
|
-
* Group: Text edit functions
|
|
32
|
-
* Functions relating to editing text elements.
|
|
33
|
-
* @namespace {PlainObject} textActions
|
|
34
|
-
* @memberof module:svgcanvas.SvgCanvas#
|
|
35
|
-
*/
|
|
29
|
+
* Group: Text edit functions
|
|
30
|
+
* Functions relating to editing text elements.
|
|
31
|
+
* @namespace {PlainObject} textActions
|
|
32
|
+
* @memberof module:svgcanvas.SvgCanvas#
|
|
33
|
+
*/
|
|
36
34
|
export const textActionsMethod = (function () {
|
|
37
35
|
let curtext
|
|
38
36
|
let textinput
|
|
@@ -42,23 +40,26 @@ export const textActionsMethod = (function () {
|
|
|
42
40
|
let chardata = []
|
|
43
41
|
let textbb // , transbb;
|
|
44
42
|
let matrix
|
|
45
|
-
let lastX
|
|
43
|
+
let lastX
|
|
44
|
+
let lastY
|
|
46
45
|
let allowDbl
|
|
47
46
|
|
|
48
47
|
/**
|
|
49
|
-
*
|
|
50
|
-
* @param {Integer} index
|
|
51
|
-
* @returns {void}
|
|
52
|
-
*/
|
|
48
|
+
*
|
|
49
|
+
* @param {Integer} index
|
|
50
|
+
* @returns {void}
|
|
51
|
+
*/
|
|
53
52
|
function setCursor (index) {
|
|
54
|
-
const empty =
|
|
53
|
+
const empty = textinput.value === ''
|
|
55
54
|
textinput.focus()
|
|
56
55
|
|
|
57
56
|
if (!arguments.length) {
|
|
58
57
|
if (empty) {
|
|
59
58
|
index = 0
|
|
60
59
|
} else {
|
|
61
|
-
if (textinput.selectionEnd !== textinput.selectionStart) {
|
|
60
|
+
if (textinput.selectionEnd !== textinput.selectionStart) {
|
|
61
|
+
return
|
|
62
|
+
}
|
|
62
63
|
index = textinput.selectionEnd
|
|
63
64
|
}
|
|
64
65
|
}
|
|
@@ -80,13 +81,13 @@ export const textActionsMethod = (function () {
|
|
|
80
81
|
|
|
81
82
|
if (!blinker) {
|
|
82
83
|
blinker = setInterval(function () {
|
|
83
|
-
const show =
|
|
84
|
+
const show = cursor.getAttribute('display') === 'none'
|
|
84
85
|
cursor.setAttribute('display', show ? 'inline' : 'none')
|
|
85
86
|
}, 600)
|
|
86
87
|
}
|
|
87
88
|
|
|
88
89
|
const startPt = ptToScreen(charbb.x, textbb.y)
|
|
89
|
-
const endPt = ptToScreen(charbb.x,
|
|
90
|
+
const endPt = ptToScreen(charbb.x, textbb.y + textbb.height)
|
|
90
91
|
|
|
91
92
|
assignAttributes(cursor, {
|
|
92
93
|
x1: startPt.x,
|
|
@@ -97,16 +98,18 @@ export const textActionsMethod = (function () {
|
|
|
97
98
|
display: 'inline'
|
|
98
99
|
})
|
|
99
100
|
|
|
100
|
-
if (selblock) {
|
|
101
|
+
if (selblock) {
|
|
102
|
+
selblock.setAttribute('d', '')
|
|
103
|
+
}
|
|
101
104
|
}
|
|
102
105
|
|
|
103
106
|
/**
|
|
104
|
-
*
|
|
105
|
-
* @param {Integer} start
|
|
106
|
-
* @param {Integer} end
|
|
107
|
-
* @param {boolean} skipInput
|
|
108
|
-
* @returns {void}
|
|
109
|
-
*/
|
|
107
|
+
*
|
|
108
|
+
* @param {Integer} start
|
|
109
|
+
* @param {Integer} end
|
|
110
|
+
* @param {boolean} skipInput
|
|
111
|
+
* @returns {void}
|
|
112
|
+
*/
|
|
110
113
|
function setSelection (start, end, skipInput) {
|
|
111
114
|
if (start === end) {
|
|
112
115
|
setCursor(end)
|
|
@@ -137,12 +140,29 @@ export const textActionsMethod = (function () {
|
|
|
137
140
|
const tl = ptToScreen(startbb.x, textbb.y)
|
|
138
141
|
const tr = ptToScreen(startbb.x + (endbb.x - startbb.x), textbb.y)
|
|
139
142
|
const bl = ptToScreen(startbb.x, textbb.y + textbb.height)
|
|
140
|
-
const br = ptToScreen(
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
143
|
+
const br = ptToScreen(
|
|
144
|
+
startbb.x + (endbb.x - startbb.x),
|
|
145
|
+
textbb.y + textbb.height
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
const dstr =
|
|
149
|
+
'M' +
|
|
150
|
+
tl.x +
|
|
151
|
+
',' +
|
|
152
|
+
tl.y +
|
|
153
|
+
' L' +
|
|
154
|
+
tr.x +
|
|
155
|
+
',' +
|
|
156
|
+
tr.y +
|
|
157
|
+
' ' +
|
|
158
|
+
br.x +
|
|
159
|
+
',' +
|
|
160
|
+
br.y +
|
|
161
|
+
' ' +
|
|
162
|
+
bl.x +
|
|
163
|
+
',' +
|
|
164
|
+
bl.y +
|
|
165
|
+
'z'
|
|
146
166
|
|
|
147
167
|
assignAttributes(selblock, {
|
|
148
168
|
d: dstr,
|
|
@@ -151,11 +171,11 @@ export const textActionsMethod = (function () {
|
|
|
151
171
|
}
|
|
152
172
|
|
|
153
173
|
/**
|
|
154
|
-
*
|
|
155
|
-
* @param {Float} mouseX
|
|
156
|
-
* @param {Float} mouseY
|
|
157
|
-
* @returns {Integer}
|
|
158
|
-
*/
|
|
174
|
+
*
|
|
175
|
+
* @param {Float} mouseX
|
|
176
|
+
* @param {Float} mouseY
|
|
177
|
+
* @returns {Integer}
|
|
178
|
+
*/
|
|
159
179
|
function getIndexFromPoint (mouseX, mouseY) {
|
|
160
180
|
// Position cursor here
|
|
161
181
|
const pt = svgCanvas.getSvgRoot().createSVGPoint()
|
|
@@ -163,7 +183,9 @@ export const textActionsMethod = (function () {
|
|
|
163
183
|
pt.y = mouseY
|
|
164
184
|
|
|
165
185
|
// No content, so return 0
|
|
166
|
-
if (chardata.length === 1) {
|
|
186
|
+
if (chardata.length === 1) {
|
|
187
|
+
return 0
|
|
188
|
+
}
|
|
167
189
|
// Determine if cursor should be on left or right of character
|
|
168
190
|
let charpos = curtext.getCharNumAtPosition(pt)
|
|
169
191
|
if (charpos < 0) {
|
|
@@ -176,7 +198,7 @@ export const textActionsMethod = (function () {
|
|
|
176
198
|
charpos = chardata.length - 2
|
|
177
199
|
}
|
|
178
200
|
const charbb = chardata[charpos]
|
|
179
|
-
const mid = charbb.x +
|
|
201
|
+
const mid = charbb.x + charbb.width / 2
|
|
180
202
|
if (mouseX > mid) {
|
|
181
203
|
charpos++
|
|
182
204
|
}
|
|
@@ -184,22 +206,22 @@ export const textActionsMethod = (function () {
|
|
|
184
206
|
}
|
|
185
207
|
|
|
186
208
|
/**
|
|
187
|
-
*
|
|
188
|
-
* @param {Float} mouseX
|
|
189
|
-
* @param {Float} mouseY
|
|
190
|
-
* @returns {void}
|
|
191
|
-
*/
|
|
209
|
+
*
|
|
210
|
+
* @param {Float} mouseX
|
|
211
|
+
* @param {Float} mouseY
|
|
212
|
+
* @returns {void}
|
|
213
|
+
*/
|
|
192
214
|
function setCursorFromPoint (mouseX, mouseY) {
|
|
193
215
|
setCursor(getIndexFromPoint(mouseX, mouseY))
|
|
194
216
|
}
|
|
195
217
|
|
|
196
218
|
/**
|
|
197
|
-
*
|
|
198
|
-
* @param {Float} x
|
|
199
|
-
* @param {Float} y
|
|
200
|
-
* @param {boolean} apply
|
|
201
|
-
* @returns {void}
|
|
202
|
-
*/
|
|
219
|
+
*
|
|
220
|
+
* @param {Float} x
|
|
221
|
+
* @param {Float} y
|
|
222
|
+
* @param {boolean} apply
|
|
223
|
+
* @returns {void}
|
|
224
|
+
*/
|
|
203
225
|
function setEndSelectionFromPoint (x, y, apply) {
|
|
204
226
|
const i1 = textinput.selectionStart
|
|
205
227
|
const i2 = getIndexFromPoint(x, y)
|
|
@@ -210,11 +232,11 @@ export const textActionsMethod = (function () {
|
|
|
210
232
|
}
|
|
211
233
|
|
|
212
234
|
/**
|
|
213
|
-
*
|
|
214
|
-
* @param {Float} xIn
|
|
215
|
-
* @param {Float} yIn
|
|
216
|
-
* @returns {module:math.XYObject}
|
|
217
|
-
*/
|
|
235
|
+
*
|
|
236
|
+
* @param {Float} xIn
|
|
237
|
+
* @param {Float} yIn
|
|
238
|
+
* @returns {module:math.XYObject}
|
|
239
|
+
*/
|
|
218
240
|
function screenToPt (xIn, yIn) {
|
|
219
241
|
const out = {
|
|
220
242
|
x: xIn,
|
|
@@ -234,11 +256,11 @@ export const textActionsMethod = (function () {
|
|
|
234
256
|
}
|
|
235
257
|
|
|
236
258
|
/**
|
|
237
|
-
*
|
|
238
|
-
* @param {Float} xIn
|
|
239
|
-
* @param {Float} yIn
|
|
240
|
-
* @returns {module:math.XYObject}
|
|
241
|
-
*/
|
|
259
|
+
*
|
|
260
|
+
* @param {Float} xIn
|
|
261
|
+
* @param {Float} yIn
|
|
262
|
+
* @returns {module:math.XYObject}
|
|
263
|
+
*/
|
|
242
264
|
function ptToScreen (xIn, yIn) {
|
|
243
265
|
const out = {
|
|
244
266
|
x: xIn,
|
|
@@ -258,22 +280,24 @@ export const textActionsMethod = (function () {
|
|
|
258
280
|
}
|
|
259
281
|
|
|
260
282
|
/**
|
|
261
|
-
*
|
|
262
|
-
* @param {Event} evt
|
|
263
|
-
* @returns {void}
|
|
264
|
-
*/
|
|
283
|
+
*
|
|
284
|
+
* @param {Event} evt
|
|
285
|
+
* @returns {void}
|
|
286
|
+
*/
|
|
265
287
|
function selectAll (evt) {
|
|
266
288
|
setSelection(0, curtext.textContent.length)
|
|
267
289
|
evt.target.removeEventListener('click', selectAll)
|
|
268
290
|
}
|
|
269
291
|
|
|
270
292
|
/**
|
|
271
|
-
*
|
|
272
|
-
* @param {Event} evt
|
|
273
|
-
* @returns {void}
|
|
274
|
-
*/
|
|
293
|
+
*
|
|
294
|
+
* @param {Event} evt
|
|
295
|
+
* @returns {void}
|
|
296
|
+
*/
|
|
275
297
|
function selectWord (evt) {
|
|
276
|
-
if (!allowDbl || !curtext) {
|
|
298
|
+
if (!allowDbl || !curtext) {
|
|
299
|
+
return
|
|
300
|
+
}
|
|
277
301
|
const zoom = svgCanvas.getZoom()
|
|
278
302
|
const ept = transformPoint(evt.pageX, evt.pageY, svgCanvas.getrootSctm())
|
|
279
303
|
const mouseX = ept.x * zoom
|
|
@@ -297,30 +321,30 @@ export const textActionsMethod = (function () {
|
|
|
297
321
|
|
|
298
322
|
return /** @lends module:svgcanvas.SvgCanvas#textActions */ {
|
|
299
323
|
/**
|
|
300
|
-
* @param {Element} target
|
|
301
|
-
* @param {Float} x
|
|
302
|
-
* @param {Float} y
|
|
303
|
-
* @returns {void}
|
|
304
|
-
*/
|
|
324
|
+
* @param {Element} target
|
|
325
|
+
* @param {Float} x
|
|
326
|
+
* @param {Float} y
|
|
327
|
+
* @returns {void}
|
|
328
|
+
*/
|
|
305
329
|
select (target, x, y) {
|
|
306
330
|
curtext = target
|
|
307
331
|
svgCanvas.textActions.toEditMode(x, y)
|
|
308
332
|
},
|
|
309
333
|
/**
|
|
310
|
-
* @param {Element} elem
|
|
311
|
-
* @returns {void}
|
|
312
|
-
*/
|
|
334
|
+
* @param {Element} elem
|
|
335
|
+
* @returns {void}
|
|
336
|
+
*/
|
|
313
337
|
start (elem) {
|
|
314
338
|
curtext = elem
|
|
315
339
|
svgCanvas.textActions.toEditMode()
|
|
316
340
|
},
|
|
317
341
|
/**
|
|
318
|
-
* @param {external:MouseEvent} evt
|
|
319
|
-
* @param {Element} mouseTarget
|
|
320
|
-
* @param {Float} startX
|
|
321
|
-
* @param {Float} startY
|
|
322
|
-
* @returns {void}
|
|
323
|
-
*/
|
|
342
|
+
* @param {external:MouseEvent} evt
|
|
343
|
+
* @param {Element} mouseTarget
|
|
344
|
+
* @param {Float} startX
|
|
345
|
+
* @param {Float} startY
|
|
346
|
+
* @returns {void}
|
|
347
|
+
*/
|
|
324
348
|
mouseDown (evt, mouseTarget, startX, startY) {
|
|
325
349
|
const pt = screenToPt(startX, startY)
|
|
326
350
|
|
|
@@ -332,20 +356,20 @@ export const textActionsMethod = (function () {
|
|
|
332
356
|
// TODO: Find way to block native selection
|
|
333
357
|
},
|
|
334
358
|
/**
|
|
335
|
-
* @param {Float} mouseX
|
|
336
|
-
* @param {Float} mouseY
|
|
337
|
-
* @returns {void}
|
|
338
|
-
*/
|
|
359
|
+
* @param {Float} mouseX
|
|
360
|
+
* @param {Float} mouseY
|
|
361
|
+
* @returns {void}
|
|
362
|
+
*/
|
|
339
363
|
mouseMove (mouseX, mouseY) {
|
|
340
364
|
const pt = screenToPt(mouseX, mouseY)
|
|
341
365
|
setEndSelectionFromPoint(pt.x, pt.y)
|
|
342
366
|
},
|
|
343
367
|
/**
|
|
344
|
-
* @param {external:MouseEvent} evt
|
|
345
|
-
* @param {Float} mouseX
|
|
346
|
-
* @param {Float} mouseY
|
|
347
|
-
* @returns {void}
|
|
348
|
-
*/
|
|
368
|
+
* @param {external:MouseEvent} evt
|
|
369
|
+
* @param {Float} mouseX
|
|
370
|
+
* @param {Float} mouseY
|
|
371
|
+
* @returns {void}
|
|
372
|
+
*/
|
|
349
373
|
mouseUp (evt, mouseX, mouseY) {
|
|
350
374
|
const pt = screenToPt(mouseX, mouseY)
|
|
351
375
|
|
|
@@ -359,25 +383,25 @@ export const textActionsMethod = (function () {
|
|
|
359
383
|
|
|
360
384
|
if (
|
|
361
385
|
evt.target !== curtext &&
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
386
|
+
mouseX < lastX + 2 &&
|
|
387
|
+
mouseX > lastX - 2 &&
|
|
388
|
+
mouseY < lastY + 2 &&
|
|
389
|
+
mouseY > lastY - 2
|
|
366
390
|
) {
|
|
367
391
|
svgCanvas.textActions.toSelectMode(true)
|
|
368
392
|
}
|
|
369
393
|
},
|
|
370
394
|
/**
|
|
371
|
-
* @function
|
|
372
|
-
* @param {Integer} index
|
|
373
|
-
* @returns {void}
|
|
374
|
-
*/
|
|
395
|
+
* @function
|
|
396
|
+
* @param {Integer} index
|
|
397
|
+
* @returns {void}
|
|
398
|
+
*/
|
|
375
399
|
setCursor,
|
|
376
400
|
/**
|
|
377
|
-
* @param {Float} x
|
|
378
|
-
* @param {Float} y
|
|
379
|
-
* @returns {void}
|
|
380
|
-
*/
|
|
401
|
+
* @param {Float} x
|
|
402
|
+
* @param {Float} y
|
|
403
|
+
* @returns {void}
|
|
404
|
+
*/
|
|
381
405
|
toEditMode (x, y) {
|
|
382
406
|
allowDbl = false
|
|
383
407
|
svgCanvas.setCurrentMode('textedit')
|
|
@@ -407,16 +431,20 @@ export const textActionsMethod = (function () {
|
|
|
407
431
|
}, 300)
|
|
408
432
|
},
|
|
409
433
|
/**
|
|
410
|
-
* @param {boolean|Element} selectElem
|
|
411
|
-
* @fires module:svgcanvas.SvgCanvas#event:selected
|
|
412
|
-
* @returns {void}
|
|
413
|
-
*/
|
|
434
|
+
* @param {boolean|Element} selectElem
|
|
435
|
+
* @fires module:svgcanvas.SvgCanvas#event:selected
|
|
436
|
+
* @returns {void}
|
|
437
|
+
*/
|
|
414
438
|
toSelectMode (selectElem) {
|
|
415
439
|
svgCanvas.setCurrentMode('select')
|
|
416
440
|
clearInterval(blinker)
|
|
417
441
|
blinker = null
|
|
418
|
-
if (selblock) {
|
|
419
|
-
|
|
442
|
+
if (selblock) {
|
|
443
|
+
selblock.setAttribute('display', 'none')
|
|
444
|
+
}
|
|
445
|
+
if (cursor) {
|
|
446
|
+
cursor.setAttribute('visibility', 'hidden')
|
|
447
|
+
}
|
|
420
448
|
curtext.style.cursor = 'move'
|
|
421
449
|
|
|
422
450
|
if (selectElem) {
|
|
@@ -440,27 +468,30 @@ export const textActionsMethod = (function () {
|
|
|
440
468
|
// }
|
|
441
469
|
},
|
|
442
470
|
/**
|
|
443
|
-
* @param {Element} elem
|
|
444
|
-
* @returns {void}
|
|
445
|
-
*/
|
|
471
|
+
* @param {Element} elem
|
|
472
|
+
* @returns {void}
|
|
473
|
+
*/
|
|
446
474
|
setInputElem (elem) {
|
|
447
475
|
textinput = elem
|
|
448
476
|
},
|
|
449
477
|
/**
|
|
450
|
-
* @returns {void}
|
|
451
|
-
*/
|
|
478
|
+
* @returns {void}
|
|
479
|
+
*/
|
|
452
480
|
clear () {
|
|
453
481
|
if (svgCanvas.getCurrentMode() === 'textedit') {
|
|
454
482
|
svgCanvas.textActions.toSelectMode()
|
|
455
483
|
}
|
|
456
484
|
},
|
|
457
485
|
/**
|
|
458
|
-
* @param {Element} _inputElem Not in use
|
|
459
|
-
* @returns {void}
|
|
460
|
-
*/
|
|
486
|
+
* @param {Element} _inputElem Not in use
|
|
487
|
+
* @returns {void}
|
|
488
|
+
*/
|
|
461
489
|
init (_inputElem) {
|
|
462
|
-
if (!curtext) {
|
|
463
|
-
|
|
490
|
+
if (!curtext) {
|
|
491
|
+
return
|
|
492
|
+
}
|
|
493
|
+
let i
|
|
494
|
+
let end
|
|
464
495
|
// if (supportsEditableText()) {
|
|
465
496
|
// curtext.select();
|
|
466
497
|
// return;
|
|
@@ -490,7 +521,7 @@ export const textActionsMethod = (function () {
|
|
|
490
521
|
curtext.addEventListener('dblclick', selectWord)
|
|
491
522
|
|
|
492
523
|
if (!len) {
|
|
493
|
-
end = { x: textbb.x +
|
|
524
|
+
end = { x: textbb.x + textbb.width / 2, width: 0 }
|
|
494
525
|
}
|
|
495
526
|
|
|
496
527
|
for (i = 0; i < len; i++) {
|
|
@@ -527,4 +558,4 @@ export const textActionsMethod = (function () {
|
|
|
527
558
|
setSelection(textinput.selectionStart, textinput.selectionEnd, true)
|
|
528
559
|
}
|
|
529
560
|
}
|
|
530
|
-
}()
|
|
561
|
+
})()
|