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