您的位置:首页 > Web前端 > JavaScript

用JavaScript实现图片剪切效果

2017-03-08 10:37 609 查看
学会如何获取鼠标的坐标位置以及监听鼠标的按下、拖动、松开等动作事件,从而实现拖动鼠标来改变图片大小。

还可以学习css中的clip属性。

一、CSS实现图片不透明及裁剪效果。
图片剪切三层结构
1、第一层opacity,给图层设置透明度
2、第二层clip,clip属性:对图片进行裁剪,实现图像的一部分显示,其他部分进行隐藏
3、第三层选取框absolute(与第二层重叠的),包括八个触点的效果

html代码:


1 <div id="box">
2     <img src="img/1.jpg" id="img1" />
3     <img src="img/1.jpg" id="img2" />
4     <div id="main">
5         <div class="Divmin up-left"></div>
6         <div class="Divmin up"></div>
7         <div class="Divmin up-right"></div>
8         <div class="Divmin right"></div>
9         <div class="Divmin right-down"></div>
10         <div class="Divmin down"></div>
11         <div class="Divmin left-down"></div>
12         <div class="Divmin left"></div>
13     </div>
14 </div>




css代码:

1  body{
2         background: #333;
3     }
4     #box{
5         width: 500px;
6         height: 380px;
7         position: absolute;
8         top: 100px;
9         left: 200px;
10     }
11     #img1,#img2{
12         position: absolute;
13         top: 0;
14         left: 0;
15     }
16     #img1{
17         opacity: 0.3;
18     }
19     #img2{
20         clip: rect(0,200px,200px,0);
21     }
22     #main{
23         position: absolute;/*第三层需用绝对定位浮在上面*/
24         width: 200px;
25         height: 200px;
26         border: 1px solid #fff;
27     }
28     .Divmin{
29         position: absolute;
30         width: 8px;
31         height: 8px;
32         background: #fff;
33     }
34     .up-left{margin-top: -4px;margin-left: -4px;cursor: nw-resize;}
35     .up{
36         left: 50%;/*父元素盒子main宽度的一半,注意要有绝对定位*/
37         margin-left:-4px;
38         top: -4px;
39         cursor: n-resize;
40     }
41     .up-right{top: -4px;right: -4px;cursor: ne-resize;}
42     .right{top: 50%;margin-top: -4px;right: -4px;cursor: e-resize;}
43     .right-down{right: -4px;bottom: -4px;cursor: se-resize;}
44     .down{bottom: -4px;left: 50%;margin-left: -4px;cursor: s-resize;}
45     .left-down{left: -4px;bottom: -4px;cursor: sw-resize;}
46     .left{left: -4px;top: 50%;margin-top: -4px;cursor: w-resize;}


 
二、javascript获取选择框偏移量


选择框鼠标拖动位置详解:
offsetLeft:元素相对于其父元素左边界的距离;
clientX:鼠标位置的横坐标;
clientWidth:元素的宽度;

offsetXY:是该事件发生的盒子模型里的坐标,与滚动条无关。
clientXY:是整个浏览器可用部分里的坐标,与滚动条无关,即需要拖动滚动条才能看到的区域不考虑。
pageXY:是整个网页里的坐标,与滚动条有关。





构造一个getPosition()函数,用于获取元素相对于屏幕左边及上边的距离
js代码如下:


1 //获取元素相对于屏幕左边及上边的距离,利用offsetLeft
2     function getPosition(el){
3         var left = el.offsetLeft;
4         var top = el.offsetTop;
5         var parent = el.offsetParent;
6         while(parent != null){
7             left += parent.offsetLeft;
8             top += parent.offsetTop;
9             parent = parent.offsetParent;
10         }
11         return {"left":left,"top":top};
12     }


 

三、javascript实现控制触点

监听鼠标的按下、拖动、松开的事件控制选取框的大小。

注意区别:

Element.clientWidth 属性表示元素的内部宽度,以像素计。该属性包括内边距,但不包括垂直滚动条(如果有的话)、边框和外边距。

即clientWidth不包括边框,offsetWidth包括边框

1)点击右面的触点

js代码:

