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.
@@ -0,0 +1,214 @@
1
+ import Konva from 'konva'
2
+ import Canvas from './canvas'
3
+ import Properties from './properties'
4
+ import Histories from './histories'
5
+ export default {
6
+ transformer: null,
7
+ linearTransformer: {
8
+ start: null,
9
+ end: null,
10
+ node: null
11
+ },
12
+ initialize() {
13
+ this.transformer = new Konva.Transformer();
14
+ Canvas.layer.add(this.transformer);
15
+ },
16
+ copySelectedNodes() {
17
+ const selectedNodes = this._nodes().map(node => node.clone());
18
+ return selectedNodes;
19
+ },
20
+ removeSelectedNodes() {
21
+ this._nodes().forEach((node) => node.destroy());
22
+ this.deselectAllNodes();
23
+ },
24
+ setPropertiesOfSelectedNodes(properties) {
25
+ const selectedNodes = this._nodes().slice();
26
+ selectedNodes.forEach((node) => {
27
+ Object.keys(properties).forEach((key) => {
28
+ if (node.getClassName() === 'Text') {
29
+ if (key === 'stroke') {
30
+ node.setAttr('fill', properties[key]);
31
+ } else if (key !== 'fill') {
32
+ node.setAttr(key, properties[key]);
33
+ }
34
+ } else {
35
+ node.setAttr(key, properties[key]);
36
+ }
37
+ });
38
+ });
39
+ },
40
+ selectNode(targetNode, isAppending = false) {
41
+ const isSelected = this._nodes().indexOf(targetNode) >= 0 || this.linearTransformer.node === targetNode;
42
+ if (!isAppending && !isSelected) {
43
+ this.selectNodes([targetNode]);
44
+ } else if (isAppending && isSelected) {
45
+ const nodes = this._nodes().slice();
46
+ if (this.linearTransformer.node) {
47
+ nodes.push(this.linearTransformer.node);
48
+ }
49
+ nodes.splice(nodes.indexOf(targetNode), 1);
50
+ this.selectNodes(nodes);
51
+ } else if (isAppending && !isSelected) {
52
+ if (this.linearTransformer.node) {
53
+ this.selectNodes([this.linearTransformer.node].concat([targetNode]));
54
+ this._removeLinearTransformer();
55
+ } else {
56
+ this.selectNodes(this._nodes().concat([targetNode]));
57
+ }
58
+ }
59
+ },
60
+ selectNodes(targetNodes) {
61
+ this._nodes([]);
62
+ if (this._hasOnlyLinearNode(targetNodes)) {
63
+ this._selectLinearNode(targetNodes[0]);
64
+ } else {
65
+ this._nodes(targetNodes);
66
+ if (targetNodes.length === 1) {
67
+ this.transformer.enabledAnchors(['top-left', 'top-center', 'top-right', 'middle-right', 'middle-left', 'bottom-left', 'bottom-center', 'bottom-right']);
68
+ } else {
69
+ this.transformer.enabledAnchors(['top-left', 'top-right', 'bottom-left', 'bottom-right']);
70
+ }
71
+ Properties.isTextNodesSelected = this._hasSelectedOnlyTextNodes()
72
+ }
73
+ Properties.setProperties(this._getCommonPropertiesOfSelectedNodes());
74
+ },
75
+ deselectAllNodes() {
76
+ this.selectNodes([]);
77
+ if (this.linearTransformer.node) {
78
+ this.linearTransformer.node.destroy();
79
+ this._removeLinearTransformer()
80
+ }
81
+ },
82
+ selectAllNodes() {
83
+ this.selectNodes(Canvas.stage.find('.node'));
84
+ },
85
+ _getCommonPropertiesOfSelectedNodes() {
86
+ const nodes = this._nodes();
87
+ if (nodes.length === 0) {
88
+ return {};
89
+ }
90
+ const firstNode = nodes[0];
91
+ const commonProperties = {};
92
+
93
+ Object.keys(firstNode.attrs).forEach((property) => {
94
+ const firstValue = firstNode.attrs[property];
95
+ const isCommon = nodes.every((node) => {
96
+ return node.attrs[property] === firstValue;
97
+ });
98
+ if (isCommon) {
99
+ if (property === 'fill') {
100
+ if (!this._hasSelectedOnlyTextNodes()) {
101
+ commonProperties.fillColor = firstValue;
102
+ }
103
+ } else if (property === 'stroke') {
104
+ commonProperties.strokeColor = firstValue;
105
+ } else if (property === 'fontSize') {
106
+ commonProperties.fontSize = firstValue;
107
+ } else if (property === 'strokeWidth') {
108
+ commonProperties.strokeWidth = firstValue;
109
+ }
110
+ }
111
+ });
112
+ return commonProperties;
113
+ },
114
+ _selectLinearNode(node) {
115
+ node.on('dragmove', () => {
116
+ if (node === this.linearTransformer.node) {
117
+ this._removeLinearTransformer()
118
+ this._showLinearTransformer(node)
119
+ }
120
+ });
121
+ this._showLinearTransformer(node)
122
+ },
123
+ _showLinearTransformer(node) {
124
+ const updateLinearNode = (() => {
125
+ const negateNodeTransform = node.getAbsoluteTransform().copy().invert();
126
+ const start = negateNodeTransform.point({
127
+ x: this.linearTransformer.start.x(),
128
+ y: this.linearTransformer.start.y()
129
+ });
130
+ const end = negateNodeTransform.point({
131
+ x: this.linearTransformer.end.x(),
132
+ y: this.linearTransformer.end.y()
133
+ });
134
+ node.points([start.x, start.y, end.x, end.y]);
135
+ })
136
+ const nodeTransform = node.getAbsoluteTransform();
137
+ const points = node.getPoints();
138
+ const start = nodeTransform.point({x: points[0], y: points[1]});
139
+ const end = nodeTransform.point({x: points[2], y: points[3]});
140
+ this.linearTransformer.start = new Konva.Circle({
141
+ x: start.x,
142
+ y: start.y,
143
+ radius: 5,
144
+ strokeWidth: 1,
145
+ stroke: '#1ca5f8',
146
+ fill: '#fff',
147
+ draggable: true
148
+ })
149
+ this.linearTransformer.end = new Konva.Circle({
150
+ x: end.x,
151
+ y: end.y,
152
+ radius: 5,
153
+ strokeWidth: 1,
154
+ stroke: '#1ca5f8',
155
+ fill: '#fff',
156
+ draggable: true
157
+ })
158
+ this.linearTransformer.node = node
159
+ this.linearTransformer.start.on('dragmove', updateLinearNode)
160
+ this.linearTransformer.end.on('dragmove', updateLinearNode)
161
+ this.linearTransformer.start.on('dragend', Histories.record)
162
+ this.linearTransformer.end.on('dragend', Histories.record)
163
+ Canvas.layer.add(this.linearTransformer.start)
164
+ Canvas.layer.add(this.linearTransformer.end)
165
+ },
166
+ _removeLinearTransformer() {
167
+ if (this.linearTransformer.start) {
168
+ this.linearTransformer.start.destroy()
169
+ }
170
+ if (this.linearTransformer.end) {
171
+ this.linearTransformer.end.destroy()
172
+ }
173
+ this.linearTransformer.start = null
174
+ this.linearTransformer.end = null
175
+ this.linearTransformer.node = null
176
+ },
177
+ _nodes(newNodes = undefined) {
178
+ if (newNodes !== undefined) {
179
+ if (newNodes.length === 0) {
180
+ this._removeLinearTransformer();
181
+ Properties.isTextNodesSelected = false;
182
+ }
183
+ this.transformer.nodes(newNodes);
184
+ this.transformer.moveToTop();
185
+ } else {
186
+ if (this.linearTransformer.node) {
187
+ return this.transformer.nodes().concat([this.linearTransformer.node]);
188
+ }
189
+ return this.transformer.nodes();
190
+ }
191
+ return [];
192
+ },
193
+ _hasOnlyLinearNode(nodes) {
194
+ if (nodes.length !== 1) {
195
+ return false;
196
+ }
197
+ const node = nodes[0];
198
+ return (node.className === 'Arrow' ||
199
+ node.className === 'Line' && node.getPoints().length === 4);
200
+ },
201
+ _hasSelectedOnlyTextNodes() {
202
+ const nodes = this._nodes();
203
+ if (nodes.length > 0) {
204
+ let hasOnlyTextNodes = true;
205
+ nodes.forEach((node) => {
206
+ if (node.getClassName() !== 'Text') {
207
+ hasOnlyTextNodes = false;
208
+ }
209
+ });
210
+ return hasOnlyTextNodes;
211
+ }
212
+ return false;
213
+ }
214
+ }
package/src/index.js ADDED
@@ -0,0 +1,9 @@
1
+ import DrawingCanvas from './components/DrawingCanvas.vue'
2
+ import ToolButtons from './components/ToolButtons.vue'
3
+ import PropertyPickers from './components/PropertyPickers.vue'
4
+
5
+ export default {
6
+ DrawingCanvas,
7
+ PropertyPickers,
8
+ ToolButtons
9
+ }
package/src/main.js ADDED
@@ -0,0 +1,8 @@
1
+ import Vue from 'vue'
2
+ import App from './App.vue'
3
+
4
+ Vue.config.productionTip = false
5
+
6
+ new Vue({
7
+ render: h => h(App)
8
+ }).$mount('#app')
@@ -0,0 +1,39 @@
1
+ const path = require("path");
2
+ module.exports = {
3
+ entry: "./src/index.js",//入口文件
4
+ output: {
5
+ path: path.resolve(__dirname, './dist'),//输出路径
6
+ publicPath: '/dist/',
7
+ filename: 'jellies-draw.js',
8
+ libraryTarget: 'umd',
9
+ umdNamedDefine: true
10
+ },
11
+ module: {
12
+ rules: [{
13
+ test: /\.vue$/,
14
+ loader: 'vue-loader'
15
+ },
16
+ {
17
+ test: /\.(less|css)$/,
18
+ use: [
19
+ { loader: "style-loader" },
20
+ { loader: "css-loader" },
21
+ { loader: "less-loader" }
22
+ ]
23
+ },
24
+ {
25
+ test: /\.js$/,
26
+ exclude: /node_modules|vue\/dist|vue-router\/|vue-loader\/|vue-hot-reload-api\//,
27
+ loader: 'babel-loader'
28
+ },
29
+ {
30
+ test: /\.(png|jpg|gif|ttf|svg|woff|woff2|eot)$/,
31
+ loader: 'url-loader',
32
+ query: {
33
+ limit: 30000,
34
+ name: '[name].[ext]?[hash]'
35
+ }
36
+ }
37
+ ]
38
+ },
39
+ }