基于JavaScript实现图片剪切效果

发布时间 - 2026-01-11 00:03:02    点击率:

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

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

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

图片剪切三层结构

1、第一层opacity,给图层设置透明度

2、第二层clip,clip属性:对图片进行裁剪,实现图像的一部分显示,其他部分进行隐藏

3、第三层选取框absolute(与第二层重叠的),包括八个触点的效果

html代码:

<div id="box">
 <img src="img/1.jpg" id="img1" />
 <img src="img/1.jpg" id="img2" />
 <div id="main">
  <div class="Divmin up-left"></div>
  <div class="Divmin up"></div>
  <div class="Divmin up-right"></div>
  <div class="Divmin right"></div>
  <div class="Divmin right-down"></div>
  <div class="Divmin down"></div>
  <div class="Divmin left-down"></div>
  <div class="Divmin left"></div>
 </div>
</div>

css代码:

body{
  background: #333;
 }
 #box{
  width: 500px;
  height: 380px;
  position: absolute;
  top: 100px;
  left: 200px;
 }
 #img1,#img2{
  position: absolute;
  top: 0;
  left: 0;
 }
 #img1{
  opacity: 0.3;
 }
 #img2{
  clip: rect(0,200px,200px,0);
 }
 #main{
  position: absolute;/*第三层需用绝对定位浮在上面*/
  width: 200px;
  height: 200px;
  border: 1px solid #fff;
 }
 .Divmin{
  position: absolute;
  width: 8px;
  height: 8px;
  background: #fff;
 }
 .up-left{margin-top: -4px;margin-left: -4px;cursor: nw-resize;}
 .up{
  left: 50%;/*父元素盒子main宽度的一半,注意要有绝对定位*/
  margin-left:-4px;
  top: -4px;
  cursor: n-resize;
 }
 .up-right{top: -4px;right: -4px;cursor: ne-resize;}
 .right{top: 50%;margin-top: -4px;right: -4px;cursor: e-resize;}
 .right-down{right: -4px;bottom: -4px;cursor: se-resize;}
 .down{bottom: -4px;left: 50%;margin-left: -4px;cursor: s-resize;}
 .left-down{left: -4px;bottom: -4px;cursor: sw-resize;}
 .left{left: -4px;top: 50%;margin-top: -4px;cursor: w-resize;}

二、javascript获取选择框偏移量

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

offsetLeft:元素相对于其父元素左边界的距离;

clientX:鼠标位置的横坐标;

clientWidth:元素的宽度;

offsetXY:是该事件发生的盒子模型里的坐标,与滚动条无关。

clientXY:是整个浏览器可用部分里的坐标,与滚动条无关,即需要拖动滚动条才能看到的区域不考虑。

pageXY:是整个网页里的坐标,与滚动条有关。

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

js代码如下:

//获取元素相对于屏幕左边及上边的距离,利用offsetLeft
 function getPosition(el){
  var left = el.offsetLeft;
  var top = el.offsetTop;
  var parent = el.offsetParent;
  while(parent != null){
   left += parent.offsetLeft;
   top += parent.offsetTop;
   parent = parent.offsetParent;
  }
  return {"left":left,"top":top};
 }

三、javascript实现控制触点

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

注意区别:

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

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

1)点击右面的触点

js代码:

var mainDiv = $('main');
 var rightDiv = $('right');
 var isDraging = false;
 var contact = "";//表示被按下的触点
 //鼠标按下时
 rightDiv.onmousedown = function(){
  isDraging = true;
  contact = "right";
 }
 //鼠标松开时
 window.onmouseup = function(){
  isDraging = false;
 }
 //鼠标移动时
 window.onmousemove = function(e){
  if(isDraging == true){
   if(contact == "right"){
    var e = e||window.event;
    var x = e.clientX;//鼠标位置的横坐标
    var widthBefore = mainDiv.offsetWidth - 2;//选取框变化前的宽度
    //var widthBefore = mainDiv.clientWidth;
    var addWidth = x - getPosition(mainDiv).left - widthBefore;//鼠标移动后选取框增加的宽度
    mainDiv.style.width = widthBefore + addWidth + 'px';//选取框变化后的宽度
   }
  }
 }
