[483] | 1 | define(["dojo/_base/kernel", "dojo/_base/declare", "dijit/_Widget", "dojo/dom-construct", "dojo/dom-style", "dojo/dom-geometry", "dojo/_base/window", "dojo/_base/lang"], function(kernel, declare, _Widget, construct, style, geometry, window, lang){ |
---|
| 2 | |
---|
| 3 | kernel.experimental("dojox.image.MagnifierLite"); |
---|
| 4 | |
---|
| 5 | return declare("dojox.image.MagnifierLite", _Widget, { |
---|
| 6 | // summary: |
---|
| 7 | // Adds magnification on a portion of an image element |
---|
| 8 | // description: |
---|
| 9 | // An unobtrusive way to add an unstyled overlay |
---|
| 10 | // above the srcNode image element. The overlay/glass is a |
---|
| 11 | // scaled version of the src image (so larger images sized down |
---|
| 12 | // are clearer). |
---|
| 13 | // |
---|
| 14 | // The logic behind requiring the src image to be large is |
---|
| 15 | // "it's going to be downloaded, anyway" so this method avoids |
---|
| 16 | // having to make thumbnails and 2 http requests among other things. |
---|
| 17 | |
---|
| 18 | // glassSize: Int |
---|
| 19 | // the width and height of the bounding box |
---|
| 20 | glassSize: 125, |
---|
| 21 | |
---|
| 22 | // scale: Decimal |
---|
| 23 | // the multiplier of the Mangification. |
---|
| 24 | scale: 6, |
---|
| 25 | |
---|
| 26 | postCreate: function(){ |
---|
| 27 | this.inherited(arguments); |
---|
| 28 | |
---|
| 29 | // images are hard to make into workable templates, so just add outer overlay |
---|
| 30 | // and skip using dijit._Templated |
---|
| 31 | this._adjustScale(); |
---|
| 32 | this._createGlass(); |
---|
| 33 | |
---|
| 34 | this.connect(this.domNode,"onmouseenter","_showGlass"); |
---|
| 35 | this.connect(this.glassNode,"onmousemove","_placeGlass"); |
---|
| 36 | this.connect(this.img,"onmouseout","_hideGlass"); |
---|
| 37 | |
---|
| 38 | // when position of domNode changes, _adjustScale needs to run. |
---|
| 39 | // window.resize isn't it always, FIXME: |
---|
| 40 | this.connect(window,"onresize","_adjustScale"); |
---|
| 41 | }, |
---|
| 42 | |
---|
| 43 | _createGlass: function(){ |
---|
| 44 | // summary: |
---|
| 45 | // make img and glassNode elements as children of the body |
---|
| 46 | |
---|
| 47 | var node = this.glassNode = construct.create('div', { |
---|
| 48 | style: { |
---|
| 49 | height: this.glassSize + "px", |
---|
| 50 | width: this.glassSize + "px" |
---|
| 51 | }, |
---|
| 52 | className: "glassNode" |
---|
| 53 | }, window.body()); |
---|
| 54 | |
---|
| 55 | this.surfaceNode = node.appendChild(construct.create('div')); |
---|
| 56 | |
---|
| 57 | this.img = construct.place(lang.clone(this.domNode), node); |
---|
| 58 | // float the image around inside the .glassNode |
---|
| 59 | style.set(this.img, { |
---|
| 60 | position: "relative", |
---|
| 61 | top: 0, left: 0, |
---|
| 62 | width: this._zoomSize.w + "px", |
---|
| 63 | height: this._zoomSize.h + "px" |
---|
| 64 | }); |
---|
| 65 | }, |
---|
| 66 | |
---|
| 67 | _adjustScale: function(){ |
---|
| 68 | // summary: |
---|
| 69 | // update the calculations should this.scale change |
---|
| 70 | |
---|
| 71 | this.offset = geometry.position(this.domNode, true); |
---|
| 72 | console.dir(this.offset); |
---|
| 73 | this._imageSize = { w: this.offset.w, h:this.offset.h }; |
---|
| 74 | this._zoomSize = { |
---|
| 75 | w: this._imageSize.w * this.scale, |
---|
| 76 | h: this._imageSize.h * this.scale |
---|
| 77 | }; |
---|
| 78 | }, |
---|
| 79 | |
---|
| 80 | _showGlass: function(e){ |
---|
| 81 | // summary: |
---|
| 82 | // show the overlay |
---|
| 83 | this._placeGlass(e); |
---|
| 84 | style.set(this.glassNode, { |
---|
| 85 | visibility: "visible", |
---|
| 86 | display:"" |
---|
| 87 | }); |
---|
| 88 | }, |
---|
| 89 | |
---|
| 90 | _hideGlass: function(e){ |
---|
| 91 | // summary: |
---|
| 92 | // hide the overlay |
---|
| 93 | style.set(this.glassNode, { |
---|
| 94 | visibility: "hidden", |
---|
| 95 | display:"none" |
---|
| 96 | }); |
---|
| 97 | }, |
---|
| 98 | |
---|
| 99 | _placeGlass: function(e){ |
---|
| 100 | // summary: |
---|
| 101 | // position the overlay centered under the cursor |
---|
| 102 | |
---|
| 103 | this._setImage(e); |
---|
| 104 | var sub = Math.floor(this.glassSize / 2); |
---|
| 105 | style.set(this.glassNode,{ |
---|
| 106 | top: Math.floor(e.pageY - sub) + "px", |
---|
| 107 | left:Math.floor(e.pageX - sub) + "px" |
---|
| 108 | }); |
---|
| 109 | }, |
---|
| 110 | |
---|
| 111 | _setImage: function(e){ |
---|
| 112 | // summary: |
---|
| 113 | // set the image's offset in the clipping window relative to the mouse position |
---|
| 114 | |
---|
| 115 | var xOff = (e.pageX - this.offset.x) / this.offset.w, |
---|
| 116 | yOff = (e.pageY - this.offset.y) / this.offset.h, |
---|
| 117 | x = (this._zoomSize.w * xOff * -1) + (this.glassSize * xOff), |
---|
| 118 | y = (this._zoomSize.h * yOff * -1) + (this.glassSize * yOff); |
---|
| 119 | |
---|
| 120 | style.set(this.img, { |
---|
| 121 | top: y + "px", |
---|
| 122 | left: x + "px" |
---|
| 123 | }); |
---|
| 124 | }, |
---|
| 125 | |
---|
| 126 | destroy: function(finalize){ |
---|
| 127 | construct.destroy(this.glassNode); |
---|
| 128 | this.inherited(arguments); |
---|
| 129 | } |
---|
| 130 | |
---|
| 131 | }); |
---|
| 132 | }); |
---|