原生js+canvas實現裁剪圖片的功能

本文是利用一個css的屬性clip,我肯定有很多人都不知道這個屬性,因爲這個屬性用到的太少了,只是在特定的條件下才會用到這個屬性。這裏我就跟大家大致的說一下它的用法,想要了解更多這個屬性的可以去查閱一下資料,在這裏跟不跟大家說了。這裏主要是講如何利用這個屬性實現選取圖片的功能。

想要了解clip 這個屬性,首先要知道這個屬性的語法:clip:rect(top,right,bottom,left),clip屬性的特點就是隻顯示這些值包裹的區域,其他的區域全都隱藏。

選取圖片這個功能大隻分爲三個部分:

第一個部分:就是隻用作展示的一張圖片,這張圖片上不做任何的功能處理。

第二個部分:也是一張圖片,這張圖片覆蓋在第一章圖片的上面,利用clip屬性只顯示選取的部分,其他的隱藏。

第三個部分:是利用canvas的圖片接口把選擇的圖片區域繪製在預覽區域

大致的效果如圖所示:

 

 

接下來直接上代碼,本人是初學者,能力有限,歡迎各位大神指點。

HTML部分:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>圖片裁剪</title>
<script src="js/test.js" ></script>
<script src="js/jquery-1.8.1.min.js" ></script>
<script src="js/jquery-ui-1.10.4.custom.min.js" ></script>
<script src="js/rem.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="box">
<img src="images/1.jpg" id="img1"/>
<img src="images/1.jpg" id="img2"/>
<div id="main">
<div class="div minDiv" id="up"></div>
<div class="div minDiv2" id="left_up"></div>
<div class="div minDiv3" id="right_up"></div>
<div class="div minDiv4" id="left"></div>
<div class="div minDiv5" id="right"></div>
<div class="div minDiv6" id="left_down"></div>
<div class="div minDiv7" id="down"></div>
<div class="div minDiv8" id="right_down"></div>
</div>
</div>
<div id="preview">
<canvas id="canvas"></canvas>
</div>
</body>
</html>

 

css部分:

 

body{
background: #333;
}
#box{
position:absolute;
top: 1rem;
left: 2rem;
height: 3.5rem;
width: 5rem;
}
#img1{
position: absolute;
opacity: 0.6;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
#img2{
position: absolute;
top: 0;
left: 0;
clip: rect(0,0.2rem,0.2rem,0);
width: 100%;
height: 100%;
}
#main{
position: absolute;
border: 1px dashed  #fff;
height: 2rem;
width: 2rem;
cursor: move;
}
.div{
position: absolute;
width: 0.08rem;
height: 0.08rem;
background: #fff;
}
.minDiv{
left: 50%;
margin-left: -0.04rem;
top: -0.04rem;
cursor: n-resize;
}
.minDiv2{
top: -0.04rem;
left: -0.04rem;
cursor: nw-resize;
}
.minDiv3{
top: -0.04rem;
right: -0.04rem;
cursor: ne-resize;
}
.minDiv4{
top: 50%;
left: -0.04rem;
margin-top: -0.04rem;
cursor: w-resize;
}
.minDiv5{
top: 50%;
margin-top: -0.04rem;
right: -0.04rem;
cursor: e-resize;
}
.minDiv6{
bottom: -0.04rem;
left: -0.04rem;
cursor: ne-resize;
}
.minDiv7{
bottom: 0;
left: 50%;
margin-bottom: -0.04rem;
margin-left: -0.04rem;
cursor: s-resize;
}
.minDiv8{
bottom: 0;
margin-bottom: -0.04rem;
right: -0.04rem;
cursor: se-resize;
}
#preview{
position: absolute;
width: 2rem;
height: 2rem;
top: 1rem;
left: 10rem;
overflow: hidden;
}
#img3{
position: absolute;
}
#canvas{
height: 100%;
width: 100%;
background: #fff;
border: 1px solid #aaa;
}

 

js部分:

 