//获取id的函数
function $(id){
 return document.getElementById(id);
}

2)点击上面触点

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

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

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

变化示意图:

js代码:

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

 3)点击左边触点

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

变化示意图:

js代码:

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

 4)点击下面触点

增加的宽度 = 鼠标位置纵坐标 - 距屏幕上边的距离 - 原先的宽度

左上角的位置不需改变

js代码:

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

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

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

      修改后的js代码如下:

window.onmousemove = function(e){
  var e = e||window.event;
  if(isDraging == true){
   switch (contact){
    case "up" : upMove(e);break;
    case "right" : rightMove(e);break;
    case "down" : downMove(e);break;
    case "left" : leftMove(e);break;
    case "up-right" : upMove(e);rightMove(e);break;
    case "down-right" : downMove(e);rightMove(e);break;
    case "down-left" : downMove(e);leftMove(e);break;
    case "up-left" : upMove(e);leftMove(e);break;
   }
  }
 }
//获取id的函数
function $(id){
 return document.getElementById(id);
}
//获取元素相对于屏幕左边及上边的距离,利用offsetLeft
 function getPosition(el){
  var left = el.offsetLeft;
  var top = el.offsetTop;
  var parent = el.offsetParent;
  while(parent != null){
   left += parent.offsetLeft;
   top += parent.offsetTop;
   parent = parent.offsetParent;
  }
  return {"left":left,"top":top};
 }
 //up移动
 function upMove(e){
  var y = e.clientY;//鼠标位置的纵坐标
  var heightBefore = mainDiv.offsetHeight - 2;//选取框变化前的高度
  var addHeight = getPosition(mainDiv).top - y;//增加的高度
  mainDiv.style.height = heightBefore + addHeight + 'px';//选取框变化后的宽度
  mainDiv.style.top = mainDiv.offsetTop - addHeight + 'px';//相当于变化后左上角的纵坐标,鼠标向上移纵坐标减小,下移增大
 }
 //right移动
 function rightMove(e){
  var x = e.clientX;//鼠标位置的横坐标
  var widthBefore = mainDiv.offsetWidth - 2;//选取框变化前的宽度
  //var widthBefore = mainDiv.clientWidth;
  var addWidth = x - getPosition(mainDiv).left - widthBefore;//鼠标移动后选取框增加的宽度
  mainDiv.style.width = widthBefore + addWidth + 'px';//选取框变化后的宽度
 }
 //down移动
 function downMove(e){
  var heightBefore = mainDiv.offsetHeight - 2;
  var addHeight = e.clientY - getPosition(mainDiv).top - mainDiv.offsetHeight;
  mainDiv.style.height = heightBefore + addHeight + 'px';
 }
 //left移动
 function leftMove(e){
  var widthBefore = mainDiv.offsetWidth - 2;
  var addWidth = getPosition(mainDiv).left - e.clientX;//增加的宽度等于距离屏幕左边的距离减去鼠标位置横坐标
  mainDiv.style.width = widthBefore + addWidth + 'px';
  mainDiv.style.left = mainDiv.offsetLeft - addWidth + 'px';//左边的距离(相当于左边位置横坐标)等于选取框距父级元素的距离减去增加的宽度
 }

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

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

四个方面图示:

js代码:

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

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的值

//右边图片预览函数
 function setPreview(){
  var top = mainDiv.offsetTop;
  var right = mainDiv.offsetLeft + mainDiv.offsetWidth;
  var bottom = mainDiv.offsetTop + mainDiv.offsetHeight;
  var left = mainDiv.offsetLeft;
  var img3 = $('img3');
  img3.style.top = -top + 'px';
  img3.style.left = -left + 'px';
  img3.style.clip = "rect("+top+"px,"+right+"px,"+bottom+"px,"+left+"px)";
 }

以上所述是小编给大家介绍的基于JavaScript实现图片剪切效果,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!


