kfb-view 2.1.11 → 2.1.14
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/.idea/git_toolbox_prj.xml +5 -0
- package/.idea/workspace.xml +73 -53
- package/example/index.js +2 -1
- package/lib/kfb-view.js +1 -1
- package/package.json +1 -1
- package/src/components/board/index.js +19 -2
- package/src/components/rotation/index.js +2 -0
- package/src/components/shape/index.js +39 -8
- package/src/index.js +2 -1
- package/src/model/label.model.js +8 -3
- package/src/tool/Arrow.js +2 -9
- package/src/tool/Bilateral.js +2 -9
- package/src/tool/Brush.js +14 -8
- package/src/tool/Combination.js +4 -3
- package/src/tool/Dot.js +3 -5
- package/src/tool/Ellipse.js +6 -14
- package/src/tool/Flag.js +2 -8
- package/src/tool/Font.js +2 -3
- package/src/tool/Line.js +2 -4
- package/src/tool/Polygon.js +6 -23
- package/src/tool/Rectangle.js +5 -14
- package/src/tool/Star.js +3 -6
- package/src/util/canvas.js +1 -4
- package/test.html +315 -0
package/test.html
ADDED
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<title>Title</title>
|
|
6
|
+
</head>
|
|
7
|
+
<body>
|
|
8
|
+
|
|
9
|
+
<canvas id="canvas" width="800" height="600"></canvas>
|
|
10
|
+
|
|
11
|
+
<script>
|
|
12
|
+
/**
|
|
13
|
+
* 清除圆形区域
|
|
14
|
+
* @param {number} x
|
|
15
|
+
* @param {number} y
|
|
16
|
+
* @param {number} radius
|
|
17
|
+
* @param {number=} [start=0]
|
|
18
|
+
* @param {number=} [end=Math.PI * 2]
|
|
19
|
+
*/
|
|
20
|
+
CanvasRenderingContext2D.prototype.clearArc =
|
|
21
|
+
function clearArc(x, y, radius, start = 0, end = Math.PI * 2) {
|
|
22
|
+
this.beginPath();
|
|
23
|
+
this.save();
|
|
24
|
+
this.arc(x, y, radius, start, end);
|
|
25
|
+
this.clip();
|
|
26
|
+
this.clearRect(x - radius, y - radius, (radius) * 2, (radius) * 2);
|
|
27
|
+
this.restore();
|
|
28
|
+
this.closePath();
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* 画箭头
|
|
33
|
+
* @param {Object} p1 线起始点
|
|
34
|
+
* @param {Object} p2 线结束点
|
|
35
|
+
* @param {number=} [theta=30] 箭头与线的夹角
|
|
36
|
+
* @param {number=} [headlen=10] 箭头的长度
|
|
37
|
+
*/
|
|
38
|
+
CanvasRenderingContext2D.prototype.drawArrow = function drawArrow(
|
|
39
|
+
p1, p2, theta = 30, headlen = 10) {
|
|
40
|
+
const angle = Math.atan2(p1.y - p2.y, p1.x - p2.x) * 180 / Math.PI;
|
|
41
|
+
const angle1 = (angle + theta) * Math.PI / 180;
|
|
42
|
+
const angle2 = (angle - theta) * Math.PI / 180;
|
|
43
|
+
const topX = headlen * Math.cos(angle1);
|
|
44
|
+
const topY = headlen * Math.sin(angle1);
|
|
45
|
+
const botX = headlen * Math.cos(angle2);
|
|
46
|
+
const botY = headlen * Math.sin(angle2);
|
|
47
|
+
let arrowX = p1.x - topX;
|
|
48
|
+
let arrowY = p2.y - topY;
|
|
49
|
+
this.moveTo(arrowX, arrowY);
|
|
50
|
+
this.moveTo(p1.x, p1.y);
|
|
51
|
+
this.lineTo(p2.x, p2.y);
|
|
52
|
+
arrowX = p2.x + topX;
|
|
53
|
+
arrowY = p2.y + topY;
|
|
54
|
+
this.moveTo(arrowX, arrowY);
|
|
55
|
+
this.lineTo(p2.x, p2.y);
|
|
56
|
+
arrowX = p2.x + botX;
|
|
57
|
+
arrowY = p2.y + botY;
|
|
58
|
+
this.lineTo(arrowX, arrowY);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* 绘制椭圆
|
|
63
|
+
* @param {number} x 椭圆中心横坐标,
|
|
64
|
+
* @param {number} y 椭圆中心纵坐标
|
|
65
|
+
* @param {number} a 椭圆横半轴长
|
|
66
|
+
* @param {number} b 椭圆纵半轴长
|
|
67
|
+
* @param {boolean=} [anticlockwise=true] false为顺时针,true为逆时针
|
|
68
|
+
*/
|
|
69
|
+
CanvasRenderingContext2D.prototype.drawOval = function drawOval(
|
|
70
|
+
x, y, a, b, anticlockwise = true) {
|
|
71
|
+
this.save();
|
|
72
|
+
// 选择a、b中的较大者作为arc方法的半径参数
|
|
73
|
+
const r = (a > b) ? a : b;
|
|
74
|
+
const ratioX = a / r; // 横轴缩放比率
|
|
75
|
+
const ratioY = b / r; // 纵轴缩放比率
|
|
76
|
+
this.scale(ratioX, ratioY); // 进行缩放(均匀压缩)
|
|
77
|
+
// 从椭圆的左端点开始逆时针绘制
|
|
78
|
+
this.moveTo((x + a) / ratioX, y / ratioY);
|
|
79
|
+
this.arc(x / ratioX, y / ratioY, r, 0, 2 * Math.PI, anticlockwise);
|
|
80
|
+
this.closePath();
|
|
81
|
+
this.restore();
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* 画多边形
|
|
86
|
+
* @param {Array} points 多边形所有的点
|
|
87
|
+
* @param {boolean=} [close=true] 是否是闭合多边形
|
|
88
|
+
* @param {boolean=} [anticlockwise=true] false为顺时针,true为逆时针
|
|
89
|
+
*/
|
|
90
|
+
CanvasRenderingContext2D.prototype.drawPolygon = function drawPolygon(
|
|
91
|
+
points, close = true, anticlockwise = true) {
|
|
92
|
+
let _points = [...points];
|
|
93
|
+
// Green公式,判断连续点组成的多边形是逆时针还是顺时针
|
|
94
|
+
let d = 0;
|
|
95
|
+
for (let i = 0; i < points.length - 1; i++) {
|
|
96
|
+
d += -0.5 * (points[i + 1].y + points[i].y) *
|
|
97
|
+
(points[i + 1].x - points[i].x);
|
|
98
|
+
}
|
|
99
|
+
// 顺时针
|
|
100
|
+
if (d > 0) {
|
|
101
|
+
if (anticlockwise) {
|
|
102
|
+
_points.reverse();
|
|
103
|
+
}
|
|
104
|
+
} else {
|
|
105
|
+
// 逆时针
|
|
106
|
+
if (!anticlockwise) {
|
|
107
|
+
_points.reverse();
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
this.moveTo(_points[0].x, _points[0].y);
|
|
111
|
+
_points.forEach((point) => {
|
|
112
|
+
this.lineTo(point.x, point.y);
|
|
113
|
+
});
|
|
114
|
+
if (close) {
|
|
115
|
+
this.lineTo(_points[0].x, _points[0].y);
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
// eslint-disable-next-line require-jsdoc
|
|
120
|
+
class BezierCurve {
|
|
121
|
+
// eslint-disable-next-line require-jsdoc
|
|
122
|
+
constructor(points) {
|
|
123
|
+
this.points = points;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// eslint-disable-next-line require-jsdoc
|
|
127
|
+
calculationPoint(t) {
|
|
128
|
+
const n = this.points.length - 1;
|
|
129
|
+
const point = {x: 0, y: 0};
|
|
130
|
+
this.points.forEach((item, index) => {
|
|
131
|
+
if (!index) {
|
|
132
|
+
point.x += item.x * Math.pow((1 - t), n - index) * Math.pow(t, index);
|
|
133
|
+
point.y += item.y * Math.pow((1 - t), n - index) * Math.pow(t, index);
|
|
134
|
+
} else {
|
|
135
|
+
point.x += this.factorial(n) / this.factorial(index) /
|
|
136
|
+
this.factorial(n - index) * item.x * Math.pow((1 - t), n - index) *
|
|
137
|
+
Math.pow(t, index);
|
|
138
|
+
point.y += this.factorial(n) / this.factorial(index) /
|
|
139
|
+
this.factorial(n - index) * item.y * Math.pow((1 - t), n - index) *
|
|
140
|
+
Math.pow(t, index);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
return point;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// eslint-disable-next-line require-jsdoc
|
|
147
|
+
factorial(num) {
|
|
148
|
+
if (num <= 1) {
|
|
149
|
+
return 1;
|
|
150
|
+
} else {
|
|
151
|
+
return num * this.factorial(num - 1);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* 绘制多次贝赛尔曲线
|
|
158
|
+
*/
|
|
159
|
+
CanvasRenderingContext2D.prototype.bezierCurve = function(...rest) {
|
|
160
|
+
if (rest.length === 1) {
|
|
161
|
+
const points = rest[0];
|
|
162
|
+
if (Array.isArray(points)) {
|
|
163
|
+
if (points.length === 1 || points.length === 0) {
|
|
164
|
+
throw new SyntaxError('Parameter length greater than 1');
|
|
165
|
+
}
|
|
166
|
+
if (points.length === 2) {
|
|
167
|
+
this.moveTo(points[0].x, points[0].y);
|
|
168
|
+
this.lineTo(points[1].x, points[1].y);
|
|
169
|
+
this.stroke();
|
|
170
|
+
}
|
|
171
|
+
if (points.length === 3) {
|
|
172
|
+
const startPoint = points[0];
|
|
173
|
+
this.moveTo(startPoint.x, startPoint.y);
|
|
174
|
+
this.quadraticCurveTo(points[1].x, points[1].y, points[2].x,
|
|
175
|
+
points[2].y);
|
|
176
|
+
this.stroke();
|
|
177
|
+
} else if (points.length === 4) {
|
|
178
|
+
const startPoint = points[0];
|
|
179
|
+
this.moveTo(startPoint.x, startPoint.y);
|
|
180
|
+
this.bezierCurveTo(points[1].x, points[1].y, points[2].x, points[2].y,
|
|
181
|
+
points[3].x, points[3].y);
|
|
182
|
+
this.stroke();
|
|
183
|
+
} else {
|
|
184
|
+
const bezierCurve = new BezierCurve(points);
|
|
185
|
+
const calculationPoints = [...new Array(101)].map(
|
|
186
|
+
(item, index) => bezierCurve.calculationPoint(index / 100));
|
|
187
|
+
for (let t = 1; t < 101; t++) {
|
|
188
|
+
this.moveTo(calculationPoints[t - 1].x, calculationPoints[t - 1].y);
|
|
189
|
+
this.lineTo(calculationPoints[t].x, calculationPoints[t].y);
|
|
190
|
+
this.stroke();
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
} else {
|
|
194
|
+
throw new SyntaxError('parameter error');
|
|
195
|
+
}
|
|
196
|
+
} else if (rest.length === 4) {
|
|
197
|
+
this.quadraticCurveTo(rest[0], rest[1], rest[2], rest[3]);
|
|
198
|
+
} else if (rest.length === 6) {
|
|
199
|
+
this.bezierCurveTo(rest[0], rest[1], rest[2], rest[3], rest[4], rest[5]);
|
|
200
|
+
} else {
|
|
201
|
+
throw new SyntaxError('parameter error');
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
</script>
|
|
207
|
+
<script>
|
|
208
|
+
const canvas = document.getElementById('canvas');
|
|
209
|
+
const ctx = canvas.getContext('2d');
|
|
210
|
+
ctx.beginPath();
|
|
211
|
+
|
|
212
|
+
drawA([{x: 10, y: 10}, {x: 50, y: 40}]);
|
|
213
|
+
drawA([{x: 70, y: 70}, {x: 120, y: 120}]);
|
|
214
|
+
|
|
215
|
+
drawB([{x: 130, y: 130}, {x: 90, y: 60}]);
|
|
216
|
+
drawB([{x: 20, y: 20}, {x: 20, y: 90}]);
|
|
217
|
+
drawF([{x: 300, y: 200}]);
|
|
218
|
+
drawF([{x: 100, y: 500}]);
|
|
219
|
+
|
|
220
|
+
function drawA(points) {
|
|
221
|
+
const startPoint = points[0];
|
|
222
|
+
const endPoint = points[points.length - 1];
|
|
223
|
+
ctx.lineWidth = 2;
|
|
224
|
+
ctx.strokeStyle = '#0000FF';
|
|
225
|
+
ctx.moveTo(startPoint.x, startPoint.y);
|
|
226
|
+
ctx.lineTo(endPoint.x, endPoint.y);
|
|
227
|
+
ctx.drawArrow(startPoint, endPoint);
|
|
228
|
+
ctx.stroke();
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function drawB(points) {
|
|
232
|
+
const startPoint = points[0];
|
|
233
|
+
const endPoint = points[points.length - 1];
|
|
234
|
+
ctx.lineWidth = 2;
|
|
235
|
+
ctx.strokeStyle = '#00FF00';
|
|
236
|
+
ctx.moveTo(startPoint.x, startPoint.y);
|
|
237
|
+
ctx.lineTo(endPoint.x, endPoint.y);
|
|
238
|
+
ctx.drawArrow(startPoint, endPoint);
|
|
239
|
+
ctx.drawArrow(endPoint, startPoint);
|
|
240
|
+
ctx.stroke();
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
function drawF(points, scale = 1) {
|
|
244
|
+
let dist = 30;
|
|
245
|
+
dist *= scale;
|
|
246
|
+
const point = points[0];
|
|
247
|
+
ctx.lineWidth = 2;
|
|
248
|
+
ctx.strokeStyle = '#0000FF';
|
|
249
|
+
ctx.moveTo(point.x, point.y);
|
|
250
|
+
ctx.lineTo(point.x, point.y - dist);
|
|
251
|
+
const _dist = dist / 5;
|
|
252
|
+
const p1 = {
|
|
253
|
+
x: point.x + _dist,
|
|
254
|
+
y: point.y - dist,
|
|
255
|
+
};
|
|
256
|
+
const p2 = {
|
|
257
|
+
x: point.x + _dist * 2,
|
|
258
|
+
y: point.y - dist - _dist,
|
|
259
|
+
};
|
|
260
|
+
const p3 = {
|
|
261
|
+
x: point.x + _dist * 4,
|
|
262
|
+
y: point.y - dist + _dist,
|
|
263
|
+
};
|
|
264
|
+
const p4 = {
|
|
265
|
+
x: point.x + dist,
|
|
266
|
+
y: point.y - dist,
|
|
267
|
+
};
|
|
268
|
+
ctx.bezierCurve([p1, p2, p3, p4]);
|
|
269
|
+
ctx.moveTo(p4.x, p4.y);
|
|
270
|
+
ctx.lineTo(p4.x, p4.y + dist / 2);
|
|
271
|
+
const p11 = {
|
|
272
|
+
x: point.x + _dist,
|
|
273
|
+
y: point.y - dist / 2,
|
|
274
|
+
};
|
|
275
|
+
const p22 = {
|
|
276
|
+
x: point.x + _dist * 2,
|
|
277
|
+
y: point.y - dist / 2 - _dist,
|
|
278
|
+
};
|
|
279
|
+
const p33 = {
|
|
280
|
+
x: point.x + _dist * 4,
|
|
281
|
+
y: point.y - dist / 2 + _dist,
|
|
282
|
+
};
|
|
283
|
+
const p44 = {
|
|
284
|
+
x: point.x + dist,
|
|
285
|
+
y: point.y - dist / 2,
|
|
286
|
+
};
|
|
287
|
+
ctx.bezierCurve([p11, p22, p33, p44]);
|
|
288
|
+
ctx.moveTo(p1.x, p1.y);
|
|
289
|
+
ctx.lineTo(p11.x, p11.y);
|
|
290
|
+
ctx.stroke();
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
console.log(new Date().getTime());
|
|
294
|
+
console.time('draw');
|
|
295
|
+
ctx.fillStyle = '#ff0000';
|
|
296
|
+
ctx.strokeStyle = '#00ff00';
|
|
297
|
+
ctx.lineWidth = 2;
|
|
298
|
+
ctx.beginPath();
|
|
299
|
+
for (let i = 0; i < 800; i++) {
|
|
300
|
+
for (let j = 0; j < 600; j++) {
|
|
301
|
+
if (i % 50 === 0 && j % 50 === 0) {
|
|
302
|
+
ctx.moveTo(i + 4, j);
|
|
303
|
+
ctx.arc(i, j, 4, 0, Math.PI * 2, !1);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
ctx.fill();
|
|
308
|
+
ctx.stroke();
|
|
309
|
+
console.timeEnd('draw');
|
|
310
|
+
console.log(new Date().getTime());
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
</script>
|
|
314
|
+
</body>
|
|
315
|
+
</html>
|