资讯专栏INFORMATION COLUMN

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

Forelax / 2393人阅读

摘要:当用户鼠标左键在按下时挂载对对象事件获取鼠标移动距离从而操作里的图像的位置移动。挂载对对象事件,清除事件的绑定。同时该事件触发后会被删除剩下的放大缩小旋转是对对象的操作坐标体系的操作。

实现效果:

裁切指定区域内的图片

旋转图片

放大图片

输出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 !!(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()
            })
        }
    }
    

组件模板



项目代码(https://github.com/L6zt/vuesrr)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/93073.html

相关文章

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

    摘要:当用户鼠标左键在按下时挂载对对象事件获取鼠标移动距离从而操作里的图像的位置移动。挂载对对象事件,清除事件的绑定。同时该事件触发后会被删除剩下的放大缩小旋转是对对象的操作坐标体系的操作。 实现效果: 裁切指定区域内的图片 旋转图片 放大图片 输出bolb 格式数据 提供给 formData 对象 效果图 showImg(https://segmentfault.com/img/bV...

    DobbyKim 评论0 收藏0
  • vue中使用viewerjs

    摘要:项目创建安装删掉生成的项目里面的修改路由创建一个代码图片描述相关配置项详情见下面键盘事件仅在下可用键退出全屏关闭退出停止播放键停止播放键查看上一张图片键查看下一张图片键放大图片键缩小图片组合键缩小到初始大小组合键放大到原始大小配置参 项目创建 vue init webpack mytest001 安装viewerjs npm install viewerjs 删掉生成的项目里面的hel...

    sarva 评论0 收藏0
  • vue中使用viewerjs

    摘要:项目创建安装删掉生成的项目里面的修改路由创建一个代码图片描述相关配置项详情见下面键盘事件仅在下可用键退出全屏关闭退出停止播放键停止播放键查看上一张图片键查看下一张图片键放大图片键缩小图片组合键缩小到初始大小组合键放大到原始大小配置参 项目创建 vue init webpack mytest001 安装viewerjs npm install viewerjs 删掉生成的项目里面的hel...

    rose 评论0 收藏0
  • vue中使用viewerjs

    摘要:项目创建安装删掉生成的项目里面的修改路由创建一个代码图片描述相关配置项详情见下面键盘事件仅在下可用键退出全屏关闭退出停止播放键停止播放键查看上一张图片键查看下一张图片键放大图片键缩小图片组合键缩小到初始大小组合键放大到原始大小配置参 项目创建 vue init webpack mytest001 安装viewerjs npm install viewerjs 删掉生成的项目里面的hel...

    Mr_houzi 评论0 收藏0
  • css揭秘笔记——视觉效果

    摘要:实现染色效果的混合模式是,它会保留上层元素的高亮信息,并从它的下层吸取色相和饱和度信息。当我们只有一个背景图像及一个透明背景色时,就不会有任何混合效果。 投影 知识点 box-shadow: [inset]? 注意: 在元素正下方的投影被裁切掉了,是没有的;而text-shadow不同,文字下方的投影不会被裁切。 box-shadow的第三个参数是模糊半径,假如设置4px...

    skinner 评论0 收藏0

发表评论

0条评论

Forelax

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<