xref: /plugin/magnifier/script.js (revision e2b9f9ac75051a415ac1ea1f9bc9bdb64a9f7dd4)
1(function ($){
2
3    var addCSSRule = (function(style){
4        var head = document.head || jQuery("head")[0] || document.documentElement;
5        var sheet = head.appendChild(style).sheet;
6        return function(selector, css){
7            var propText = Object.keys(css).map(function(p){
8                return p+":"+css[p];
9            }).join(";");
10            sheet.insertRule(selector + "{" + propText + "}", sheet.cssRules.length);
11            return sheet;
12        };
13    })(document.createElement("style"));
14
15    /**
16     * normalizeEvent
17     *
18     * Firefox does not implement offsetX, OffsetY, so we have to detect for this an
19     * manually calculate it ourselves using the pageX, pageY less the event
20     * target's left offset and right offset
21     *
22     * If using a browser that supports offsetX, OffsetY, just return the event,
23     * don't need to do anything
24     */
25    var normalizeEvent = function(event) {
26      if(!event.offsetX) {
27        event.offsetX = (event.pageX - $(event.target).offset().left);
28        event.offsetY = (event.pageY - $(event.target).offset().top);
29      }
30      return event.data;
31    };
32
33    // private
34    var magnifier = function(){
35
36        this.rootNode = null;
37        this.magnifierImage = null;
38        this.magnifierContent = null;
39    };
40
41    (function(_){
42
43        var magnifierRoot = null;
44        var currentAngleSheet = null;
45
46        _.init = function(magnifierNode) {
47
48            this.rootNode = magnifierNode;
49            this.magnifierImage = new Image();
50            this.magnifierImage.src = this.rootNode.attr('magnifierImage');
51
52            // register other handlers
53            this.rootNode.mousemove(this, _.mousemove);
54            this.rootNode.mouseout(this, _.mouseout);
55            this.rootNode.mouseover(this, _.mouseover);
56        };
57
58        _.mouseover = function(event)
59        {
60            var $$ = normalizeEvent(event);
61            if ( magnifierRoot == null ) {
62
63                magnifierRoot = $('<svg></svg>').addClass('magnifierWrapper').attr('pointer-events', 'none');
64                $$.magnifierContent = $('<rect></rect>').addClass('magnifierContent').css('backgroundImage', 'url(' + $$.rootNode.attr('magnifierImage') + ')');
65                magnifierRoot.append($$.magnifierContent);
66
67                // macht im Opera Problem ...
68                $("body").append(magnifierRoot);
69            }
70
71            _.mousemove(event);
72        };
73
74        _.mousemove = function(event)
75        {
76            var $$ = normalizeEvent(event);
77            _.setPosition(event.pageX,event.pageY, event.offsetX, event.offsetY, $$);
78        };
79
80        _.mouseout = function(event)
81        {
82            var $$ = normalizeEvent(event);
83            var rootOffset = $$.rootNode.offset();
84            // Check Position over Element before removing!
85            if ( rootOffset.left > event.offsetX ||
86                 (rootOffset.left + $$.rootNode.width()) < event.offsetX ||
87                 rootOffset.top < event.offsetY ||
88                 (rootOffset.top + rootOffset.height) > event.offsetY )
89                 {
90                    if ( magnifierRoot ) {
91                        magnifierRoot.remove();
92                        magnifierRoot = null;
93                    }
94                 }
95        };
96
97        _.setPosition = function(x, y, contentX, contentY, $$)
98        {
99            if ( !$$ || !$$.magnifierImage || !contentX || !contentY || !$$.magnifierContent ) {
100                return;
101            }
102
103            // Background position
104            var posX = -(contentX / $$.rootNode.width() * $$.magnifierImage.width - $$.magnifierContent.width() / 2);
105            var posY = -(contentY / $$.rootNode.height() * $$.magnifierImage.height - $$.magnifierContent.height() / 2);
106
107            // Radial position
108            var position = (1 / $$.rootNode.width() * ($$.rootNode.width() - contentX));
109            var arc = -(110 * position + 35) * Math.PI / 180;
110
111            var left0 = 202;
112            var top0 = 0;
113
114            var left = left0 * Math.cos(arc) - top0 * Math.sin(arc) - 165;
115            var top = left0 * Math.sin(arc) + top0 * Math.cos(arc) + 113;
116            var angle = 'rotate(' + (position * -110) + 'deg)';
117
118            if ( currentAngleSheet != null ) {
119                $(currentAngleSheet).remove();
120            }
121
122            currentAngleSheet = addCSSRule("div.magnifierWrapper:after,svg.magnifierWrapper:after", {
123                                                                '-webkit-transform': angle,
124                                                                '-moz-transform': angle,
125                                                                '-o-transform': angle,
126                                                                '-ms-transform': angle
127                                    });
128
129            $$.magnifierContent.css({
130                                        'background-position': posX + "px " + posY + "px",
131                                        'backgroundPositionX': posX,
132                                        'backgroundPositionY': posY,
133                                        'margin-left' : left,
134                                        'margin-top': top
135                                    });
136
137            if ( !magnifierRoot || !x || !y ) {
138                return;
139            }
140
141            magnifierRoot.offset({ left:x - 18, top: y - magnifierRoot.height() });
142        };
143
144    })(magnifier.prototype);
145
146    // public
147    $.magnify = function(magnifierNode) {
148        return (new magnifier()).init(magnifierNode);
149    };
150
151    $(function(){
152        $('img.magnifierImage').each(function(index, item){
153            $.magnify($(item));
154        });
155    });
156
157})(jQuery);
158