JavaScript实现图片裁剪与选取框交互详解
本文详细解析如何使用JavaScript结合CSS实现图片裁剪效果。通过监听鼠标按下、移动和松开事件,动态计算选取框的偏移量与尺寸变化。重点讲解如何利用CSS clip属性隐藏非选中区域,并通过多层DOM结构实现选取框的拖动、缩放及局部高亮显示,最终完成完整的图片剪切交互逻辑。
图片剪切功能概述与CSS实现
掌握获取鼠标坐标位置的方法,并监听鼠标的按下、拖动和松开等事件,从而通过拖动鼠标来调整图片的大小。
同时需要熟悉CSS中的clip属性,用于控制图像的显示区域。
一、使用CSS实现图片的不透明处理及裁剪效果。
图片剪切功能涉及三层DOM结构。
1、第一层为透明度控制,通过设置图层的opacity属性来实现半透明效果。
2、第二层使用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获取选取框偏移量
二、使用JavaScript获取选取框的偏移量。
详细解析选取框鼠标拖动时的位置计算逻辑:
offsetLeft:表示元素相对于其父元素左边界的距离。
clientX:表示鼠标位置的横坐标。
clientWidth:表示元素的宽度。
offsetXY:表示事件发生时的盒子模型坐标,该值与滚动条无关。
clientXY:表示整个浏览器可用区域内的坐标,与滚动条无关,即不考虑需要拖动滚动条才能看到的区域。
pageXY:表示整个网页内的坐标,该值与滚动条有关。

构造一个getPosition()函数,用于获取元素相对于屏幕左边及上边的距离。
JavaScript代码如下:
//获取元素相对于屏幕左边及上边的距离,利用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控制触点与尺寸调整
三、使用JavaScript实现控制触点。
通过监听鼠标的按下、拖动和松开事件来控制选取框的大小变化。
需要注意以下区别:
Element.clientWidth属性表示元素的内部宽度,以像素计。该属性包括内边距,但不包括垂直滚动条(如果有的话)、边框和外边距。
即clientWidth不包括边框,而offsetWidth包括边框。
1)点击右侧触点时的处理逻辑。
JavaScript代码如下:
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值增大。
变化示意图如下:

JavaScript代码如下:
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)点击左侧触点时的处理逻辑。
原理同点击上方触点,宽度和左边的位置都会发生变化。
变化示意图如下:

JavaScript代码如下:
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)点击下方触点时的处理逻辑。
增加的宽度等于鼠标位置纵坐标减去距屏幕上边的距离再减去原先的宽度。
左上角的位置不需改变。
JavaScript代码如下:
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语句来简化代码。
修改后的JavaScript代码如下:
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属性。
四个方面图示如下:

JavaScript代码如下:
//设置选取框图片区域明亮显示
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)鼠标移动时会导致图片被选中,可在JavaScript代码中添加一行代码以禁止图片被选中。
//禁止图片被选中
document.onselectstart = new Function('event.returnValue = false;');
也可以在CSS样式里添加 *{user-select:none}。
该样式表示文本不可选中,对图片和div具有相同的效果。
五、实现选取框位置的可拖动功能。
首先需要阻止事件冒泡。
JavaScript代码如下:
//鼠标按下触点时
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)起作用,必须让作用元素为相对或绝对定位。
JavaScript部分同样是利用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实现图片剪切效果,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对本站网站的支持!
JavaScript零基础入门:从环境搭建到运行第一段代码
2026-11-05 15:29:58
HTML链接中javascript:void(0)的作用及现代替代方案
2026-11-05 10:07:47
在线调试 JS 时怎么引入 jQuery 或 Vue 等第三方库
2026-11-05 08:53:56
原生JavaScript实现简易颜色选择器原理与代码
2026-11-03 23:22:19
JS原生表单序列化:FormData与URLSearchParams用法详解
2026-11-03 23:13:21
