Project

General

Profile

Statistics
| Revision:

root / trunk / web / dojo / dojox / gfx / canvas.js @ 10

History | View | Annotate | Download (13.8 KB)

1 9 andrej.cim
/*
2
        Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
3
        Available via Academic Free License >= 2.1 OR the modified BSD license.
4
        see: http://dojotoolkit.org/license for details
5
*/
6
7
8
if(!dojo._hasResource["dojox.gfx.canvas"]){
9
dojo._hasResource["dojox.gfx.canvas"]=true;
10
dojo.provide("dojox.gfx.canvas");
11
dojo.require("dojox.gfx._base");
12
dojo.require("dojox.gfx.shape");
13
dojo.require("dojox.gfx.path");
14
dojo.require("dojox.gfx.arc");
15
dojo.require("dojox.gfx.decompose");
16
dojo.experimental("dojox.gfx.canvas");
17
(function(){
18
var d=dojo,g=dojox.gfx,gs=g.shape,ga=g.arc,m=g.matrix,mp=m.multiplyPoint,pi=Math.PI,_1=2*pi,_2=pi/2;
19
d.extend(g.Shape,{_render:function(_3){
20
_3.save();
21
this._renderTransform(_3);
22
this._renderShape(_3);
23
this._renderFill(_3,true);
24
this._renderStroke(_3,true);
25
_3.restore();
26
},_renderTransform:function(_4){
27
if("canvasTransform" in this){
28
var t=this.canvasTransform;
29
_4.translate(t.dx,t.dy);
30
_4.rotate(t.angle2);
31
_4.scale(t.sx,t.sy);
32
_4.rotate(t.angle1);
33
}
34
},_renderShape:function(_5){
35
},_renderFill:function(_6,_7){
36
if("canvasFill" in this){
37
if("canvasFillImage" in this){
38
this.canvasFill=_6.createPattern(this.canvasFillImage,"repeat");
39
delete this.canvasFillImage;
40
}
41
_6.fillStyle=this.canvasFill;
42
if(_7){
43
_6.fill();
44
}
45
}else{
46
_6.fillStyle="rgba(0,0,0,0.0)";
47
}
48
},_renderStroke:function(_8,_9){
49
var s=this.strokeStyle;
50
if(s){
51
_8.strokeStyle=s.color.toString();
52
_8.lineWidth=s.width;
53
_8.lineCap=s.cap;
54
if(typeof s.join=="number"){
55
_8.lineJoin="miter";
56
_8.miterLimit=s.join;
57
}else{
58
_8.lineJoin=s.join;
59
}
60
if(_9){
61
_8.stroke();
62
}
63
}else{
64
if(!_9){
65
_8.strokeStyle="rgba(0,0,0,0.0)";
66
}
67
}
68
},getEventSource:function(){
69
return null;
70
},connect:function(){
71
},disconnect:function(){
72
}});
73
var _a=function(_b,_c,_d){
74
var _e=_b.prototype[_c];
75
_b.prototype[_c]=_d?function(){
76
this.surface.makeDirty();
77
_e.apply(this,arguments);
78
_d.call(this);
79
return this;
80
}:function(){
81
this.surface.makeDirty();
82
return _e.apply(this,arguments);
83
};
84
};
85
_a(g.Shape,"setTransform",function(){
86
if(this.matrix){
87
this.canvasTransform=g.decompose(this.matrix);
88
}else{
89
delete this.canvasTransform;
90
}
91
});
92
_a(g.Shape,"setFill",function(){
93
var fs=this.fillStyle,f;
94
if(fs){
95
if(typeof (fs)=="object"&&"type" in fs){
96
var _f=this.surface.rawNode.getContext("2d");
97
switch(fs.type){
98
case "linear":
99
case "radial":
100
f=fs.type=="linear"?_f.createLinearGradient(fs.x1,fs.y1,fs.x2,fs.y2):_f.createRadialGradient(fs.cx,fs.cy,0,fs.cx,fs.cy,fs.r);
101
d.forEach(fs.colors,function(_10){
102
f.addColorStop(_10.offset,g.normalizeColor(_10.color).toString());
103
});
104
break;
105
case "pattern":
106
var img=new Image(fs.width,fs.height);
107
this.surface.downloadImage(img,fs.src);
108
this.canvasFillImage=img;
109
}
110
}else{
111
f=fs.toString();
112
}
113
this.canvasFill=f;
114
}else{
115
delete this.canvasFill;
116
}
117
});
118
_a(g.Shape,"setStroke");
119
_a(g.Shape,"setShape");
120
dojo.declare("dojox.gfx.Group",g.Shape,{constructor:function(){
121
gs.Container._init.call(this);
122
},_render:function(ctx){
123
ctx.save();
124
this._renderTransform(ctx);
125
this._renderFill(ctx);
126
this._renderStroke(ctx);
127
for(var i=0;i<this.children.length;++i){
128
this.children[i]._render(ctx);
129
}
130
ctx.restore();
131
}});
132
dojo.declare("dojox.gfx.Rect",gs.Rect,{_renderShape:function(ctx){
133
var s=this.shape,r=Math.min(s.r,s.height/2,s.width/2),xl=s.x,xr=xl+s.width,yt=s.y,yb=yt+s.height,xl2=xl+r,xr2=xr-r,yt2=yt+r,yb2=yb-r;
134
ctx.beginPath();
135
ctx.moveTo(xl2,yt);
136
if(r){
137
ctx.arc(xr2,yt2,r,-_2,0,false);
138
ctx.arc(xr2,yb2,r,0,_2,false);
139
ctx.arc(xl2,yb2,r,_2,pi,false);
140
ctx.arc(xl2,yt2,r,pi,pi+_2,false);
141
}else{
142
ctx.lineTo(xr2,yt);
143
ctx.lineTo(xr,yb2);
144
ctx.lineTo(xl2,yb);
145
ctx.lineTo(xl,yt2);
146
}
147
ctx.closePath();
148
}});
149
var _11=[];
150
(function(){
151
var u=ga.curvePI4;
152
_11.push(u.s,u.c1,u.c2,u.e);
153
for(var a=45;a<360;a+=45){
154
var r=m.rotateg(a);
155
_11.push(mp(r,u.c1),mp(r,u.c2),mp(r,u.e));
156
}
157
})();
158
dojo.declare("dojox.gfx.Ellipse",gs.Ellipse,{setShape:function(){
159
g.Ellipse.superclass.setShape.apply(this,arguments);
160
var s=this.shape,t,c1,c2,r=[],M=m.normalize([m.translate(s.cx,s.cy),m.scale(s.rx,s.ry)]);
161
t=mp(M,_11[0]);
162
r.push([t.x,t.y]);
163
for(var i=1;i<_11.length;i+=3){
164
c1=mp(M,_11[i]);
165
c2=mp(M,_11[i+1]);
166
t=mp(M,_11[i+2]);
167
r.push([c1.x,c1.y,c2.x,c2.y,t.x,t.y]);
168
}
169
this.canvasEllipse=r;
170
return this;
171
},_renderShape:function(ctx){
172
var r=this.canvasEllipse;
173
ctx.beginPath();
174
ctx.moveTo.apply(ctx,r[0]);
175
for(var i=1;i<r.length;++i){
176
ctx.bezierCurveTo.apply(ctx,r[i]);
177
}
178
ctx.closePath();
179
}});
180
dojo.declare("dojox.gfx.Circle",gs.Circle,{_renderShape:function(ctx){
181
var s=this.shape;
182
ctx.beginPath();
183
ctx.arc(s.cx,s.cy,s.r,0,_1,1);
184
}});
185
dojo.declare("dojox.gfx.Line",gs.Line,{_renderShape:function(ctx){
186
var s=this.shape;
187
ctx.beginPath();
188
ctx.moveTo(s.x1,s.y1);
189
ctx.lineTo(s.x2,s.y2);
190
}});
191
dojo.declare("dojox.gfx.Polyline",gs.Polyline,{setShape:function(){
192
g.Polyline.superclass.setShape.apply(this,arguments);
193
var p=this.shape.points,f=p[0],r=[],c,i;
194
if(p.length){
195
if(typeof f=="number"){
196
r.push(f,p[1]);
197
i=2;
198
}else{
199
r.push(f.x,f.y);
200
i=1;
201
}
202
for(;i<p.length;++i){
203
c=p[i];
204
if(typeof c=="number"){
205
r.push(c,p[++i]);
206
}else{
207
r.push(c.x,c.y);
208
}
209
}
210
}
211
this.canvasPolyline=r;
212
return this;
213
},_renderShape:function(ctx){
214
var p=this.canvasPolyline;
215
if(p.length){
216
ctx.beginPath();
217
ctx.moveTo(p[0],p[1]);
218
for(var i=2;i<p.length;i+=2){
219
ctx.lineTo(p[i],p[i+1]);
220
}
221
}
222
}});
223
dojo.declare("dojox.gfx.Image",gs.Image,{setShape:function(){
224
g.Image.superclass.setShape.apply(this,arguments);
225
var img=new Image();
226
this.surface.downloadImage(img,this.shape.src);
227
this.canvasImage=img;
228
return this;
229
},_renderShape:function(ctx){
230
var s=this.shape;
231
ctx.drawImage(this.canvasImage,s.x,s.y,s.width,s.height);
232
}});
233
dojo.declare("dojox.gfx.Text",gs.Text,{_renderShape:function(ctx){
234
var s=this.shape;
235
}});
236
_a(g.Text,"setFont");
237
var _12={M:"_moveToA",m:"_moveToR",L:"_lineToA",l:"_lineToR",H:"_hLineToA",h:"_hLineToR",V:"_vLineToA",v:"_vLineToR",C:"_curveToA",c:"_curveToR",S:"_smoothCurveToA",s:"_smoothCurveToR",Q:"_qCurveToA",q:"_qCurveToR",T:"_qSmoothCurveToA",t:"_qSmoothCurveToR",A:"_arcTo",a:"_arcTo",Z:"_closePath",z:"_closePath"};
238
dojo.declare("dojox.gfx.Path",g.path.Path,{constructor:function(){
239
this.lastControl={};
240
},setShape:function(){
241
this.canvasPath=[];
242
return g.Path.superclass.setShape.apply(this,arguments);
243
},_updateWithSegment:function(_13){
244
var _14=d.clone(this.last);
245
this[_12[_13.action]](this.canvasPath,_13.action,_13.args);
246
this.last=_14;
247
g.Path.superclass._updateWithSegment.apply(this,arguments);
248
},_renderShape:function(ctx){
249
var r=this.canvasPath;
250
ctx.beginPath();
251
for(var i=0;i<r.length;i+=2){
252
ctx[r[i]].apply(ctx,r[i+1]);
253
}
254
},_moveToA:function(_15,_16,_17){
255
_15.push("moveTo",[_17[0],_17[1]]);
256
for(var i=2;i<_17.length;i+=2){
257
_15.push("lineTo",[_17[i],_17[i+1]]);
258
}
259
this.last.x=_17[_17.length-2];
260
this.last.y=_17[_17.length-1];
261
this.lastControl={};
262
},_moveToR:function(_18,_19,_1a){
263
if("x" in this.last){
264
_18.push("moveTo",[this.last.x+=_1a[0],this.last.y+=_1a[1]]);
265
}else{
266
_18.push("moveTo",[this.last.x=_1a[0],this.last.y=_1a[1]]);
267
}
268
for(var i=2;i<_1a.length;i+=2){
269
_18.push("lineTo",[this.last.x+=_1a[i],this.last.y+=_1a[i+1]]);
270
}
271
this.lastControl={};
272
},_lineToA:function(_1b,_1c,_1d){
273
for(var i=0;i<_1d.length;i+=2){
274
_1b.push("lineTo",[_1d[i],_1d[i+1]]);
275
}
276
this.last.x=_1d[_1d.length-2];
277
this.last.y=_1d[_1d.length-1];
278
this.lastControl={};
279
},_lineToR:function(_1e,_1f,_20){
280
for(var i=0;i<_20.length;i+=2){
281
_1e.push("lineTo",[this.last.x+=_20[i],this.last.y+=_20[i+1]]);
282
}
283
this.lastControl={};
284
},_hLineToA:function(_21,_22,_23){
285
for(var i=0;i<_23.length;++i){
286
_21.push("lineTo",[_23[i],this.last.y]);
287
}
288
this.last.x=_23[_23.length-1];
289
this.lastControl={};
290
},_hLineToR:function(_24,_25,_26){
291
for(var i=0;i<_26.length;++i){
292
_24.push("lineTo",[this.last.x+=_26[i],this.last.y]);
293
}
294
this.lastControl={};
295
},_vLineToA:function(_27,_28,_29){
296
for(var i=0;i<_29.length;++i){
297
_27.push("lineTo",[this.last.x,_29[i]]);
298
}
299
this.last.y=_29[_29.length-1];
300
this.lastControl={};
301
},_vLineToR:function(_2a,_2b,_2c){
302
for(var i=0;i<_2c.length;++i){
303
_2a.push("lineTo",[this.last.x,this.last.y+=_2c[i]]);
304
}
305
this.lastControl={};
306
},_curveToA:function(_2d,_2e,_2f){
307
for(var i=0;i<_2f.length;i+=6){
308
_2d.push("bezierCurveTo",_2f.slice(i,i+6));
309
}
310
this.last.x=_2f[_2f.length-2];
311
this.last.y=_2f[_2f.length-1];
312
this.lastControl.x=_2f[_2f.length-4];
313
this.lastControl.y=_2f[_2f.length-3];
314
this.lastControl.type="C";
315
},_curveToR:function(_30,_31,_32){
316
for(var i=0;i<_32.length;i+=6){
317
_30.push("bezierCurveTo",[this.last.x+_32[i],this.last.y+_32[i+1],this.lastControl.x=this.last.x+_32[i+2],this.lastControl.y=this.last.y+_32[i+3],this.last.x+_32[i+4],this.last.y+_32[i+5]]);
318
this.last.x+=_32[i+4];
319
this.last.y+=_32[i+5];
320
}
321
this.lastControl.type="C";
322
},_smoothCurveToA:function(_33,_34,_35){
323
for(var i=0;i<_35.length;i+=4){
324
var _36=this.lastControl.type=="C";
325
_33.push("bezierCurveTo",[_36?2*this.last.x-this.lastControl.x:this.last.x,_36?2*this.last.y-this.lastControl.y:this.last.y,_35[i],_35[i+1],_35[i+2],_35[i+3]]);
326
this.lastControl.x=_35[i];
327
this.lastControl.y=_35[i+1];
328
this.lastControl.type="C";
329
}
330
this.last.x=_35[_35.length-2];
331
this.last.y=_35[_35.length-1];
332
},_smoothCurveToR:function(_37,_38,_39){
333
for(var i=0;i<_39.length;i+=4){
334
var _3a=this.lastControl.type=="C";
335
_37.push("bezierCurveTo",[_3a?2*this.last.x-this.lastControl.x:this.last.x,_3a?2*this.last.y-this.lastControl.y:this.last.y,this.last.x+_39[i],this.last.y+_39[i+1],this.last.x+_39[i+2],this.last.y+_39[i+3]]);
336
this.lastControl.x=this.last.x+_39[i];
337
this.lastControl.y=this.last.y+_39[i+1];
338
this.lastControl.type="C";
339
this.last.x+=_39[i+2];
340
this.last.y+=_39[i+3];
341
}
342
},_qCurveToA:function(_3b,_3c,_3d){
343
for(var i=0;i<_3d.length;i+=4){
344
_3b.push("quadraticCurveTo",_3d.slice(i,i+4));
345
}
346
this.last.x=_3d[_3d.length-2];
347
this.last.y=_3d[_3d.length-1];
348
this.lastControl.x=_3d[_3d.length-4];
349
this.lastControl.y=_3d[_3d.length-3];
350
this.lastControl.type="Q";
351
},_qCurveToR:function(_3e,_3f,_40){
352
for(var i=0;i<_40.length;i+=4){
353
_3e.push("quadraticCurveTo",[this.lastControl.x=this.last.x+_40[i],this.lastControl.y=this.last.y+_40[i+1],this.last.x+_40[i+2],this.last.y+_40[i+3]]);
354
this.last.x+=_40[i+2];
355
this.last.y+=_40[i+3];
356
}
357
this.lastControl.type="Q";
358
},_qSmoothCurveToA:function(_41,_42,_43){
359
for(var i=0;i<_43.length;i+=2){
360
var _44=this.lastControl.type=="Q";
361
_41.push("quadraticCurveTo",[this.lastControl.x=_44?2*this.last.x-this.lastControl.x:this.last.x,this.lastControl.y=_44?2*this.last.y-this.lastControl.y:this.last.y,_43[i],_43[i+1]]);
362
this.lastControl.type="Q";
363
}
364
this.last.x=_43[_43.length-2];
365
this.last.y=_43[_43.length-1];
366
},_qSmoothCurveToR:function(_45,_46,_47){
367
for(var i=0;i<_47.length;i+=2){
368
var _48=this.lastControl.type=="Q";
369
_45.push("quadraticCurveTo",[this.lastControl.x=_48?2*this.last.x-this.lastControl.x:this.last.x,this.lastControl.y=_48?2*this.last.y-this.lastControl.y:this.last.y,this.last.x+_47[i],this.last.y+_47[i+1]]);
370
this.lastControl.type="Q";
371
this.last.x+=_47[i];
372
this.last.y+=_47[i+1];
373
}
374
},_arcTo:function(_49,_4a,_4b){
375
var _4c=_4a=="a";
376
for(var i=0;i<_4b.length;i+=7){
377
var x1=_4b[i+5],y1=_4b[i+6];
378
if(_4c){
379
x1+=this.last.x;
380
y1+=this.last.y;
381
}
382
var _4d=ga.arcAsBezier(this.last,_4b[i],_4b[i+1],_4b[i+2],_4b[i+3]?1:0,_4b[i+4]?1:0,x1,y1);
383
d.forEach(_4d,function(p){
384
_49.push("bezierCurveTo",p);
385
});
386
this.last.x=x1;
387
this.last.y=y1;
388
}
389
this.lastControl={};
390
},_closePath:function(_4e,_4f,_50){
391
_4e.push("closePath",[]);
392
this.lastControl={};
393
}});
394
d.forEach(["moveTo","lineTo","hLineTo","vLineTo","curveTo","smoothCurveTo","qCurveTo","qSmoothCurveTo","arcTo","closePath"],function(_51){
395
_a(g.Path,_51);
396
});
397
dojo.declare("dojox.gfx.TextPath",g.path.TextPath,{_renderShape:function(ctx){
398
var s=this.shape;
399
}});
400
dojo.declare("dojox.gfx.Surface",gs.Surface,{constructor:function(){
401
gs.Container._init.call(this);
402
this.pendingImageCount=0;
403
this.makeDirty();
404
},setDimensions:function(_52,_53){
405
this.width=g.normalizedLength(_52);
406
this.height=g.normalizedLength(_53);
407
if(!this.rawNode){
408
return this;
409
}
410
this.rawNode.width=_52;
411
this.rawNode.height=_53;
412
this.makeDirty();
413
return this;
414
},getDimensions:function(){
415
return this.rawNode?{width:this.rawNode.width,height:this.rawNode.height}:null;
416
},_render:function(){
417
if(this.pendingImageCount){
418
return;
419
}
420
var ctx=this.rawNode.getContext("2d");
421
ctx.save();
422
ctx.clearRect(0,0,this.rawNode.width,this.rawNode.height);
423
for(var i=0;i<this.children.length;++i){
424
this.children[i]._render(ctx);
425
}
426
ctx.restore();
427
if("pendingRender" in this){
428
clearTimeout(this.pendingRender);
429
delete this.pendingRender;
430
}
431
},makeDirty:function(){
432
if(!this.pendingImagesCount&&!("pendingRender" in this)){
433
this.pendingRender=setTimeout(d.hitch(this,this._render),0);
434
}
435
},downloadImage:function(img,url){
436
var _54=d.hitch(this,this.onImageLoad);
437
if(!this.pendingImageCount++&&"pendingRender" in this){
438
clearTimeout(this.pendingRender);
439
delete this.pendingRender;
440
}
441
img.onload=_54;
442
img.onerror=_54;
443
img.onabort=_54;
444
img.src=url;
445
},onImageLoad:function(){
446
if(!--this.pendingImageCount){
447
this._render();
448
}
449
},getEventSource:function(){
450
return null;
451
},connect:function(){
452
},disconnect:function(){
453
}});
454
g.createSurface=function(_55,_56,_57){
455
if(!_56&&!_57){
456
var pos=d.position(_55);
457
_56=_56||pos.w;
458
_57=_57||pos.h;
459
}
460
if(typeof _56=="number"){
461
_56=_56+"px";
462
}
463
if(typeof _57=="number"){
464
_57=_57+"px";
465
}
466
var s=new g.Surface(),p=d.byId(_55),c=p.ownerDocument.createElement("canvas");
467
c.width=dojox.gfx.normalizedLength(_56);
468
c.height=dojox.gfx.normalizedLength(_57);
469
p.appendChild(c);
470
s.rawNode=c;
471
s._parent=p;
472
s.surface=s;
473
return s;
474
};
475
var C=gs.Container,_58={add:function(_59){
476
this.surface.makeDirty();
477
return C.add.apply(this,arguments);
478
},remove:function(_5a,_5b){
479
this.surface.makeDirty();
480
return C.remove.apply(this,arguments);
481
},clear:function(){
482
this.surface.makeDirty();
483
return C.clear.apply(this,arguments);
484
},_moveChildToFront:function(_5c){
485
this.surface.makeDirty();
486
return C._moveChildToFront.apply(this,arguments);
487
},_moveChildToBack:function(_5d){
488
this.surface.makeDirty();
489
return C._moveChildToBack.apply(this,arguments);
490
}};
491
d.mixin(gs.Creator,{createObject:function(_5e,_5f){
492
var _60=new _5e();
493
_60.surface=this.surface;
494
_60.setShape(_5f);
495
this.add(_60);
496
return _60;
497
}});
498
d.extend(g.Group,_58);
499
d.extend(g.Group,gs.Creator);
500
d.extend(g.Surface,_58);
501
d.extend(g.Surface,gs.Creator);
502
})();
503
}