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 相关文章推荐
js 获取服务器控件值的代码
Mar 05 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(一)让静态人物动起来
Jan 23 Javascript
js动态拼接正则表达式的两种方法
Mar 04 Javascript
jQuery实现自定义下拉列表
Jan 05 Javascript
jQuery中extend函数详解
Jul 13 Javascript
Web开发必知Javascript技巧大全
Feb 23 Javascript
Javascript中获取浏览器类型和操作系统版本等客户端信息常用代码
Jun 28 Javascript
AngularJs concepts详解及示例代码
Sep 01 Javascript
React学习笔记之条件渲染(一)
Jul 02 Javascript
vue父组件向子组件传递多个数据的实例
Mar 01 Javascript
layer.alert自定义关闭回调事件的方法
Sep 27 Javascript
JS实现旋转木马轮播图
Jan 01 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
yii框架源码分析之创建controller代码
2011/06/28 PHP
php中使用parse_url()对网址进行解析的实现代码(parse_url详解)
2012/01/03 PHP
使用phpexcel类实现excel导入mysql数据库功能(实例代码)
2016/05/12 PHP
PHP实现webshell扫描文件木马的方法
2017/07/31 PHP
PHP设计模式(八)装饰器模式Decorator实例详解【结构型】
2020/05/02 PHP
用showModalDialog弹出页面后,提交表单总是弹出一个新窗口
2009/07/18 Javascript
js 居中漂浮广告
2010/03/21 Javascript
仅img元素创建后不添加到文档中会执行onload事件的解决方法
2011/07/31 Javascript
javascript入门之string对象【新手必看】
2016/11/22 Javascript
servlet+jquery实现文件上传进度条示例代码
2017/01/25 Javascript
JS查找字符串中出现最多的字符及个数统计
2017/02/04 Javascript
ubuntu编译nodejs所需的软件并安装
2017/09/12 NodeJs
seajs模块压缩问题与解决方法实例分析
2017/10/10 Javascript
解决VUE框架 导致绑定事件的阻止冒泡失效问题
2018/02/24 Javascript
Angularjs实现多图片上传预览功能
2018/07/18 Javascript
小程序实现多列选择器
2019/02/15 Javascript
如何基于javascript实现贪吃蛇游戏
2020/02/09 Javascript
[03:19]2016国际邀请赛中国区预选赛第四日TOP10镜头集锦
2016/07/01 DOTA
[30:00]完美世界DOTA2联赛PWL S2 Rebirth vs LBZS 第二场 11.28
2020/12/01 DOTA
scrapy自定义pipeline类实现将采集数据保存到mongodb的方法
2015/04/16 Python
Python Pywavelet 小波阈值实例
2019/01/09 Python
Python之pymysql的使用小结
2019/07/01 Python
在vscode中配置python环境过程解析
2019/09/28 Python
opencv python 图片读取与显示图片窗口未响应问题的解决
2020/04/24 Python
Django分组聚合查询实例分享
2020/04/29 Python
keras中的loss、optimizer、metrics用法
2020/06/15 Python
python中delattr删除对象方法的代码分析
2020/12/15 Python
python 使用xlsxwriter循环向excel中插入数据和图片的操作
2021/01/01 Python
css3学习心得分享
2013/08/19 HTML / CSS
完美实现CSS垂直居中的11种方法
2021/03/27 HTML / CSS
社团活动总结书
2014/06/27 职场文书
党支部书记四风问题整改措施
2014/09/24 职场文书
群众路线剖析材料(四风问题)
2014/10/08 职场文书
人事任命通知书
2015/04/21 职场文书
小学六一儿童节活动总结
2015/05/05 职场文书
Python实现视频自动打码的示例代码
2022/04/08 Python