jellies-draw 0.1.0
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/.eslintrc.js +89 -0
- package/README.md +24 -0
- package/babel.config.js +5 -0
- package/package.json +65 -0
- package/public/favicon.ico +0 -0
- package/public/index.html +17 -0
- package/src/App.vue +93 -0
- package/src/assets/jellies-draw-tool.ttf +0 -0
- package/src/components/DrawingCanvas.vue +66 -0
- package/src/components/PropertyPickers.vue +218 -0
- package/src/components/ToolButton.vue +125 -0
- package/src/components/ToolButtons.vue +113 -0
- package/src/components/functions/canvas.js +136 -0
- package/src/components/functions/clipboard.js +32 -0
- package/src/components/functions/histories.js +53 -0
- package/src/components/functions/properties.js +126 -0
- package/src/components/functions/tools/arrow.js +70 -0
- package/src/components/functions/tools/clear.js +8 -0
- package/src/components/functions/tools/ellipse.js +73 -0
- package/src/components/functions/tools/eraser.js +51 -0
- package/src/components/functions/tools/image.js +74 -0
- package/src/components/functions/tools/index.js +23 -0
- package/src/components/functions/tools/line.js +56 -0
- package/src/components/functions/tools/pen.js +61 -0
- package/src/components/functions/tools/rectangle.js +71 -0
- package/src/components/functions/tools/selector.js +47 -0
- package/src/components/functions/tools/text.js +178 -0
- package/src/components/functions/transformer.js +214 -0
- package/src/index.js +9 -0
- package/src/main.js +8 -0
- package/webpack.config.js +39 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import Properties from '../properties'
|
|
2
|
+
import Canvas from '../canvas'
|
|
3
|
+
import Konva from 'konva'
|
|
4
|
+
import Histories from '../histories'
|
|
5
|
+
export default {
|
|
6
|
+
add(file) {
|
|
7
|
+
Properties.tool = 'selector'
|
|
8
|
+
const reader = new FileReader()
|
|
9
|
+
reader.onload = () => {
|
|
10
|
+
this.generate({
|
|
11
|
+
x: 10,
|
|
12
|
+
y: 10,
|
|
13
|
+
imageUrl: reader.result,
|
|
14
|
+
needToRecord: true
|
|
15
|
+
})
|
|
16
|
+
}
|
|
17
|
+
reader.readAsDataURL(file)
|
|
18
|
+
},
|
|
19
|
+
bindEvents(newImage) {
|
|
20
|
+
newImage.off('transformend')
|
|
21
|
+
newImage.off('dragend')
|
|
22
|
+
newImage.on('transformend', Histories.record)
|
|
23
|
+
newImage.on('dragend', Histories.record)
|
|
24
|
+
},
|
|
25
|
+
generate({ x, y, scaleX, scaleY, skewX, rotation, imageUrl, needToRecord = false }) {
|
|
26
|
+
const image = new Image()
|
|
27
|
+
image.onload = () => {
|
|
28
|
+
const { width, height } = this.getImageSize(scaleX, scaleY, image)
|
|
29
|
+
const newImage = new Konva.Image({
|
|
30
|
+
x,
|
|
31
|
+
y,
|
|
32
|
+
width,
|
|
33
|
+
height,
|
|
34
|
+
scaleX,
|
|
35
|
+
scaleY,
|
|
36
|
+
skewX,
|
|
37
|
+
rotation,
|
|
38
|
+
image,
|
|
39
|
+
imageUrl,
|
|
40
|
+
name: 'node',
|
|
41
|
+
nodeType: 'image',
|
|
42
|
+
draggable: true
|
|
43
|
+
})
|
|
44
|
+
this.bindEvents(newImage)
|
|
45
|
+
Canvas.layer.add(newImage)
|
|
46
|
+
if (needToRecord) {
|
|
47
|
+
Histories.record()
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
image.src = imageUrl
|
|
51
|
+
},
|
|
52
|
+
getImageSize(scaleX, scaleY, image) {
|
|
53
|
+
if (!scaleX && !scaleY) {
|
|
54
|
+
return {}
|
|
55
|
+
}
|
|
56
|
+
if (image.width > Canvas.stage.width() || image.height > Canvas.stage.height()) {
|
|
57
|
+
const ratio = image.width / image.height
|
|
58
|
+
if (image.width > image.height) {
|
|
59
|
+
return {
|
|
60
|
+
width: Canvas.stage.width(),
|
|
61
|
+
height: Canvas.stage.width() / ratio
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
width: Canvas.stage.height() * ratio,
|
|
66
|
+
height: Canvas.stage.height()
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
width: image.width,
|
|
71
|
+
height: image.height
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import Rectangle from './rectangle';
|
|
2
|
+
import Ellipse from './ellipse';
|
|
3
|
+
import Image from './image';
|
|
4
|
+
import Line from './line';
|
|
5
|
+
import Arrow from './arrow';
|
|
6
|
+
import Pen from './pen';
|
|
7
|
+
import Eraser from './eraser';
|
|
8
|
+
import Text from './text';
|
|
9
|
+
import Selector from './selector';
|
|
10
|
+
import Clear from './clear';
|
|
11
|
+
|
|
12
|
+
export default {
|
|
13
|
+
rectangle: Rectangle,
|
|
14
|
+
ellipse: Ellipse,
|
|
15
|
+
image: Image,
|
|
16
|
+
line: Line,
|
|
17
|
+
arrow: Arrow,
|
|
18
|
+
pen: Pen,
|
|
19
|
+
eraser: Eraser,
|
|
20
|
+
text: Text,
|
|
21
|
+
selector: Selector,
|
|
22
|
+
clear: Clear
|
|
23
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import Konva from 'konva'
|
|
2
|
+
import Properties from '../properties'
|
|
3
|
+
import Canvas from '../canvas'
|
|
4
|
+
import Histories from '../histories'
|
|
5
|
+
export default {
|
|
6
|
+
temporalShape: null,
|
|
7
|
+
startX: 0,
|
|
8
|
+
startY: 0,
|
|
9
|
+
show({ offsetX, offsetY }) {
|
|
10
|
+
Canvas.isDrawing = true;
|
|
11
|
+
this.startX = offsetX
|
|
12
|
+
this.startY = offsetY
|
|
13
|
+
const stroke = Properties.strokeColor
|
|
14
|
+
const strokeWidth = Properties.strokeWidth
|
|
15
|
+
const newLine = this.generate({
|
|
16
|
+
points: [offsetX, offsetY, offsetX, offsetY],
|
|
17
|
+
stroke,
|
|
18
|
+
strokeWidth
|
|
19
|
+
})
|
|
20
|
+
this.temporalShape = newLine
|
|
21
|
+
Canvas.layer.add(this.temporalShape)
|
|
22
|
+
},
|
|
23
|
+
change({ offsetX, offsetY }) {
|
|
24
|
+
if (Canvas.isDrawing) {
|
|
25
|
+
this.temporalShape.points([this.startX, this.startY, offsetX, offsetY]);
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
finish() {
|
|
29
|
+
Properties.tool = 'selector'
|
|
30
|
+
this.temporalShape = null
|
|
31
|
+
},
|
|
32
|
+
generate({ x, y, scaleX, scaleY, points, stroke, strokeWidth }) {
|
|
33
|
+
const newLine = new Konva.Line({
|
|
34
|
+
x,
|
|
35
|
+
y,
|
|
36
|
+
scaleX,
|
|
37
|
+
scaleY,
|
|
38
|
+
points,
|
|
39
|
+
stroke,
|
|
40
|
+
strokeWidth,
|
|
41
|
+
name: 'node',
|
|
42
|
+
nodeType: 'line',
|
|
43
|
+
lineCap: 'round',
|
|
44
|
+
bezier: false,
|
|
45
|
+
strokeScaleEnabled: false
|
|
46
|
+
})
|
|
47
|
+
this.bindEvents(newLine)
|
|
48
|
+
return newLine
|
|
49
|
+
},
|
|
50
|
+
bindEvents(newLine) {
|
|
51
|
+
newLine.off('transformend')
|
|
52
|
+
newLine.off('dragend')
|
|
53
|
+
newLine.on('transformend', Histories.record)
|
|
54
|
+
newLine.on('dragend', Histories.record)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import Konva from 'konva'
|
|
2
|
+
import Properties from '../properties'
|
|
3
|
+
import Canvas from '../canvas'
|
|
4
|
+
import Histories from '../histories'
|
|
5
|
+
export default {
|
|
6
|
+
temporalCurveTrajectory: null,
|
|
7
|
+
temporalShape: null,
|
|
8
|
+
startX: 0,
|
|
9
|
+
startY: 0,
|
|
10
|
+
show({ offsetX, offsetY }) {
|
|
11
|
+
Canvas.isDrawing = true;
|
|
12
|
+
this.startX = offsetX
|
|
13
|
+
this.startY = offsetY
|
|
14
|
+
this.temporalCurveTrajectory = null
|
|
15
|
+
const stroke = Properties.strokeColor
|
|
16
|
+
const strokeWidth = Properties.strokeWidth
|
|
17
|
+
const newCurve = this.generate({
|
|
18
|
+
points: [offsetX, offsetY, offsetX, offsetY],
|
|
19
|
+
stroke,
|
|
20
|
+
strokeWidth
|
|
21
|
+
})
|
|
22
|
+
this.temporalShape = newCurve
|
|
23
|
+
Canvas.layer.add(this.temporalShape)
|
|
24
|
+
},
|
|
25
|
+
change({ offsetX, offsetY }) {
|
|
26
|
+
if (Canvas.isDrawing) {
|
|
27
|
+
if (!this.temporalCurveTrajectory) {
|
|
28
|
+
this.temporalCurveTrajectory = [this.startX, this.startY]
|
|
29
|
+
}
|
|
30
|
+
this.temporalCurveTrajectory.push(offsetX, offsetY)
|
|
31
|
+
this.temporalShape.points(this.temporalCurveTrajectory);
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
finish() {
|
|
35
|
+
this.temporalShape = null
|
|
36
|
+
},
|
|
37
|
+
generate({ x, y, scaleX, scaleY, points, stroke, strokeWidth }) {
|
|
38
|
+
const newLine = new Konva.Line({
|
|
39
|
+
x,
|
|
40
|
+
y,
|
|
41
|
+
scaleX,
|
|
42
|
+
scaleY,
|
|
43
|
+
points,
|
|
44
|
+
stroke,
|
|
45
|
+
strokeWidth,
|
|
46
|
+
name: 'node',
|
|
47
|
+
nodeType: 'pen',
|
|
48
|
+
lineCap: 'round',
|
|
49
|
+
bezier: false,
|
|
50
|
+
strokeScaleEnabled: false
|
|
51
|
+
})
|
|
52
|
+
this.bindEvents(newLine)
|
|
53
|
+
return newLine
|
|
54
|
+
},
|
|
55
|
+
bindEvents(newLine) {
|
|
56
|
+
newLine.off('transformend')
|
|
57
|
+
newLine.off('dragend')
|
|
58
|
+
newLine.on('transformend', Histories.record)
|
|
59
|
+
newLine.on('dragend', Histories.record)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import Konva from 'konva'
|
|
2
|
+
import Properties from '../properties'
|
|
3
|
+
import Canvas from '../canvas'
|
|
4
|
+
import Histories from '../histories'
|
|
5
|
+
export default {
|
|
6
|
+
temporalShape: null,
|
|
7
|
+
startX: 0,
|
|
8
|
+
startY: 0,
|
|
9
|
+
show({ offsetX, offsetY }) {
|
|
10
|
+
Canvas.isDrawing = true;
|
|
11
|
+
this.startX = offsetX
|
|
12
|
+
this.startY = offsetY
|
|
13
|
+
const fill = Properties.fillColor
|
|
14
|
+
const stroke = Properties.strokeColor
|
|
15
|
+
const strokeWidth = Properties.strokeWidth
|
|
16
|
+
const newRectangle = this.generate({
|
|
17
|
+
x: offsetX,
|
|
18
|
+
y: offsetY,
|
|
19
|
+
width: 1,
|
|
20
|
+
height: 1,
|
|
21
|
+
fill,
|
|
22
|
+
stroke,
|
|
23
|
+
strokeWidth
|
|
24
|
+
})
|
|
25
|
+
this._checkRectangleAndChangeToCell(newRectangle)
|
|
26
|
+
this.temporalShape = newRectangle
|
|
27
|
+
Canvas.layer.add(this.temporalShape)
|
|
28
|
+
},
|
|
29
|
+
change({ offsetX, offsetY }) {
|
|
30
|
+
if (Canvas.isDrawing) {
|
|
31
|
+
this.temporalShape.width(offsetX - this.startX)
|
|
32
|
+
this.temporalShape.height(offsetY - this.startY)
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
finish() {
|
|
36
|
+
Properties.tool = 'selector'
|
|
37
|
+
this.temporalShape = null
|
|
38
|
+
},
|
|
39
|
+
_checkRectangleAndChangeToCell(newRectangle) {
|
|
40
|
+
setTimeout(() => {
|
|
41
|
+
if (!this.temporalShape && newRectangle.width() < 5 && newRectangle.height() < 5) {
|
|
42
|
+
newRectangle.width(30)
|
|
43
|
+
newRectangle.height(30)
|
|
44
|
+
}
|
|
45
|
+
}, 200)
|
|
46
|
+
},
|
|
47
|
+
generate({ x, y, scaleX, scaleY, width, height, fill, stroke, strokeWidth }) {
|
|
48
|
+
const newRectangle = new Konva.Rect({
|
|
49
|
+
x,
|
|
50
|
+
y,
|
|
51
|
+
scaleX,
|
|
52
|
+
scaleY,
|
|
53
|
+
width,
|
|
54
|
+
height,
|
|
55
|
+
fill,
|
|
56
|
+
stroke,
|
|
57
|
+
strokeWidth,
|
|
58
|
+
name: 'node',
|
|
59
|
+
nodeType: 'rectangle',
|
|
60
|
+
strokeScaleEnabled: false
|
|
61
|
+
})
|
|
62
|
+
this.bindEvents(newRectangle)
|
|
63
|
+
return newRectangle
|
|
64
|
+
},
|
|
65
|
+
bindEvents(newRectangle) {
|
|
66
|
+
newRectangle.off('transformend')
|
|
67
|
+
newRectangle.off('dragend')
|
|
68
|
+
newRectangle.on('transformend', Histories.record)
|
|
69
|
+
newRectangle.on('dragend', Histories.record)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import Konva from 'konva'
|
|
2
|
+
import Canvas from '../canvas'
|
|
3
|
+
import Transformer from '../transformer'
|
|
4
|
+
export default {
|
|
5
|
+
startX: 0,
|
|
6
|
+
startY: 0,
|
|
7
|
+
selector: null,
|
|
8
|
+
show({ offsetX, offsetY }) {
|
|
9
|
+
this.selector = new Konva.Rect({
|
|
10
|
+
fill: 'rgba(176,188,207,0.3)',
|
|
11
|
+
visible: true,
|
|
12
|
+
x: offsetX,
|
|
13
|
+
y: offsetY,
|
|
14
|
+
width: 0,
|
|
15
|
+
height: 0
|
|
16
|
+
});
|
|
17
|
+
Canvas.layer.add(this.selector);
|
|
18
|
+
this.startX = offsetX;
|
|
19
|
+
this.startY = offsetY;
|
|
20
|
+
},
|
|
21
|
+
change({ offsetX, offsetY }) {
|
|
22
|
+
if (this.selector) {
|
|
23
|
+
this.selector.setAttrs({
|
|
24
|
+
x: Math.min(this.startX, offsetX),
|
|
25
|
+
y: Math.min(this.startY, offsetY),
|
|
26
|
+
width: Math.abs(this.startX - offsetX),
|
|
27
|
+
height: Math.abs(this.startY - offsetY)
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
finish() {
|
|
32
|
+
if (this.selector) {
|
|
33
|
+
Transformer.selectNodes(Canvas.stage.find('.node').filter(node => this._isInSelector(node)));
|
|
34
|
+
this.selector.destroy();
|
|
35
|
+
this.selector = null
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
isSelecting() {
|
|
39
|
+
return this.selector !== null
|
|
40
|
+
},
|
|
41
|
+
_isInSelector(node) {
|
|
42
|
+
return Konva.Util.haveIntersection(
|
|
43
|
+
this.selector.getClientRect(),
|
|
44
|
+
node.getClientRect()
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import Konva from 'konva'
|
|
2
|
+
import Properties from '../properties'
|
|
3
|
+
import Canvas from '../canvas'
|
|
4
|
+
import Transformer from '../transformer'
|
|
5
|
+
import Histories from '../histories'
|
|
6
|
+
export default {
|
|
7
|
+
temporalText: null,
|
|
8
|
+
textarea: null,
|
|
9
|
+
textareaEditingHandler: null,
|
|
10
|
+
disableTextareaHandler: null,
|
|
11
|
+
handleTextareaTimer: null,
|
|
12
|
+
show({ offsetX, offsetY }) {
|
|
13
|
+
if (!Canvas.isEditingText) {
|
|
14
|
+
const newText = this.generate({
|
|
15
|
+
text: '',
|
|
16
|
+
x: offsetX,
|
|
17
|
+
y: offsetY,
|
|
18
|
+
fontSize: Properties.fontSize,
|
|
19
|
+
width: 200,
|
|
20
|
+
fill: Properties.strokeColor
|
|
21
|
+
})
|
|
22
|
+
this.temporalText = newText
|
|
23
|
+
Canvas.layer.add(this.temporalText)
|
|
24
|
+
clearTimeout(this.handleTextareaTimer)
|
|
25
|
+
this.handleTextareaTimer = setTimeout(() => {
|
|
26
|
+
this._handleEnableTextarea(newText)
|
|
27
|
+
}, 200)
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
bindEvents(newText) {
|
|
31
|
+
newText.off('dblclick dbltap')
|
|
32
|
+
newText.off('transform')
|
|
33
|
+
newText.off('transformend')
|
|
34
|
+
newText.off('dragend')
|
|
35
|
+
newText.on('dblclick dbltap', () => {
|
|
36
|
+
this._handleEnableTextarea(newText)
|
|
37
|
+
})
|
|
38
|
+
newText.on('transform', () => {
|
|
39
|
+
newText.setAttrs({
|
|
40
|
+
width: newText.width() * newText.scaleX(),
|
|
41
|
+
height: newText.height() * newText.scaleY(),
|
|
42
|
+
scaleX: 1,
|
|
43
|
+
scaleY: 1
|
|
44
|
+
})
|
|
45
|
+
})
|
|
46
|
+
newText.on('transformend', Histories.record)
|
|
47
|
+
newText.on('dragend', Histories.record)
|
|
48
|
+
},
|
|
49
|
+
change() {
|
|
50
|
+
return
|
|
51
|
+
},
|
|
52
|
+
finish() {
|
|
53
|
+
return
|
|
54
|
+
},
|
|
55
|
+
_handleEnableTextarea(newText) {
|
|
56
|
+
Canvas.isEditingText = true;
|
|
57
|
+
Properties.tool = 'text'
|
|
58
|
+
this.temporalText = newText;
|
|
59
|
+
newText.hide();
|
|
60
|
+
Transformer.deselectAllNodes();
|
|
61
|
+
|
|
62
|
+
const textPosition = newText.absolutePosition();
|
|
63
|
+
const areaPosition = {
|
|
64
|
+
x: Canvas.stage.container().offsetLeft + textPosition.x,
|
|
65
|
+
y: Canvas.stage.container().offsetTop + textPosition.y
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
if (this.textarea) {
|
|
69
|
+
this.textarea.removeEventListener('keydown', this.textareaEditingHandler);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
this.textarea = document.createElement('textarea');
|
|
73
|
+
document.body.appendChild(this.textarea);
|
|
74
|
+
|
|
75
|
+
this.textarea.value = newText.text();
|
|
76
|
+
this.textarea.style.position = 'absolute';
|
|
77
|
+
this.textarea.style.top = `${areaPosition.y}px`;
|
|
78
|
+
this.textarea.style.left = `${areaPosition.x}px`;
|
|
79
|
+
this.textarea.style.width = `${newText.width() - newText.padding() * 2}px`;
|
|
80
|
+
this.textarea.style.height =
|
|
81
|
+
`${ newText.height() - newText.padding() * 2 + 5 }px`;
|
|
82
|
+
this.textarea.style.fontSize = `${ newText.fontSize() }px`;
|
|
83
|
+
this.textarea.style.border = 'none';
|
|
84
|
+
this.textarea.style.padding = '0';
|
|
85
|
+
this.textarea.style.margin = '0';
|
|
86
|
+
this.textarea.style.overflow = 'hidden';
|
|
87
|
+
this.textarea.style.background = 'none';
|
|
88
|
+
this.textarea.style.outline = 'none';
|
|
89
|
+
this.textarea.style.resize = 'none';
|
|
90
|
+
this.textarea.style.lineHeight = newText.lineHeight();
|
|
91
|
+
this.textarea.style.fontFamily = newText.fontFamily();
|
|
92
|
+
this.textarea.style.transformOrigin = 'left top';
|
|
93
|
+
this.textarea.style.textAlign = newText.align();
|
|
94
|
+
this.textarea.style.color = newText.fill();
|
|
95
|
+
const rotation = newText.rotation();
|
|
96
|
+
let transform = '';
|
|
97
|
+
if (rotation) {
|
|
98
|
+
transform += `rotateZ(${ rotation }deg)`;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
let px = 0;
|
|
102
|
+
|
|
103
|
+
const isFirefox =
|
|
104
|
+
navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
|
|
105
|
+
if (isFirefox) {
|
|
106
|
+
px += 2 + Math.round(newText.fontSize() / 20);
|
|
107
|
+
}
|
|
108
|
+
transform += `translateY(-${ px }px)`;
|
|
109
|
+
|
|
110
|
+
this.textarea.style.transform = transform;
|
|
111
|
+
|
|
112
|
+
this.textarea.style.height = 'auto';
|
|
113
|
+
this.textarea.style.height = `${this.textarea.scrollHeight + 3}px`;
|
|
114
|
+
|
|
115
|
+
this.textarea.focus();
|
|
116
|
+
|
|
117
|
+
this.textareaEditingHandler = this._handleTextareaEditing.bind(this);
|
|
118
|
+
this.disableTextareaHandler = this._handleDisableTextarea.bind(this);
|
|
119
|
+
this.textarea.addEventListener('keydown', this.textareaEditingHandler);
|
|
120
|
+
setTimeout(() => {
|
|
121
|
+
window.addEventListener('mousedown', this.disableTextareaHandler);
|
|
122
|
+
});
|
|
123
|
+
},
|
|
124
|
+
_handleDisableTextarea(event) {
|
|
125
|
+
if (event.target !== this.textarea) {
|
|
126
|
+
this.temporalText.text(this.textarea.value)
|
|
127
|
+
this.textarea.remove()
|
|
128
|
+
window.removeEventListener('mousedown', this.disableTextareaHandler)
|
|
129
|
+
this.temporalText.show()
|
|
130
|
+
Properties.tool = 'selector'
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
_handleTextareaEditing() {
|
|
134
|
+
const scale = this.temporalText.getAbsoluteScale().x;
|
|
135
|
+
this._setTextareaWidth(this.temporalText.width() * scale);
|
|
136
|
+
this.textarea.style.height = 'auto';
|
|
137
|
+
this.textarea.style.height =
|
|
138
|
+
`${this.textarea.scrollHeight + this.temporalText.fontSize() }px`;
|
|
139
|
+
},
|
|
140
|
+
_setTextareaWidth(newWidth) {
|
|
141
|
+
if (!newWidth) {
|
|
142
|
+
newWidth = this.textNode.placeholder.length * this.temporalText.fontSize();
|
|
143
|
+
}
|
|
144
|
+
const isSafari = /^((?!chrome|android).)*safari/i.test(
|
|
145
|
+
navigator.userAgent
|
|
146
|
+
);
|
|
147
|
+
const isFirefox =
|
|
148
|
+
navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
|
|
149
|
+
if (isSafari || isFirefox) {
|
|
150
|
+
newWidth = Math.ceil(newWidth);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const isEdge =
|
|
154
|
+
document.documentMode || /Edge/.test(navigator.userAgent);
|
|
155
|
+
if (isEdge) {
|
|
156
|
+
newWidth += 1;
|
|
157
|
+
}
|
|
158
|
+
this.textarea.style.width = `${ newWidth }px`;
|
|
159
|
+
},
|
|
160
|
+
generate({ text, x, y, fill, fontSize, width, height, scaleX, scaleY }) {
|
|
161
|
+
const newText = new Konva.Text({
|
|
162
|
+
text,
|
|
163
|
+
x,
|
|
164
|
+
y,
|
|
165
|
+
fill,
|
|
166
|
+
fontSize,
|
|
167
|
+
width,
|
|
168
|
+
height,
|
|
169
|
+
scaleX,
|
|
170
|
+
scaleY,
|
|
171
|
+
name: 'node',
|
|
172
|
+
nodeType: 'text',
|
|
173
|
+
strokeEnabled: false
|
|
174
|
+
});
|
|
175
|
+
this.bindEvents(newText)
|
|
176
|
+
return newText
|
|
177
|
+
}
|
|
178
|
+
}
|