js+jquery实现图片裁剪功能


Posted in Javascript onJanuary 02, 2015

现在我们在使用各大网站的个人中心时,都有个上传个人头像的功能。用户在上传了个人照片之后,可能不符合网站的要求,于是要求用户对照片进行裁剪,最终根据用户裁剪的尺寸生成头像。这个功能真是太棒了,原来不懂js的时候,感觉很神奇,太神奇了。心想哪天要是自己也能搞明白这里面的技术,那该多牛呀~大家是不是也有何我一样的想法呀~哈哈~~

下面我们就来用javascript来实现这个功能吧。

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>clip</title>

<style type="text/css">

*{ padding:0; margin:0;}

ul{ list-style-type:none; overflow:hidden; zoom:1; width:1000px; margin:30px auto; }

li{ float:left; width:500px;}

#container{width:480px; height:480px; margin:0 auto; border:1px solid #999; position:relative;background:url(http://images.cnblogs.com/cnblogs_com/wtcsy/192373/r_xx.jpg);}

#container .block{height:100px; width:100px; border:1px solid #000000; position:absolute; left:50px; top:50px; background:#fff;filter:alpha(opacity=30);opacity:0.3; cursor:move;}

#container .tips{ position:absolute; padding:5px; border:1px solid #ccc;background:#fff;filter:alpha(opacity=60);opacity:0.6; display:none; font-size:12px; color:#333; ;}

.tips span{ display:inline-block;zoom:1; width:28px;}

