JS实现图片剪裁并预览效果


Posted in Javascript onAugust 12, 2016

今天又疯狂学习了web前端的图片剪裁效果,可以有个区域来框住图片的某一部分,并可以预览框住的部分 

效果图如下:

JS实现图片剪裁并预览效果

看着是不是很炫呢

简单介绍下实现方法吧

1.布局就是左右两块div,右边的好说,主要是左边的,左边的用绝对布局的方式分了3层,最下面一层是一个半透明的图片,中间一层是原图,但被剪切成只有一块,也只显示这一块,可以用clip:rect方法实现,然后最上面一层就是自己写的一个边框,在边框上加了8个点,分别给这8个点定义位置。 

2.然后JS代码用了鼠标的点击事件来实现。 

下面贴上自己的代码:

index.html (这里要引用两个js文件,分别是jquery和jquery-ui,其中jquery可以引用网上的,jquery-ui我是自己下在本地引用的,大家可以自己去官网下载,不引用则不能实现拖动剪切框) 

<!DOCTYPE HTML>
<html>
<head lang="en">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>图片剪切</title>
<script src="http://cdn.bootcss.com/jquery/2.2.0/jquery.min.js" type="text/javascript"></script>
<script src="js/jquery-ui-1.12.0/jquery-ui.min.js"></script>
<link href="img.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="img.js"></script>
</head>
<body>
 <div id="box">
 <img src="images/1.jpg" id="img1">
 <img src="images/1.jpg" id="img2">
 <div id="main">
 <div id="left-up" class="minDiv left-up"></div>
 <div id="up" class="minDiv up"></div>
 <div id="right-up" class="minDiv right-up"></div>
 <div id="right" class="minDiv right"></div>
 <div id="right-down" class="minDiv right-down"></div>
 <div id="down" class="minDiv down"></div>
 <div id="left-down" class="minDiv left-down"></div>
 <div id="left" class="minDiv left"></div>
 </div>
 </div>
 <div id="preview">
 <img src="images/1.jpg" id="img3">
 </div>

</body>
</html>
 img.css
 

body {
 background-color: #333;
}

#box {
 position: absolute;
 top: 200px;
 left: 100px;
 width: 600px;
 height: 319px;
}

#img1 {
 /*不透明度*/
 opacity: 0.3;
 position:absolute;
 top: 0;
 left: 0;

}

#img2 {
 position: absolute;
 top: 0;
 left: 0;

 /*用于剪切图像的函数
 clip: rect(top,right,bottom,left);
 top表示剪切区域顶部离图片顶部的距离
 right表示剪切区域右边离图片左边的距离,即长+left
 bottom表示剪切区域底部离图片顶部的距离,即宽+top
 left表示剪切区域左边离图片左边的距离
 */
 clip: rect(0, 200px, 200px, 0);
}

#main {
 position: absolute;
 border: 1px solid #fff;
 width:200px;
 height: 200px;
}

#preview {
 position: absolute;
 width: 600px;
 height: 319px;
 top:200px;
 left: 720px;
}
#preview img{
 /*要让函数setPreview里的clip函数达到作用,要给img增加绝对定位或者相对定位
 但由于父元素是绝对定位,所以这里是绝对定位*/
 position: absolute;
}

.minDiv {
 position: absolute;
 width: 8px;
 height: 8px;
 background-color: #fff;
}

.left-up {
 top:-4px;
 left: -4px;

 /*鼠标变化 n-北 w-西 s-南 e-东*/
 cursor: nw-resize;
}

.up {
 /*距最近的一个position属性为absolute或者relative的父级元素左边50%的距离
 除此之外 top right bottom也是距最近的一个position属性为absolute或者relative的父级元素
 的距离
 */
 left: 50%;
 /*距离左边-4px即向左边移动4px*/
 margin-left: -4px;
 top:-4px;
 cursor: n-resize;
}

.right-up {
 right: -4px;
 top: -4px;
 cursor: ne-resize;
}

.right {
 top: 50%;
 margin-top:-4px;
 right: -4px;
 cursor: e-resize;
}

