最近工作真心忙碌,几乎没时间写博客。今天趁周末来仿一个QQ头像裁剪功能插件。效果如下:

所有文件都可在我的Github上下载,从头到尾从简到繁按步骤一共分了9个HTML文件,每个步骤文件里的注释都写的很清楚,故在本博客内不赘述。

原理:

主要是通过css的clip来裁剪图片可视区域,拖动剪裁窗口这里使用了JQ-UI的draggable插件(但是缩放没有,贪方便可以使用Resizable插件,但都用插件的话就没有研究的意义了)。

缩放功能原理其实很简单,不外乎获取剪裁框的offset()或position(),以及各容器宽高、鼠标位置,然后做个大杂侩计算。

只能说咱做前端的必须要认真耐心地去做计算,虽然过程颇为麻烦,但绝对不是“做不出来”。有的朋友在做某些功能前,可能会因为需要涉及较麻烦的计算就放弃,这是不靠谱的做法。

P.S.:像效果图中会存在图片被选中(变蓝色)的情况,是因为本章直接用的img,如果不喜欢这种图片被选中的情况,可以用一个div直接设置背景替换img即可(不过这里得使用background-size:100% 100%,如果不考虑IE8-的话,利用这种方法交互视觉上感觉会更好些)

贴一下最终版的代码,想要从头看起的朋友可以去我上方提供的连接查看。

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>裁剪头像</title>
<script src="jq.js"></script>
<script src="draggable.js"></script>
<style type="text/css">
body {background-color: #333;}
.pic_wrap{ position:relative; float:left;margin:100px; width:320px; height:320px; background:black; }
.pic_wrap img{position:absolute;width:320px; height:320px;}
.pic1{opacity:0.5;}
.pic2{clip:rect(0 150px 150px 0);}
.clip_box{position:absolute; margin-left:-1px; margin-top:-1px;width:150px; height:150px; border:solid 1px white; cursor:move;}
.clip_box span{display:block; position:absolute; width:8px; height:9px; background:white; border-radius:4px;}
#lt{left:-4px; top:-4px; cursor:nw-resize;}
#rt{right:-4px; top:-4px; cursor:ne-resize}
#lb{left:-4px; bottom:-4px; cursor:sw-resize}
#rb{right:-4px; bottom:-4px; cursor:se-resize}
.preview{ margin-top:100px; position:relative; float:left;width:100px; height:100px; overflow:hidden;}
.pic3{ position:absolute;}
</style>
<script type="text/javascript">
$(function(){
var $picWrap = $("#pic_wrap");
var $rawPic = $picWrap.find("img:eq(0)");
var $clipPic = $picWrap.find("img:eq(1)");
var $clipBox = $("#clip_box");
var $prePic = $("#pic3"); //获取预览图
var prebox_w = $("#preview").width(); //获取预览图容器宽度/高度
var $lt = $("#lt");
var $rt = $("#rt");
var $lb = $("#lb");
var $rb = $("#rb");
var wrap_w = $picWrap.width();
var isResize = !1;
var flag = "";
$lt.mousedown(function(e){
e.stopPropagation();
isResize=!0;
flag = "leftTop";
})
$rt.mousedown(function(e){
e.stopPropagation();
isResize=!0;
flag = "rightTop";
})
$lb.mousedown(function(e){
e.stopPropagation();
isResize=!0;
flag = "leftDown";
})
$rb.mousedown(function(e){
e.stopPropagation();
isResize=!0;
flag = "rightDown";
})
$(window).mouseup(function(){
isResize=!1;
flag = "";
})
$clipBox.find("span").mousemove(function(e){
e.stopPropagation();
})
$clipBox.draggable({
containment: "#pic_wrap",
drag: function(){
setClip();
},
stop: function(){
var box_pl = $clipBox.position().left;
var box_pt = $clipBox.position().top;
var box_w = $clipBox.width();
if(box_pl+box_w>wrap_w){
var l = wrap_w - box_w;
$clipBox.css("left",l);
}
if(box_pt+box_w>wrap_w){
var t = wrap_w - box_w;
$clipBox.css("top",t);
}
setClip();
}
});
$picWrap.mousemove(function(e){
if(isResize){
var x = e.pageX;
var y = e.pageY;
switch(flag){
case "leftTop":leftTop(x);console.log("aa");break;
case "rightTop":rightTop(y);break;
case "leftDown":leftDown(x);break;
case "rightDown":rightDown(y);break;
default: break;
}
}
})
function leftTop(x){
var box_ol = $clipBox.offset().left;
var box_pl = $clipBox.position().left;
var box_pt = $clipBox.position().top;
var box_w = $clipBox.width();
var s = x - box_ol;
var newLeft = box_pl + s;
var newWidth = box_w - s;
var newTop = box_pt + s;
newLeft = newLeft<=0?0:newLeft;
newTop = newTop<=0?0:newTop;
if(newTop+newWidth>=wrap_w){
newWidth = newWidth<8?8:newWidth;
newLeft = newLeft+newWidth>wrap_w?newLeft-8:newLeft;
newTop = wrap_w - newWidth;
}
if(newLeft+newWidth>=wrap_w-8){
newWidth = newWidth<8?8:newWidth;
newLeft = wrap_w - newWidth;
}
$clipBox.css({"left":newLeft,"width":newWidth,"height":newWidth,"top":newTop}); setClip();
}
function rightTop(y){
var box_ot = $clipBox.offset().top;
var box_pt = $clipBox.position().top;
var box_pl = $clipBox.position().left;
var box_h = $clipBox.height();
var s = y - box_ot;
var newTop = box_pt + s;
var newHeight = box_h - s;
newTop = newTop<=0?0:newTop;
if(newHeight+box_pl>=wrap_w){
return false;
}
$clipBox.css({"top":newTop,"width":newHeight,"height":newHeight});
setClip();
}
function leftDown(x){
var box_ol = $clipBox.offset().left;
var box_pl = $clipBox.position().left;
var box_pt = $clipBox.position().top;
var box_w = $clipBox.width();
var s = x - box_ol;
var newLeft = box_pl + s;
var newWidth = box_w - s;
newLeft = newLeft<=0?0:newLeft;
if(newWidth+box_pt>=wrap_w){
return false;
}
$clipBox.css({"left":newLeft,"width":newWidth,"height":newWidth});
setClip();
}
function rightDown(y){
var box_ot = $clipBox.offset().top;
var box_pl = $clipBox.position().left;
var newHeight = y - box_ot;
if(newHeight+box_pl>=wrap_w){
return false;
}
$clipBox.css({"width":newHeight,"height":newHeight});
setClip();
}
function setClip(){
var t = $clipBox.position().top;
var r = $clipBox.position().left + $clipBox.width();
var b = $clipBox.position().top + $clipBox.height();
var l = $clipBox.position().left;
var rect = "rect("+t+"px "+r+"px "+b+"px "+l+"px)";
$clipPic.css("clip",rect);
//预览图设置
var w = $clipBox.width();
var pre_w = prebox_w / w * wrap_w ; //存在比例 prebox_w / pre_w = w / wrap_w
var pre_t = pre_w / wrap_w *t; //存在比例 pre_t / t = pre_w / wrap_w
var pre_r = pre_w / wrap_w *r; //存在比例 pre_r / r = pre_w / wrap_w
var pre_b = pre_w / wrap_w *b; //存在比例 pre_b / b = pre_w / wrap_w
var pre_l = pre_w / wrap_w *l; //存在比例 pre_l / l = pre_w / wrap_w
var prect = "rect("+pre_t+"px "+pre_r+"px "+pre_b+"px "+pre_l+"px)";
$prePic.css({"width":pre_w,"height":pre_w,"clip":prect,"left":-pre_l,"top":-pre_t});
}
setClip();
})
</script>
</head>
<body>
<div class="pic_wrap" id="pic_wrap">
<img class="pic1" src="logo.jpg" />
<img class="pic2" src="logo.jpg" />
<div class="clip_box" id="clip_box">
<span id="lt"></span>
<span id="rt"></span>
<span id="lb"></span>
<span id="rb"></span>
</div>
</div> <div id="preview" class="preview">
<img class="pic3" id="pic3" src="logo.jpg" />
</div>
</body>
</html>

共勉~

用JQuery仿造QQ头像裁剪功能的更多相关文章

  1. jQuery实现用户头像裁剪插件cropbox.js

    几乎每一个网页是必备图片上传,图片裁剪功能,这里通过cropbox.js插件实现该功能. <script src="js/jquery-1.11.1.min.js">& ...

  2. Android 实现最新版QQ图像裁剪功能

    这是依据翔神那篇高仿微信图像截取改的  能够先去看  Android 高仿微信头像截取 打造不一样的自己定义控件 这篇文章. 眼下还有个小问题.就是截取成圆形图片之后 会有黑色的边框填充.不知道怎么解 ...

  3. Vue 之 vue-cropper 组件实现头像裁剪功能

    组件与api地址: npm地址地址:https://www.npmjs.com/package/vue-cropper/v/0.4.7 GitHub地址:https://github.com/xyxi ...

  4. jQuery插件ImgAreaSelect 实例讲解一(头像上传预览和裁剪功能)

    上一节随笔中,我们已经知道了关于jQuery插件ImgAreaSelect基本的知识:那么现在看一下实例: 首先,要知道我们应该实现什么功能? (1)图片能够实现上传预览功能 (2)拖拽裁剪图片,使其 ...

  5. Android实现类似换QQ头像功能(图片裁剪)

    现在几乎所有的App都有用户登录模块,需要设置用户头像,而关于用户头像部分无疑也是比较头疼的,目前大部分应用的头像部分会有两种方式:一种是利用系统的裁剪功能去获取用户头像,一种就是获取到图片或者照片的 ...

  6. android 设置头像以及裁剪功能

    在android的开发过程中,经常遇到设置用户头像以及裁剪图像大小的功能.昨天我遇到了设置用户头像的功能,开始不知道怎么搞,在技术群里问也没人回 答,就研究了微信用户设置头像的功能,了解到用户设置图像 ...

  7. 基于jQuery头像裁剪插件cropbox

    今天给大家分享一款基于jQuery头像裁剪插件cropbox,这是一款简单实用的jQuery头像在线裁剪插件.该插件适用于适用浏览器:IE8.360.FireFox.Chrome.Safari.Ope ...

  8. struts2+jsp+jquery+Jcrop实现图片裁剪并上传

    <1> 使用html标签上传需要裁剪的大图. <2> 在页面呈现大图,使用Jcrop(Jquery)对大图进行裁剪,并且可以进行预览. <3> 选择好截取部分之后发 ...

  9. 如何用CropBox实现头像裁剪并与java后台交互

    如何用CropBox实现头像裁剪并与java后台交互 参考网站:https://developer.mozilla.org/zh-CN/docs/Web/API/Blob 参考: http://blo ...

随机推荐

  1. HTML超标记语言

     Html超文本标记语言,负责描绘Web世界的骨架. 〇.工具 http;//www.w3cchool.com.cn 一.Tim Bemers Lee 万维网之父: Html设计者: W3C创始人: ...

  2. css 字间距、CSS字体间距、css 字符间距设置

    1.text-indent设置抬头距离css缩进 2.letter-spacing来设置字与字间距_字符间距离,字体间距css样式

  3. openfire+strophe

    其实是关于strophe的使用的,因为openfire那部分我并没有安装,项目过程中是直接访问的已经部署好的服务器了. 关于使用strophe+ openfire完成 即时通讯,做到及时的信息交互,主 ...

  4. php特性包括哪些?

    PHP的特性包括: 1. PHP 独特的语法混合了 C.Java.Perl 以及 PHP 自创新的语法. 2. PHP可以比CGI或者Perl更快速的执行动态网页——动态页面方面,与其他的编程语言相比 ...

  5. px4flow通过iic读取具体寄存器数据程序

    底层通信用了昨天写好的iic,今天结合官方资料成功读出所有指定寄存器的数据附上源码 include.h主要包括了一些stm32 IO控制的宏定义,具体参考正点原子所有例程中都有的sys.h头文件 in ...

  6. iOS 取绝对值函数

    1.abs(a) 处理int类型a的取绝对值 2.fabsf(a)  处理float类型a的取绝对值 3.fabs(a)   处理double类型a的取绝对值

  7. Java程序员从笨鸟到菜鸟之(一百零一)sql注入攻击详解(二)sql注入过程详解

    在上篇博客中我们分析了sql注入的原理,今天我们就来看一下sql注入的整体过程,也就是说如何进行sql注入,由于本人数据库和网络方面知识有限,此文章是对网上大量同类文章的分析与总结,其中有不少直接引用 ...

  8. Raab判别法确定级数是否收敛

  9. Java中的继承与静态static等的执行先后顺序

    package extend; public class X { Y y=new Y(); static{  System.out.println("tttt"); } X(){  ...

  10. MySQL入门手册

    本文内容摘自MySQL5.6官方文档,主要选取了在实践过程中所用到的部分文字解释,力求只摘录重点,快速学会使用MySQL,本文所贴代码地方就是我亲自练习过的代码,凡本文没有练习过的代码都没有贴在此处, ...