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

网友投稿 832 2023-02-15


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

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

实现效果:

裁切指定区域内的图片

旋转图片

放大图片

输出bolb 格式数据 提供给 formData 对象

效果图

大概原理:

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

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

挂载对 window 对象mousemove事件 ---> 获取 鼠标移动x,y距离.从而操作 canvas里的图像的位置移动。

挂载对 window 对象mouseup 事件, 清除 mousemove事件的绑定。(同时该事件触发后会被删除)

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

代码

dom.js

export const on = ({el, type, fn}) => {

if (typeof window) {

if (window.addEventListener) {

el.addEventListener(type, fn, false)

} else {

el.attachEvent(`on${type}`, fn)

}

}

}

export const off = ({el, type, fn}) => {

if (typeof window) {

if (window.addEventListener) {

el.removeEventListener(type, fn)

} else {

el.detachEvent(`on${type}`, fn)

}

}

}

export const once = ({el, type, fn}) => {

const hyFn = (event) => {

try {

fn(event)

}

finally {

off({el, type, fn: hyFn})

}

}

on({el, type, 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 !!(parenthttp://Node.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()

})

}

}

组件模板

:width="clip.width"

:height="clip.height"

@mousedown="handleClip($event)"

>

:width="clip.width"

:height="clip.height"

@mousedown="handleClip($event)"

>

+

-

{{scale}}

upload

cancel

生成文件


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:接口测试主要测哪些方面(接口测试是测试什么内容)
下一篇:vue slot 在子组件中显示父组件传递的模板
相关文章

 发表评论

暂时没有评论,来抢沙发吧~