# js  # 实现图片剪切  # js实现点击后将文字或图片复制到剪贴板的方法  # php+js实现图片的上传、裁剪、预览、提交示例  # js+jquery实现图片裁剪功能  # jquery imgareaselect 使用利用js与程序结合实现图片剪切  # 使用JavaScript+canvas实现图片裁剪  # 基于原生JS实现图片裁剪  # javascript 图片裁剪技巧解读  # JS实现图片剪裁并预览效果  # 利用Javascript裁剪图片并存储的简单实现  # 鼠标  # 拖动  # 按下  # 相对于  # 滚动条  # 第二层  # 小编  # 第三层  # 还可以  # 在此  # 要有  # 可在  # 给大家  # 使其  # 要让  # 在上面  # 不需  # 但不  # 不包括  # 图层 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel Seeder怎么填充数据_Laravel数据库填充器的使用方法与技巧  如何在阿里云域名上完成建站全流程?  Laravel如何生成API文档?(Swagger/OpenAPI教程)  Laravel如何编写单元测试和功能测试?(PHPUnit示例)  如何在Windows环境下新建FTP站点并设置权限?  宙斯浏览器文件分类查看教程 快速筛选视频文档与图片方法  Laravel用户认证怎么做_Laravel Breeze脚手架快速实现登录注册功能  Angular 表单中正确绑定输入值以确保提交与验证正常工作  Laravel怎么生成URL_Laravel路由命名与URL生成函数详解  JavaScript中的标签模板是什么_它如何扩展字符串功能  Laravel怎么生成二维码图片_Laravel集成Simple-QrCode扩展包与参数设置【实战】  Win11怎么关闭资讯和兴趣_Windows11任务栏设置隐藏小组件  Windows10电脑怎么设置虚拟光驱_Win10右键装载ISO镜像文件  Laravel如何使用Eloquent进行子查询  EditPlus 正则表达式 实战(3)  北京网页设计制作网站有哪些,继续教育自动播放怎么设置?  js代码实现下拉菜单【推荐】  Laravel如何记录日志_Laravel Logging系统配置与自定义日志通道  google浏览器怎么清理缓存_谷歌浏览器清除缓存加速详细步骤  Laravel Fortify是什么,和Jetstream有什么关系  如何用wdcp快速搭建高效网站?  Win11搜索栏无法输入_解决Win11开始菜单搜索没反应问题【技巧】  EditPlus中的正则表达式实战(5)  Linux安全能力提升路径_长期防护思维说明【指导】  laravel服务容器和依赖注入怎么理解_laravel服务容器与依赖注入解析  Win11怎么查看显卡温度 Win11任务管理器查看GPU温度【技巧】  用yum安装MySQLdb模块的步骤方法  如何生成腾讯云建站专用兑换码?  javascript事件捕获机制【深入分析IE和DOM中的事件模型】  网站制作软件免费下载安装,有哪些免费下载的软件网站?  Laravel如何集成微信支付SDK_Laravel使用yansongda-pay实现扫码支付【实战】  免费的流程图制作网站有哪些,2025年教师初级职称申报网上流程?  如何在阿里云通过域名搭建网站?  Laravel Docker环境搭建教程_Laravel Sail使用指南  专业型网站制作公司有哪些,我设计专业的,谁给推荐几个设计师兼职类的网站?  Laravel的.env文件有什么用_Laravel环境变量配置与管理详解  网站制作软件有哪些,制图软件有哪些?  Laravel Session怎么存储_Laravel Session驱动配置详解  Laravel项目结构怎么组织_大型Laravel应用的最佳目录结构实践  Win11怎样安装网易有道词典_Win11安装词典教程【步骤】  laravel怎么配置和使用PHP-FPM来优化性能_laravel PHP-FPM配置与性能优化方法  Laravel如何配置.env文件管理环境变量_Laravel环境变量使用与安全管理  如何快速辨别茅台真假?关键步骤解析  高端建站三要素:定制模板、企业官网与响应式设计优化  北京网站制作的公司有哪些,北京白云观官方网站?  如何快速搭建支持数据库操作的智能建站平台?  Laravel如何集成第三方登录_Laravel Socialite实现微信QQ微博登录  Laravel广播系统如何实现实时通信_Laravel Reverb与WebSockets实战教程  JavaScript模板引擎Template.js使用详解  如何自定义safari浏览器工具栏?个性化设置safari浏览器界面教程【技巧】