<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.Container {
position: relative;
box-sizing: border-box;
border: 1px solid red;
width: 0;
height: 0;
display: none;
overflow: hidden;
}
.Masks {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 99;
background: rgba(0, 0, 0, .5);
}
.Intercept {
cursor: move;
position: absolute;
top: 0;
left: 0;
z-index: 999;
}
/* 上下左右 */
.nodetop {
position: absolute;
top: -4px;
left: 50%;
transform: translateX(-50%);
width: 30px;
height: 8px;
background: #fff;
border-radius: 4px;
cursor: n-resize;
}
.nodebottom {
position: absolute;
bottom: -4px;
left: 50%;
transform: translateX(-50%);
width: 30px;
height: 8px;
background: #fff;
border-radius: 4px;
cursor: s-resize;
}
.nodeleft {
position: absolute;
top: 50%;
left: -4px;
transform: translateY(-50%);
width: 8px;
height: 30px;
background: #fff;
border-radius: 4px;
cursor: w-resize;
}
.noderight {
position: absolute;
top: 50%;
right: -4px;
transform: translateY(-50%);
width: 8px;
height: 30px;
background: #fff;
border-radius: 4px;
cursor: e-resize;
}
</style>
</head>
<body>
<input id="npt" type="file" accept="image/png,image/jpeg">
<img id="img" src="" alt="">
<script>
function Trim(obj, callback) {
this.canvas = document.createElement("canvas");// 创建canvas对象
this.ctx = this.canvas.getContext('2d'); // canvas方法
this.imgurl = ''; // base64地址
this.width = 0; // 图片宽
this.height = 0; // 图片高
this.dv = document.createElement('div'); // 最外层div
this.Masks = document.createElement('div'); // 蒙层
this.Intercept = document.createElement('div'); // 截取框
this.nodetop = document.createElement('div'); // 上
this.nodebottom = document.createElement('div'); // 下
this.nodeleft = document.createElement('div'); // 左
this.noderight = document.createElement('div'); // 右
this.dragging = false; // 判断是否是节点在移动
this.position = []; //移动点位
//x y为要裁剪的左上角的坐标,xx yy为右下角的坐标
this.clone = [
{ x: 0, y: 0 },
{ xx: 0, yy: 0 }
]
// 重新渲染的canvas
this.nCanvas = document.createElement('canvas');
this.nCtx = this.nCanvas.getContext('2d');
this.callback = callback; //回调函数
this._base64Url(obj.id);
}
// 解析上传的图片
Trim.prototype._base64Url = function (id) {
// 获取图片base64数据
var npt = document.querySelector(id);
npt.onchange = () => {
var reader = new FileReader();
reader.readAsDataURL(npt.files[0]);
reader.onloadend = (e) => {
this.imgurl = e.target.result;
// 渲染图片
this._creatImg()
};
};
}
// 渲染图片到canvas上
Trim.prototype._creatImg = function () {
var image = new Image();
image.src = this.imgurl;
image.addEventListener('load', () => {
// 获取原图宽高
this.width = image.width < 500 ? image.width : (image.width / 2);
this.height = image.width < 500 ? image.height : (image.height / 2);
//设置canvas大小与原图宽高一致
this.canvas.height = this.height;
this.canvas.width = this.width;
// 在canvas绘制图片
this.ctx.drawImage(image, 0, 0, this.width, this.height);
// 设置dv
this._creatDv();
})
}
// 创建div
Trim.prototype._creatDv = function () {
// 把canvas追加到dv上
this.dv.appendChild(this.canvas);
// 创建最外层div
document.body.appendChild(this.dv);
this.dv.className = 'Container';
// 设置dv样式
this.dv.style.display = 'block';
this.dv.style.width = `${this.width}px`;
this.dv.style.height = `${this.height}px`;
// 创建蒙层
this.Masks.className = 'Masks';
this.dv.appendChild(this.Masks);
// 创建截取区域
this.dv.appendChild(this.Intercept);
this.Intercept.className = 'Intercept';
this.Intercept.style.width = `${this.width / 2}px`;
this.Intercept.style.height = `${this.height / 2}px`;
this.Intercept.style.top = `${this.height / 4}px`;
this.Intercept.style.left = `${this.width / 4}px`;
// 设置截图信息
this.clone = [
{ x: this.Intercept.offsetLeft, y: this.Intercept.offsetTop },
{ xx: this.Intercept.offsetLeft + this.width / 2, yy: this.Intercept.offsetTop + this.height / 2 }
]
// 调用截图
this._Screenshots();
// 按下鼠标
this.Intercept.addEventListener('mousedown', (e) => {
this.dragging = true
this.position = [e.clientX, e.clientY]
})
// 移动鼠标
this.Intercept.addEventListener('mousemove', (e) => {
//判断是否点击div
if (this.dragging === false) {
return;
}
// 获取鼠标移动坐标
const x = e.clientX;
const y = e.clientY;
// 鼠标移动坐标减去点击坐标
const deltax = x - this.position[0]
const deltay = y - this.position[1]
// 把字符串转为数字
const left = parseInt(this.Intercept.offsetLeft)
const top = parseInt(this.Intercept.offsetTop)
// 设置div偏移量
if ((left + deltax + this.Intercept.offsetWidth) <= this.width && (left + deltax) >= 0) {
this.Intercept.style.left = left + deltax + 'px'
}
if ((top + deltay + this.Intercept.offsetHeight) <= this.height && (top + deltay) >= 0) {
this.Intercept.style.top = top + deltay + 'px'
}
this.clone = [
{ x: this.Intercept.offsetLeft, y: this.Intercept.offsetTop },
{ xx: this.Intercept.offsetLeft + this.width / 2, yy: this.Intercept.offsetTop + this.height / 2 }
]
// 鼠标移动坐标覆盖点击坐标
this.position = [x, y]
this._Screenshots();
// 阻止事件冒泡
e.stopPropagation();
})
// 松开鼠标
this.Intercept.addEventListener('mouseup', () => {
// 取消移动
this.dragging = false
})
// 移入documen取消移动
document.addEventListener('mousemove', () => {
this.dragging = false;
this.position = [0, 0]
})
}
Trim.prototype._Screenshots = function () {
// 截图宽度
var w = this.clone[1].xx - this.clone[0].x;
// 截图高度
var h = this.clone[1].yy - this.clone[0].y;
// 获取截图区域内容,截图区域的像素点矩阵
var cutImage = this.ctx.getImageData(this.clone[0].x, this.clone[0].y, w + 1, h + 1);
// 设置重新渲染canvas的参数
this.nCanvas.width = w;
this.nCanvas.height = h;
this.nCtx.putImageData(cutImage, 0, 0);// 将画布上指定矩形的像素数据,通过 putImageData() 方法将图像数据放回画布
// 把canvas节点添加到可移动div里面去
this.Intercept.appendChild(this.nCanvas)
// 回调函数把值传出去
let imgurl = this.nCanvas.toDataURL('image/png')
this.callback(imgurl);
}
let a = new Trim({
id: '#npt'
}, function (data) {
console.log(data)
})
</script>
</body>
</html>
截图
最新推荐文章于 2024-05-20 09:31:00 发布