User:BrandonXLF/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 {	var sampleImg = 'https://upload.wikimedia.org/wikipedia/commons/thumb/7/7b/Dew_on_grass_Luc_Viatour.jpg/1920px-Dew_on_grass_Luc_Viatour.jpg';

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 = $(''),		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')) { document.title = 'CSS Image Crop - ' + mw.config.get('wgSiteName'); $('#firstHeading').text('CSS Image Crop');

mw.util.$content.find('.mw-body-content') .empty .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(' Width: ') .append($('').append(width)) )				.append($(' ') .append(' Height: ') .append($('').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.offset.left, parent.width - parseInt(area.css('right'))));		});

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

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

repos(south, function(e) {			area.css('bottom', clamp(0, parent.height - e.pageY + parent.offset.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]); });	} });