.right-down {
 bottom: -4px;
 right: -4px;
 cursor: se-resize;
}

.down {
 left: 50%;
 margin-left: -4px;
 bottom: -4px;
 cursor: s-resize;
}

.left-down {
 left: -4px;
 bottom: -4px;
 cursor: sw-resize;
}

.left {
 bottom: 50%;
 margin-bottom: -4px;
 left: -4px;
 cursor: w-resize;
}
 img.js
 

// 在元素加载完之后执行,确保元素可以成功获取
window.onload =function(){

 document.onselectstart = new Function('event.returnValue=false;');
 $("#main").draggable({containment:'parent', drag:setChoice});
 var img = document.getElementById("img2");

 var rightDiv = document.getElementById("right");
 var upDiv = document.getElementById("up");
 var leftDiv = document.getElementById("left");
 var downDiv = document.getElementById("down");
 var leftupDiv = document.getElementById("left-up");
 var rightupDiv = document.getElementById("right-up");
 var rightdownDiv = document.getElementById("right-down");
 var leftdownDiv = document.getElementById("left-down");

 var mainDiv = document.getElementById("main");
 var ifKeyDown = false; 

 var contact = "";// 表示被按下的触点

 //鼠标按下状态
 rightDiv.onmousedown = function(e) {
 /*拖动效果引入的jquery 和 jquery-ui也会去触发鼠标点击事件,
 所以为了防止自己定义的点击事件和引入的点击事件冲突,传入e并加入以下
 这条语句,防止冒泡。冒泡是指鼠标点击里面的元素时也会触发父元素的一些事件*/
 e.stopPropagation();
 ifKeyDown = true;
 contact = "right";
 }
 upDiv.onmousedown = function(e) {
 e.stopPropagation();
 ifKeyDown = true;
 contact = "up";
 }
 leftDiv.onmousedown = function(e) {
 e.stopPropagation();
 ifKeyDown = true;
 contact = "left";
 }
 downDiv.onmousedown = function(e) {
 e.stopPropagation();
 ifKeyDown = true;
 contact = "down";
 }
 leftupDiv.onmousedown = function(e) {
 e.stopPropagation();
 ifKeyDown = true;
 contact = "left-up";
 }
 rightupDiv.onmousedown = function(e) {
 e.stopPropagation();
 ifKeyDown = true;
 contact = "right-up";
 }
 rightdownDiv.onmousedown = function(e) {
 e.stopPropagation();
 ifKeyDown = true;
 contact = "right-down";
 }
 leftdownDiv.onmousedown = function(e) {
 e.stopPropagation();
 ifKeyDown = true;
 contact = "left-down";
 }

 //鼠标松开状态
 window.onmouseup = function() {
 ifKeyDown = false;
 }

 //鼠标移动事件
 window.onmousemove = function(e) {
 if(ifKeyDown == true){

 switch(contact){
 case "right": rightMove(e); break;
 case "up": upMove(e); break;
 case "left": leftMove(e); break;
 case "down": downMove(e); break;
 case "left-up": leftMove(e); upMove(e); break;
 case "right-up": rightMove(e); upMove(e); break;
 case "right-down": rightMove(e); downMove(e); break;
 case "left-down": leftMove(e); downMove(e); break;
 }

 }
 setChoice();
 setPreview();
 
 }
 //右边移动
 function rightMove(e) {
 var x = e.clientX; //鼠标x坐标
 var addWidth = ""; //鼠标移动后选取框增加的宽度
 var widthBefore = mainDiv.offsetWidth - 2; //选取框变化前的宽度,减2是为了减去边框border的宽,左右两边各为1px,所以是2
 addWidth = x - getPosition(mainDiv).left //鼠标移动后增加的宽度
 if(widthBefore <= img.width){
 mainDiv.style.width = addWidth + "px"; //选取框变化后的宽度
 } else {
 mainDiv.style.width = img.width + "px";
 }
 }

 //上边移动
 function upMove(e) {
 var topBefore = mainDiv.offsetTop;
 var y = e.clientY;//鼠标纵坐标
 var addHeight = 0;
 var mainY = getPosition(mainDiv).top;//选取框相对于屏幕上边的距离
 addHeight = y - mainY; //增加的高度
 var heightBefore = mainDiv.offsetHeight - 2;
 var bottom = topBefore + heightBefore;

 var heightAfter = heightBefore - addHeight;
 var topAfter = mainDiv.offsetTop + addHeight;

 if(topAfter < bottom && topAfter > -2){
 mainDiv.style.height = heightAfter + "px";
 mainDiv.style.top = topAfter + "px";
 }

 }

 //左边移动
 function leftMove(e) {
 // 左边框变化前距离父元素左边的距离
 var leftBefore = mainDiv.offsetLeft;
 // 鼠标按下停止后鼠标距离浏览器左边界的距离
 var x = e.clientX;
 // 定义增加的宽度
 var addWidth = 0;
 // 变化之前剪辑框的宽度
 var widthBefore = mainDiv.offsetWidth - 2;
 // 变化之前左边框距离浏览器左边界的距离
 var mainDivLeft = getPosition(mainDiv).left;
 // 右边框距离父元素的左边的距离
 var right = leftBefore + widthBefore;
 // 增加的宽度
 addWidth = x - mainDivLeft;
 // 变化之后剪辑框的宽度
 var widthAfter = widthBefore - addWidth;
 // 变化之后剪辑框离左边的距离
 var leftAfter = mainDiv.offsetLeft + addWidth;
 // 防止左边框移到右边框以外区域
 if(leftAfter < right && leftAfter > -2) {
 // 定义变化后的宽度
 mainDiv.style.width = widthAfter + "px";
 // 定义变化后距离左边父元素的距离
 mainDiv.style.left = leftAfter + "px";
 }
 
 }

 //下边移动
 function downMove(e) {
 var y = e.clientY;
 var addHeight = 0;
 var heightBefore = mainDiv.offsetHeight - 2;
 addHeight = y - getPosition(mainDiv).top;
 if(heightBefore <= img.height) {
 mainDiv.style.height = addHeight + "px";
 } else {
 mainDiv.style.height = img.height + "px";
 }
 
 }


 // 获取元素相对于屏幕左边的距离,利用offsetLeft
 // node为传入的元素
 function getPosition(node) {
 /*获取元素相对于父元素的左边距*/
 var left = node.offsetLeft;
 /*获取元素相对于父元素的上边距*/
 var top = node.offsetTop;
 /*获取元素的父元素*/
 var parent = node.offsetParent;
 /*判断是否存在父元素,存在则一直加上左边距,一直算出元素相对于浏览器
 左边界的距离*/
 while(parent != null) {
 /*循环累加子元素相对于父元素的左边距*/
 left += parent.offsetLeft;
 /*循环累加子元素相对于父元素的上边距*/
 top += parent.offsetTop;
 /*循环获取父元素的父元素,直至没有父元素为止*/
 parent = parent.offsetParent;
 }
 return {"left":left,"top":top};
 }


 //设置选取区域高亮可见
 function setChoice() {
 var top = mainDiv.offsetTop;
 var right = mainDiv.offsetLeft + mainDiv.offsetWidth;
 var bottom = mainDiv.offsetTop + mainDiv.offsetHeight;
 var left = mainDiv.offsetLeft;
 img.style.clip = "rect("+ top+"px,"+ right+"px,"+ bottom +"px,"+ left+"px"+")"
 }

 //预览函数
 function setPreview() {
 var top = mainDiv.offsetTop;
 var right = mainDiv.offsetLeft + mainDiv.offsetWidth;
 var bottom = mainDiv.offsetTop + mainDiv.offsetHeight;
 var left = mainDiv.offsetLeft;
 var img3 = document.getElementById("img3");
 img3.style.clip = "rect("+ top+"px,"+ right+"px,"+ bottom +"px,"+ left+"px"+")"
 
 img3.style.top = -(top) + "px";
 img3.style.left = -(left) + "px";
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
表单内同名元素的控制
Nov 22 Javascript
setTimeout与setInterval在不同浏览器下的差异
Jan 24 Javascript
jquery 插件学习(六)
Aug 06 Javascript
iframe异步加载实现点击左边菜单加载右边内容实例讲解
Mar 04 Javascript
jQuery的css() 方法使用指南
May 03 Javascript
node.js下LDAP查询实例分享
Sep 30 Javascript
Vue.js实现网格列表布局转换方法
Aug 25 Javascript
关于HTTP传输中gzip压缩的秘密探索分析
Jan 12 Javascript
尝试自己动手用react来写一个分页组件(小结)
Feb 09 Javascript
vue2 v-model/v-text 中使用过滤器的方法示例
May 09 Javascript
vue 中使用 watch 出现了如下的报错的原因分析
May 21 Javascript
微信小程序实现原生步骤条
Jul 25 Javascript
JS数组去掉重复数据只保留一条的实现代码
Aug 11 #Javascript
分享JS数组求和与求最大值的方法
Aug 11 #Javascript
利用JavaScript阻止表单提交的两种方法
Aug 11 #Javascript
防止Node.js中错误导致进程阻塞的办法
Aug 11 #Javascript
JavaScript中 ES6 generator数据类型详解
Aug 11 #Javascript
基于MVC5和Bootstrap的jQuery TreeView树形控件(二)之数据支持json字符串、list集合
Aug 11 #Javascript
基于MVC5和Bootstrap的jQuery TreeView树形控件(一)之数据支持json字符串、list集合
Aug 11 #Javascript
You might like
PHP 在5.1.* 和5.2.*之间 PDO数据库操作中的不同之处小结
2012/03/07 PHP
PHP实现今天是星期几的几种写法
2013/09/26 PHP
PHP输出Excel PHPExcel的方法
2018/07/26 PHP
PHP hex2bin()函数用法讲解
2019/02/25 PHP
一行代码告别document.getElementById
2012/06/01 Javascript
常规表格多表头查询示例
2014/02/21 Javascript
用js读、写、删除Cookie代码分享及详细注释说明
2014/06/05 Javascript
input标签内容改变的触发事件介绍
2014/06/18 Javascript
javascript引用类型之时间Date和数组Array
2015/08/27 Javascript
JavaScript识别网页关键字并进行描红的方法
2015/11/09 Javascript
JS实现合并两个数组并去除重复项只留一个的方法
2015/12/17 Javascript
JavaScript中文件上传API详解
2016/04/01 Javascript
第一次接触Bootstrap框架
2016/10/24 Javascript
12306 刷票脚本及稳固刷票脚本(防挂)
2017/01/04 Javascript
微信小程序(三):网络请求
2017/01/13 Javascript
vue2.0使用swiper组件实现轮播效果
2017/11/27 Javascript
详解React native fetch遇到的坑
2018/08/30 Javascript
vue element 关闭当前tab 跳转到上一路由操作
2020/07/22 Javascript
详谈vue中router-link和传统a链接的区别
2020/07/22 Javascript
[01:14]DOTA2亚洲邀请赛小组赛赛前花絮
2017/03/27 DOTA
Python抓取框架Scrapy爬虫入门:页面提取
2017/12/01 Python
Python面向对象之类和实例用法分析
2019/06/08 Python
Python 读取WAV音频文件 画频谱的实例
2020/03/14 Python
CSS3的新特性介绍
2008/10/31 HTML / CSS
时尚的CSS3进度条效果
2012/02/22 HTML / CSS
css3中检验表单的required,focus,valid和invalid样式
2014/02/21 HTML / CSS
基于HTML5 的人脸识别活体认证的实现方法
2016/06/22 HTML / CSS
软件工程师面试题
2012/06/25 面试题
单位在职证明范本
2014/01/09 职场文书
集团薪酬管理制度
2014/01/13 职场文书
年度优秀员工获奖感言
2014/08/15 职场文书
2014年保密工作总结
2014/11/22 职场文书
求职简历自我评价范文
2015/03/10 职场文书
2019年新郎保证书3篇
2019/10/17 职场文书
导游词之无锡梅园
2019/11/28 职场文书
React Fragment介绍与使用详解
2021/11/11 Javascript