zoukankan      html  css  js  c++  java
  • 用JavaScript实现图片剪切效果

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

    还可以学习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     }



  • 相关阅读:
    丁丁又病了
    领导之所以是领导
    丁丁的进步
    最近比较烦
    批量更新数据表
    转帖:《EnterLib PIAB深入剖析》系列博文汇总
    XML DOM介绍
    转大白话系列之C#委托与事件讲解大结局
    using
    jQuery工作原理解析以及源代码示例
  • 原文地址:https://www.cnblogs.com/Lovebugs/p/6506029.html
Copyright © 2011-2022 走看看