User:JPxG/CSSImageCrop.js

/*** CSS Image Crop ***/

// A utility to use to crop an image // Documentation at en:w:User:BrandonXLF/CSSImageCrop // By en:w:User:BrandonXLF function resetfields { document.getElementById("widthinput").value = "300"; document.getElementById("heightinput").value = "300"; document.getElementById("leftinput").value = "0"; document.getElementById("topinput").value = "0"; update; } $(function {	var sampleImg = 'https://upload.wikimedia.org/wikipedia/commons/c/ca/1x1.png';

mw.util.addPortletLink('p-tb', mw.util.getUrl('Special:BlankPage/CSSImageCrop'), 'CSS image crop');

function clamp(min, x, max) { return Math.min(max, Math.max(min, x)); }

function update { var mult = img.width / size.val, mult2 = size.val / img.width; area.css({			left: clamp(0, left.val, (parent.width * mult2) - parseInt(area.css('right'))) * mult + 'px',			top: clamp(0, top.val, (parent.height * mult2)  - parseInt(area.css('bottom'))) * mult + 'px',			right: clamp(0, (parent.width * mult2) - width.val - left.val, (parent.width * mult2) - parseInt(area.css('left'))) * mult + 'px',			bottom: clamp(0, (parent.height * mult2)  - height.val - top.val, (parent.height * mult2) - parseInt(area.css('top'))) * mult + 'px'

});		setcode;	}

function setcode { var mult = size.val / img.width; width.val(Math.round(area.width * mult)); height.val(Math.round(area.height * mult)); left.val(Math.round(area.position.left * mult)); top.val(Math.round(area.position.top * mult)); makecode; }

function makecode { textarea.val(			''		); }

function repos(ele, func) { ele.on('mousedown', function(e) {			e.stopPropagation;			function move(e) {				func(e);				setcode;			}			function up {				$(document.body).off('mousemove', move);				$(document.body).off('mouseup', up);			}			$(document.body).on('mousemove', move);			$(document.body).on('mouseup', up);		}); }

var parent = $(' '), area = $(''), img = $('').on('load', function {			if (!$('#img').attr('data-loaded')) {				$('#img').attr('data-loaded', 'true');				return;			}			$('#img').width($('#img').get(0).naturalWidth);			size.val($('#img').get(0).naturalWidth);		}), north = $(' '), south = $(' '), east = $(' '), west = $(' '), file = $('').on('change', function {			img.attr('src', 'https://en.wikipedia.org/wiki/Special:Filepath/' + file.val);		}), size = $('').on('change', setcode), textarea = $(''), button = $('Reset fields '), width = $('').on('change', update), height = $('').on('change', update), left = $('').on('change', update), top = $('').on('change', update), location = $(			'' +			' (none) ' +			' none ' +			' right ' +			' left ' +			' center ' +			' '		).on('change', makecode), desc = $('').on('change', makecode);

if (mw.config.get('wgCanonicalSpecialPageName') == 'Blankpage' && window.location.href.includes('CSSImageCrop')) { mw.util.$content.find('.mw-body-content') .html(' CSS Image Crop ') .append($(' ')				.append($(' ') .append(' File: ') .append($('').append(file)) )				.append($(' ') .append(' Size: ') .append($('').append(size)) )				.append('  ')				.append($(' ') .append(' ') .append($('')						.append(parent .append(img) .append(area								.append(west)								.append(east)								.append(north)								.append(south)								.append($(' ') .on('mousedown', function(e) {										e.stopPropagation;										north.trigger('mousedown');										west.trigger('mousedown');									}) )								.append($(' ') .on('mousedown', function(e) {										e.stopPropagation;										north.trigger('mousedown');										east.trigger('mousedown');									}) )								.append($(' ') .on('mousedown', function(e) {										e.stopPropagation;										south.trigger('mousedown');										west.trigger('mousedown');									}) )								.append($(' ') .on('mousedown', function(e) {										e.stopPropagation;										south.trigger('mousedown');										east.trigger('mousedown');									}) )							)						)					)				)				.append($(' ') .append(' Auto: ') .append($('').append(button)) )				.append($(' ') .append(' Width: ') .append($('<td style="width:100%;">').append(width)) )				.append($(' ') .append(' Height: ') .append($('<td style="width:100%;">').append(height)) )				.append($(' ') .append(' Left: ') .append($('<td style="width:100%;">').append(left)) )				.append($(' ') .append(' Top: ') .append($('<td style="width:100%;">').append(top)) )				.append('  ')				.append($(' ') .append(' <abbr title="Position">Pos : ') .append($('<td style="width:100%;">').append(location)) )				.append($(' ') .append(' Desc: ') .append($('<td style="width:100%;">').append(desc)) )				.append('  ')				.append($(' ') .append(' ') .append($('<td style="width:100%;">')						.append($(' ') .append(textarea) .append($( ' Preview ' + '<a href="https://en.wikipedia.org/wiki/Template:CSS_image_crop">Template:CSS image crop</a>' ).on('click', function { $.post('https://en.wikipedia.org/w/api.php?origin=*', {									action: 'parse',									text: textarea.val,									format: 'json',									prop: 'text'								}).done(function(res) {									$('#res').css('marginTop', '8px').html(res.parse.text['*']);								}); }))							.append($(' ')) )					)				)			);

repos(west, function(e) {			area.css('left', clamp(0, e.pageX - parent.position.left, parent.width - parseInt(area.css('right'))));		});

repos(east, function(e) {			area.css('right', clamp(0, parent.width - e.pageX + parent.position.left, parent.width - parseInt(area.css('left'))));		});

repos(north, function(e) {			area.css('top', clamp(0, e.pageY - parent.position.top, parent.height - parseInt(area.css('bottom'))));		});

repos(south, function(e) {			area.css('bottom', clamp(0, parent.height - e.pageY + parent.position.top, parent.height - parseInt(area.css('top'))));		});

repos(area, function(e) {			var pos = [				parseInt(area.css('left')) + e.originalEvent.movementX,				parseInt(area.css('right')) - e.originalEvent.movementX,				parseInt(area.css('top')) + e.originalEvent.movementY,				parseInt(area.css('bottom')) - e.originalEvent.movementY			];			if (pos[0] < 0 || pos[1] < 0 || pos[2] < 0 || pos[3] < 0) return;			area.css('left', pos[0]);			area.css('right', pos[1]);			area.css('top', pos[2]);			area.css('bottom', pos[3]);		}); } });