MediaWiki:Imagemap-Highlight.js
来自百问网嵌入式Linux wiki
注意:在保存之后,您可能需要清除浏览器缓存才能看到所作出的变更的影响。
- Firefox或Safari:按住Shift的同时单击刷新,或按Ctrl-F5或Ctrl-R(Mac为⌘-R)
- Google Chrome:按Ctrl-Shift-R(Mac为⌘-Shift-R)
- Internet Explorer:按住Ctrl的同时单击刷新,或按Ctrl-F5
- Opera:前往菜单 → 设置(Mac为Opera → Preferences),然后隐私和安全 → 清除浏览数据 → 缓存的图片和文件。
$(document).ready(function() {
var
//add this class to all elements created by the script. the reason is that we call the script again on
//window resize, and use the class to remove all the "artefacts" we created in the previous run.
myClassName = 'imageMapHighlighterArtefacts',
liHighlightClass = 'liHighlighting',
// "2d context" attributes used for highlighting.
areaHighLighting = {fillStyle: 'rgba(41,59,107,0.4)', strokeStyle: 'rgba(41,59,107,1.0)', lineJoin: 'round', lineWidth: 4,
shadowOffsetX: 0, shadowOffsetY: 0, shadowBlur: 0, shadowColor: 'white'},
areaHighLightingAll = {fillStyle: 'rgba(185,196,202,0.0)', strokeStyle: 'rgba(41,59,107,1.0)', lineJoin: 'round', lineWidth: 4,
shadowOffsetX: 0, shadowOffsetY: 0, shadowBlur: 0, shadowColor: 'white'},
//every imagemap that wants highlighting, should reside in a div of this 'class':
hilightDivMarker = '.imageMapHighlighter',
// specifically for wikis - redlinks tooltip adds this message
pageDoesntExistMessage = (mw && mw.config && mw.config.get('wgUserLanguage') == 'he')
? ' (??? ???? ????)'
: ' (page does not exist)';
function drawMarker(context, areas) { // this is where the magic is done.
function drawPoly(coords) {
context.moveTo(coords.shift(), coords.shift());
while (coords.length)
context.lineTo(coords.shift(), coords.shift());
}
for (var i in areas) {
var area = areas[i];
if( !area.coords ) {
continue;
}
var coords = areas[i].coords.split(',');
context.beginPath();
switch (areas[i].shape) {
case 'rect': drawPoly([coords[0], coords[1], coords[0], coords[3], coords[2], coords[3], coords[2], coords[1]]); break;
case 'circle': context.arc(coords[0],coords[1],coords[2],0,Math.PI*2); break;//x,y,r,startAngle,endAngle
case 'poly': drawPoly(coords); break;
}
context.closePath();
context.stroke();
context.fill();
}
}
function mouseAction(e) {
var $this = $(this),
context = $this.data('context'),
map = $this.data('map');
$.extend(context, areaHighLightingAll);
var activate = e.type == 'mouseenter';
$this.toggleClass(liHighlightClass, activate);
context.clearRect(0, 0, context.canvas.width, context.canvas.height);
//console.log("mouseAction " + activate);
if (activate) {
$('area', map).each(function() {
var $this = $(this), text = this.title, areas = new Array();
areas.push(this);
drawMarker(context, areas);
});
$.extend(context, areaHighLighting);
drawMarker(context, $this.data('areas'));
//if ($.client.profile().name === 'msie') { // ie9: dimwit needs to be told twice.
// context.clearRect(0, 0, context.canvas.width, context.canvas.height);
// drawMarker(context, $this.data('areas'));
//}
}
}
function mouseActionAll(e) {
var $this = $(this),
context = $this.data('context'),
map = $this.data('map');
$.extend(context, areaHighLightingAll);
//console.log("mouseActionAll " + e.type);
if (e.type == 'mouseenter') {
$('area', map).each(function() {
var $this = $(this), text = this.title, areas = new Array();
areas.push(this);
drawMarker(context, areas);
});
} else {
context.clearRect(0, 0, context.canvas.width, context.canvas.height);
}
}
// massage the area "href" and create a human legible string to be used as the tooltip of "li"
function pageOfHref(href, cssClass) {
var page = href.replace(document.location.protocol + wgServer + "/wiki/", '').replace(/.*\/\//, '').replace(/_/g, ' ');
page = page.replace(/#(.*)/, function(toReplace){return toReplace.replace(/\.([\dA-F]{2})/g, '%$1');});
page = decodeURIComponent(page); // used for "title" of legends - just like "normal" wiki links.
if (cssClass.indexOf('new') + 1)
page += pageDoesntExistMessage;
return page;
}
function init() {
mw.util.addCSS('li.' + myClassName + '{white-space:nowrap;}\n' + //css for li element
'li.' + liHighlightClass + '{text-decoration: underline;}\n' + //css for highlighted li element.
'.rtl li.' + myClassName + '{float: right; margin-left: 3em;}\n' +
'.ltr li.' + myClassName + '{float: left; margin-right: 3em;}');
$(hilightDivMarker+ ' img').each(function() {
var img = $(this), map = img.siblings('map:first');
if (!('area', map).length)
return; //not an imagemap. inside "each" anonymous function, 'return' means "continue".
var w = img.width(), h = img.height();
var dims = {position: 'absolute', width: w + 'px', height: h + 'px', border: 0, top:0, left:0};
var jcanvas = $('<canvas>', {'class': myClassName})
.css(dims)
.attr({width: w, height: h});
var bgimg = $('<img>', {'class': myClassName, src: img.attr('src')})
.css(dims);//completely inert image. this is what we see.
var context = $.extend(jcanvas[0].getContext("2d"), areaHighLighting);
// this is where the magic is done: prepare a sandwich of the inert bgimg at the bottom,
// the canvas above it, and the original, image, on top.
// so canvas won't steal the mouse events.
// pack them all TIGHTLY in a newly minted "relative" div, so when page chnage
// (other scripts adding elements, window resize etc.), canvas and imagese remain aligned.
var div = $('<div>').css({position: 'relative', width: w + 'px', height: h + 'px'});
img.before(div); // put the div just above the image, and ...
div.append(bgimg) // place the background image in the div
.append(jcanvas)// and the canvas. both are "absolute", so they don't occupy space in the div
.append(img); // now yank the original image from the window and place it on top.
img.fadeTo(1, 0); // make the image transparent - we see canvas and bgimg through it.
var ol = $('<ol>', {'class': myClassName}).css({clear: 'both', marginTop: '1.5em', paddingLeft: '1.5em'});
// ol below image, hr below ol. original caption pushed below hr.
div.after($('<hr>', {'class': myClassName}).css('clear', 'both')).after(ol);
var lis = {}; //collapse areas with same caption to one list item
$('area', map).each(function() {
var $this = $(this), text = this.title;
var li = lis[text]; // title already met? use the same li
if (!li) { //no? create a new one.
var href = this.href, cssClass = this['class'] || '';
lis[text] = li = $('<li>', {'class': myClassName})
.append($('<a>', {href: href, title: pageOfHref(href, cssClass), text: text, 'class': cssClass}))
.bind('mouseenter mouseleave', mouseAction)
.data('areas', [])
.data('map', map)
.data('context', context);
ol.append(li);
}
li.data('areas').push(this); //add the area to the li
$(this).bind('mouseenter mouseleave', function(e) {li.trigger(e);})
});
$(this).bind('mouseenter mouseleave', mouseActionAll)
.data('context', context)
.data('map', map);
});
}
//has at least one "imagehighlight" div, and canvas-capable browser:
if ($(hilightDivMarker).length && $('<canvas>')[0].getContext)
init();
});