功能介紹:圖片通過原生input上傳,使用canvas進(jìn)行圖片裁剪。 裁剪框限制不允許超出圖片范圍,圖片限制了最大寬高(自行修改要的尺寸),點(diǎn)擊確認(rèn)獲取新的base64圖片數(shù)據(jù)文章來源:http://www.zghlxwxcb.cn/news/detail-507263.html
注:fixed布局不適用該方案,若是fixed布局請(qǐng)查看另一篇文章
效果圖:
上代碼文章來源地址http://www.zghlxwxcb.cn/news/detail-507263.html
<!DOCTYPE HTML>
<html>
<head lang="en">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>圖片裁剪</title>
</head>
<body>
<input id="npt" type="file">
<div id="box">
<img style="position:absolute;top:0px;left:0px;opacity: 0.3;" src="" id="img1" />
<img style="position:absolute;top:0px;left:0px;clip: rect(50px, 250px, 250px, 50px);" src="" id="img2" />
<!--第三層需用絕對(duì)定位浮在上面-->
<div id="dragDiv" style="position: absolute;width: 200px;height: 200px;border: 1px solid #fff;top:50px;left:50px;">
<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 class="Divmin-btn" style="right: 68px;background-color: #2d87f5;" id="confirmBtn">確定</div>
<div class="Divmin-btn" style="right: 0px;background-color: #f5a52d;">取消</div>
</div>
<div style="position: absolute; right: 0;">
<img src="" id="later" alt="">
</div>
</div>
</body>
</html>
<style>
body {}
#box {
width: 1200px;
height: 600px;
background: #333;
position: absolute;
top: 50px;
left: 50px;
}
.Divmin-btn {
bottom: -40px;
width: 60px;
height: 30px;
line-height: 30px;
color: white;
font-size: 12px;
text-align: center;
display: inline-block;
position: absolute;
border-radius: 3px 3px 3px 3px;
}
.Divmin-btn:hover {
background-color: rgba(60, 103, 222, 0.6);
color: #efeeee;
}
.Divmin-btn:active {
background-color: rgba(69, 94, 167, 0.6);
color: #efeeee;
}
.Divmin {
position: absolute;
width: 8px;
height: 8px;
background: #fff;
}
.up-left {
margin-top: -4px;
margin-left: -4px;
cursor: nw-resize;
}
.up {
left: 50%;
/*父元素盒子dragDiv寬度的一半,注意要有絕對(duì)定位*/
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;
}
#img1,
#img2 {
max-width: 600px;
max-height: 300px;
}
</style>
<script type="text/javascript">
//禁止圖片被選中
document.onselectstart = new Function('event.returnValue = false;');
let confirmBtn = document.getElementById('confirmBtn')
confirmBtn.addEventListener('click', () => {
drawRect();
})
// 獲取圖片base64數(shù)據(jù)
let npt = document.getElementById("npt");
npt.onchange = function () {
let reader = new FileReader();
reader.readAsDataURL(npt.files[0]);
reader.onloadend = function (e) {
img1.src = e.target.result;
img2.src = e.target.result;
// console.log(e.target.result);// 圖片的base64數(shù)據(jù)
getImage(e.target.result)
};
}
let canvas = document.createElement("canvas");
let ctx = canvas.getContext('2d');
// 創(chuàng)建圖片
let getImage = function (b64) {
// 創(chuàng)建圖片對(duì)象
let image = new Image();
image.src = `${b64}`;
image.onload = function () {
// 獲取原圖寬高
let height = img1.offsetHeight;
let width = img1.offsetWidth;
//設(shè)置canvas大小與原圖寬高一致
canvas.height = height;
canvas.width = width;
// 在canvas繪制圖片
ctx.drawImage(this, 0, 0, width, height);
// 截圖:
// drawRect();
// 圖片上傳后設(shè)置裁剪框與圖片大小一致
dragDiv.style.height = img1.offsetHeight + 'px'
dragDiv.style.width = img1.offsetWidth + 'px'
dragDiv.style.top = 0 + 'px';
dragDiv.style.left = 0 + 'px';
setChoice();
}
};
// 繪制截圖矩陣
let drawRect = function () {
let top = dragDiv.offsetTop;
let right = dragDiv.offsetLeft + dragDiv.offsetWidth;
let bottom = dragDiv.offsetTop + dragDiv.offsetHeight;
let left = dragDiv.offsetLeft;
// 截圖寬度
let w = right - left;
// 截圖高度
let h = bottom - top;
// 獲取截圖區(qū)域內(nèi)容,截圖區(qū)域的像素點(diǎn)矩陣
let cutImage = ctx.getImageData(left, top, w, h);
// 裁剪后的base64數(shù)據(jù)
let newImage = createNewCanvas(cutImage, w, h);
later.src = newImage;
// console.log(newImage);// 裁剪后的base64數(shù)據(jù)
};
var createNewCanvas = function (content, width, height) {
var nCanvas = document.createElement('canvas');
var nCtx = nCanvas.getContext('2d');
nCanvas.width = width;
nCanvas.height = height;
nCtx.putImageData(content, 0, 0);// 將畫布上指定矩形的像素?cái)?shù)據(jù),通過 putImageData() 方法將圖像數(shù)據(jù)放回畫布
return nCanvas.toDataURL('image/png');
}
//獲取id的函數(shù)
function $(id) {
if (id.indexOf(".") == 0) {
let className = id.substring(1, id.length);
let els = document.getElementsByClassName(className);
return els[0];
}
return document.getElementById(id);
}
//獲取元素相對(duì)于屏幕左邊及上邊的距離,利用offsetLeft
function getPosition(el) {
let left = el.offsetLeft;
let top = el.offsetTop;
let parent = el.offsetParent;
while (parent != null) {
left += parent.offsetLeft;
top += parent.offsetTop;
parent = parent.offsetParent;
}
return { "left": left, "top": top };
}
let dragDiv = $('dragDiv');
let box = $('box')
let img1 = $('img1')
let rightDiv = $('.right');
let isDraging = false;
let contact = "";//表示被按下的觸點(diǎn)
//鼠標(biāo)按下時(shí)
$('.right').onmousedown = function () {
isDraging = true;
contact = "right";
}
$('.left').onmousedown = function () {
isDraging = true;
contact = "left";
}
$('.down').onmousedown = function () {
isDraging = true;
contact = "down";
}
$('.up').onmousedown = function () {
isDraging = true;
contact = "up";
}
$('.up-right').onmousedown = function () {
isDraging = true;
contact = "up-right";
}
$('.right-down').onmousedown = function () {
isDraging = true;
contact = "down-right";
}
$('.up-left').onmousedown = function () {
isDraging = true;
contact = "up-left";
}
$('.left-down').onmousedown = function () {
isDraging = true;
contact = "down-left";
}
//鼠標(biāo)松開時(shí)
window.onmouseup = function () {
isDraging = false;
}
//鼠標(biāo)移動(dòng)時(shí)
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;
}
}
}
//up移動(dòng)
function upMove(e) {
let y = e.clientY;//鼠標(biāo)位置的縱坐標(biāo)
let heightBefore = dragDiv.offsetHeight - 2;//選取框變化前的高度
let addHeight = getPosition(dragDiv).top - y;//增加的高度
let height = heightBefore + addHeight
let top = dragDiv.offsetTop - addHeight
if (top <= 1 || height <= 1) return
dragDiv.style.height = height + 'px';//選取框變化后的寬度
dragDiv.style.top = top + 'px';//相當(dāng)于變化后左上角的縱坐標(biāo),鼠標(biāo)向上移縱坐標(biāo)減小,下移增大
setChoice();
}
//right移動(dòng)
function rightMove(e) {
let allWidth = img1.offsetWidth + box.offsetLeft
let x = e.clientX;//鼠標(biāo)位置的橫坐標(biāo)
let widthBefore = dragDiv.offsetWidth - 2;//選取框變化前的寬度
//let widthBefore = dragDiv.clientWidth;
if (x >= allWidth) return
let addWidth = x - getPosition(dragDiv).left - widthBefore;//鼠標(biāo)移動(dòng)后選取框增加的寬度
dragDiv.style.width = widthBefore + addWidth + 'px';//選取框變化后的寬度
setChoice();
}
//down移動(dòng)
function downMove(e) {
let heightBefore = dragDiv.offsetHeight - 2;
let bottom = box.offsetTop + img1.offsetHeight
let addHeight = e.clientY - getPosition(dragDiv).top - dragDiv.offsetHeight;
if (e.clientY >= bottom) return
let height = heightBefore + addHeight
dragDiv.style.height = heightBefore + addHeight + 'px';
setChoice();
}
//left移動(dòng)
function leftMove(e) {
let widthBefore = dragDiv.offsetWidth - 2;
let addWidth = getPosition(dragDiv).left - e.clientX;//增加的寬度等于距離屏幕左邊的距離減去鼠標(biāo)位置橫坐標(biāo)
let width = widthBefore + addWidth
let left = dragDiv.offsetLeft - addWidth
if (left <= 1 || width <= 1) return
dragDiv.style.width = width + 'px';
dragDiv.style.left = left + 'px';//左邊的距離(相當(dāng)于左邊位置橫坐標(biāo))等于選取框距父級(jí)元素的距離減去增加的寬度
setChoice();
}
//設(shè)置選取框圖片區(qū)域明亮顯示
function setChoice() {
let top = dragDiv.offsetTop;
let right = dragDiv.offsetLeft + dragDiv.offsetWidth;
let bottom = dragDiv.offsetTop + dragDiv.offsetHeight;
let left = dragDiv.offsetLeft;
$('img2').style.clip = "rect(" + top + "px," + right + "px," + bottom + "px," + left + "px)";
}
</script>
到了這里,關(guān)于原生JS實(shí)現(xiàn)圖片裁剪功能的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!