source: Dev/trunk/src/client/dojox/drawing/annotations/BoxShadow.js @ 532

Last change on this file since 532 was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

File size: 9.2 KB
Line 
1define(["dojo", "dojo/_base/Color", "../util/oo"],
2function(dojo, Color, oo){
3
4return oo.declare(
5        function(/*Object*/options){
6                this.stencil = options.stencil;
7                this.util = options.stencil.util;
8                this.mouse = options.stencil.mouse;
9                this.style = options.stencil.style;
10               
11                var shadowDefaults = {
12                        // summary:
13                        //              When passing a shadow object into a stencil, that shadow
14                        //              object will be mixed in with these defaults.
15
16                        // size: Number
17                        //              Works together with mult. Both affect the size and quality
18                        //              of the shadow. size affects the actual size and mult affects the
19                        //              lineWidths that overlap to make the shadow. Generally you want a
20                        //              bigger 'size' than 'mult'. The defaults are good for a shadow, but
21                        //              you will want to increase them when making a glow.
22                        //              TODO: Make this more clear or use other properties.
23                        size:6,
24
25                        // mult: Number
26                        //              Works together with size.  Both affect the size and quality
27                        //              of the shadow. size affects the actual size and mult affects the
28                        //              lineWidths that overlap to make the shadow. Generally you want a
29                        //              bigger 'size' than 'mult'. The defaults are good for a shadow, but
30                        //              you will want to increase them when making a glow.
31                        //              TODO: Make this more clear or use other properties.
32                        mult:4,
33
34                        // alpha: Float
35                        //              Affects the alpha of the shadow. Because this is multiple shapes
36                        //              overlapped, you want much less than you may think. .1 is pretty
37                        //              dark and . is black. Higher numbers also give a sharper edge.
38                        alpha:.05,
39
40                        // place: String
41                        //              Tells the position of the shadow:
42                        //
43                        //              - B: bottom
44                        //              - T: top
45                        //              - L: left
46                        //              - R: right
47                        //              - C: center, or a glow
48                        //
49                        //              Can be used in combinations such as BR, BL, L, T, etc. 'C' should
50                        //              be used by itself.
51                        place:"BR",
52
53                        // color: String
54                        //              The color of the shadow or glow.
55                        color:"#646464"
56                };
57               
58                delete options.stencil;
59                this.options = dojo.mixin(shadowDefaults, options);
60                this.options.color = new Color(this.options.color)
61                this.options.color.a = this.options.alpha;
62                switch(this.stencil.shortType){
63                        case "image":
64                        case "rect":
65                                this.method = "createForRect"; break;
66                        case "ellipse":
67                                this.method = "createForEllipse"; break;
68                        case "line":
69                                this.method = "createForLine"; break;
70                        case "path":
71                                this.method = "createForPath"; break;
72                                //      path is a bit of a hassle. Plus I think in IE it would be
73                                //slower than the political process. Maybe TODO.
74                        case "vector":
75                                this.method = "createForZArrow"; break;
76                        default:
77                                console.warn("A shadow cannot be made for Stencil type ", this.stencil.type);
78                }
79               
80                if(this.method){
81                        this.render();
82                        this.stencil.connectMult([
83                                [this.stencil, "onTransform", this, "onTransform"],
84                                this.method=="createForZArrow"?[this.stencil, "render", this, "render"]:[this.stencil, "render", this, "onRender"],
85                                [this.stencil, "onDelete", this, "destroy"]
86                        ]);
87                }
88        },
89        {
90                // summary:
91                //              Creates a box shadow under solid objects. Can change the
92                //              shadow direction, color, size, and intensity. Can center
93                //              the shadow and make it a Glow.
94                // description:
95                //              This is a pseudo shadow, created by duplicating the
96                //              original stencil and increasing the line weight while
97                //              reducing the opacity. Therefore it will not work with
98                //              text. Also won't look very good if the Stencil has no
99                //              fill or is transparent. Can't do knockouts or inner
100                //              shadows. Currently can't do paths - while doable, it
101                //              will most likely choke IE into certain death.
102
103                showing:true,
104                render: function(){
105                        if(this.container){
106                                this.container.removeShape();
107                        }
108                        this.container = this.stencil.container.createGroup();
109                        this.container.moveToBack();
110                       
111                        var o = this.options,
112                                size = o.size,
113                                mult = o.mult,
114                                d = this.method == "createForPath"
115                                        ? this.stencil.points
116                                        : this.stencil.data,
117                                r = d.r || 1,
118                                p = o.place,
119                                c = o.color;
120                               
121                        this[this.method](o, size, mult, d, r, p, c);
122                },
123               
124                hide: function(){
125                        if(this.showing){
126                                this.showing = false;
127                                this.container.removeShape();
128                        }
129                },
130               
131                show: function(){
132                        if(!this.showing){
133                                this.showing = true;
134                                this.stencil.container.add(this.container);
135                        }
136                },
137               
138                createForPath: function(o, size, mult, pts, r, p, c){
139                        var sh = size * mult / 4,
140                                shy = /B/.test(p) ? sh : /T/.test(p) ? sh*-1 : 0,
141                                shx = /R/.test(p) ? sh : /L/.test(p) ? sh*-1 : 0;
142                       
143                        var closePath = true;
144                       
145                        for(var i=1;i<=size;i++){
146                                var lineWidth = i * mult;
147                                //var rect = this.container.createLine({x1:d.x1+shx, y1:d.y1+shy, x2:d.x2+shx, y2:d.y2+shy})
148                                //      .setStroke({width:lineWidth, color:c, cap:"round"})
149                       
150                                if(dojox.gfx.renderer=="svg"){
151                                        var strAr = [];
152                                        dojo.forEach(pts, function(o, i){
153                                                if(i==0){
154                                                        strAr.push("M " + (o.x+shx) +" "+ (o.y+shy));
155                                                }else{
156                                                        var cmd = o.t || "L ";
157                                                        strAr.push(cmd + (o.x+shx) +" "+ (o.y+shy)); // Z + undefined works here
158                                                }
159                                        }, this);
160                                        if(closePath){
161                                                strAr.push("Z");
162                                        }
163                                        this.container.createPath(strAr.join(", ")).setStroke({width:lineWidth, color:c, cap:"round"})
164                                       
165                                }else{
166                                        // Leaving this code for VML. It seems slightly faster but times vary.
167                                        var pth = this.container.createPath({}).setStroke({width:lineWidth, color:c, cap:"round"})
168                                       
169                                        dojo.forEach(this.points, function(o, i){
170                                                if(i==0 || o.t=="M"){
171                                                        pth.moveTo(o.x+shx, o.y+shy);
172                                                }else if(o.t=="Z"){
173                                                        closePath && pth.closePath();
174                                                }else{
175                                                        pth.lineTo(o.x+shx, o.y+shy);
176                                                }
177                                        }, this);
178                                       
179                                        closePath && pth.closePath();
180                                }
181                       
182                       
183                        }
184                },
185               
186                createForLine: function(o, size, mult, d, r, p, c){
187                       
188                        var sh = size * mult / 4,
189                                shy = /B/.test(p) ? sh : /T/.test(p) ? sh*-1 : 0,
190                                shx = /R/.test(p) ? sh : /L/.test(p) ? sh*-1 : 0;
191                        for(var i=1;i<=size;i++){
192                                var lineWidth = i * mult;
193                                this.container.createLine({x1:d.x1+shx, y1:d.y1+shy, x2:d.x2+shx, y2:d.y2+shy})
194                                        .setStroke({width:lineWidth, color:c, cap:"round"})
195                        }
196                },
197                createForEllipse: function(o, size, mult, d, r, p, c){
198               
199                        var sh = size * mult / 8,
200                                shy = /B/.test(p) ? sh : /T/.test(p) ? sh*-1 : 0,
201                                shx = /R/.test(p) ? sh*.8 : /L/.test(p) ? sh*-.8 : 0;
202                       
203                        for(var i=1;i<=size;i++){
204                                var lineWidth = i * mult;
205                                this.container.createEllipse({cx:d.cx+shx, cy:d.cy+shy, rx:d.rx-sh, ry:d.ry-sh, r:r})
206                                        .setStroke({width:lineWidth, color:c})
207                        }
208                },
209               
210                createForRect: function(o, size, mult, d, r, p, c){
211                       
212                        var sh = size * mult / 2,
213                                shy = /B/.test(p) ? sh : /T/.test(p) ? 0 : sh /2,
214                                shx = /R/.test(p) ? sh : /L/.test(p) ? 0 : sh /2;
215                       
216                        for(var i=1;i<=size;i++){
217                                var lineWidth = i * mult;
218                                this.container.createRect({x:d.x+shx, y:d.y+shy, width:d.width-sh, height:d.height-sh, r:r})
219                                        .setStroke({width:lineWidth, color:c})
220                        }
221                },
222               
223                arrowPoints: function(){
224                        // summary:
225                        //              Creates data used to draw arrow head.
226
227                        var d = this.stencil.data;
228                        var radius = this.stencil.getRadius();
229                        var angle = this.style.zAngle + 30;
230
231                        var pt = this.util.pointOnCircle(d.x1, d.y1, radius*.75, angle);
232                       
233                        var obj = {
234                                start:{
235                                        x:d.x1,
236                                        y:d.y1
237                                },
238                                x:pt.x,
239                                y:pt.y
240                        }
241                        var angle = this.util.angle(obj);
242                        var lineLength = this.util.length(obj);
243                        var al = this.style.arrows.length;
244                        var aw = this.style.arrows.width/3;
245                        if(lineLength<al){
246                                al = lineLength/2;
247                        }
248
249                        var p1 = this.util.pointOnCircle(obj.x, obj.y, -al, angle-aw);
250                        var p2 = this.util.pointOnCircle(obj.x, obj.y, -al, angle+aw);
251                        return [
252                                {x:obj.x, y:obj.y},
253                                p1,
254                                p2
255                        ];
256                },
257               
258                createForZArrow: function(o, size, mult, pts, r, p, c){
259                        if(this.stencil.data.cosphi<1 || !this.stencil.points[0]){ return; }
260                        var sh = size * mult / 4,
261                                shy = /B/.test(p) ? sh : /T/.test(p) ? sh*-1 : 0,
262                                shx = /R/.test(p) ? sh : /L/.test(p) ? sh*-1 : 0;
263                        var closePath = true;
264                        for(var i=1;i<=size;i++){
265                                var lineWidth = i * mult;
266                                pts = this.arrowPoints();
267                                if(!pts){ return; }
268                                if(dojox.gfx.renderer=="svg"){
269                                       
270                                        var strAr = [];
271                                        dojo.forEach(pts, function(o, i){
272                                                if(i==0){
273                                                        strAr.push("M " + (o.x+shx) +" "+ (o.y+shy));
274                                                }else{
275                                                        var cmd = o.t || "L ";
276                                                        strAr.push(cmd + (o.x+shx) +" "+ (o.y+shy)); // Z + undefined works here
277                                                }
278                                        }, this);
279                                        if(closePath){
280                                                strAr.push("Z");
281                                        }
282
283                                        this.container.createPath(strAr.join(", ")).setStroke({width:lineWidth, color:c, cap:"round"}).setFill(c);
284                                       
285                                }else{
286                                        // Leaving this code for VML. It seems slightly faster but times vary.
287                                        var pth = this.container.createPath({}).setStroke({width:lineWidth, color:c, cap:"round"})
288                                       
289                                        dojo.forEach(pts, function(o, i){
290                                                if(i==0 || o.t=="M"){
291                                                        pth.moveTo(o.x+shx, o.y+shy);
292                                                }else if(o.t=="Z"){
293                                                        closePath && pth.closePath();
294                                                }else{
295                                                        pth.lineTo(o.x+shx, o.y+shy);
296                                                }
297                                        }, this);
298                                       
299                                        closePath && pth.closePath();
300                                }
301                                var sp = this.stencil.points;
302                                this.container.createLine({x1:sp[0].x, y1:sp[0].y, x2:pts[0].x, y2:pts[0].y})
303                                        .setStroke({width:lineWidth, color:c, cap:"round"});
304                       
305                        }
306                },
307
308                onTransform: function(){
309                        this.render();
310                },
311                onRender: function(){
312                        this.container.moveToBack();
313                },
314                destroy: function(){
315                        if(this.container){
316                                this.container.removeShape();
317                        }
318                }
319        }
320);
321
322});
Note: See TracBrowser for help on using the repository browser.