/// /* * 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, { /// /// fetch css value /// ///style name f: function (c) { return parseInt($(this).css(c)); }, /// /// preload bitmap /// ///callback function, it'll be fired after the 'preload' has completed 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; } }, /// /// zoom in or zoom out the bitmap /// /// use the global variable 'zoomValue' as zoom rate /// /// 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); }); }, /// /// resize, drag and drop /// ///parameters, include limited value(left and top),condition and callback function 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); }); }); }, /// /// bitmap cutter, main function /// ///parameters 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); /// /// zoom interface /// ///current zoom value function izoom(zv) { $bcglobal.$zoomValue = zv; $bcglobal.$img.scaleBitmap($bcglobal.$zoomValue); $bcglobal.$thumbimg.scaleBitmap($bcglobal.$zoomValue); scissors.createThumbnail(); } /// /// image rotation interface /// ///rotate angle(degree) 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); } } }); } /// /// image movement /// ///move direction(left, up, right, down) 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 = $('
').appendTo(ps.renderTo); var $cr = $('
').appendTo(ps.renderTo); //bitmap holder var $holder = $('
') .css(ps.holderSize) .appendTo($cl); //options var $opts = $('
' + '' + '
' + ' ' + ' ' + ' ' + ' ' + ' ' + ' ' + ' ' + '
' + '' + '
').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 = $('
') .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 = $('
 
') .css(ps.cutterSize) .css({ 'opacity': 0.4, 'left': cutterLeft, 'top': cutterTop }).appendTo($holder); //initialize zoom value $bcglobal.$zoomValue = 1; //image var $img = $('') .appendTo($holder); //thumbnail var $thumbimg = $('') .appendTo( $('
') .css(ps.cutterSize) .appendTo($cr) ); var $generate = $('' + ps.lang.generate + '') .appendTo($cr); var $newimg = $('') .appendTo($cr).hide(); var $processed = $('
' + ps.lang.process + '
') .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; }); } }); /// /// text format(same as c-sharp, /// e.g.: 'example {0}: {2}'.format('A','none')) /// output: example A: none /// String.prototype.format = function () { var args = arguments; return this.replace(/{(\d{1})}/g, function () { return args[arguments[1]]; }); };