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 相关文章推荐
ext checkboxgroup 回填数据解决
Aug 21 Javascript
jQuery移除tr无效的解决方法(tr是动态添加)
Sep 22 Javascript
JS从一组数据中找到指定的单条数据的方法
Jun 02 Javascript
JSON字符串转换JSONObject和JSONArray的方法
Jun 03 Javascript
Node.js包管理器Yarn的入门介绍与安装
Oct 17 Javascript
Bootstrap实现渐变顶部固定自适应导航栏
Aug 27 Javascript
jQuery插件HighCharts绘制2D柱状图、折线图的组合双轴图效果示例【附demo源码下载】
Mar 09 Javascript
javascript 中的继承实例详解
May 05 Javascript
微信小程序-滚动消息通知的实例代码
Aug 03 Javascript
详解如何去除vue项目中的#——History模式
Oct 13 Javascript
JS实现图片旋转动画效果封装与使用示例
Jul 09 Javascript
解决jquery validate 验证不通过后验证正确的信息仍残留在label上的方法
Aug 27 jQuery
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
在JavaScript中调用php程序
2009/03/09 PHP
PHP DataGrid 实现代码
2009/08/12 PHP
php 仿Comsenz安装效果代码打包提供下载
2010/05/09 PHP
php开发留言板的CRUD(增,删,改,查)操作
2012/04/19 PHP
php excel reader读取excel内容存入数据库实现代码
2012/12/06 PHP
php中的观察者模式简单实例
2015/01/20 PHP
PHP实现链式操作的三种方法详解
2017/11/16 PHP
浅析PHP数据导出知识点
2018/02/17 PHP
在Windows上安装Node.js模块的方法
2011/09/25 Javascript
JSON.stringify 语法实例讲解
2012/03/14 Javascript
nodejs win7下安装方法
2012/05/24 NodeJs
JavaScript实现GriwView单列全选(自写代码)
2013/05/13 Javascript
无闪烁更新网页内容JS实现
2013/12/19 Javascript
Javascript快速排序算法详解
2014/12/03 Javascript
jQuery中hasClass()方法用法实例
2015/01/06 Javascript
使用RequireJS库加载JavaScript模块的实例教程
2016/06/06 Javascript
js简单实现调整网页字体大小的方法
2016/07/23 Javascript
原生JavaScript实现AJAX、JSONP
2017/02/07 Javascript
JavaScript中最常用的10种代码简写技巧总结
2017/06/28 Javascript
Angularjs上传图片实例详解
2017/08/06 Javascript
vue 之 css module的使用方法
2018/12/04 Javascript
vue-calendar-component 封装多日期选择组件的实例代码
2020/12/04 Vue.js
TensorFlow打印tensor值的实现方法
2018/07/27 Python
记一次python 内存泄漏问题及解决过程
2018/11/29 Python
学习python的前途 python挣钱
2019/02/27 Python
Python matplotlib以日期为x轴作图代码实例
2019/11/22 Python
新年福利来一波之Python轻松集齐五福(demo)
2020/01/20 Python
python将数据插入数据库的代码分享
2020/08/16 Python
Python 如何操作 SQLite 数据库
2020/08/17 Python
python批量修改文件名的示例
2020/09/27 Python
python 日志模块logging的使用场景及示例
2021/01/04 Python
个性与发展自我评价
2014/02/11 职场文书
电影地道战观后感
2015/06/04 职场文书
微信小程序结合ThinkPHP5授权登陆后获取手机号
2021/11/23 PHP
剧场版《转生恶役只好拔除破灭旗标》公开最新视觉图 2023年上映
2022/04/02 日漫
SQL Server中的逻辑函数介绍
2022/05/25 SQL Server