栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > Web开发 > JavaScript

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

JavaScript 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

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()
      })
    }
  }

组件模板




  @component-namespace jc {
    @component clip-image{
      position: relative;
      width: 100%;
      canvas {
 position: relative;
 width: 100%;
 height: 100%;
 cursor: pointer;
 box-shadow: 0 0 3px #333;
      }
      input {
 display: none;
      }
      .base64-hidden {
 position: absolute;
 top: 0;
 left: 0;
 display: block;
 width: 100%;
 height: auto;
 z-index: -999;
 opacity: 0;
      }
      .clip-scale-btn {
 position: relative;
      @utils-clearfix;
margin-bottom: 5px;
 text-align: center;
 a {
   float: left;
   width: 20px;
   height: 20px;
   border-radius: 50%;
   color: #fff;
   background: #49a9ee;
   text-align: center;
   cursor: pointer;
 }
&>.poor, &>.right-rotate {
 float: right;
}
      &>span{
      position: absolute;
      z-index: -9;
      top: 0;
      left: 0;
 display: block;
 position: relative;
 width: 100%;
  text-align: center;
 height: 20px;
 line-height: 20px;
      }
      }
      .upload-warp {
      @utils-clearfix;
      .upload-btn,.upload-cancel {
   float: left;
   display:inline-block;
   width: 60px;
   height: 25px;
   line-height: 25px;
   color: #fff;
   border-radius: 5px;
   background: #49a9ee;
   box-shadow: 0 0 0 #333;
   text-align: center;
   top: 0;
   left: 0;
   right: 0;
   bottom: 0;
   margin: auto;
   cursor: pointer;
   margin-top: 5px;
 }
      .upload-cancel{
 background: gray;
 float: right;
      }
      }
      .to-send-file {
 margin-top: 5px;
 display: block;
 width: 50px;
 height: 25px;
 line-height: 25px;
 color: #fff;
 border-radius: 5px;
 background: #49a9ee;
 cursor: pointer;
      }
    }

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持考高分网。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/82151.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号