User:Xover/loupe.js

/* global $, mw */ "use strict";

console.log("loupe.js loading");

// Make sure the necessary modules are loaded mw.loader.using(['mediawiki.util', 'mediawiki.api'], function {	console.log("loupe.js in mw.loader.using");

// Wait for the page to be parsed (new-style $(document).ready) $(function { 	console.log("loupe.js in $(document).ready");   // Only active on Page:-namespace pages.    if (mw.config.get('wgCanonicalNamespace') !== 'Page') {      return;    }	console.log("loupe.js passed namespace check");

// Page image is statically positioned in view mode, so force it to relative if (mw.config.get('wgAction') == 'view') { $('.prp-page-image').css('position', 'relative'); }

// Pre-load loading GIF var loadingGifUrl = '//upload.wikimedia.org/wikipedia/commons/4/42/Loading.gif'; $(' ').attr('src', loadingGifUrl).appendTo('body').hide;

// Track whether full-sized image has loaded var fullwidth_image_loaded = false;

// Set up the loupe var loupe = $(' ').attr('id', 'loupe').css({      'width': '200px',      'height': '125px',      'position': 'absolute',      'border-radius': '.2ex',      'box-shadow': '0 0 0 1px rgba(0, 0, 0, 0.85), 0 0 7px 7px rgba(0, 0, 0, 0.25), inset 0 0 40px 2px rgba(0, 0, 0, 0.25)',      'background-color': 'white',      'background-image': "url('" + loadingGifUrl + "')",      'background-repeat': 'no-repeat',      'background-position': 'center',      'cursor': 'crosshair',      'display': 'none'    }).appendTo('.mw-content-text').hide;

var fullsize_width = $('.prp-page-image img').data('fileWidth');

var match = /(.*?)\/(\d+)/.exec(mw.config.get('wgTitle')); var file = match[1]; var page = match[2];

console.log("loupe.js about to call API");

var api = new mw.Api; api.get({     'action': 'query',      'prop': 'imageinfo',      'titles': "File:" + file,      'formatversion': 2,      'format': 'json',      'iiprop': 'url',      'iiurlwidth': fullsize_width,      'iiurlparam': "page" + page + "-" + fullsize_width + "px"    }) .done(function(data) {     console.log("loupe.js API call called .done(" + data.query.pages[0].imageinfo[0].thumburl + ")");      var thumburl = data.query.pages[0].imageinfo[0].thumburl;      $(' ').on('load', {thumburl: thumburl}, function(e) { console.log("loupe.js DOM called .on(load)"); var thumburl = e.data.thumburl; fullwidth_image_loaded = true; $('#loupe').css({'background-image': "url('" + thumburl + "')"}); }).attr('src', thumburl).appendTo('body').hide;   });

// Now set up the mouse tracking and loupe display $('.prp-page-image').mousemove(function(e) {     var img = $('.prp-page-image img');      var img_offset = img.offset;      var imgX = img_offset.left;      var imgY = img_offset.top;      var imgW = img.width;      var imgH = img.height;

// Subtract the page image container offsets from the mouse offsets to     // make the mouse offsets relative to the page image container. var mX = e.pageX - imgX; var mY = e.pageY - imgY; // Fade in the loupe if the mouse offsets are within the bounds of the // page image container. Otherwise, fade it out. //     // Apply a safety margin since mousemove events are coalesced and there is      // a window where the mouse can be outside .prp-page-image, so it no      // longer gets mousemove events, but still inside the image rectangle so      // it doesn't fade the loupe out. // FIXME: Should get clever with .mouseenter here instead. var fuzz = 5; var insideRightEdge = mX < (imgW - fuzz) ? true : false; var insideLeftEdge  = mX > (   0 + fuzz) ? true : false; var insideTopEdge   = mY < (imgH - fuzz) ? true : false; var insideBottomEdge = mY > (  0 + fuzz) ? true : false; if (insideRightEdge && insideLeftEdge && insideTopEdge && insideBottomEdge) { $("#loupe").fadeIn(200); } else { $("#loupe").fadeOut(200); }

// Position full-resolution image relative to mouse position so that the // magnification effect works. if ($('#loupe').is(':visible')) { // Calculate the position of the loupe relative to the mouse position. var loupe_left = mX - ($('#loupe').width / 2); var loupe_top = mY - ($('#loupe').height / 2);

// Percentage offset of the mouse pointer in the small image, which // translates to a percentage offset for the large image. // FIXME: Need an "accelleration curve" here, so that the offset between // the mouse position (center) and edge of the loupe doesn't cut off the // edge of the image (problem on tight margins). var bgposition_left = (100 / imgW) * mX; var bgposition_top = (100 / imgH) * mY; var bgposition = bgposition_left + "% " + bgposition_top + "%"; if (!fullwidth_image_loaded) { bgposition = 'center'; }       // Position the loupe and background. $("#loupe").css({left: loupe_left, top: loupe_top, backgroundPosition: bgposition}); }   });

}); // END: $(document).ready }); // END: mw.loader.using