source: Dev/trunk/src/client/dojox/image/LightboxNano.js @ 529

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

Added Dojo 1.9.3 release.

File size: 8.5 KB
Line 
1define(["dojo", "dojo/fx"], function(dojo, fx) {
2
3        var abs = "absolute",
4                vis = "visibility",
5                getViewport = function(){
6                        // summary:
7                        //              Returns the dimensions and scroll position of the viewable area of a browser window
8                        var scrollRoot = (dojo.doc.compatMode == "BackCompat") ? dojo.body() : dojo.doc.documentElement,
9                                scroll = dojo._docScroll();
10                                return { w: scrollRoot.clientWidth, h: scrollRoot.clientHeight, l: scroll.x, t: scroll.y };
11                        }
12        ;
13
14        return dojo.declare("dojox.image.LightboxNano", null, {
15                // summary:
16                //              A simple "nano" version of the lightbox.
17                // description:
18                //              Very lightweight lightbox which only displays a larger image.  There is
19                //              no support for a caption or description.  The lightbox can be closed by
20                //              clicking any where or pressing any key.  This widget is intended to be
21                //              used on `<a>` and `<img>` tags.  Upon creation, if the domNode is `<img>` tag,
22                //              then it is wrapped in an `<a>` tag, then a `<div class="enlarge">` is placed
23                //              inside the `<a>` and can be styled to display an icon that the original
24                //              can be enlarged.
25                // example:
26                //      |       <a dojoType="dojox.image.LightboxNano" href="/path/to/largeimage.jpg"><img src="/path/to/thumbnail.jpg"></a>
27                // example:
28                //      |       <img dojoType="dojox.image.LightboxNano" src="/path/to/thumbnail.jpg" href="/path/to/largeimage.jpg">
29
30                // href: string
31                //              URL to the large image to show in the lightbox.
32                href: "",
33
34                // duration: int
35                //              The delay in milliseconds of the LightboxNano open and close animation.
36                duration: 500,
37
38                // preloadDelay: int
39                //              The delay in milliseconds after the LightboxNano is created before preloading the larger image.
40                preloadDelay: 5000,
41
42                constructor: function(/*Object?*/p, /*DomNode?*/n){
43                        // summary:
44                        //              Initializes the DOM node and connect onload event
45                        var _this = this;
46
47                        dojo.mixin(_this, p);
48                        n = _this._node = dojo.byId(n);
49
50                        // if we have a origin node, then prepare it to show the LightboxNano
51                        if(n){
52                                if(!/a/i.test(n.tagName)){
53                                        var a = dojo.create("a", { href: _this.href, "class": n.className }, n, "after");
54                                        n.className = "";
55                                        a.appendChild(n);
56                                        n = a;
57                                }
58
59                                dojo.style(n, "position", "relative");
60                                _this._createDiv("dojoxEnlarge", n);
61                                dojo.setSelectable(n, false);
62                                _this._onClickEvt = dojo.connect(n, "onclick", _this, "_load");
63                        }
64
65                        if(_this.href){
66                                setTimeout(function(){
67                                        (new Image()).src = _this.href;
68                                        _this._hideLoading();
69                                }, _this.preloadDelay);
70                        }
71                },
72
73                destroy: function(){
74                        // summary:
75                        //              Destroys the LightboxNano and it's DOM node
76                        var a = this._connects || [];
77                        a.push(this._onClickEvt);
78                        dojo.forEach(a, dojo.disconnect);
79                        dojo.destroy(this._node);
80                },
81
82                _createDiv: function(/*String*/cssClass, /*DomNode*/refNode, /*boolean*/display){
83                        // summary:
84                        //              Creates a div for the enlarge icon and loading indicator layers
85                        return dojo.create("div", { // DomNode
86                                "class": cssClass,
87                                style: {
88                                        position: abs,
89                                        display: display ? "" : "none"
90                                }
91                        }, refNode);
92                },
93
94                _load: function(/*Event*/e){
95                        // summary:
96                        //              Creates the large image and begins to show it
97                        var _this = this;
98
99                        e && dojo.stopEvent(e);
100
101                        if(!_this._loading){
102                                _this._loading = true;
103                                _this._reset();
104
105                                var i = _this._img = dojo.create("img", {
106                                                style: {
107                                                        visibility: "hidden",
108                                                        cursor: "pointer",
109                                                        position: abs,
110                                                        top: 0,
111                                                        left: 0,
112                                                        zIndex: 9999999
113                                                }
114                                        }, dojo.body()),
115                                        ln = _this._loadingNode,
116                                        n = dojo.query("img", _this._node)[0] || _this._node,
117                                        a = dojo.position(n, true),
118                                        c = dojo.contentBox(n),
119                                        b = dojo._getBorderExtents(n)
120                                ;
121
122                                if(ln == null){
123                                        _this._loadingNode = ln = _this._createDiv("dojoxLoading", _this._node, true);
124                                        var l = dojo.marginBox(ln);
125                                        dojo.style(ln, {
126                                                left: parseInt((c.w - l.w) / 2) + "px",
127                                                top: parseInt((c.h - l.h) / 2) + "px"
128                                        });
129                                }
130
131                                c.x = a.x - 10 + b.l;
132                                c.y = a.y - 10 + b.t;
133                                _this._start = c;
134
135                                _this._connects = [dojo.connect(i, "onload", _this, "_show")];
136
137                                i.src = _this.href;
138                        }
139                },
140
141                _hideLoading: function(){
142                        // summary:
143                        //              Hides the animated loading indicator
144                        if(this._loadingNode){
145                                dojo.style(this._loadingNode, "display", "none");
146                        }
147                        this._loadingNode = false;
148                },
149
150                _show: function(){
151                        // summary:
152                        //              The image is now loaded, calculate size and display
153                        var _this = this,
154                                vp = getViewport(),
155                                w = _this._img.width,
156                                h = _this._img.height,
157                                vpw = parseInt((vp.w - 20) * 0.9),
158                                vph = parseInt((vp.h - 20) * 0.9),
159                                dd = dojo.doc,
160                                bg = _this._bg = dojo.create("div", {
161                                        style: {
162                                                backgroundColor: "#000",
163                                                opacity: 0.0,
164                                                position: abs,
165                                                zIndex: 9999998
166                                        }
167                                }, dojo.body()),
168                                ln = _this._loadingNode
169                        ;
170
171                        if(_this._loadingNode){
172                                _this._hideLoading();
173                        }
174                        dojo.style(_this._img, {
175                                border: "10px solid #fff",
176                                visibility: "visible"
177                        });
178                        dojo.style(_this._node, vis, "hidden");
179
180                        _this._loading = false;
181
182                        _this._connects = _this._connects.concat([
183                                dojo.connect(dd, "onmousedown", _this, "_hide"),
184                                dojo.connect(dd, "onkeypress", _this, "_key"),
185                                dojo.connect(window, "onresize", _this, "_sizeBg")
186                        ]);
187
188                        if(w > vpw){
189                                h = h * vpw / w;
190                                w = vpw;
191                        }
192                        if(h > vph){
193                                w = w * vph / h;
194                                h = vph;
195                        }
196
197                        _this._end = {
198                                x: (vp.w - 20 - w) / 2 + vp.l,
199                                y: (vp.h - 20 - h) / 2 + vp.t,
200                                w: w,
201                                h: h
202                        };
203
204                        _this._sizeBg();
205
206                        dojo.fx.combine([
207                                _this._anim(_this._img, _this._coords(_this._start, _this._end)),
208                                _this._anim(bg, { opacity: 0.5 })
209                        ]).play();
210                },
211
212                _sizeBg: function(){
213                        // summary:
214                        //              Resize the background to fill the page
215                        var dd = dojo.doc.documentElement;
216                        dojo.style(this._bg, {
217                                top: 0,
218                                left: 0,
219                                width: dd.scrollWidth + "px",
220                                height: dd.scrollHeight + "px"
221                        });
222                },
223
224                _key: function(/*Event*/e){
225                        // summary:
226                        //              A key was pressed, so hide the lightbox
227                        dojo.stopEvent(e);
228                        this._hide();
229                },
230
231                _coords: function(/*Object*/s, /*Object*/e){
232                        // summary:
233                        //              Returns animation parameters with the start and end coords
234                        return { // Object
235                                left:   { start: s.x, end: e.x },
236                                top:    { start: s.y, end: e.y },
237                                width:  { start: s.w, end: e.w },
238                                height: { start: s.h, end: e.h }
239                        };
240                },
241
242                _hide: function(){
243                        // summary:
244                        //              Closes the lightbox
245                        var _this = this;
246                        dojo.forEach(_this._connects, dojo.disconnect);
247                        _this._connects = [];
248                        dojo.fx.combine([
249                                _this._anim(_this._img, _this._coords(_this._end, _this._start), "_reset"),
250                                _this._anim(_this._bg, {opacity:0})
251                        ]).play();
252                },
253
254                _reset: function(){
255                        // summary:
256                        //              Destroys the lightbox
257                        dojo.style(this._node, vis, "visible");
258                        dojo.destroy(this._img);
259                        dojo.destroy(this._bg);
260                        this._img = this._bg = null;
261                        this._node.focus();
262                },
263
264                _anim: function(/*DomNode*/node, /*Object*/args, /*Function*/onEnd){
265                        // summary:
266                        //              Creates the lightbox open/close and background fadein/out animations
267                        return dojo.animateProperty({ // dojo.Animation
268                                node: node,
269                                duration: this.duration,
270                                properties: args,
271                                onEnd: onEnd ? dojo.hitch(this, onEnd) : null
272                        });
273                },
274               
275                show: function(/*Object?*/args){
276                        // summary:
277                        //              Shows this LightboxNano programatically. Allows passing a new href and
278                        //              a programmatic origin.
279                        // args: Object?
280                        //              An object with optional members of `href` and `origin`.
281                        //              `origin` can be be a String|Id of a DomNode to use when
282                        //              animating the opening of the image (the 'box' effect starts
283                        //              from this origin point. eg: { origin: e.target })
284                        //              If there's no origin, it will use the center of the viewport.
285                        //              The `href` member is a string URL for the image to be
286                        //              displayed. Omitting either of these members will revert to
287                        //              the default href (which could be absent in some cases) and
288                        //              the original srcNodeRef for the widget.
289                        args = args || {};
290                        this.href = args.href || this.href;
291
292                        var n = dojo.byId(args.origin),
293                                vp = getViewport();
294
295                        // if we don't have a valid origin node, then create one as a reference
296                        // that is centered in the viewport
297                        this._node = n || dojo.create("div", {
298                                        style: {
299                                                position: abs,
300                                                width: 0,
301                                                hieght: 0,
302                                                left: (vp.l + (vp.w / 2)) + "px",
303                                                top: (vp.t + (vp.h / 2)) + "px"
304                                        }
305                                }, dojo.body())
306                        ;
307
308                        this._load();
309
310                        // if we don't have a valid origin node, then destroy the centered reference
311                        // node since load() has already been called and it's not needed anymore.
312                        if(!n){
313                                dojo.destroy(this._node);
314                        }
315                }
316        });
317
318});
Note: See TracBrowser for help on using the repository browser.