vue实现裁切图片同时实现放大、缩小、旋转功能

前端之家收集整理的这篇文章主要介绍了vue实现裁切图片同时实现放大、缩小、旋转功能前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

本篇文章主要介绍了vue实现裁切图片同时实现放大、缩小、旋转功能分享给大家,具体如下:

实现效果

  1. 裁切指定区域内的图片
  2. 旋转图片
  3. 放大图片
  4. 输出bolb 格式数据 提供给 formData 对象

效果

大概原理:

利用h5 FileReader 对象, 获取 上传到浏览器的文件” ,文件形式 为base64形式, 把 base64 赋给canvas的上下文。

然后给canvas 元素上加入对(mousedown)监听事件。 当用户鼠标左键在canvas按下时:

  1. 挂载对 window 对象mousemove事件 ---> 获取 鼠标移动x,y距离.从而操作 canvas里的图像的位置移动。
  2. 挂载对 window 对象mouseup 事件, 清除 mousemove事件的绑定。(同时该事件触发后会被删除

剩下的 放大、缩小 、 旋转 是对 canvas 对象的操作/坐标体系的操作。具体api详见mdn canvas 文档

代码

dom.js

{ if (typeof window) { if (window.addEventListener) { el.addEventListener(type,fn,false) } else { el.attachEvent(`on${type}`,fn) } } } export const off = ({el,fn}) => { if (typeof window) { if (window.addEventListener) { el.removeEventListener(type,fn) } else { el.detachEvent(`on${type}`,fn) } } } export const once = ({el,fn}) => { const hyFn = (event) => { try { fn(event) } finally { off({el,fn: hyFn}) } } on({el,fn: hyFn}) } // 最后一个 export const fbTwice = ({fn,time = 300}) => { let [cTime,k] = [null,null] // 获取当前时间 const getTime = () => new Date().getTime() // 混合函数 const hyFn = () => { const ags = argments return () => { clearTimeout(k) k = cTime = null fn(...ags) } } return () => { if (cTime == null) { k = setTimeout(hyFn(...arguments),time) cTime = getTime() } else { if ( getTime() - cTime < 0) { // 清除之前的函数堆 ---- 重新记录 clearTimeout(k) k = null cTime = getTime() k = setTimeout(hyFn(...arguments),time) } }} } export const contains = function(parentNode,childNode) { if (parentNode.contains) { return parentNode != childNode && parentNode.contains(childNode) } else { return !!(parentNode.compareDocumentPosition(childNode) & 16) } } export const addClass = function (el,className) { if (typeof el !== "object") { console.log('el is not elem') return null } let classList = el['className'] classList = classList === '' ? [] : classList.split(/\s+/) if (classList.indexOf(className) === -1) { classList.push(className) el.className = classList.join(' ') } else { console.warn('warn className current') } } export const removeClass = function (el,className) { let classList = el['className'] classList = classList === '' ? [] : classList.split(/\s+/) classList = classList.filter(item => { return item !== className }) el.className = classList.join(' ') } export const delay = ({fn,time}) => { let oT = null let k = null return () => { // 当前时间 let cT = new Date().getTime() const fixFn = () => { k = oT = null fn() } if (k === null) { oT = cT k = setTimeout(fixFn,time) return } if (cT - oT < time) { oT = cT clearTimeout(k) k = setTimeout(fixFn,time) }
}

}
export const Event = function () {
// 类型
this.typeList = {}
}
Event.prototype.on = function ({type,fn}){
if (this.typeList.hasOwnProperty(type)) {
this.typeList[type].push(fn)
} else {
this.typeList[type] = []
this.typeList[type].push(fn)
}
}
Event.prototype.off = function({type,fn}) {
if (this.typeList.hasOwnProperty(type)) {
let list = this.typeList[type]
let index = list.indexOf(fn)
if (index !== -1 ) {
list.splice(index,1)
}

} else {
  console.warn('not has this type')
}

}
Event.prototype.once = function ({type,fn}) {
const fixFn = () => {
fn()
this.off({type,fn: fixFn})
}
this.on({type,fn: fixFn})
}
Event.prototype.trigger = function (type){
if (this.typeList.hasOwnProperty(type)) {
this.typeList[type].forEach(fn => {
fn()
})
}
}

组件模板