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 相关文章推荐
简单实例处理url特殊符号&amp;处理(2种方法)
Apr 02 Javascript
JQuery中关于jquery.js与jquery.min.js的比较探讨
May 15 Javascript
js window.print实现打印特定控件或内容
Sep 16 Javascript
详谈angularjs中路由页面强制更新的问题
Apr 24 Javascript
解决JS内存泄露之js对象和dom对象互相引用问题
Jun 25 Javascript
Three.js利用Detector.js插件如何实现兼容性检测详解
Sep 26 Javascript
webpack学习教程之前端性能优化总结
Dec 05 Javascript
解决Vue不能检测数组或对象变动的问题
Feb 24 Javascript
vue-router 手势滑动触发返回功能
Sep 30 Javascript
webpack4+react多页面架构的实现
Oct 25 Javascript
使用ESLint禁止项目导入特定模块的方法步骤
Mar 04 Javascript
javascript代码实现简易计算器
Jan 25 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
PHP用FTP类上传文件视频等的简单实现方法
2016/09/23 PHP
php设计模式之备忘模式分析【星际争霸游戏案例】
2020/03/24 PHP
10款新鲜出炉的 jQuery 插件(Ajax 插件,有幻灯片、图片画廊、菜单等)
2011/06/08 Javascript
seajs1.3.0源码解析之module依赖有序加载
2012/11/07 Javascript
HTML复选框和单选框 checkbox和radio事件介绍
2012/12/12 Javascript
两个数组去重的JS代码
2013/12/04 Javascript
jquery修改属性值实例代码(设置属性值)
2014/01/06 Javascript
javascript中解析四则运算表达式的算法和示例
2014/08/11 Javascript
javascript数组排序汇总
2015/07/07 Javascript
用svg制作富有动态的tooltip
2015/07/17 Javascript
探究Javascript模板引擎mustache.js使用方法
2016/01/26 Javascript
详解JavaScript中数组的reduce方法
2016/12/02 Javascript
jquery.tableSort.js表格排序插件使用方法详解
2020/08/12 Javascript
Javascript中绑定click事件的四种方式介绍
2018/10/26 Javascript
[01:23:45]DOTA2-DPC中国联赛 正赛 CDEC vs Dragon BO3 第一场 1月22日
2021/03/11 DOTA
Python编程求解二叉树中和为某一值的路径代码示例
2018/01/04 Python
Python反爬虫技术之防止IP地址被封杀的讲解
2019/01/09 Python
浅谈keras.callbacks设置模型保存策略
2020/06/18 Python
详解基于python的图像Gabor变换及特征提取
2020/10/26 Python
python 实现简易的记事本
2020/11/30 Python
基础的CSS3弹性盒Flexbox布局使用实例
2016/04/08 HTML / CSS
HTML5 中新的全局属性(整理)
2013/07/31 HTML / CSS
使用html5 canvas 画时钟代码实例分享
2015/11/11 HTML / CSS
使用纯HTML5编写一款网页上的时钟的代码分享
2015/11/16 HTML / CSS
多视角3D逼真HTML5水波动画
2016/03/03 HTML / CSS
东南亚排名第一的服务市场:kaodim
2019/03/28 全球购物
函授本科毕业生自我鉴定
2013/10/16 职场文书
应聘文员自荐信范文
2014/03/11 职场文书
农村结婚典礼司仪主持词
2014/03/14 职场文书
学术会议主持词
2014/03/17 职场文书
第二课堂活动总结
2014/05/07 职场文书
交警个人先进事迹材料
2014/05/11 职场文书
初中政治教师教学反思
2016/02/23 职场文书
让人瞬间清醒的句子,句句经典,字字如金
2019/07/08 职场文书
Python中的socket网络模块介绍
2022/07/23 Python
怎么禁用Win11输入法 最新Win11输入法关闭教程
2022/08/05 数码科技