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