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取两个数组的交集|差集|并集|补集|去重示例代码
Aug 07 Javascript
基于JQuery实现的Select级联
Jan 27 Javascript
JS实现的3D拖拽翻页效果代码
Oct 31 Javascript
Javascript数组循环遍历之forEach详解
Nov 07 Javascript
js对字符串进行编码的方法总结(推荐)
Nov 10 Javascript
js前端实现多图图片上传预览的两个方法(推荐)
Nov 18 Javascript
利用jQuery实现一个简单的表格上下翻页效果
Mar 14 Javascript
JS身份证信息验证正则表达式
Jun 12 Javascript
深入理解node.js http模块
Jan 24 Javascript
inquirer.js一个用户与命令行交互的工具详解
May 18 Javascript
es6中比较有用的7个技巧小结
Jul 12 Javascript
JavaScript十大取整方法实例教程
Dec 03 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算法实例分享
2015/07/14 PHP
PHP封装的验证码工具类定义与用法示例
2018/08/22 PHP
PHP使用mysqli同时执行多条sql查询语句的实例
2019/03/22 PHP
浅谈laravel 5.6 安装 windows上使用composer的安装过程
2019/10/18 PHP
jQuery 注意事项 与原因分析
2009/04/24 Javascript
window.opener用法和用途实例介绍
2013/08/19 Javascript
判断文档离浏览器顶部的距离的方法
2014/01/08 Javascript
jquery实现的一个简单进度条效果实例
2014/05/12 Javascript
nodejs中实现路由功能
2014/12/29 NodeJs
浅谈EasyUI中编辑treegrid的方法
2015/03/01 Javascript
浅谈angular懒加载的一些坑
2016/08/20 Javascript
JS插件plupload.js实现多图上传并显示进度条
2016/11/29 Javascript
超全面的vue.js使用总结
2017/02/12 Javascript
javascript简单写的判断电话号码实例
2017/05/24 Javascript
EasyUI在Panel上动态添加LinkButton按钮
2017/08/11 Javascript
详解VUE里子组件如何获取父组件动态变化的值
2018/12/26 Javascript
详解如何使用nvm管理Node.js多版本
2019/05/06 Javascript
vue.js+ElementUI实现进度条提示密码强度效果
2020/01/18 Javascript
[00:56]PWL开团时刻DAY8——追追追追追!
2020/11/09 DOTA
Python减少循环层次和缩进的技巧分析
2016/03/15 Python
用python实现百度翻译的示例代码
2018/03/09 Python
python3+PyQt5实现自定义流体混合窗口部件
2018/04/24 Python
TensorFlow实现iris数据集线性回归
2018/09/07 Python
Django 路由系统URLconf的使用
2018/10/11 Python
Python3.5面向对象与继承图文实例详解
2019/04/24 Python
python PIL/cv2/base64相互转换实例
2020/01/09 Python
Python列表嵌套常见坑点及解决方案
2020/09/30 Python
Python批量修改xml的坐标值全部转为整数的实例代码
2020/11/26 Python
allbeauty美国:英国在线美容店
2019/03/11 全球购物
用C语言实现文件读写操作
2013/10/27 面试题
优秀管理者获奖感言
2014/02/17 职场文书
销售主管竞聘书
2014/03/31 职场文书
英雄儿女观后感
2015/06/09 职场文书
董事长新年致辞
2015/07/29 职场文书
基于tensorflow权重文件的解读
2021/05/26 Python
Python基本数据类型之字符串str
2021/07/21 Python