.rRightDown,.rLeftDown,.rLeftUp,.rRightUp,.rRight,.rLeft,.rUp,.rDown{

position:absolute;background:#f00;width:6px;height:6px;z-index:5;font-size:0;}

.rLeftDown,.rRightUp{cursor:ne-resize;}

.rRightDown,.rLeftUp{cursor:nw-resize;}

.rRight,.rLeft{cursor:e-resize;}

.rUp,.rDown{cursor:n-resize;}

.rRightDown{ bottom:-3px; right:-3px;}

.rLeftDown{ bottom:-3px; left:-3px;}

.rRightUp{ top:-3px; right:-3px;}

.rLeftUp{ top:-3px; left:-3px;}

.rRight{ right:-3px; top:50%}

.rLeft{ left:-3px; top:50%}

.rUp{ top:-3px; left:50%}

.rDown{ bottom:-3px; left:50%}

#imgC{ border:1px solid #CCC; width:0; height:0; margin:0 auto;background:url(http://images.cnblogs.com/cnblogs_com/wtcsy/192373/r_xx.jpg);}

.code {

    background: none repeat scroll 0 0 #E3F4F9;

    border: 1px solid #BAE2F0;

    font: 12px "Courier New",Courier,monospace;

    margin: 30px auto;

    padding: 10px 10px 40px;

 width:980px;

}

.code p{ height:24px; line-height:24px;}

.code span{ display:inline-block;zoom:1; margin-right:5px; width:85px; font-weight:bold; color:#00F}

</style>

</head>

<body>

<div class="code">

 <div class="how">使用方法</div>

    <p>$("#container").clip({

  imgC : $("#imgC"),

        blockClass : "block",

        tipsClass  : "tips"        

 });</p>

    <p><span>imgC :</span> 表示裁剪图片的容器,也就是右边的图</p>

    <p><span>blockClass :</span> block的样式名  也就是页面上的可以拖动的滑块的样式 因为怕和别的页面上的样式重名  默认是block</p>

    <p><span>tipsClass  :</span> tips的样式名   也就是页面上显示left width height top的那个span的样式名 默认是tips</p>

</div>

<ul>

 <li>

     <div id="container"></div>

    </li>

    <li>

     <div id="imgC"></div>

    </li>

</ul>

<script type="text/javascript" src="http://common.cnblogs.com/script/jquery.js"></script>

<script type="text/javascript">

(function(){

 var dBody = document.body,

  dDoc = document.documentElement,

  ie   = $.browser.msie;

 ie&&($.browser.version=="6.0")

  &&document.execCommand("BackgroundImageCache", false, true); 

 var  clip =  function(options){

  this.init.call(this,options); 

 }

 clip.prototype = {

  options :{

   moveCallBack : function(){},

   blockClass : "block",

   tipsClass  : "tips"

  },

  init : function(options){   

   $.extend(this,this.options,options||{});

   if(!this.container || !this.imgC){

    return;

   }

   this.container = $(this.container);

   var self = this;

   this.block = $('<div class="'+this.blockClass+'">\

     <div action="rightDown" class="rRightDown"></div>\

     <div action="leftDown" class="rLeftDown"></div>\

     <div action="rightUp" class="rRightUp"></div>\

     <div action="leftUp" class="rLeftUp"></div>\

     <div action="right" class="rRight"></div>\

     <div action="left" class="rLeft"></div>\

     <div action="up" class="rUp"></div>\

     <div action="down" class="rDown" ></div>\

       </div>')

   .bind("mousedown.r",function(e){self.start(e)})

   .appendTo(this.container[0]);

   this.tips = $('<span class="'+this.tipsClass+'" />').appendTo(this.container[0]);

   this.setImg();

  },

  setImg : function(){

   var block = this.block;

   var left  = block.css("left"),

    top   = block.css("top"),

    height = block.height(),

    width  = block.width();

   this.imgC.css({

    height: height,

    width : width,

    "background-position" : "-"+left+" -"+top

   });

   this.tips.html("left:<span>"+parseInt(left) + "</span>top:<span>" + +parseInt(top) + "</span>width:<span>"+width+ "</span>height:<span>"+height+"</span>");

  },

  start : function(e){      

   var $elem     = $(e.target),

    block     = this.block,

    self      = this,

    move      = false,

    container = this.container,

    action    = $elem.attr("action");

   //这个 每次都要计算 基本dom结构的改变 浏览器的缩放 都会让里面的值发生改变 

   this.offset = $.extend({height:container.height(),width:container.width()},container.offset());

   this.blockOriginal = {height:block.height(),width:block.width(),left:parseInt(block.css("left")),top:parseInt(block.css("top"))};

   if(action){

    this.fun = this[action];    

   }else{

    this.x = e.clientX - this.offset.left - this.blockOriginal.left ;

    this.y = e.clientY - this.offset.top - this.blockOriginal.top;

    move = true;

   }   

   ie

    &&this.block[0].setCapture();

   this.tips.show();

   $(document)

    .bind("mousemove.r",function(e){self.move(e,move)})

    .bind("mouseup.r",function(){self.end()});   

  },

  end  : function(){

   $(document)

    .unbind("mousemove.r")

    .unbind("mouseup.r");

   ie 

    &&this.block[0].releaseCapture();

   this.tips.hide(); 

  },

  move : function(e,isMove){

   window.getSelection 

    ? window.getSelection().removeAllRanges() 

    : document.selection.empty();

    

   var block = this.block; 

   if(isMove){

    var left = Math.max(0,e.clientX - this.offset.left - this.x);

    left = Math.min(left,this.offset.width - this.blockOriginal.width);

    var top = Math.max(0,e.clientY - this.offset.top - this.y);

    top = Math.min(top,this.offset.height - this.blockOriginal.height);

    block.css({left:left,top:top});    

   }else{

    var offset = this.fun(e);

    block.css(offset);

   }

   

   this.setImg();

   this.moveCallBack();

  },

  down : function(e){

   var blockOriginal = this.blockOriginal, 

    sTop = Math.max(dBody.scrollTop,dDoc.scrollTop), //出现垂直方向滚动条时候 要计算这个  

    offset = this.offset;

    

   if(e.clientY-offset.top>=blockOriginal.top-sTop){

    var height = Math.min(offset.height - blockOriginal.top,e.clientY-offset.top-blockOriginal.top+sTop),

     top = blockOriginal.top;

   }else{

    var height = Math.min(offset.top+blockOriginal.top-e.clientY-sTop,blockOriginal.top),

     top = Math.max(e.clientY - offset.top+sTop,0);

   }

   return {height:height, top:top};

  },

  up : function(e){

   var blockOriginal = this.blockOriginal,

    sTop = Math.max(dBody.scrollTop,dDoc.scrollTop),

    offset = this.offset;

   if(e.clientY-offset.top-blockOriginal.height<=blockOriginal.top-sTop){

    var top = Math.max(e.clientY-offset.top+sTop,0),

     maxHeight = blockOriginal.top + blockOriginal.height,

     height = Math.min(maxHeight,blockOriginal.top + blockOriginal.height -(e.clientY-offset.top)-sTop);     

   }else{

    var height = Math.min(e.clientY-offset.top-blockOriginal.top-blockOriginal.height+sTop,offset.height-blockOriginal.top-blockOriginal.height),

     top = blockOriginal.top+blockOriginal.height;  

   }

   return {height:height, top:top};

  },

  left : function(e){

   var blockOriginal = this.blockOriginal,

    offset = this.offset;

    

   if(e.clientX - offset.left - blockOriginal.width - blockOriginal.left<=0){

    var left  = Math.max(e.clientX - offset.left,0),

     width = Math.min(blockOriginal.left + blockOriginal.width,blockOriginal.left + blockOriginal.width -(e.clientX-offset.left));

   }else{

    var width = Math.min(e.clientX-offset.left-blockOriginal.left-blockOriginal.width,offset.width-blockOriginal.left-blockOriginal.width),

     left  = blockOriginal.left + blockOriginal.width;

   }

   return {left : left,  width : width};

  },

  right : function(e){

   var blockOriginal = this.blockOriginal,

    offset = this.offset;

   if(e.clientX-offset.left>=blockOriginal.left){

    var width = Math.min(offset.width - blockOriginal.left,e.clientX - offset.left - blockOriginal.left),

     left  = blockOriginal.left;

   }else{

    var width = Math.min(offset.left + blockOriginal.left - e.clientX,blockOriginal.left),

     left  = Math.max(e.clientX - offset.left,0);

   }

   return {left : left,  width : width};

  },

  rightDown : function(e){

   return $.extend(this.right(e),this.down(e));  

  },

  leftDown : function(e){

   return $.extend(this.left(e),this.down(e));

  },

  rightUp : function(e){

   return $.extend(this.right(e),this.up(e));

  },

  leftUp : function(e){

   return $.extend(this.left(e),this.up(e));

  },

  getValue : function(){

   var block = this.block;

   return {

    left   : parseInt(block.css("left")),

    top    : parseInt(block.css("top")),

    width  : block.width(),

    height : block.height()

   }

  }

 }

 $.fn.clip = function(options){

  options.container = this;

  return new clip(options);

 }

})();

 xx = $("#container").clip({

  imgC : $("#imgC")

 })

</script>

</body>

</html>

是不是很炫酷啊,小伙伴们,学学本示例的思路吧。

Javascript 相关文章推荐
js 事件小结 表格区别
Aug 13 Javascript
jQuery 对象中的类数组操作
Apr 27 Javascript
node.js中的fs.readFileSync方法使用说明
Dec 15 Javascript
基于css3新属性transform及原生js实现鼠标拖动3d立方体旋转
Jun 12 Javascript
BootStrap树状图显示功能
Nov 24 Javascript
JS仿Base.js实现的继承示例
Apr 07 Javascript
js实现会跳动的日历效果(完整实例)
Oct 18 Javascript
关于Webpack dev server热加载失败的解决方法
Feb 22 Javascript
AngularJS动态添加数据并删除的实例
Feb 27 Javascript
使用Vue动态生成form表单的实例代码
Apr 26 Javascript
JavaScript ES6常用基础知识总结
Feb 09 Javascript
vue之debounce属性被移除及处理详解
Nov 13 Javascript
javascript 构造函数方式定义对象
Jan 02 #Javascript
深入探寻javascript定时器
Jan 02 #Javascript
JavaScript中的Truthy和Falsy介绍
Jan 01 #Javascript
JavaScript中的null和undefined区别介绍
Jan 01 #Javascript
JavaScript中的全局对象介绍
Jan 01 #Javascript
原生javascript获取元素样式
Dec 31 #Javascript
JavaScript分析、压缩工具JavaScript Analyser
Dec 31 #Javascript
You might like
Yii实现自动加载类地图的方法
2015/04/01 PHP
php计算两个坐标(经度,纬度)之间距离的方法
2015/04/17 PHP
Laravel 修改默认日志文件名称和位置的例子
2019/10/17 PHP
在 IE 中调用 javascript 打开 Excel 表
2006/12/21 Javascript
JavaScript与DropDownList 区别分析
2010/01/01 Javascript
Javascript拓展String方法小结
2013/07/08 Javascript
jquery 列表双向选择器之改进版
2013/08/09 Javascript
java和javascript获取word文档的书签位置对比
2014/06/19 Javascript
javascript实现playfair和hill密码算法
2014/12/07 Javascript
IE下支持文本框和密码框placeholder效果的JQuery插件分享
2015/01/31 Javascript
jQuery设置指定网页元素宽度和高度的方法
2015/03/25 Javascript
jQuery插件jRumble实现网页元素抖动
2015/06/05 Javascript
jquery实现先淡出再折叠收起的动画效果
2015/08/07 Javascript
微信小程序去哪里找 小程序到底如何使用(附小程序名单)
2017/01/09 Javascript
深入理解vue-router之keep-alive
2017/08/31 Javascript
Three.js利用dat.GUI如何简化试验流程详解
2017/09/26 Javascript
微信小程序返回多级页面的实现方法
2017/10/27 Javascript
ES6中的迭代器、Generator函数及Generator函数的异步操作方法
2019/05/12 Javascript
vue中npm包全局安装和局部安装过程
2019/09/03 Javascript
vue中使用带隐藏文本信息的图片、图片水印的方法
2020/04/24 Javascript
Python的Flask框架与数据库连接的教程
2015/04/20 Python
在Python中使用列表生成式的教程
2015/04/27 Python
在Python中处理时间之clock()方法的使用
2015/05/22 Python
python随机取list中的元素方法
2018/04/08 Python
TensorFlow实现随机训练和批量训练的方法
2018/04/28 Python
pycharm运行scrapy过程图解
2019/11/22 Python
通过python调用adb命令对App进行性能测试方式
2020/04/23 Python
解决windows上安装tensorflow时报错,“DLL load failed: 找不到指定的模块”的问题
2020/05/20 Python
获取CSDN文章内容并转换为markdown文本的python
2020/09/06 Python
pandas 按日期范围筛选数据的实现
2021/02/20 Python
美国领先的水果篮送货公司和新鲜水果供应商:The Fruit Company
2018/02/13 全球购物
高中教师评语大全
2014/04/25 职场文书
公司募捐倡议书
2014/05/14 职场文书
男方婚礼答谢词
2015/01/20 职场文书
2015年七年级班主任工作总结
2015/05/21 职场文书
导游词之张家界
2019/10/31 职场文书