1     var mainDiv = $('main');
2     var rightDiv = $('right');
3     var isDraging = false;
4     var contact = "";//表示被按下的触点
5     //鼠标按下时
6     rightDiv.onmousedown = function(){
7         isDraging = true;
8         contact = "right";
9     }
10     //鼠标松开时
11     window.onmouseup = function(){
12         isDraging = false;
13     }
14     //鼠标移动时
15     window.onmousemove = function(e){
16         if(isDraging == true){
17             if(contact == "right"){
18                 var e = e||window.event;
19                 var x = e.clientX;//鼠标位置的横坐标
20                 var widthBefore = mainDiv.offsetWidth - 2;//选取框变化前的宽度
21                 //var widthBefore = mainDiv.clientWidth;
22                 var addWidth = x - getPosition(mainDiv).left - widthBefore;//鼠标移动后选取框增加的宽度
23                 mainDiv.style.width = widthBefore + addWidth + 'px';//选取框变化后的宽度
24             }
25         }
26     }
27
28 //获取id的函数
29 function $(id){
30     return document.getElementById(id);
31 }


 

2)点击上面触点 

点击上面中间的触点移动时,选取框的高度和左上角的位置都需要变化。

增加的高度=选取框相对于屏幕上面的距离 - 鼠标位置的纵坐标

选取框左上角的top值要减去增加的高度,因为鼠标向上移动时高度增加,top值减小,下移时高度减小,top增大。

变化示意图:



js代码:

1 else if(contact == "up"){
2                 var y = e.clientY;//鼠标位置的纵坐标
3                 var heightBefore = mainDiv.offsetHeight - 2;//选取框变化前的高度
4                 var addHeight = getPosition(mainDiv).top - y;//增加的高度
5                 mainDiv.style.height = heightBefore + addHeight + 'px';//选取框变化后的宽度
6                 mainDiv.style.top = mainDiv.offsetTop - addHeight + 'px';//相当于变化后左上角的纵坐标,鼠标向上移纵坐标减小,下移增大
7             }


 

 3)点击左边触点

原理同点击上面触点,宽度和左边的位置都会变化

变化示意图:



js代码:

1 else if(contact == "left"){
2                     var widthBefore = mainDiv.offsetWidth - 2;
3                     var addWidth = getPosition(mainDiv).left - e.clientX;//增加的宽度等于距离屏幕左边的距离减去鼠标位置横坐标
4                     mainDiv.style.width = widthBefore + addWidth + 'px';
5                     mainDiv.style.left = mainDiv.offsetLeft - addWidth + 'px';//左边的距离(相当于左边位置横坐标)等于选取框距父级元素的距离减去增加的宽度
6             }


 4)点击下面触点

增加的宽度 = 鼠标位置纵坐标 - 距屏幕上边的距离 - 原先的宽度
左上角的位置不需改变
js代码:


1 else if(contact = "down"){
2                 var heightBefore = mainDiv.offsetHeight - 2;
3                 var addHeight = e.clientY - getPosition(mainDiv).top - mainDiv.offsetHeight;
4                 mainDiv.style.height = heightBefore + addHeight + 'px';
5             }




 5)点四个角时的变化是高度和宽度变化的叠加,所以最好将上面四个变化的过程封装成函数,便于维护和代码复用。

      如果用if else 需要判断8次,所以改为switch语句来简化代码

      修改后的js代码如下:

