source: Dev/branches/rest-dojo-ui/client/dojox/image/LightboxNano.js @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

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