User:BrandonXLF/CSSImageCrop.js
/*** CSS Image Crop ***/
// A utility to use {{CSS image crop}} 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(
'{{CSS image crop\n' +
'|Image = ' + file.val() + '\n' +
'|bSize = ' + size.val() + '\n' +
'|cWidth = ' + width.val() + '\n' +
'|cHeight = ' + height.val() + '\n' +
'|oLeft = ' + left.val() + '\n' +
'|oTop = ' + top.val() + '\n' +
(location.val() ? '|Location = ' + location.val() + '\n' : '') +
(desc.val() ? '|Description = ' + desc.val() + '\n' : '') +
'}}'
);
}
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 = $(
'
'' +
'' +
'' +
'' +
'' +
''
).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($('
File: | ')').append(file))
) .append($(' | ||||||||||||||||||
Size: | ')').append(size))
) .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($(' ').append(left))
| ) .append($(' .append(' Top: | ')
.append($(' ').append(top))
| ) .append(' .append($(' .append(' Pos: | ')
.append($(' ').append(location))
| ) .append($(' .append(' Desc: | ')
.append($(' ').append(desc))
| ) .append(' .append($(' .append(' ')
| .append($(' ')
| .append($(' ')
.append(textarea) .append($( ' ' + ).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]); }); } }); |