You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
466 lines
19 KiB
Plaintext
466 lines
19 KiB
Plaintext
/// <reference path="jquery.js" />
|
|
/*
|
|
* bitmapcutter
|
|
* version: 1.0.0 (05/24/2009)
|
|
* @ jQuery v1.2.*
|
|
*
|
|
* Licensed under the GPL:
|
|
* http://gplv3.fsf.org
|
|
*
|
|
* Copyright 2008, 2009 Jericho [ thisnamemeansnothing[at]gmail.com ]
|
|
*
|
|
*/
|
|
//using global variables to store the data
|
|
window.$bcglobal = {
|
|
$originalSize: { width: 0, top: 0 },
|
|
$zoomValue: 1.0,
|
|
$thumbimg: null,
|
|
$img: null,
|
|
$cutter: null
|
|
};
|
|
$.extend(
|
|
$.fn, {
|
|
///<summary>
|
|
/// fetch css value
|
|
///</summary>
|
|
///<param name="c">style name</param>
|
|
f: function (c) {
|
|
return parseInt($(this).css(c));
|
|
},
|
|
///<summary>
|
|
/// preload bitmap
|
|
///</summary>
|
|
///<param name="callback">callback function, it'll be fired after the 'preload' has completed</param>
|
|
loadBitmap: function (callback) {
|
|
var me = this,
|
|
bitmapCutterHolder = new Image(),
|
|
src = me.attr('rel');
|
|
bitmapCutterHolder.src = src;
|
|
this.onCompleted = function () {
|
|
$(me).attr('src', src);
|
|
$bcglobal.$originalSize = { width: bitmapCutterHolder.width, height: bitmapCutterHolder.height };
|
|
callback(src);
|
|
};
|
|
if ($.browser.msie) {
|
|
if (bitmapCutterHolder.readyState == "complete") {
|
|
me.onCompleted();
|
|
}
|
|
else bitmapCutterHolder.onreadystatechange = function () {
|
|
if (this.readyState == "complete") {
|
|
me.onCompleted();
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
bitmapCutterHolder.onload = me.onCompleted;
|
|
}
|
|
},
|
|
///<summary>
|
|
/// zoom in or zoom out the bitmap
|
|
///<remarks>
|
|
/// use the global variable 'zoomValue' as zoom rate
|
|
///</remarks>
|
|
///</summary>
|
|
scaleBitmap: function () {
|
|
return this.each(function () {
|
|
var me = $(this),
|
|
os = $bcglobal.$originalSize,
|
|
zoomValue = $bcglobal.$zoomValue;
|
|
|
|
me.hide();
|
|
if (os.width > 0 && os.height > 0) {
|
|
me.height(os.height * zoomValue)
|
|
.width(os.width * zoomValue);
|
|
}
|
|
var p = me.parent(),
|
|
w = me.width(),
|
|
h = me.height(),
|
|
t = (p.height() - h) / 2,
|
|
l = (p.width() - w) / 2;
|
|
me.css({ 'top': t, 'left': l }).show();
|
|
$('.jquery-bitmapcutter-info').html(w + ' : ' + h);
|
|
});
|
|
},
|
|
///<summary>
|
|
/// resize, drag and drop
|
|
///</summary>
|
|
///<param name="setting">parameters, include limited value(left and top),condition and callback function</param>
|
|
dragndrop: function (setting) {
|
|
var ps = $.fn.extend({
|
|
limited: {
|
|
lw: { min: 0, max: 100 },
|
|
th: { min: 0, max: 100 }
|
|
},
|
|
handler: null,
|
|
callback: function (e) { }
|
|
}, setting);
|
|
var dragndrop = {
|
|
drag: function (e) {
|
|
var d = e.data.d;
|
|
var p = {
|
|
left: Math.min(Math.max(e.pageX + d.left, ps.limited.lw.min), ps.limited.lw.max),
|
|
top: Math.min(Math.max(e.pageY + d.top, ps.limited.th.min), ps.limited.th.max),
|
|
target: d.target
|
|
};
|
|
ps.callback(p);
|
|
},
|
|
drop: function (e) {
|
|
$("#cutterDiv").unbind('mousemove', dragndrop.drag).unbind('mouseup', dragndrop.drop);
|
|
}
|
|
};
|
|
return this.each(function () {
|
|
if (ps.handler == null) { ps.handler = $(this) };
|
|
var handler = (typeof ps.handler == 'string' ? $(ps.handler) : ps.handler);
|
|
handler.bind('mousedown', function (e) {
|
|
var data = {
|
|
target: $(this),
|
|
left: $(this).f('left') - e.pageX,
|
|
top: $(this).f('top') - e.pageY
|
|
};
|
|
$("#cutterDiv").bind('mousemove', { d: data }, dragndrop.drag).bind('mouseup', dragndrop.drop);
|
|
});
|
|
});
|
|
},
|
|
///<summary>
|
|
/// bitmap cutter, main function
|
|
///</summary>
|
|
///<param name="setting">parameters</param>
|
|
bitmapCutter: function (settings) {
|
|
var lang = {
|
|
zoomout: 'Zoom out',
|
|
zoomin: 'Zoom in',
|
|
original: 'Original size',
|
|
clockwise: 'Clockwise rotation({0} degrees)',
|
|
counterclockwise: 'Counterclockwise rotation({0} degrees)',
|
|
generate: '开始裁切!',
|
|
process: 'Please wait, transaction is processing......',
|
|
left: 'Left',
|
|
right: 'Right',
|
|
up: 'Up',
|
|
down: 'Down'
|
|
};
|
|
var ps = $.fn.extend({
|
|
src: '',
|
|
renderTo: $(document.body),
|
|
holderSize: { width: 300, height: 400 },
|
|
cutterSize: { width: 70, height: 70 },
|
|
zoomStep: 0.2,
|
|
zoomIn: 2.0,
|
|
zoomOut: 0.1,
|
|
rotateAngle: 90,
|
|
//pixel
|
|
moveStep: 100,
|
|
onGenerated: function (src) { },
|
|
lang: lang
|
|
}, settings);
|
|
|
|
//fill parameters
|
|
ps.lang = $.extend(lang, ps.lang);
|
|
ps.lang.clockwise = ps.lang.clockwise.format(ps.rotateAngle);
|
|
ps.lang.counterclockwise = ps.lang.counterclockwise.format(ps.rotateAngle);
|
|
///<sammary>
|
|
/// zoom interface
|
|
///</sammary>
|
|
///<param name="zv">current zoom value</param>
|
|
function izoom(zv) {
|
|
$bcglobal.$zoomValue = zv;
|
|
$bcglobal.$img.scaleBitmap($bcglobal.$zoomValue);
|
|
$bcglobal.$thumbimg.scaleBitmap($bcglobal.$zoomValue);
|
|
scissors.createThumbnail();
|
|
}
|
|
///<sammary>
|
|
/// image rotation interface
|
|
///</sammary>
|
|
///<param name="angle">rotate angle(degree)</param>
|
|
function irotate(angle) {
|
|
var img = $bcglobal.$img,
|
|
thumbimg = $bcglobal.$thumbimg,
|
|
zoomValue = $bcglobal.$zoomValue,
|
|
//Use 'rel' but not 'src', this helps to make sure that the 'src' attribute was not start with 'http://localhost:8888/...'(msie)
|
|
src = img.attr('rel');
|
|
$.ajax({
|
|
url: 'scissors.axd',
|
|
dataType: 'json',
|
|
data: { action: 'RotateBitmap', src: src, angle: angle, t: Math.random() },
|
|
error: function (msg) {
|
|
location = location;
|
|
},
|
|
success: function (json) {
|
|
if (json.msg == 'success') {
|
|
$bcglobal.$originalSize = json.size;
|
|
//clear cache of img
|
|
src += '?t=' + Math.random();
|
|
img.attr('src', src).scaleBitmap();
|
|
thumbimg.attr('src', src).scaleBitmap();
|
|
scissors.createThumbnail();
|
|
}
|
|
else {
|
|
alert(json.msg);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
///<sammary>
|
|
/// image movement
|
|
///</sammary>
|
|
///<param name="direction">move direction(left, up, right, down)</param>
|
|
function imove(direction) {
|
|
var thumbimg = $bcglobal.$thumbimg,
|
|
img = $bcglobal.$img,
|
|
cutter = $bcglobal.$cutter,
|
|
w = img.width(),
|
|
h = img.height(),
|
|
l = img.f('left'),
|
|
t = img.f('top');
|
|
|
|
if (w <= ps.holderSize.width && h <= ps.holderSize.height) {
|
|
return;
|
|
}
|
|
var limited = {
|
|
left: { min: Math.min(ps.holderSize.width - w, 0), max: Math.max(ps.holderSize.width - w, 0) },
|
|
top: { min: Math.min(ps.holderSize.height - h, 0), max: Math.max(ps.holderSize.height - h, 0) }
|
|
};
|
|
/*
|
|
* it's really a weird thing that i cant use '
|
|
* img.animate({
|
|
* d: v
|
|
* }, function() {
|
|
* thumbimg.fadeIn();
|
|
* scissors.createThumbnail();
|
|
* });
|
|
* '
|
|
* here (d was the direction-'left' and 'top', v was the position data to be calculated!)
|
|
* maybe it's the json to haunt me;-)
|
|
*/
|
|
if (!img.is(':animated')) {
|
|
thumbimg.fadeOut();
|
|
var v = 0, d = {};
|
|
switch (direction) {
|
|
case 'left':
|
|
v = Math.min(limited.left.max, l + ps.moveStep);
|
|
d = { left: v };
|
|
break;
|
|
case 'right':
|
|
v = Math.max(limited.left.min, l - ps.moveStep);
|
|
d = { left: v };
|
|
break;
|
|
case 'up':
|
|
v = Math.min(limited.top.max, t + ps.moveStep);
|
|
d = { top: v };
|
|
break;
|
|
case 'down':
|
|
v = Math.max(limited.top.min, t - ps.moveStep);
|
|
d = { top: v };
|
|
break;
|
|
}
|
|
|
|
img.animate(d, function () {
|
|
thumbimg.fadeIn();
|
|
scissors.createThumbnail();
|
|
});
|
|
}
|
|
}
|
|
var scissors = {
|
|
createThumbnail: function () {
|
|
var thumbimg = $bcglobal.$thumbimg,
|
|
img = $bcglobal.$img,
|
|
cutter = $bcglobal.$cutter;
|
|
|
|
thumbimg.css({
|
|
'left': -cutter.f('left') + img.f('left'),
|
|
'top': -cutter.f('top') + img.f('top')
|
|
});
|
|
},
|
|
zoomin: function () {
|
|
//window.console && console.log('zoom value: %s', zoomValue);
|
|
izoom.call(this, Math.min($bcglobal.$zoomValue + ps.zoomStep, ps.zoomIn));
|
|
},
|
|
zoomout: function () {
|
|
//window.console && console.log('zoom value: %s', zoomValue);
|
|
izoom.call(this, Math.max($bcglobal.$zoomValue - ps.zoomStep, ps.zoomOut));
|
|
},
|
|
original: function () {
|
|
izoom.call(this, 1, 1);
|
|
},
|
|
clockwise: function () {
|
|
irotate.call(this, ps.rotateAngle);
|
|
},
|
|
counterclockwise: function (e) {
|
|
irotate.call(this, -ps.rotateAngle);
|
|
},
|
|
left: function () {
|
|
imove.call(this, 'left');
|
|
},
|
|
up: function () {
|
|
imove.call(this, 'up');
|
|
},
|
|
right: function () {
|
|
imove.call(this, 'right');
|
|
},
|
|
down: function () {
|
|
imove.call(this, 'down');
|
|
}
|
|
};
|
|
ps.renderTo = (typeof ps.renderTo == 'string' ? $(ps.renderTo) : ps.renderTo);
|
|
|
|
var $cl = $('<div class="jquery-bitmapcutter-cl" onselectstart="return false;"></div>').appendTo(ps.renderTo);
|
|
var $cr = $('<div class="jquery-bitmapcutter-cr"></div>').appendTo(ps.renderTo);
|
|
|
|
//bitmap holder
|
|
var $holder = $('<div class="jquery-bitmapcutter-holder jquery-loader" />')
|
|
.css(ps.holderSize)
|
|
.appendTo($cl);
|
|
|
|
//options
|
|
var $opts = $('<div class="jquery-bitmapcutter-opts" >' +
|
|
'<div class="r1c1"><a href="javascript:void(0)" onfocus="this.blur()" class="up"> </a></div>' +
|
|
'<div class="r2c1">' +
|
|
'<a href="javascript:void(0)" onfocus="this.blur()" class="zoomout"> </a>' +
|
|
'<a href="javascript:void(0)" onfocus="this.blur()" class="zoomin"> </a>' +
|
|
'<a href="javascript:void(0)" onfocus="this.blur()" class="left"> </a>' +
|
|
'<a href="javascript:void(0)" onfocus="this.blur()" class="original"> </a>' +
|
|
'<a href="javascript:void(0)" onfocus="this.blur()" class="right"> </a>' +
|
|
'<a href="javascript:void(0)" onfocus="this.blur()" class="counterclockwise"> </a>' +
|
|
'<a href="javascript:void(0)" onfocus="this.blur()" class="clockwise"> </a>' +
|
|
'</div>' +
|
|
'<div class="r3c1"><a href="javascript:void(0)" onfocus="this.blur()" class="down"> </a></div>' +
|
|
'</div>').insertAfter($holder);
|
|
|
|
$opts.css('width', ps.holderSize.width)
|
|
.find('div.r2c1>a:eq(0)')
|
|
.css('margin-left', (ps.holderSize.width - (16 + 6) * 7 + 3) / 2);
|
|
|
|
//informations of bitmap
|
|
var $info = $('<div title="Size Of Bitmap" class="jquery-bitmapcutter-info" />')
|
|
.insertAfter($opts)
|
|
.css('width', ps.holderSize.width);
|
|
|
|
//cutter
|
|
var cutterLeft = (ps.holderSize.width - ps.cutterSize.width) / 2;
|
|
var cutterTop = (ps.holderSize.height - ps.cutterSize.height) / 2;
|
|
var $cutter = $('<div id="cutterDiv" class="jquery-bitmapcutter-cutter" > </div>')
|
|
.css(ps.cutterSize)
|
|
.css({
|
|
'opacity': 0.4,
|
|
'left': cutterLeft, 'top': cutterTop
|
|
}).appendTo($holder);
|
|
//initialize zoom value
|
|
$bcglobal.$zoomValue = 1;
|
|
|
|
//image
|
|
var $img = $('<img alt="" rel="' + ps.src + '" />')
|
|
.appendTo($holder);
|
|
|
|
//thumbnail
|
|
var $thumbimg = $('<img alt="" rel="' + ps.src + '" />')
|
|
.appendTo(
|
|
$('<div class="jquery-bitmapcutter-thumbnail" />')
|
|
.css(ps.cutterSize)
|
|
.appendTo($cr)
|
|
);
|
|
|
|
var $generate = $('<a href="javascript:void(0)" class="generate" onfocus="this.blur()" >' + ps.lang.generate + '</a>')
|
|
.appendTo($cr);
|
|
|
|
var $newimg = $('<img class="jquery-bitmapcutter-newimg" alt="" src="" />')
|
|
.appendTo($cr).hide();
|
|
|
|
var $processed = $('<div class="process">' + ps.lang.process + '</div>')
|
|
.hide()
|
|
.appendTo($cr);
|
|
|
|
$img.loadBitmap(function (e) {
|
|
$img.scaleBitmap();
|
|
$holder.removeClass('jquery-loader');
|
|
|
|
var ks = {
|
|
k37: 'left',
|
|
k38: 'up',
|
|
k39: 'right',
|
|
k40: 'down',
|
|
k45: 'zoomout',
|
|
k61: 'zoomin'
|
|
};
|
|
|
|
$().keypress(function (e) {
|
|
var k = (e.keyCode || e.which);
|
|
//window.console && console.log('key code: %s', k);
|
|
if ((k >= 37 && k <= 40) || k == 45 || k == 61) {
|
|
var func = cceval('scissors.' + cceval('(ks.k' + k + ')') + '');
|
|
func();
|
|
}
|
|
});
|
|
|
|
$thumbimg.attr('src', $img.attr('src')).scaleBitmap();
|
|
|
|
$opts.find('a').each(function () {
|
|
var me = $(this), c = me.attr('class');
|
|
me.attr('title', cceval('(ps.lang.' + c + ')'))
|
|
.bind('click', cceval('(scissors.' + c + ')'));
|
|
});
|
|
|
|
$cutter.dragndrop({
|
|
limited: {
|
|
lw: { min: 0, max: ps.holderSize.width - ps.cutterSize.width },
|
|
th: { min: 0, max: ps.holderSize.height - ps.cutterSize.height }
|
|
},
|
|
callback: function (e) {
|
|
$cutter.css({
|
|
left: e.left,
|
|
top: e.top
|
|
});
|
|
scissors.createThumbnail();
|
|
}
|
|
});
|
|
|
|
$generate.click(function () {
|
|
var me = $(this);
|
|
|
|
me.fadeOut();
|
|
$opts.fadeOut();
|
|
$cutter.fadeOut();
|
|
$info.hide();
|
|
$processed.fadeIn();
|
|
$.get('scissors.axd', {
|
|
action: 'GenerateBitmap',
|
|
src: ps.src,
|
|
zoom: $bcglobal.$zoomValue,
|
|
x: $thumbimg.f('left'),
|
|
y: $thumbimg.f('top'),
|
|
width: ps.cutterSize.width,
|
|
height: ps.cutterSize.height,
|
|
t: Math.random()
|
|
}, function (json) {
|
|
json = cceval("(" + json + ")");
|
|
if (json.msg == 'success') {
|
|
me.fadeIn();
|
|
$opts.fadeIn();
|
|
$cutter.fadeIn();
|
|
$info.show();
|
|
$processed.fadeOut();
|
|
$newimg.attr('src', json.src).show();
|
|
ps.onGenerated(json.src);
|
|
}
|
|
else {
|
|
alert(json.msg);
|
|
}
|
|
}
|
|
);
|
|
});
|
|
$bcglobal.$cutter = $cutter;
|
|
$bcglobal.$img = $img;
|
|
$bcglobal.$thumbimg = $thumbimg;
|
|
});
|
|
}
|
|
});
|
|
///<summary>
|
|
/// text format(same as c-sharp,
|
|
/// e.g.: 'example {0}: {2}'.format('A','none'))
|
|
/// output: example A: none
|
|
///</summary>
|
|
String.prototype.format = function () {
|
|
var args = arguments;
|
|
return this.replace(/{(\d{1})}/g, function () {
|
|
return args[arguments[1]];
|
|
});
|
|
}; |