1  window.onmousemove = function(e){
2         var e = e||window.event;
3         if(isDraging == true){
4            switch (contact){
5                case "up" : upMove(e);break;
6                case "right" : rightMove(e);break;
7                case "down" : downMove(e);break;
8                case "left" : leftMove(e);break;
9                case "up-right" : upMove(e);rightMove(e);break;
10                case "down-right" : downMove(e);rightMove(e);break;
11                case "down-left" : downMove(e);leftMove(e);break;
12                case "up-left" : upMove(e);leftMove(e);break;
13            }
14         }
15     }
16
17 //获取id的函数
18 function $(id){
19     return document.getElementById(id);
20 }
21 //获取元素相对于屏幕左边及上边的距离,利用offsetLeft
22     function getPosition(el){
23         var left = el.offsetLeft;
24         var top = el.offsetTop;
25         var parent = el.offsetParent;
26         while(parent != null){
27             left += parent.offsetLeft;
28             top += parent.offsetTop;
29             parent = parent.offsetParent;
30         }
31         return {"left":left,"top":top};
32     }
33     //up移动
34     function upMove(e){
35         var y = e.clientY;//鼠标位置的纵坐标
36         var heightBefore = mainDiv.offsetHeight - 2;//选取框变化前的高度
37         var addHeight = getPosition(mainDiv).top - y;//增加的高度
38         mainDiv.style.height = heightBefore + addHeight + 'px';//选取框变化后的宽度
39         mainDiv.style.top = mainDiv.offsetTop - addHeight + 'px';//相当于变化后左上角的纵坐标,鼠标向上移纵坐标减小,下移增大
40     }
41     //right移动
42     function rightMove(e){
43         var x = e.clientX;//鼠标位置的横坐标
44         var widthBefore = mainDiv.offsetWidth - 2;//选取框变化前的宽度
45         //var widthBefore = mainDiv.clientWidth;
46         var addWidth = x - getPosition(mainDiv).left - widthBefore;//鼠标移动后选取框增加的宽度
47         mainDiv.style.width = widthBefore + addWidth + 'px';//选取框变化后的宽度
48     }
49     //down移动
50     function downMove(e){
51         var heightBefore = mainDiv.offsetHeight - 2;
52         var addHeight = e.clientY - getPosition(mainDiv).top - mainDiv.offsetHeight;
53         mainDiv.style.height = heightBefore + addHeight + 'px';
54     }
55     //left移动
56     function leftMove(e){
57         var widthBefore = mainDiv.offsetWidth - 2;
58         var addWidth = getPosition(mainDiv).left - e.clientX;//增加的宽度等于距离屏幕左边的距离减去鼠标位置横坐标
59         mainDiv.style.width = widthBefore + addWidth + 'px';
60         mainDiv.style.left = mainDiv.offsetLeft - addWidth + 'px';//左边的距离(相当于左边位置横坐标)等于选取框距父级元素的距离减去增加的宽度
61     }


 

四、实现选取框区域明亮显示

1)选取框内的第二层图片需重新设置其clip属性

四个方面图示:



js代码:

1  //设置选取框图片区域明亮显示
2     function setChoice(){
3         var top = mainDiv.offsetTop;
4         var right = mainDiv.offsetLeft + mainDiv.offsetWidth;
5         var bottom = mainDiv.offsetTop + mainDiv.offsetHeight;
6         var left = mainDiv.offsetLeft;
7         img2.style.clip = "rect("+top+"px,"+right+"px,"+bottom+"px,"+left+"px)";
8     }


 
2)鼠标移动时会导致图片被选中,可在js代码中添加一行代码使其禁止图片被选中


//禁止图片被选中
document.onselectstart = new Function('event.returnValue = false;');


也可以在css样式里添加 *{user-select:none}
意思是文本不可选中,对图片跟div有一样的效果。

五、实现选取框位置可拖动

首先要阻止事件冒泡
js代码如下:


//鼠标按下触点时
rightDiv.onmousedown = function(e){
e.stopPropagation();
isDraging = true;
contact = "right";
}


鼠标拖拽效果的实现可见另一篇随笔http://www.cnblogs.com/vampire170204/p/6422914.html

六、实现图片剪切区域预览

新增一个图片预览区域的div

html代码:

<div id="preview">
<img src="img/1.jpg" id="img3" />
</div>


css代码:

#preview{
position: absolute;
width: 500px;
height: 380px;
top: 100px;
left:710px ;
}
#preview #img3{position: absolute;}


注意:要让clip:rect(top,right,bottom,left) 起作用,必须让作用元素为相对/绝对定位。

js部分同样是利用clip属性,和setChoice()函数同时被调用

同时为了让右边预览区的左上角位置固定,需要设置其top和left的值

1 //右边图片预览函数
2     function setPreview(){
3         var top = mainDiv.offsetTop;
4         var right = mainDiv.offsetLeft + mainDiv.offsetWidth;
5         var bottom = mainDiv.offsetTop + mainDiv.offsetHeight;
6         var left = mainDiv.offsetLeft;
7         var img3 = $('img3');
8         img3.style.top = -top + 'px';
9         img3.style.left = -left + 'px';
10         img3.style.clip = "rect("+top+"px,"+right+"px,"+bottom+"px,"+left+"px)";
11     }


来源:http://www.cnblogs.com/vampire170204/p/6506029.html

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: