jmgraph 3.2.16 → 3.2.18
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/LICENSE +21 -21
- package/README.md +251 -428
- package/build/gulpfile.js +142 -142
- package/build/package-lock.json +10666 -0
- package/build/package.json +71 -71
- package/dev.js +9 -9
- package/dist/jmgraph.core.min.js +1 -1
- package/dist/jmgraph.core.min.js.map +1 -1
- package/dist/jmgraph.js +3500 -2668
- package/dist/jmgraph.min.js +1 -1
- package/example/ball.html +216 -216
- package/example/base.html +111 -111
- package/example/canvas.html +53 -53
- package/example/cell.html +283 -283
- package/example/controls/arc.html +128 -128
- package/example/controls/arrowline.html +77 -77
- package/example/controls/bezier.html +298 -298
- package/example/controls/img.html +96 -96
- package/example/controls/label.html +86 -86
- package/example/controls/line.html +172 -172
- package/example/controls/prismatic.html +62 -62
- package/example/controls/rect.html +63 -63
- package/example/controls/resize.html +111 -111
- package/example/controls/test.html +359 -359
- package/example/es.html +69 -69
- package/example/es5module.html +62 -63
- package/example/heartarc.html +115 -115
- package/example/index.html +46 -46
- package/example/js/require.js +4 -4
- package/example/love/img/bling/bling.tps +265 -265
- package/example/love/img/bling.json +87 -87
- package/example/love/img/bling.tps +295 -295
- package/example/love/img/love.json +95 -95
- package/example/love/img/love.tps +315 -315
- package/example/love/img/qq/qq.tps +399 -399
- package/example/love/img/qq.json +242 -242
- package/example/love/index.html +40 -40
- package/example/love/js/game.js +558 -558
- package/example/music.html +210 -210
- package/example/node/test.js +137 -137
- package/example/pdf.html +186 -186
- package/example/progress.html +172 -172
- package/example/pso.html +147 -147
- package/example/sort.html +804 -815
- package/example/tweenjs.html +83 -83
- package/example/webgl.html +278 -278
- package/example/xfj/index.html +331 -331
- package/example/xfj/shake.js +48 -48
- package/example/xfj/testori.html +75 -75
- package/index.js +99 -99
- package/package.json +58 -56
- package/src/core/jmControl.js +1376 -1531
- package/src/core/jmEvents.js +240 -281
- package/src/core/jmGradient.js +231 -231
- package/src/core/jmGraph.js +569 -569
- package/src/core/jmList.js +92 -157
- package/src/core/jmObject.js +83 -103
- package/src/core/jmPath.js +35 -35
- package/src/core/jmProperty.js +71 -110
- package/src/core/jmShadow.js +65 -65
- package/src/core/jmUtils.js +906 -919
- package/src/lib/earcut.js +680 -680
- package/src/lib/earcut.md +73 -73
- package/src/lib/webgl/base.js +522 -452
- package/src/lib/webgl/core/buffer.js +48 -48
- package/src/lib/webgl/core/mapSize.js +40 -40
- package/src/lib/webgl/core/mapType.js +43 -43
- package/src/lib/webgl/core/program.js +138 -138
- package/src/lib/webgl/core/shader.js +13 -13
- package/src/lib/webgl/core/texture.js +60 -60
- package/src/lib/webgl/gradient.js +168 -168
- package/src/lib/webgl/index.js +137 -11
- package/src/lib/webgl/path.js +568 -561
- package/src/shapes/jmArrowLine.js +36 -36
- package/src/shapes/jmImage.js +244 -244
- package/src/shapes/jmLabel.js +271 -271
- package/src/shapes/jmResize.js +332 -330
package/src/core/jmGraph.js
CHANGED
|
@@ -1,569 +1,569 @@
|
|
|
1
|
-
import {jmUtils} from "./jmUtils.js";
|
|
2
|
-
import {jmList} from "./jmList.js";
|
|
3
|
-
import {jmProperty} from './jmProperty.js';
|
|
4
|
-
import {jmShadow} from "./jmShadow.js";
|
|
5
|
-
import {jmGradient} from "./jmGradient.js";
|
|
6
|
-
import {jmEvents} from "./jmEvents.js";
|
|
7
|
-
import {jmControl} from "./jmControl.js";
|
|
8
|
-
import {jmPath} from "./jmPath.js";
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* jmGraph画图类库
|
|
12
|
-
* 对canvas画图api进行二次封装,使其更易调用,省去很多重复的工作。
|
|
13
|
-
*
|
|
14
|
-
* @module jmGraph
|
|
15
|
-
* @class jmGraph
|
|
16
|
-
* @extends jmControl
|
|
17
|
-
* @param {element} canvas 标签canvas
|
|
18
|
-
* @param {object} option 参数:{width:宽,height:高}
|
|
19
|
-
* @param {function} callback 初始化后的回调
|
|
20
|
-
*/
|
|
21
|
-
export default class jmGraph extends jmControl {
|
|
22
|
-
|
|
23
|
-
constructor(canvas, option, callback) {
|
|
24
|
-
if(typeof option == 'function') {
|
|
25
|
-
callback = option;
|
|
26
|
-
option = {};
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
option = option || {};
|
|
30
|
-
//option.mode = '2d'; // webgl | 2d 暂不支持webgl
|
|
31
|
-
option.interactive = true;
|
|
32
|
-
option.isRegular = true;// 规则的
|
|
33
|
-
|
|
34
|
-
super(option, 'jmGraph');
|
|
35
|
-
|
|
36
|
-
this.option = option || {};
|
|
37
|
-
|
|
38
|
-
this.devicePixelRatio = 1; // 根据屏幕的缩放倍数
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* 工具类
|
|
42
|
-
* @property utils/util
|
|
43
|
-
* @type {jmUtils}
|
|
44
|
-
*/
|
|
45
|
-
this.util = this.utils = jmUtils;
|
|
46
|
-
// 模式 webgl | 2d
|
|
47
|
-
this.mode = option.mode || '2d';
|
|
48
|
-
|
|
49
|
-
//如果是小程序
|
|
50
|
-
if(typeof wx != 'undefined' && wx.canIUse && wx.canIUse('canvas')) {
|
|
51
|
-
if(typeof canvas === 'string') canvas = wx.createSelectorQuery().select('#' + canvas);
|
|
52
|
-
this.isWXMiniApp = true;// 微信小程序平台
|
|
53
|
-
this.container = canvas;
|
|
54
|
-
}
|
|
55
|
-
else {
|
|
56
|
-
if(typeof canvas === 'string' && typeof document != 'undefined') {
|
|
57
|
-
canvas = document.getElementById(canvas);
|
|
58
|
-
}
|
|
59
|
-
else if(canvas.length) {
|
|
60
|
-
canvas = canvas[0];
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if(!canvas.getContext && typeof document != 'undefined') {
|
|
64
|
-
this.container = canvas;
|
|
65
|
-
let cn = document.createElement('canvas');
|
|
66
|
-
canvas.appendChild(cn);
|
|
67
|
-
cn.width = canvas.offsetWidth||canvas.clientWidth;
|
|
68
|
-
cn.height = canvas.offsetHeight||canvas.clientHeight;
|
|
69
|
-
canvas = cn;
|
|
70
|
-
}
|
|
71
|
-
else {
|
|
72
|
-
this.container = canvas.parentElement;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
this.canvas = canvas;
|
|
76
|
-
this.context = canvas.getContext(this.mode);
|
|
77
|
-
|
|
78
|
-
this.textureCanvas = option.textureCanvas || null;
|
|
79
|
-
|
|
80
|
-
// webgl模式
|
|
81
|
-
if(this.mode === 'webgl') {
|
|
82
|
-
|
|
83
|
-
this.context.enable(this.context.BLEND);// 开启混合功能:(注意,它不可和gl.DEPTH_TEST一起使用)
|
|
84
|
-
this.context.blendFunc(this.context.SRC_ALPHA, this.context.ONE_MINUS_SRC_ALPHA); // 指定混合函数:
|
|
85
|
-
// webglcontextlost webglcontextrestored
|
|
86
|
-
jmUtils.bindEvent(canvas, 'webglcontextlost', (e)=> {
|
|
87
|
-
console.log('canvas webglcontextlost', e);
|
|
88
|
-
this.emit('webglcontextlost', e);
|
|
89
|
-
});
|
|
90
|
-
jmUtils.bindEvent(canvas, 'webglcontextrestored', (e)=> {
|
|
91
|
-
console.log('canvas webglcontextrestored', e);
|
|
92
|
-
this.emit('webglcontextrestored', e);
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
this.__init(callback);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* 初始化画布
|
|
100
|
-
* @method init
|
|
101
|
-
*/
|
|
102
|
-
__init(callback) {
|
|
103
|
-
/**
|
|
104
|
-
* 当前所有图形类型
|
|
105
|
-
* @property shapes
|
|
106
|
-
* @type {object}
|
|
107
|
-
*/
|
|
108
|
-
this.shapes = Object.assign({
|
|
109
|
-
"path": jmPath,
|
|
110
|
-
}, this.option.shapes);
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* 画控件前初始化
|
|
114
|
-
* 为了解决一像素线条问题
|
|
115
|
-
*/
|
|
116
|
-
this.on('beginDraw', function() {
|
|
117
|
-
this.context.translate && this.context.translate(0.5, 0.5);
|
|
118
|
-
});
|
|
119
|
-
/**
|
|
120
|
-
* 结束控件绘制 为了解决一像素线条问题
|
|
121
|
-
*/
|
|
122
|
-
this.on('endDraw', function() {
|
|
123
|
-
this.context.translate && this.context.translate(-0.5, -0.5);
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
// devicePixelRatio初始化
|
|
127
|
-
let dpr = typeof window != 'undefined' && window.devicePixelRatio > 1? window.devicePixelRatio : 1;
|
|
128
|
-
if(this.isWXMiniApp) {
|
|
129
|
-
dpr = wx.getWindowInfo().pixelRatio || 1;
|
|
130
|
-
}
|
|
131
|
-
this.devicePixelRatio = dpr;
|
|
132
|
-
// 为了解决锯齿问题,先放大canvas再缩放
|
|
133
|
-
this.dprScaleSize = this.devicePixelRatio > 1? this.devicePixelRatio : 2;
|
|
134
|
-
|
|
135
|
-
if(this.option.width > 0) this.width = this.option.width;
|
|
136
|
-
if(this.option.height > 0) this.height = this.option.height;
|
|
137
|
-
this.resize();
|
|
138
|
-
|
|
139
|
-
//绑定事件
|
|
140
|
-
this.eventHandler = new jmEvents(this, this.canvas.canvas || this.canvas);
|
|
141
|
-
|
|
142
|
-
//如果指定了自动刷新
|
|
143
|
-
if(this.option.autoRefresh) {
|
|
144
|
-
this.autoRefresh();
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
if(callback) callback(this);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// 重置canvas大小,并判断高清屏,画图先放大二倍
|
|
151
|
-
resize(w, h) {
|
|
152
|
-
if(!this.canvas) return;
|
|
153
|
-
|
|
154
|
-
this.__normalSize = this.__normalSize || { width: 0, height: 0};
|
|
155
|
-
w = w || this.__normalSize.width || this.width, h = h || this.__normalSize.height || this.height;
|
|
156
|
-
|
|
157
|
-
if(w) this.__normalSize.width = w;
|
|
158
|
-
if(h) this.__normalSize.height = h;
|
|
159
|
-
|
|
160
|
-
this.css('width', w + "px");
|
|
161
|
-
this.css('height', h + "px");
|
|
162
|
-
if(this.mode === '2d') {
|
|
163
|
-
this.canvas.height = h * this.dprScaleSize;
|
|
164
|
-
this.canvas.width = w * this.dprScaleSize;
|
|
165
|
-
if(this.dprScaleSize !== 1) this.context.scale && this.context.scale(this.dprScaleSize, this.dprScaleSize);
|
|
166
|
-
}
|
|
167
|
-
else {
|
|
168
|
-
this.canvas.width = w;
|
|
169
|
-
this.canvas.height = h;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
this.context.viewport && this.context.viewport(0, 0, w, h);
|
|
173
|
-
this.needUpdate = true;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* 宽度
|
|
178
|
-
* @property width
|
|
179
|
-
* @type {number}
|
|
180
|
-
*/
|
|
181
|
-
get width() {
|
|
182
|
-
if(this.__normalSize && this.__normalSize.width) return this.__normalSize.width;
|
|
183
|
-
if(this.canvas) return this.canvas.width;
|
|
184
|
-
return 0;
|
|
185
|
-
}
|
|
186
|
-
set width(v) {
|
|
187
|
-
this.needUpdate = true;
|
|
188
|
-
if(this.canvas) {
|
|
189
|
-
this.resize(v);
|
|
190
|
-
}
|
|
191
|
-
return v;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* 高度
|
|
196
|
-
* @property height
|
|
197
|
-
* @type {number}
|
|
198
|
-
*/
|
|
199
|
-
get height() {
|
|
200
|
-
if(this.__normalSize && this.__normalSize.height) return this.__normalSize.height;
|
|
201
|
-
if(this.canvas) return this.canvas.height;
|
|
202
|
-
return 0;
|
|
203
|
-
}
|
|
204
|
-
set height(v) {
|
|
205
|
-
this.needUpdate = true;
|
|
206
|
-
if(this.canvas) {
|
|
207
|
-
this.resize(0, v);
|
|
208
|
-
}
|
|
209
|
-
return v;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* 创建jmGraph的静态对象
|
|
214
|
-
*
|
|
215
|
-
* @method create
|
|
216
|
-
* @return {jmGraph} jmGraph实例对象
|
|
217
|
-
*/
|
|
218
|
-
static create(...args) {
|
|
219
|
-
return new jmGraph(...args);
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
* 获取当前画布在浏览器中的绝对定位
|
|
224
|
-
*
|
|
225
|
-
* @method getPosition
|
|
226
|
-
* @return {postion} 返回定位坐标
|
|
227
|
-
*/
|
|
228
|
-
getPosition() {
|
|
229
|
-
const p = this.isWXMiniApp? {
|
|
230
|
-
left: 0,
|
|
231
|
-
top: 0
|
|
232
|
-
} :jmUtils.getElementPosition(this.canvas.canvas || this.canvas);
|
|
233
|
-
|
|
234
|
-
p.width = this.width;
|
|
235
|
-
p.height = this.height;
|
|
236
|
-
p.right = p.left + p.width;
|
|
237
|
-
p.bottom = p.top + p.height;
|
|
238
|
-
return p;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
/**
|
|
242
|
-
* 注册图形类型,图形类型必需有统一的构造函数。参数为画布句柄和参数对象。
|
|
243
|
-
*
|
|
244
|
-
* @method registerShape
|
|
245
|
-
* @param {string} name 控件图形名称
|
|
246
|
-
* @param {class} shape 图形控件类型
|
|
247
|
-
*/
|
|
248
|
-
registerShape(name, shape) {
|
|
249
|
-
this.shapes[name] = shape;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
/**
|
|
253
|
-
* 从已注册的图形类创建图形
|
|
254
|
-
* 简单直观创建对象
|
|
255
|
-
*
|
|
256
|
-
* @method createShape
|
|
257
|
-
* @param {string} shape 注册控件的名称 也可以直接是控件类型
|
|
258
|
-
* @param {object} args 实例化控件的参数
|
|
259
|
-
* @return {object} 已实例化控件的对象
|
|
260
|
-
*/
|
|
261
|
-
createShape(shape, args) {
|
|
262
|
-
if(typeof shape === 'string') {
|
|
263
|
-
shape = this.shapes[shape];
|
|
264
|
-
}
|
|
265
|
-
if(shape) {
|
|
266
|
-
if(!args) args = {};
|
|
267
|
-
args.graph = this;
|
|
268
|
-
let obj = new shape(args);
|
|
269
|
-
return obj;
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
/**
|
|
274
|
-
* 生成阴影对象
|
|
275
|
-
*
|
|
276
|
-
* @method createShadow
|
|
277
|
-
* @param {number} x x偏移量
|
|
278
|
-
* @param {number} y y偏移量
|
|
279
|
-
* @param {number} blur 模糊值
|
|
280
|
-
* @param {string} color 颜色
|
|
281
|
-
* @return {jmShadow} 阴影对象
|
|
282
|
-
*/
|
|
283
|
-
createShadow(x, y, blur, color) {
|
|
284
|
-
const sh = new jmShadow(x, y, blur, color);
|
|
285
|
-
return sh;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
/**
|
|
289
|
-
* 生成线性渐变对象
|
|
290
|
-
*
|
|
291
|
-
* @method createLinearGradient
|
|
292
|
-
* @param {number} x1 线性渐变起始点X坐标
|
|
293
|
-
* @param {number} y1 线性渐变起始点Y坐标
|
|
294
|
-
* @param {number} x2 线性渐变结束点X坐标
|
|
295
|
-
* @param {number} y2 线性渐变结束点Y坐标
|
|
296
|
-
* @return {jmGradient} 线性渐变对象
|
|
297
|
-
*/
|
|
298
|
-
createLinearGradient(x1, y1, x2, y2, stops=[]) {
|
|
299
|
-
const gradient = new jmGradient({
|
|
300
|
-
type:'linear',
|
|
301
|
-
x1: x1,
|
|
302
|
-
y1: y1,
|
|
303
|
-
x2: x2,
|
|
304
|
-
y2: y2,
|
|
305
|
-
stops
|
|
306
|
-
});
|
|
307
|
-
return gradient;
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
/**
|
|
311
|
-
* 生成放射渐变对象
|
|
312
|
-
*
|
|
313
|
-
* @method createRadialGradient
|
|
314
|
-
* @param {number} x1 放射渐变小圆中心X坐标
|
|
315
|
-
* @param {number} y1 放射渐变小圆中心Y坐标
|
|
316
|
-
* @param {number} r1 放射渐变小圆半径
|
|
317
|
-
* @param {number} x2 放射渐变大圆中心X坐标
|
|
318
|
-
* @param {number} y2 放射渐变大圆中心Y坐标
|
|
319
|
-
* @param {number} r2 放射渐变大圆半径
|
|
320
|
-
* @return {jmGradient} 放射渐变对象
|
|
321
|
-
*/
|
|
322
|
-
createRadialGradient(x1, y1, r1, x2, y2, r2, stops=[]) {
|
|
323
|
-
const gradient = new jmGradient({
|
|
324
|
-
type:'radial',
|
|
325
|
-
x1: x1,
|
|
326
|
-
y1: y1,
|
|
327
|
-
r1: r1,
|
|
328
|
-
x2: x2,
|
|
329
|
-
y2: y2,
|
|
330
|
-
r2: r2,
|
|
331
|
-
stops
|
|
332
|
-
});
|
|
333
|
-
return gradient;
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
/**
|
|
337
|
-
* 重新刷新整个画板
|
|
338
|
-
* 以加入动画事件触发延时10毫秒刷新,保存最尽的调用只刷新一次,加强性能的效果。
|
|
339
|
-
*
|
|
340
|
-
* @method refresh
|
|
341
|
-
*/
|
|
342
|
-
refresh() {
|
|
343
|
-
//加入动画,触发redraw,会导致多次refresh只redraw一次
|
|
344
|
-
/*this.animate(function() {
|
|
345
|
-
return false;
|
|
346
|
-
},100,'jmgraph_refresh');*/
|
|
347
|
-
this.redraw();
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
/**
|
|
351
|
-
* 重新刷新整个画板
|
|
352
|
-
* 此方法直接重画,与refresh效果类似
|
|
353
|
-
*
|
|
354
|
-
* @method redraw
|
|
355
|
-
* @param {number} [w] 清除画布的宽度
|
|
356
|
-
* @param {number} [h] 清除画布的高度
|
|
357
|
-
*/
|
|
358
|
-
redraw(w, h) {
|
|
359
|
-
this.clear(w||this.width, h||this.height);
|
|
360
|
-
this.paint();
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
/**
|
|
364
|
-
* 清除画布
|
|
365
|
-
*
|
|
366
|
-
* @method clear
|
|
367
|
-
* @param {number} [w] 清除画布的宽度
|
|
368
|
-
* @param {number} [h] 清除画布的高度
|
|
369
|
-
*/
|
|
370
|
-
clear(w, h) {
|
|
371
|
-
if(!w || !h) {
|
|
372
|
-
w = this.width;
|
|
373
|
-
h = this.height;
|
|
374
|
-
/*if(this.scaleSize) {
|
|
375
|
-
w = w / this.scaleSize.x;
|
|
376
|
-
h = h / this.scaleSize.y;
|
|
377
|
-
}*/
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
if(this.context.clearRect) {
|
|
381
|
-
if(this.style && this.style.fill) {
|
|
382
|
-
this.points = [
|
|
383
|
-
{x:0, y:0},
|
|
384
|
-
{x:w, y:0},
|
|
385
|
-
{x:w, y:h},
|
|
386
|
-
{x:0, y:h}
|
|
387
|
-
];
|
|
388
|
-
this.style.close = true;// 封闭填充
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
this.context.clearRect(0, 0, w, h);
|
|
392
|
-
}
|
|
393
|
-
else if(this.mode === 'webgl' && this.context.clear) {
|
|
394
|
-
const color = this.style && this.style.fill? this.utils.hexToRGBA(this.style.fill): {
|
|
395
|
-
r: 0,
|
|
396
|
-
g: 0,
|
|
397
|
-
b: 0,
|
|
398
|
-
a: 0
|
|
399
|
-
};
|
|
400
|
-
this.context.clearColor(color.r, color.g, color.b, color.a); // 设置清空颜色缓冲时的颜色值
|
|
401
|
-
this.context.clear(this.context.COLOR_BUFFER_BIT); // 清空颜色缓冲区,也就是清空画布
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
/**
|
|
406
|
-
* 设置画布样式,此处只是设置其css样式
|
|
407
|
-
*
|
|
408
|
-
* @method css
|
|
409
|
-
* @param {string} name 样式名
|
|
410
|
-
* @param {string} value 样式值
|
|
411
|
-
*/
|
|
412
|
-
css(name, value) {
|
|
413
|
-
if(this.canvas && this.canvas.style) {
|
|
414
|
-
if(typeof value != 'undefined') this.canvas.style[name] = value;
|
|
415
|
-
return this.canvas.style[name];
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
/**
|
|
420
|
-
* 生成路径对象
|
|
421
|
-
*
|
|
422
|
-
* @method createPath
|
|
423
|
-
* @param {array} points 路径中的描点集合
|
|
424
|
-
* @param {style} style 当前路径的样式
|
|
425
|
-
* @return {jmPath} 路径对象jmPath
|
|
426
|
-
*/
|
|
427
|
-
createPath(points, style, option={}) {
|
|
428
|
-
const path = this.createShape('path',{
|
|
429
|
-
points: points,
|
|
430
|
-
style: style,
|
|
431
|
-
...option
|
|
432
|
-
});
|
|
433
|
-
return path;
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
/**
|
|
437
|
-
* 生成直线
|
|
438
|
-
*
|
|
439
|
-
* @method createLine
|
|
440
|
-
* @param {point} start 直线的起点
|
|
441
|
-
* @param {point} end 直线的终点
|
|
442
|
-
* @param {style} 直线的样式
|
|
443
|
-
* @return {jmLine} 直线对象
|
|
444
|
-
*/
|
|
445
|
-
createLine(start, end, style) {
|
|
446
|
-
const line = this.createShape('line', {
|
|
447
|
-
start: start,
|
|
448
|
-
end: end,
|
|
449
|
-
style: style
|
|
450
|
-
});
|
|
451
|
-
return line;
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
/**
|
|
455
|
-
* 缩小整个画布按比例0.9
|
|
456
|
-
*
|
|
457
|
-
* @method zoomOut
|
|
458
|
-
*/
|
|
459
|
-
zoomOut() {
|
|
460
|
-
this.scale(0.9 ,0.9);
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
/**
|
|
464
|
-
* 放大 每次增大0.1的比例
|
|
465
|
-
*
|
|
466
|
-
* @method zoomIn
|
|
467
|
-
*/
|
|
468
|
-
zoomIn() {
|
|
469
|
-
this.scale(1.1 ,1.1);
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
/**
|
|
473
|
-
* 大小复原
|
|
474
|
-
*
|
|
475
|
-
* @method zoomActual
|
|
476
|
-
*/
|
|
477
|
-
zoomActual() {
|
|
478
|
-
if(this.scaleSize) {
|
|
479
|
-
this.scale(1 / this.scaleSize.x ,1 / this.scaleSize.y);
|
|
480
|
-
}
|
|
481
|
-
else {
|
|
482
|
-
this.scale(1 ,1);
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
/**
|
|
487
|
-
* 放大缩小画布
|
|
488
|
-
*
|
|
489
|
-
* @method scale
|
|
490
|
-
* @param {number} dx 缩放X轴比例
|
|
491
|
-
* @param {number} dy 缩放Y轴比例
|
|
492
|
-
*/
|
|
493
|
-
scale(dx, dy) {
|
|
494
|
-
if(!this.normalSize) {
|
|
495
|
-
this.normalSize = {
|
|
496
|
-
width: this.canvas.width,
|
|
497
|
-
height: this.canvas.height
|
|
498
|
-
};
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
//this.context.scale && this.context.scale(dx,dy);
|
|
502
|
-
if(!this.scaleSize) {
|
|
503
|
-
this.scaleSize = {x: 1,y: 1};
|
|
504
|
-
}
|
|
505
|
-
else {
|
|
506
|
-
this.scaleSize = {x: dx * this.scaleSize.x, y: dy * this.scaleSize.y};
|
|
507
|
-
}
|
|
508
|
-
this.canvas.style && (this.canvas.style.transform = `scale(${this.scaleSize.x}, ${this.scaleSize.y})`);
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
/**
|
|
512
|
-
* 保存为base64图形数据
|
|
513
|
-
*
|
|
514
|
-
* @method toDataURL
|
|
515
|
-
* @return {string} 当前画布图的base64字符串
|
|
516
|
-
*/
|
|
517
|
-
toDataURL() {
|
|
518
|
-
let data = this.canvas.toDataURL?this.canvas.toDataURL():'';
|
|
519
|
-
return data;
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
/**
|
|
523
|
-
* 自动刷新画版
|
|
524
|
-
* @param {function} callback 执行回调
|
|
525
|
-
*/
|
|
526
|
-
autoRefresh(callback) {
|
|
527
|
-
if(this.___isAutoRefreshing) return;
|
|
528
|
-
const self = this;
|
|
529
|
-
this.___isAutoRefreshing = true;
|
|
530
|
-
|
|
531
|
-
const refreshStartTime = Date.now();
|
|
532
|
-
function update() {
|
|
533
|
-
if(self.destroyed) {
|
|
534
|
-
self.___isAutoRefreshing = false;
|
|
535
|
-
return;// 已销毁
|
|
536
|
-
}
|
|
537
|
-
if(self.needUpdate) self.redraw();
|
|
538
|
-
|
|
539
|
-
const time = Date.now() - refreshStartTime;
|
|
540
|
-
// 触发刷新事件
|
|
541
|
-
self.emit('update', time);
|
|
542
|
-
|
|
543
|
-
self.__requestAnimationFrameFunHandler && self.cancelAnimationFrame(self.__requestAnimationFrameFunHandler);
|
|
544
|
-
self.__requestAnimationFrameFunHandler = self.requestAnimationFrame(update);
|
|
545
|
-
if(callback) callback();
|
|
546
|
-
}
|
|
547
|
-
self.__requestAnimationFrameFunHandler && this.cancelAnimationFrame(self.__requestAnimationFrameFunHandler);
|
|
548
|
-
self.__requestAnimationFrameFunHandler = this.requestAnimationFrame(update);
|
|
549
|
-
return this;
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
// 销毁当前对象
|
|
553
|
-
destroy() {
|
|
554
|
-
this.eventHandler.destroy();
|
|
555
|
-
this.destroyed = true;// 标记已销毁
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
export {
|
|
560
|
-
jmGraph,
|
|
561
|
-
jmUtils,
|
|
562
|
-
jmList,
|
|
563
|
-
jmProperty,
|
|
564
|
-
jmShadow,
|
|
565
|
-
jmGradient,
|
|
566
|
-
jmEvents,
|
|
567
|
-
jmControl,
|
|
568
|
-
jmPath,
|
|
569
|
-
};
|
|
1
|
+
import {jmUtils} from "./jmUtils.js";
|
|
2
|
+
import {jmList} from "./jmList.js";
|
|
3
|
+
import {jmProperty} from './jmProperty.js';
|
|
4
|
+
import {jmShadow} from "./jmShadow.js";
|
|
5
|
+
import {jmGradient} from "./jmGradient.js";
|
|
6
|
+
import {jmEvents} from "./jmEvents.js";
|
|
7
|
+
import {jmControl} from "./jmControl.js";
|
|
8
|
+
import {jmPath} from "./jmPath.js";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* jmGraph画图类库
|
|
12
|
+
* 对canvas画图api进行二次封装,使其更易调用,省去很多重复的工作。
|
|
13
|
+
*
|
|
14
|
+
* @module jmGraph
|
|
15
|
+
* @class jmGraph
|
|
16
|
+
* @extends jmControl
|
|
17
|
+
* @param {element} canvas 标签canvas
|
|
18
|
+
* @param {object} option 参数:{width:宽,height:高}
|
|
19
|
+
* @param {function} callback 初始化后的回调
|
|
20
|
+
*/
|
|
21
|
+
export default class jmGraph extends jmControl {
|
|
22
|
+
|
|
23
|
+
constructor(canvas, option, callback) {
|
|
24
|
+
if(typeof option == 'function') {
|
|
25
|
+
callback = option;
|
|
26
|
+
option = {};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
option = option || {};
|
|
30
|
+
//option.mode = '2d'; // webgl | 2d 暂不支持webgl
|
|
31
|
+
option.interactive = true;
|
|
32
|
+
option.isRegular = true;// 规则的
|
|
33
|
+
|
|
34
|
+
super(option, 'jmGraph');
|
|
35
|
+
|
|
36
|
+
this.option = option || {};
|
|
37
|
+
|
|
38
|
+
this.devicePixelRatio = 1; // 根据屏幕的缩放倍数
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* 工具类
|
|
42
|
+
* @property utils/util
|
|
43
|
+
* @type {jmUtils}
|
|
44
|
+
*/
|
|
45
|
+
this.util = this.utils = jmUtils;
|
|
46
|
+
// 模式 webgl | 2d
|
|
47
|
+
this.mode = option.mode || '2d';
|
|
48
|
+
|
|
49
|
+
//如果是小程序
|
|
50
|
+
if(typeof wx != 'undefined' && wx.canIUse && wx.canIUse('canvas')) {
|
|
51
|
+
if(typeof canvas === 'string') canvas = wx.createSelectorQuery().select('#' + canvas);
|
|
52
|
+
this.isWXMiniApp = true;// 微信小程序平台
|
|
53
|
+
this.container = canvas;
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
if(typeof canvas === 'string' && typeof document != 'undefined') {
|
|
57
|
+
canvas = document.getElementById(canvas);
|
|
58
|
+
}
|
|
59
|
+
else if(canvas.length) {
|
|
60
|
+
canvas = canvas[0];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if(!canvas.getContext && typeof document != 'undefined') {
|
|
64
|
+
this.container = canvas;
|
|
65
|
+
let cn = document.createElement('canvas');
|
|
66
|
+
canvas.appendChild(cn);
|
|
67
|
+
cn.width = canvas.offsetWidth||canvas.clientWidth;
|
|
68
|
+
cn.height = canvas.offsetHeight||canvas.clientHeight;
|
|
69
|
+
canvas = cn;
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
this.container = canvas.parentElement;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
this.canvas = canvas;
|
|
76
|
+
this.context = canvas.getContext(this.mode);
|
|
77
|
+
|
|
78
|
+
this.textureCanvas = option.textureCanvas || null;
|
|
79
|
+
|
|
80
|
+
// webgl模式
|
|
81
|
+
if(this.mode === 'webgl') {
|
|
82
|
+
|
|
83
|
+
this.context.enable(this.context.BLEND);// 开启混合功能:(注意,它不可和gl.DEPTH_TEST一起使用)
|
|
84
|
+
this.context.blendFunc(this.context.SRC_ALPHA, this.context.ONE_MINUS_SRC_ALPHA); // 指定混合函数:
|
|
85
|
+
// webglcontextlost webglcontextrestored
|
|
86
|
+
jmUtils.bindEvent(canvas, 'webglcontextlost', (e)=> {
|
|
87
|
+
console.log('canvas webglcontextlost', e);
|
|
88
|
+
this.emit('webglcontextlost', e);
|
|
89
|
+
});
|
|
90
|
+
jmUtils.bindEvent(canvas, 'webglcontextrestored', (e)=> {
|
|
91
|
+
console.log('canvas webglcontextrestored', e);
|
|
92
|
+
this.emit('webglcontextrestored', e);
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
this.__init(callback);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* 初始化画布
|
|
100
|
+
* @method init
|
|
101
|
+
*/
|
|
102
|
+
__init(callback) {
|
|
103
|
+
/**
|
|
104
|
+
* 当前所有图形类型
|
|
105
|
+
* @property shapes
|
|
106
|
+
* @type {object}
|
|
107
|
+
*/
|
|
108
|
+
this.shapes = Object.assign({
|
|
109
|
+
"path": jmPath,
|
|
110
|
+
}, this.option.shapes);
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* 画控件前初始化
|
|
114
|
+
* 为了解决一像素线条问题
|
|
115
|
+
*/
|
|
116
|
+
this.on('beginDraw', function() {
|
|
117
|
+
this.context.translate && this.context.translate(0.5, 0.5);
|
|
118
|
+
});
|
|
119
|
+
/**
|
|
120
|
+
* 结束控件绘制 为了解决一像素线条问题
|
|
121
|
+
*/
|
|
122
|
+
this.on('endDraw', function() {
|
|
123
|
+
this.context.translate && this.context.translate(-0.5, -0.5);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
// devicePixelRatio初始化
|
|
127
|
+
let dpr = typeof window != 'undefined' && window.devicePixelRatio > 1? window.devicePixelRatio : 1;
|
|
128
|
+
if(this.isWXMiniApp) {
|
|
129
|
+
dpr = wx.getWindowInfo().pixelRatio || 1;
|
|
130
|
+
}
|
|
131
|
+
this.devicePixelRatio = dpr;
|
|
132
|
+
// 为了解决锯齿问题,先放大canvas再缩放
|
|
133
|
+
this.dprScaleSize = this.devicePixelRatio > 1? this.devicePixelRatio : 2;
|
|
134
|
+
|
|
135
|
+
if(this.option.width > 0) this.width = this.option.width;
|
|
136
|
+
if(this.option.height > 0) this.height = this.option.height;
|
|
137
|
+
this.resize();
|
|
138
|
+
|
|
139
|
+
//绑定事件
|
|
140
|
+
this.eventHandler = new jmEvents(this, this.canvas.canvas || this.canvas);
|
|
141
|
+
|
|
142
|
+
//如果指定了自动刷新
|
|
143
|
+
if(this.option.autoRefresh) {
|
|
144
|
+
this.autoRefresh();
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if(callback) callback(this);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// 重置canvas大小,并判断高清屏,画图先放大二倍
|
|
151
|
+
resize(w, h) {
|
|
152
|
+
if(!this.canvas) return;
|
|
153
|
+
|
|
154
|
+
this.__normalSize = this.__normalSize || { width: 0, height: 0};
|
|
155
|
+
w = w || this.__normalSize.width || this.width, h = h || this.__normalSize.height || this.height;
|
|
156
|
+
|
|
157
|
+
if(w) this.__normalSize.width = w;
|
|
158
|
+
if(h) this.__normalSize.height = h;
|
|
159
|
+
|
|
160
|
+
this.css('width', w + "px");
|
|
161
|
+
this.css('height', h + "px");
|
|
162
|
+
if(this.mode === '2d') {
|
|
163
|
+
this.canvas.height = h * this.dprScaleSize;
|
|
164
|
+
this.canvas.width = w * this.dprScaleSize;
|
|
165
|
+
if(this.dprScaleSize !== 1) this.context.scale && this.context.scale(this.dprScaleSize, this.dprScaleSize);
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
this.canvas.width = w;
|
|
169
|
+
this.canvas.height = h;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
this.context.viewport && this.context.viewport(0, 0, w, h);
|
|
173
|
+
this.needUpdate = true;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* 宽度
|
|
178
|
+
* @property width
|
|
179
|
+
* @type {number}
|
|
180
|
+
*/
|
|
181
|
+
get width() {
|
|
182
|
+
if(this.__normalSize && this.__normalSize.width) return this.__normalSize.width;
|
|
183
|
+
if(this.canvas) return this.canvas.width;
|
|
184
|
+
return 0;
|
|
185
|
+
}
|
|
186
|
+
set width(v) {
|
|
187
|
+
this.needUpdate = true;
|
|
188
|
+
if(this.canvas) {
|
|
189
|
+
this.resize(v);
|
|
190
|
+
}
|
|
191
|
+
return v;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* 高度
|
|
196
|
+
* @property height
|
|
197
|
+
* @type {number}
|
|
198
|
+
*/
|
|
199
|
+
get height() {
|
|
200
|
+
if(this.__normalSize && this.__normalSize.height) return this.__normalSize.height;
|
|
201
|
+
if(this.canvas) return this.canvas.height;
|
|
202
|
+
return 0;
|
|
203
|
+
}
|
|
204
|
+
set height(v) {
|
|
205
|
+
this.needUpdate = true;
|
|
206
|
+
if(this.canvas) {
|
|
207
|
+
this.resize(0, v);
|
|
208
|
+
}
|
|
209
|
+
return v;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* 创建jmGraph的静态对象
|
|
214
|
+
*
|
|
215
|
+
* @method create
|
|
216
|
+
* @return {jmGraph} jmGraph实例对象
|
|
217
|
+
*/
|
|
218
|
+
static create(...args) {
|
|
219
|
+
return new jmGraph(...args);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* 获取当前画布在浏览器中的绝对定位
|
|
224
|
+
*
|
|
225
|
+
* @method getPosition
|
|
226
|
+
* @return {postion} 返回定位坐标
|
|
227
|
+
*/
|
|
228
|
+
getPosition() {
|
|
229
|
+
const p = this.isWXMiniApp? {
|
|
230
|
+
left: 0,
|
|
231
|
+
top: 0
|
|
232
|
+
} :jmUtils.getElementPosition(this.canvas.canvas || this.canvas);
|
|
233
|
+
|
|
234
|
+
p.width = this.width;
|
|
235
|
+
p.height = this.height;
|
|
236
|
+
p.right = p.left + p.width;
|
|
237
|
+
p.bottom = p.top + p.height;
|
|
238
|
+
return p;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* 注册图形类型,图形类型必需有统一的构造函数。参数为画布句柄和参数对象。
|
|
243
|
+
*
|
|
244
|
+
* @method registerShape
|
|
245
|
+
* @param {string} name 控件图形名称
|
|
246
|
+
* @param {class} shape 图形控件类型
|
|
247
|
+
*/
|
|
248
|
+
registerShape(name, shape) {
|
|
249
|
+
this.shapes[name] = shape;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* 从已注册的图形类创建图形
|
|
254
|
+
* 简单直观创建对象
|
|
255
|
+
*
|
|
256
|
+
* @method createShape
|
|
257
|
+
* @param {string} shape 注册控件的名称 也可以直接是控件类型
|
|
258
|
+
* @param {object} args 实例化控件的参数
|
|
259
|
+
* @return {object} 已实例化控件的对象
|
|
260
|
+
*/
|
|
261
|
+
createShape(shape, args) {
|
|
262
|
+
if(typeof shape === 'string') {
|
|
263
|
+
shape = this.shapes[shape];
|
|
264
|
+
}
|
|
265
|
+
if(shape) {
|
|
266
|
+
if(!args) args = {};
|
|
267
|
+
args.graph = this;
|
|
268
|
+
let obj = new shape(args);
|
|
269
|
+
return obj;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* 生成阴影对象
|
|
275
|
+
*
|
|
276
|
+
* @method createShadow
|
|
277
|
+
* @param {number} x x偏移量
|
|
278
|
+
* @param {number} y y偏移量
|
|
279
|
+
* @param {number} blur 模糊值
|
|
280
|
+
* @param {string} color 颜色
|
|
281
|
+
* @return {jmShadow} 阴影对象
|
|
282
|
+
*/
|
|
283
|
+
createShadow(x, y, blur, color) {
|
|
284
|
+
const sh = new jmShadow(x, y, blur, color);
|
|
285
|
+
return sh;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* 生成线性渐变对象
|
|
290
|
+
*
|
|
291
|
+
* @method createLinearGradient
|
|
292
|
+
* @param {number} x1 线性渐变起始点X坐标
|
|
293
|
+
* @param {number} y1 线性渐变起始点Y坐标
|
|
294
|
+
* @param {number} x2 线性渐变结束点X坐标
|
|
295
|
+
* @param {number} y2 线性渐变结束点Y坐标
|
|
296
|
+
* @return {jmGradient} 线性渐变对象
|
|
297
|
+
*/
|
|
298
|
+
createLinearGradient(x1, y1, x2, y2, stops=[]) {
|
|
299
|
+
const gradient = new jmGradient({
|
|
300
|
+
type:'linear',
|
|
301
|
+
x1: x1,
|
|
302
|
+
y1: y1,
|
|
303
|
+
x2: x2,
|
|
304
|
+
y2: y2,
|
|
305
|
+
stops
|
|
306
|
+
});
|
|
307
|
+
return gradient;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* 生成放射渐变对象
|
|
312
|
+
*
|
|
313
|
+
* @method createRadialGradient
|
|
314
|
+
* @param {number} x1 放射渐变小圆中心X坐标
|
|
315
|
+
* @param {number} y1 放射渐变小圆中心Y坐标
|
|
316
|
+
* @param {number} r1 放射渐变小圆半径
|
|
317
|
+
* @param {number} x2 放射渐变大圆中心X坐标
|
|
318
|
+
* @param {number} y2 放射渐变大圆中心Y坐标
|
|
319
|
+
* @param {number} r2 放射渐变大圆半径
|
|
320
|
+
* @return {jmGradient} 放射渐变对象
|
|
321
|
+
*/
|
|
322
|
+
createRadialGradient(x1, y1, r1, x2, y2, r2, stops=[]) {
|
|
323
|
+
const gradient = new jmGradient({
|
|
324
|
+
type:'radial',
|
|
325
|
+
x1: x1,
|
|
326
|
+
y1: y1,
|
|
327
|
+
r1: r1,
|
|
328
|
+
x2: x2,
|
|
329
|
+
y2: y2,
|
|
330
|
+
r2: r2,
|
|
331
|
+
stops
|
|
332
|
+
});
|
|
333
|
+
return gradient;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* 重新刷新整个画板
|
|
338
|
+
* 以加入动画事件触发延时10毫秒刷新,保存最尽的调用只刷新一次,加强性能的效果。
|
|
339
|
+
*
|
|
340
|
+
* @method refresh
|
|
341
|
+
*/
|
|
342
|
+
refresh() {
|
|
343
|
+
//加入动画,触发redraw,会导致多次refresh只redraw一次
|
|
344
|
+
/*this.animate(function() {
|
|
345
|
+
return false;
|
|
346
|
+
},100,'jmgraph_refresh');*/
|
|
347
|
+
this.redraw();
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* 重新刷新整个画板
|
|
352
|
+
* 此方法直接重画,与refresh效果类似
|
|
353
|
+
*
|
|
354
|
+
* @method redraw
|
|
355
|
+
* @param {number} [w] 清除画布的宽度
|
|
356
|
+
* @param {number} [h] 清除画布的高度
|
|
357
|
+
*/
|
|
358
|
+
redraw(w, h) {
|
|
359
|
+
this.clear(w||this.width, h||this.height);
|
|
360
|
+
this.paint();
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* 清除画布
|
|
365
|
+
*
|
|
366
|
+
* @method clear
|
|
367
|
+
* @param {number} [w] 清除画布的宽度
|
|
368
|
+
* @param {number} [h] 清除画布的高度
|
|
369
|
+
*/
|
|
370
|
+
clear(w, h) {
|
|
371
|
+
if(!w || !h) {
|
|
372
|
+
w = this.width;
|
|
373
|
+
h = this.height;
|
|
374
|
+
/*if(this.scaleSize) {
|
|
375
|
+
w = w / this.scaleSize.x;
|
|
376
|
+
h = h / this.scaleSize.y;
|
|
377
|
+
}*/
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
if(this.context.clearRect) {
|
|
381
|
+
if(this.style && this.style.fill) {
|
|
382
|
+
this.points = [
|
|
383
|
+
{x:0, y:0},
|
|
384
|
+
{x:w, y:0},
|
|
385
|
+
{x:w, y:h},
|
|
386
|
+
{x:0, y:h}
|
|
387
|
+
];
|
|
388
|
+
this.style.close = true;// 封闭填充
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
this.context.clearRect(0, 0, w, h);
|
|
392
|
+
}
|
|
393
|
+
else if(this.mode === 'webgl' && this.context.clear) {
|
|
394
|
+
const color = this.style && this.style.fill? this.utils.hexToRGBA(this.style.fill): {
|
|
395
|
+
r: 0,
|
|
396
|
+
g: 0,
|
|
397
|
+
b: 0,
|
|
398
|
+
a: 0
|
|
399
|
+
};
|
|
400
|
+
this.context.clearColor(color.r, color.g, color.b, color.a); // 设置清空颜色缓冲时的颜色值
|
|
401
|
+
this.context.clear(this.context.COLOR_BUFFER_BIT); // 清空颜色缓冲区,也就是清空画布
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* 设置画布样式,此处只是设置其css样式
|
|
407
|
+
*
|
|
408
|
+
* @method css
|
|
409
|
+
* @param {string} name 样式名
|
|
410
|
+
* @param {string} value 样式值
|
|
411
|
+
*/
|
|
412
|
+
css(name, value) {
|
|
413
|
+
if(this.canvas && this.canvas.style) {
|
|
414
|
+
if(typeof value != 'undefined') this.canvas.style[name] = value;
|
|
415
|
+
return this.canvas.style[name];
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* 生成路径对象
|
|
421
|
+
*
|
|
422
|
+
* @method createPath
|
|
423
|
+
* @param {array} points 路径中的描点集合
|
|
424
|
+
* @param {style} style 当前路径的样式
|
|
425
|
+
* @return {jmPath} 路径对象jmPath
|
|
426
|
+
*/
|
|
427
|
+
createPath(points, style, option={}) {
|
|
428
|
+
const path = this.createShape('path',{
|
|
429
|
+
points: points,
|
|
430
|
+
style: style,
|
|
431
|
+
...option
|
|
432
|
+
});
|
|
433
|
+
return path;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* 生成直线
|
|
438
|
+
*
|
|
439
|
+
* @method createLine
|
|
440
|
+
* @param {point} start 直线的起点
|
|
441
|
+
* @param {point} end 直线的终点
|
|
442
|
+
* @param {style} 直线的样式
|
|
443
|
+
* @return {jmLine} 直线对象
|
|
444
|
+
*/
|
|
445
|
+
createLine(start, end, style) {
|
|
446
|
+
const line = this.createShape('line', {
|
|
447
|
+
start: start,
|
|
448
|
+
end: end,
|
|
449
|
+
style: style
|
|
450
|
+
});
|
|
451
|
+
return line;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* 缩小整个画布按比例0.9
|
|
456
|
+
*
|
|
457
|
+
* @method zoomOut
|
|
458
|
+
*/
|
|
459
|
+
zoomOut() {
|
|
460
|
+
this.scale(0.9 ,0.9);
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* 放大 每次增大0.1的比例
|
|
465
|
+
*
|
|
466
|
+
* @method zoomIn
|
|
467
|
+
*/
|
|
468
|
+
zoomIn() {
|
|
469
|
+
this.scale(1.1 ,1.1);
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* 大小复原
|
|
474
|
+
*
|
|
475
|
+
* @method zoomActual
|
|
476
|
+
*/
|
|
477
|
+
zoomActual() {
|
|
478
|
+
if(this.scaleSize) {
|
|
479
|
+
this.scale(1 / this.scaleSize.x ,1 / this.scaleSize.y);
|
|
480
|
+
}
|
|
481
|
+
else {
|
|
482
|
+
this.scale(1 ,1);
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* 放大缩小画布
|
|
488
|
+
*
|
|
489
|
+
* @method scale
|
|
490
|
+
* @param {number} dx 缩放X轴比例
|
|
491
|
+
* @param {number} dy 缩放Y轴比例
|
|
492
|
+
*/
|
|
493
|
+
scale(dx, dy) {
|
|
494
|
+
if(!this.normalSize) {
|
|
495
|
+
this.normalSize = {
|
|
496
|
+
width: this.canvas.width,
|
|
497
|
+
height: this.canvas.height
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
//this.context.scale && this.context.scale(dx,dy);
|
|
502
|
+
if(!this.scaleSize) {
|
|
503
|
+
this.scaleSize = {x: 1,y: 1};
|
|
504
|
+
}
|
|
505
|
+
else {
|
|
506
|
+
this.scaleSize = {x: dx * this.scaleSize.x, y: dy * this.scaleSize.y};
|
|
507
|
+
}
|
|
508
|
+
this.canvas.style && (this.canvas.style.transform = `scale(${this.scaleSize.x}, ${this.scaleSize.y})`);
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
/**
|
|
512
|
+
* 保存为base64图形数据
|
|
513
|
+
*
|
|
514
|
+
* @method toDataURL
|
|
515
|
+
* @return {string} 当前画布图的base64字符串
|
|
516
|
+
*/
|
|
517
|
+
toDataURL() {
|
|
518
|
+
let data = this.canvas.toDataURL?this.canvas.toDataURL():'';
|
|
519
|
+
return data;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
/**
|
|
523
|
+
* 自动刷新画版
|
|
524
|
+
* @param {function} callback 执行回调
|
|
525
|
+
*/
|
|
526
|
+
autoRefresh(callback) {
|
|
527
|
+
if(this.___isAutoRefreshing) return;
|
|
528
|
+
const self = this;
|
|
529
|
+
this.___isAutoRefreshing = true;
|
|
530
|
+
|
|
531
|
+
const refreshStartTime = Date.now();
|
|
532
|
+
function update() {
|
|
533
|
+
if(self.destroyed) {
|
|
534
|
+
self.___isAutoRefreshing = false;
|
|
535
|
+
return;// 已销毁
|
|
536
|
+
}
|
|
537
|
+
if(self.needUpdate) self.redraw();
|
|
538
|
+
|
|
539
|
+
const time = Date.now() - refreshStartTime;
|
|
540
|
+
// 触发刷新事件
|
|
541
|
+
self.emit('update', time);
|
|
542
|
+
|
|
543
|
+
self.__requestAnimationFrameFunHandler && self.cancelAnimationFrame(self.__requestAnimationFrameFunHandler);
|
|
544
|
+
self.__requestAnimationFrameFunHandler = self.requestAnimationFrame(update);
|
|
545
|
+
if(callback) callback();
|
|
546
|
+
}
|
|
547
|
+
self.__requestAnimationFrameFunHandler && this.cancelAnimationFrame(self.__requestAnimationFrameFunHandler);
|
|
548
|
+
self.__requestAnimationFrameFunHandler = this.requestAnimationFrame(update);
|
|
549
|
+
return this;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
// 销毁当前对象
|
|
553
|
+
destroy() {
|
|
554
|
+
this.eventHandler.destroy();
|
|
555
|
+
this.destroyed = true;// 标记已销毁
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
export {
|
|
560
|
+
jmGraph,
|
|
561
|
+
jmUtils,
|
|
562
|
+
jmList,
|
|
563
|
+
jmProperty,
|
|
564
|
+
jmShadow,
|
|
565
|
+
jmGradient,
|
|
566
|
+
jmEvents,
|
|
567
|
+
jmControl,
|
|
568
|
+
jmPath,
|
|
569
|
+
};
|