window.onload = function(){
document.onselectstart = new Function('event.returnValue=false;');//禁止圖片被選中
var box = document.getElementById('box');
var rightDiv = document.getElementById('right');//右邊觸點
var mainDiv = document.getElementById('main');
var up = document.getElementById('up');
var left = document.getElementById('left');
var down = document.getElementById('down');
var left_up = document.getElementById('left_up');
var right_up = document.getElementById('right_up');
var left_down = document.getElementById('left_down');
var right_down = document.getElementById('right_down');
var ifKeyDown = false;//鼠標按下狀態
var contact = "";//表示被按下的觸點
setChoice();
//鼠標按下事件
rightDiv.onmousedown = function(e){
e.stopPropagation();//阻止事件冒泡
ifKeyDown = true;
contact = "rightDiv";
}
up.onmousedown = function(e){
e.stopPropagation();
ifKeyDown = true;
contact = "up";
}
left.onmousedown = function(e){
e.stopPropagation();
ifKeyDown = true;
contact = "left"
}
down.onmousedown = function(e){
e.stopPropagation();
ifKeyDown = true;
contact = "down";
}
left_up.onmousedown = function(e){
e.stopPropagation();
ifKeyDown = true;
contact = "left_up";
}
left_down.onmousedown = function(e){
e.stopPropagation();
ifKeyDown = true;
contact = "left_down";
}
right_up.onmousedown = function(e){
e.stopPropagation();
ifKeyDown = true;
contact = "right_up";
}
right_down.onmousedown = function(e){
e.stopPropagation();
ifKeyDown = true;
contact = "right_down";
}
mainDiv.onmousedown = function(e){
e.stopPropagation();
ifKeyDown = true;
contact = "box";
}
//鼠標鬆開事件
window.onmouseup = function(){
ifKeyDown = false;
contact = "";
}
//鼠標移動事件
window.onmousemove = function(e){
if(ifKeyDown){
switch (contact){
case "rightDiv":rightMove(e);break;
case "up":upMove(e);break;
case "left":leftMove(e);break;
case "down":downMove(e);break;
case "left_up":leftMove(e);upMove(e);break;
case "left_down":leftMove(e);downMove(e);break;
case "right_up":rightMove(e);upMove(e);break;
case "right_down":rightMove(e);downMove(e);break;
// case "box":tuo(e);break;
}

}
setChoice();

}
//選取框按下拖拽事件
var disX;
var disY;
mainDiv.onmousedown = function(e){
ifKeyDown = true;
var oEvent = e || event;
disX = oEvent.clientX - mainDiv.offsetLeft;
disY = oEvent.clientY - mainDiv.offsetTop;
document.onmousemove = function(e){
var oEvent = e || event;
var l = oEvent.clientX - disX;
var t = oEvent.clientY - disY;
if (l < 0) {
l = 0;
} else if(l > box.offsetWidth - mainDiv.offsetWidth){
l = box.offsetWidth - mainDiv.offsetWidth;
}
if (t < 0) {
t = 0;
} else if(t > box.offsetHeight - mainDiv.offsetHeight){
t = box.offsetHeight - mainDiv.offsetHeight;
}
mainDiv.style.top = t +"px";
mainDiv.style.left = l +"px";
setPreview();
}
document.onmouseup = function(){
document.onmousemove = null;
document.onmouseup =null;
}
return false;

}
//設置選取區域高亮可見
function setChoice(){
var top = mainDiv.offsetTop;
var right = mainDiv.offsetLeft + mainDiv.offsetWidth;
var bottom = mainDiv.offsetTop + mainDiv.offsetHeight;
var left = mainDiv.offsetLeft;
var img2 = document.getElementById('img2');
img2.style.clip = "rect("+top+"px,"+right+"px,"+bottom+"px,"+left+"px)";
setPreview();
}
//獲取圖片的縮放比例
function bili(img,box){
var w = Math.round(img.width / box.offsetWidth * 100) / 100;
var h = Math.round(img.height / box.offsetHeight * 100) /100;
return {"w":w,"h":h};
}
//預覽函數
function setPreview(){
var l = mainDiv.offsetLeft;//選取框左上角的座標
var t = mainDiv.offsetTop;
var tt = right_down.offsetTop - right_up.offsetTop;//選取框的高度
var ll = right_down.offsetLeft - left_down.offsetLeft;//寬度
console.log(l+"  "+ t)
var canvas = document.getElementById('canvas');
var context = canvas.getContext("2d");
var box = document.getElementById('box');
var img = new Image();
img.src = "images/1.jpg";
img.onload = function(){
context.drawImage(img,l*bili(img,box).w,t*bili(img,box).h,ll*bili(img,box).w,tt*bili(img,box).h,0,0,canvas.width,canvas.height);
}
}
//右邊移動
function rightMove(e){
var x = e.clientX;//鼠標X座標s
if (x > getPosition(box).left + box.offsetWidth) {
x = getPosition(box).left + box.offsetWidth;
}
var widthBefore = mainDiv.offsetWidth-2;//選取框變換前的寬度
var addWidth = "";//鼠標移動後選取框增加的寬度
addWidth = x - getPosition(mainDiv).left - widthBefore;//鼠標移動後增加的寬度
mainDiv.style.width = addWidth + widthBefore +"px";//選取框變換後的寬度
}
//上邊移動
function upMove(e){
var y = e.clientY;//鼠標縱座標
if(y < getPosition(box).top){
y = getPosition(box).top;
}
var heightBefore = mainDiv.offsetHeight - 2;//原來的高度
var mainY = getPosition(mainDiv).top;//選取框相對於屏幕上邊的距離
var addHeight = mainY - y;//增加的高度
mainDiv.style.height = heightBefore + addHeight +"px";
mainDiv.style.top = mainDiv.offsetTop - addHeight +"px";
}
//下邊移動
function downMove(e){
var y = e.clientY;//鼠標縱座標
if(y > getPosition(box).top + box.offsetHeight){
y = getPosition(box).top + box.offsetHeight
}
var heightBefore = mainDiv.offsetHeight - 2;//選取框變換之前的高度
var mainY = getPosition(mainDiv).top;//選取框相對於父級的高度
var addHeight = y - heightBefore - mainY;//增加的高度
mainDiv.style.height = addHeight +heightBefore + "px";
}
//左邊移動
function leftMove(e){
var x = e.clientX;//鼠標的座標
if(x < getPosition(box).left){
x = getPosition(box).left;
}
var widthBefore = mainDiv.offsetWidth - 2;//選框變化前的寬度
var mainX = getPosition(mainDiv).left;
var addWidth = mainX - x ;//增加的寬度
mainDiv.style.width = widthBefore + addWidth +"px";//選款變換後的寬度
mainDiv.style.left = mainDiv.offsetLeft - addWidth +"px";
}
}


//獲取元素相對於屏幕左邊的距離
function getPosition(obj){
var left = obj.offsetLeft;
var top = obj.offsetTop;
var parent = obj.offsetParent;
while(parent != null){
left += parent.offsetLeft;
top += parent.offsetTop;
parent = parent.offsetParent;

}
return {"left":left,"top":top};
}

想要獲得更多資料的  請微信搜索公衆號 【熱血科技】,關注一下即可。

發佈了41 篇原創文章 · 獲贊 53 · 訪問量 28萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章