canvas实现图片简单裁剪下载保存

canvas实现图片简单裁剪下载保存

const _$ = sel => document.querySelector(sel)
class CutImg {
	constructor(sel){
		this.box = _$(sel)
		this.imgCanvas = document.createElement('canvas')
		this.previewCanvas = document.createElement('canvas')
		
		this.box.appendChild(this.imgCanvas)
		this.box.appendChild(this.previewCanvas)
		this.previewCanvas.style.display = 'none'
		
		this.imgCtx = null
		this.previewCtx = null
		
		this.loadImg = null
	}
	inputFile(file){
		let _this = this
		let img = file[0]
		let reader = new FileReader()
		reader.readAsDataURL(img)
		
		reader.onloadend = function(){
			_this.loadImg = new Image()
			_this.loadImg.src = reader.result
			_this.loadImg.onload = function(){
				_this.initImgCtx(_this.loadImg)
			}
		}
	}
	initImgCtx(img){
		if(!this.loadImg){
			this.loadImg = img
		}
		if(!this.imgCtx){
			this.imgCtx = this.imgCanvas.getContext('2d')
			this.addEvent()
		}else{
			this.imgCtx.clearRect(0,0,this.imgCanvas.width, this.imgCanvas.height)
		}
		this.imgCanvas.width = img.width
		this.imgCanvas.height = img.height
		this.imgCtx.drawImage(img, 0, 0)
	}
	addEvent(){
		let down = false, ctx = this.imgCtx, cutCanvas = this.imgCanvas, cx1, cy1, cx2, cy2
		cutCanvas.addEventListener('mousedown', function(ev){
			down = true
			ctx.beginPath()
			ctx.strokeStyle = '#f00'
			cx1 = ev.offsetX
			cy1 = ev.offsetY
			
		})
		cutCanvas.addEventListener('mousemove', (ev) => {
			if(down){
				ctx.clearRect(0, 0, cutCanvas.width, cutCanvas.height)
				ctx.beginPath()
				
				cx2 = ev.offsetX
				cy2 = ev.offsetY
				
				ctx.drawImage(this.loadImg, 0, 0)
				ctx.rect(cx1, cy1, cx2 - cx1, cy2 - cy1)
				ctx.stroke()
			}
		})
		cutCanvas.addEventListener('mouseup', () => {
			if(down){
				ctx.strokeStyle = '#fff'
				ctx.rect(cx1, cy1, cx2 - cx1, cy2 - cy1)
				ctx.stroke()
				if(cx1 === cx2 && cy1 === cy2) return down = false;
				previewImg.bind(this)()
			}
			down = false
		})
		cutCanvas.addEventListener('mouseout', function(){
			down = false
		})
		function previewImg(){
			if(!this.previewCtx){
				this.previewCtx = this.previewCanvas.getContext('2d')
			}
			this.previewCanvas.width = cx2 - cx1
			this.previewCanvas.height = cy2 - cy1
			
			this.previewCtx.drawImage(this.loadImg, cx1, cy1, cx2 - cx1, cy2 - cy1, 0, 0, cx2 - cx1, cy2 - cy1)
			
			this.downUrl = this.getDownUrl(this.previewCanvas.toDataURL())
		}
	}
	getDownUrl(url){
		let typeArr = url.split(';base64,')
		let fileType = typeArr[0].split(':')[1]
		let aBase64 = window.atob(typeArr[1])
		let len = aBase64.length
		let uInt8Array = new Uint8Array(len)
		for(let i = 0; i < len; i++){
			uInt8Array[i] = aBase64.charCodeAt(i)
		}
		let blob = new Blob([uInt8Array], { type: fileType })
		return URL.createObjectURL(blob)
	}
	downImg(){
		let a = document.createElement('a')
		a.download = 'img_' + new Date().toLocaleString()
		a.href = this.downUrl
		a.click()
	}
}	

//let Cut = new CutImg('#id') 初始化
// Cut.inputFile($('#input').files)	加载图片文件
// Cut.initImgCtx(img)	加载DOM图片
// Cut.downImg()	下载裁剪图
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值