MediaWiki:Imagemap-Hightlight.js: Unterschied zwischen den Versionen

Aus FAKTURA-X Wiki
Zur Navigation springen Zur Suche springen
 
(23 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt)
Zeile 13: Zeile 13:
//, areaHighLighting = {fillStyle: 'rgba(0,0,0,0.35)', strokeStyle: 'yellow', lineJoin: 'round', lineWidth: 2}
//, areaHighLighting = {fillStyle: 'rgba(0,0,0,0.35)', strokeStyle: 'yellow', lineJoin: 'round', lineWidth: 2}
                 , areaHighLighting = {fillStyle: 'rgba(0,0,0,0.1)', strokeStyle: 'red', lineJoin: 'round', lineWidth: 2}
                 , areaHighLighting = {fillStyle: 'rgba(0,0,0,0.1)', strokeStyle: 'red', lineJoin: 'round', lineWidth: 2}
                , areaHighLightingAll = {fillStyle: 'rgba(0,0,0,0)', strokeStyle: 'red', lineJoin: 'round', lineWidth: 2}
//every imagemap that wants highlighting, should reside in a div of this 'class':
//every imagemap that wants highlighting, should reside in a div of this 'class':
, hilightDivMarker = '.imageMapHighlighter'
, hilightDivMarker = '.imageMapHighlighter'
Zeile 23: Zeile 24:
   
   
   
   
function drawMarker(context, areas) { // this is where the magic is done.
function drawMarker(context, areas) { // this is where the magic is done.
   
   
function drawPoly(coords) {
function drawPoly(coords) {
Zeile 45: Zeile 46:
}
}
   
   
function viewElement(e) {
function mouseAction(e) {
var $this = $(this),
var $this = $(this),
context = $this.data('context'),
context = $this.data('context');
activate = 1,
$.extend(context, areaHighLighting);
var activate = e.type == 'mouseenter';
li = $this.prop('tagName') == 'LI';
li = $this.prop('tagName') == 'LI';
if (li && activate) { // in this case, we need to test visibility vis a vis scrolling
if (li && activate) { // in this case, we need to test visibility vis a vis scrolling
Zeile 57: Zeile 59:
ol.animate({scrollTop: ol.scrollTop() + top - ol.height() / 2});
ol.animate({scrollTop: ol.scrollTop() + top - ol.height() / 2});
}
}
//$this.toggleClass(liHighlightClass, activate);
$this.toggleClass(liHighlightClass, activate);
//context.clearRect(0, 0, context.canvas.width, context.canvas.height);
context.clearRect(0, 0, context.canvas.width, context.canvas.height);
if (activate) {
if (activate) {
drawMarker(context, $this.data('areas'));
drawMarker(context, $this.data('areas'));
Zeile 67: Zeile 69:
}
}
}
}
function mouseActionAll(e) {
var $this = $(this),
context = $this.data('context'),
map = $this.data('map');
$.extend(context, areaHighLightingAll);
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"
// massage the area "href" and create a human legible string to be used as the tooltip of "li"
function pageOfHref(href, cssClass) {
function pageOfHref(href, cssClass) {
var page = href.replace(document.location.protocol + wgServer + "/wiki/", '').replace(/.*\/\//, '').replace(/_/g, ' ');
var page = href.replace(document.location.protocol + mw.config.get( 'wgServerName' ) + "/wiki/", '').replace(/.*\/\//, '').replace(/_/g, ' '); /*JSC 210819: veraltete Funktion ausgetauscht */
page = page.replace(/#(.*)/, function(toReplace){return toReplace.replace(/\.([\dA-F]{2})/g, '%$1');});
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.
page = decodeURIComponent(page); // used for "title" of legends - just like "normal" wiki links.
Zeile 79: Zeile 98:
   
   
function init() {
function init() {
appendCSS('li.' + myClassName + '{white-space:nowrap;}\n' + //css for li element
mw.util.addCSS('li.' + myClassName + '{white-space:nowrap;}\n' + //css for li element
'li.' + liHighlightClass + '{background-color:yellow;}\n' + //css for highlighted li element.
'li.' + liHighlightClass + '{background-color:yellow;}\n' + //css for highlighted li element.
'.rtl li.' + myClassName + '{float: right; margin-left: 3em;}\n' +
'.rtl li.' + myClassName + '{float: right; margin-left: 3em;}\n' +
Zeile 107: Zeile 126:
img.fadeTo(1, 0); // make the image transparent - we see canvas and bgimg through it.
img.fadeTo(1, 0); // make the image transparent - we see canvas and bgimg through it.
var ol = $('<ol>', {'class': myClassName})
var ol = $('<ol>', {'class': myClassName})
.css({clear: 'both', margin: 0, listStyle: 'none', maxHeight: '24em', maxWidth: w + 'px', overflowY: 'auto', position: 'relative'})
.css({clear: 'both', margin: 0, listStyle: 'none', maxWidth: w + 'px', float: 'left', position: 'relative', display: 'none'})
.attr({'data-expandtext' : expandLegend, 'data-collapsetext': collapseLegend});
.attr({'data-expandtext' : expandLegend, 'data-collapsetext': collapseLegend});
                       
// ol below image, hr below ol. original caption pushed below hr.
// ol below image, hr below ol. original caption pushed below hr.
div.after($('<hr>', {'class': myClassName}).css('clear', 'both')).after(ol);
//div.after($('<hr>', {'class': myClassName}).css('clear', 'both')).after(ol);
var lis = {}; //collapse areas with same caption to one list item
var lis = {}; //collapse areas with same caption to one list item
$('area', map).each(function() {
$('area', map).each(function() {
Zeile 119: Zeile 137:
var href = this.href, cssClass = this['class'] || '';
var href = this.href, cssClass = this['class'] || '';
lis[text] = li = $('<li>', {'class': myClassName})
lis[text] = li = $('<li>', {'class': myClassName})
.append($('{{a}}', {href: href, title: pageOfHref(href, cssClass), text: text, 'class': cssClass}))
.append($('<a>', {href: href, title: pageOfHref(href, cssClass), text: text, 'class': cssClass}))  
                                                .css({fillStyle: 'rgba(0,0,0,0.1)', strokeStyle: 'red', lineJoin: 'round', lineWidth: 2})
.bind('mouseenter mouseleave', mouseAction)
                                                .bind('mouseover mouseout', viewElement)
.data('areas', [])
.data('areas', [])
.data('context', context)
.data('context', context)
.appendTo(ol);
.appendTo(ol);
                                        viewElement();
}
}
li.data('areas').push(this); //add the area to the li
li.data('areas').push(this); //add the area to the li
$(this).bind('mouseover mouseout', function(e) {li.trigger(e);})
$(this).bind('mouseenter mouseleave', function(e) {li.trigger(e);})
});
});
$(this).bind('mouseenter mouseleave', mouseActionAll)
.data('context', context)
.data('map', map);
ol.addClass('mw-collapsed')
ol.addClass('mw-collapsed')
.makeCollapsible();
.makeCollapsible();

Aktuelle Version vom 19. Juni 2021, 15:36 Uhr

// Hervorheben der klickbaren Felder einer Imagemap.
// Modifiziert von:
// http://he.wikipedia.org/wiki/%D7%9E%D7%93%D7%99%D7%94_%D7%95%D7%99%D7%A7%D7%99:Imagemap-Highlight.js

$(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(0,0,0,0.35)', strokeStyle: 'yellow', lineJoin: 'round', lineWidth: 2}
                , areaHighLighting = {fillStyle: 'rgba(0,0,0,0.1)', strokeStyle: 'red', lineJoin: 'round', lineWidth: 2}
                , areaHighLightingAll = {fillStyle: 'rgba(0,0,0,0)', strokeStyle: 'red', lineJoin: 'round', lineWidth: 2}
//every imagemap that wants highlighting, should reside in a div of this 'class':
		, hilightDivMarker = '.imageMapHighlighter'
// specifically for wikis - redlinks tooltip adds this message
		, de = mw && mw.config && mw.config.get('wgUserLanguage') == 'de'
		, pageDoesntExistMessage = ' (Seite existiert nicht)'
		                , expandLegend = 'ּVerknüpfungen anzeigen'
		, collapseLegend = 'Verknüpfungen verstecken'
		;
 
 
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 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');
		$.extend(context, areaHighLighting);
		var activate = e.type == 'mouseenter';
			li = $this.prop('tagName') == 'LI';
		if (li && activate) { // in this case, we need to test visibility vis a vis scrolling
			var height = $this.height(),
				ol = $this.parent(),
				top = $this.position().top;
			if (top < 0 || top + height > ol.height()) 
				ol.animate({scrollTop: ol.scrollTop() + top - ol.height() / 2});
		}
		$this.toggleClass(liHighlightClass, activate);
		context.clearRect(0, 0, context.canvas.width, context.canvas.height);
		if (activate) {
			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);
		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 + mw.config.get( 'wgServerName' ) + "/wiki/", '').replace(/.*\/\//, '').replace(/_/g, ' '); /*JSC 210819: veraltete Funktion ausgetauscht */
		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 + '{background-color:yellow;}\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', margin: 0, listStyle: 'none', maxWidth: w + 'px', float: 'left', position: 'relative', display: 'none'})
				.attr({'data-expandtext' : expandLegend, 'data-collapsetext': collapseLegend});
			// 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('context', context)
						.appendTo(ol);
				}
				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);
			ol.addClass('mw-collapsed')
			.makeCollapsible();
		});
	}
 
	//has at least one "imagehighlight" div, and canvas-capable browser:
	if ($(hilightDivMarker).length && $('<canvas>')[0].getContext)
		mw.loader.using('jquery.makeCollapsible', init);
});