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