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

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

一、CSS实现图片不透明及裁剪效果。

  1. 图片剪切三层结构
  2. 1、第一层opacity,给图层设置透明度
  3. 2、第二层clipclip属性:对图片进行裁剪,实现图像的一部分显示,其他部分进行隐藏
  4. 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>
  1.  

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. ;
  14. ;
  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;}
  1. 二、javascript获取选择框偏移量

选择框鼠标拖动位置详解:

  1. offsetLeft:元素相对于其父元素左边界的距离;
  2. clientX:鼠标位置的横坐标;
  3. clientWidth:元素的宽度;

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

  1.  
  1. 构造一个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. }

  1.  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. }
  1.  

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. }
  1. 2)鼠标移动时会导致图片被选中,可在js代码中添加一行代码使其禁止图片被选中
  1. //禁止图片被选中
  2. document.onselectstart = new Function('event.returnValue = false;');
  1. 也可以在css样式里添加 *{user-select:none}
    意思是文本不可选中,对图片跟div有一样的效果。

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

    首先要阻止事件冒泡
    js代码如下:
  1. //鼠标按下触点时
  2. rightDiv.onmousedown = function(e){
  3. e.stopPropagation();
  4. isDraging = true;
  5. contact = "right";
  6. }

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

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

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

html代码:

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

css代码:

  1. #preview{
  2. position: absolute;
  3. width: 500px;
  4. height: 380px;
  5. top: 100px;
  6. left:710px ;
  7. }
  8. #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. }


用JavaScript实现图片剪切效果的更多相关文章

  1. 原生javascript实现图片放大镜效果

    当我们在电商网站上购买商品时,经常会看到这样一种效果,当我们把鼠标放到我们浏览的商品图片上时,会出现类似放大镜一样的一定区域的放大效果,方便消费者观察商品.今天我对这一技术,进行简单实现,实现图片放大 ...

  2. 《JavaScript 实战》:JavaScript 实现图片切割效果

    很久之前就在一个网站的截取相片的功能中看到这个效果,也叫图片裁剪.图片剪切(设置一下也可以做出放大镜等类似的效果).当时觉得很神奇,碍于水平有限,没做出来.前些日子突然想做一个透镜效果,就突然想到了这 ...

  3. Canvas + JavaScript 制作图片粒子效果

    首先看一下源图和转换成粒子效果的对比图:       左侧图片为源图,右侧图片为粒子效果图.该效果是在Canvas画布上制作的.将图片制作成粒子效果相对而言是比较简单的.重点了解两个知识点即可 1:图 ...

  4. 使用CSS的clip-path实现图片剪切效果

    最近有个业务需求:校对图片文本信息,如下图所示,当鼠标点击文本中某一行的时候,文本上会显示对应行图片同时左侧会显示对应位置的画框. clip-path 今天要说的主题是:如何剪切原图中的部分图片?(前 ...

  5. javascript 实现图片拖动

    javascript实现图片拖动效果并不难,主要的思路如下 1:给图片绑定监听鼠标按下对象,设置拖动属性为true 2:鼠标抬起:拖动属性为false 鼠标移动:改变坐标即可,新坐标=图片原始坐标+鼠 ...

  6. HTML5+javascript实现图片加载进度动画效果

    在网上找资料的时候,看到网上有图片加载进度的效果,手痒就自己也写了一个. 图片加载完后,隐藏loading效果. 想看加载效果,请ctrel+F5强制刷新或者清理缓存. 效果预览:   0%   // ...

  7. ASP.NET中使用JavaScript实现图片自动水平滚动效果

    参照网上的资料,在ASP.NET中使用JavaScript实现图片自动水平滚动效果. 1.页面前台代码: <%@ Page Language="C#" AutoEventWi ...

  8. javascript图片放大镜效果展示

    javascript图片放大镜效果展示 <!DOCTYPE html> <html> <head lang="en"> <meta cha ...

  9. JavaScript仿百度图片浏览效果(转载)

    转载来源:https://www.jb51.net/article/98030.htm 这是一个非常好的案例,然而jquery的时代正在徐徐关闭. 当你调整浏览器宽高,你会发现它不是自适应的.当你想把 ...

随机推荐

  1. Intel为什么做不好手机CPU?

    Intel大名鼎鼎,在CPU界无人不知无人不晓,然而在当前主流的手机CPU市场上却是远远落后日本的ARM公司,这到底是Intel技术不足,还是ARM过于强大呢,今天我们就来探讨一下. 故事要从2006 ...

  2. 在DFS和BFS中一般情况可以不用vis[][]数组标记

    开始学dfs 与bfs 时一直喜欢用vis[][]来标记有没有访问过, 现在我觉得没有必要用vis[][]标记了 看代码 用'#'表示墙,'.'表示道路 if(所有情况都满足){ map[i][j]= ...

  3. Java Ant Could not find the main class: org.eclipse.ant.internal.launching.remote.InternalAntRunner. Program

    参考:http://blog.csdn.net/jiangtaoking/article/details/49151763 The solution is to go to Run as → Exte ...

  4. C# 定时器计划任务

    函数类: public class MyPlan { public void RunMyplan(object source, ElapsedEventArgs e) { //读取配置文件设定的日期时 ...

  5. 如何利用jquery 实现表格数据的搜索功能

    在表格的操作中,常常会遇到通过关键字来搜索结果,这个功能用jquery的filter实现非常简单. 我以一个小例子说明: <table> <thead> <tr cols ...

  6. 消息队列NetMQ 原理分析2-IO线程和完成端口

    消息队列NetMQ 原理分析2-IO线程和完成端口 前言 介绍 目的 IO线程 初始化IO线程 Proactor 启动Procator线程轮询 处理socket 获取超时时间 从完成端口获取处理完的状 ...

  7. asp.net权限认证:Windows认证

    asp.net权限认证系列 asp.net权限认证:Forms认证 asp.net权限认证:HTTP基本认证(http basic) asp.net权限认证:Windows认证 asp.net权限认证 ...

  8. sql查询调优之where条件排序字段以及limit使用索引的奥秘

       奇怪的慢sql 我们先来看2条sql 第一条: select * from acct_trans_log WHERE  acct_id = 1000000000009000757 order b ...

  9. ArcGIS Desktop 10.5 安装实录

    ArcGIS Desktop 10.5 安装实录 by 李远祥 几天前已经收到ArcGIS10.5的最终版安装介质,终于有时间可以安装一下.尽管ArcGIS10.5系列中,桌面软件不是主角,但笔者还是 ...

  10. .NET十五周年生日快乐 (3月7日发布Visual Studio 2017正式版?)

    今天 是.NET 对世界首次亮相15 周年.2002 年 2 月 13 日,第一版本的.NET 发布作为 Visual Studio.NET 的一部分.它仿佛就在昨天为微软建设成"下一代 W ...