天天看點

使用vue-cropper實作圖檔裁剪,放大縮小,實時預覽等

效果圖

使用vue-cropper實作圖檔裁剪,放大縮小,實時預覽等

1、安裝

npm install vue-cropper -S
           

2、main.js引用

import VueCropper from 'vue-cropper' 
import Antd from 'ant-design-vue';
import 'ant-design-vue/dist/antd.css';

Vue.config.productionTip = false
Vue.use(Antd)
Vue.use(VueCropper)
           

3、主要檔案(封裝成元件)

<template>
  <div id="cropper">
    <VueCropper ref="cropper"
                :img='url'
                :info=option.info
                :outputSize=option.outputSize
                :outputType=option.outputType
                :canMove=option.canMove
                :autoCrop=option.autoCrop
                :autoCropWidth=option.autoCropWidth
                :autoCropHeight=option.autoCropHeight
                :fixedBox=option.fixedBox
                :original=option.original
                :infoTrue=option.infoTrue
                :centerBox=option.centerBox
                :canMoveBox=option.canMoveBox
                :canScale=option.canScale
                :fixed=option.fixed
                :fixedNumber=option.fixedNumber
                @realTime="realTime">
    </VueCropper>
    <a-button type="primary"
              @click="chooseImg">選擇圖檔</a-button>
    <input type="file"
           @change="getFile"
           accept="image/*"
           ref="imginput"
           id="img-input">
    <a-button type="primary"
              @click="startCrop">儲存截圖</a-button>
    <a-button type="primary"
              @click="scaleBigger">放大</a-button>
    <a-button type="primary"
              @click="scaleSmaller">縮小</a-button>
    <a-button type="primary"
              @click="rotateLeft">左旋轉</a-button>
    <a-button type="primary"
              @click="rotateRight">右旋轉</a-button>
    <a-button type="primary"
              @click="reload">重置大小</a-button>
    <a-button type="primary"
              @click="rotateClear">重置旋轉</a-button>
    <a-button type="primary"
              @click="refresh">重置所有</a-button>
    <a-progress :percentage="percentage"
                v-show="isShow"></a-progress>
    <!-- 預覽圖檔 -->
    <div v-html="previewHTML"></div>
  </div>

</template>
<script>
import { VueCropper } from 'vue-cropper'
import { pathToBase64, base64ToPath } from 'image-tools'

export default {
  data() {
    return {
      option: {
        outputSize: 1, // 裁剪生成圖檔的品質 0.1 - 1
        outputType: 'png', //	裁剪生成圖檔的格式 jpeg || png || webp
        canScale: true, // 圖檔是否允許滾輪縮放 預設true
        autoCrop: true, // 是否預設生成截圖框 預設false
        canMove: true, //上傳圖檔是否可以移動 預設true
        autoCropWidth: 200, //預設生成截圖框寬度	容器的80%	0~max
        autoCropHeight: 200, //預設生成截圖框高度	容器的80%	0~max
        // fixedBox: true, // 固定截圖框大小 不允許改變	false	true | false
        fixed: true, //是否開啟截圖框寬高固定比例
        original: false, // 上傳圖檔按照原始比例渲染	false	true | false
        infoTrue: false, // 為展示真實輸出圖檔寬高 false 展示看到的截圖框寬高	false	true | false
        centerBox: true, // 截圖框是否被限制在圖檔裡面	false	true | false
        canMoveBox: true, //截圖框能否拖動	true	true | false
        fixedNumber: [1, 1] // 截圖框的寬高比例 [寬度, 高度]
      },
      url: '',
      previewHTML: '',
      cropperSrc: '',
      param: {
        // 上傳參數
        originalFilename: '',
        contentType: 'image/jpeg',
        cropImgPath: '', // 接口要求傳入截圖的圖檔路徑格式為blob:http://192.168.0.109:8080/95dbc0cd-5624-4e11-8a45-b7a1a855020d
      },
      flag: true,
      percentage: 0,// 上傳進度
      isShow: false
    }
  },
  components: {
    VueCropper
  },
  methods: {
    // 點選選擇圖檔
    chooseImg() {
      this.$refs.imginput.click()
    },
    //儲存截圖
    startCrop() {
      if (!this.flag) return false
      this.flag = false
      // 擷取截圖的base64 資料
      this.$refs.cropper.getCropData(data => {
        this.cropperSrc = data;
        // base64資料轉成圖檔(用了插件)
        base64ToPath(data)
          .then(path => {
            this.param.cropImgPath = path;
            console.log(path);
            // 上傳到伺服器
        this.upload(this.param);
          })
          .catch(error => {
            console.error(error)
          })
      })
    },
    // 圖檔放大
    scaleBigger() {
      this.$refs.cropper.changeScale(1)
    },
    // 圖檔縮小
    scaleSmaller() {
      this.$refs.cropper.changeScale(-1)
    },
    // 圖檔左旋轉90°
    rotateLeft() {
      this.$refs.cropper.rotateLeft()
    },
    // 圖檔右旋轉90°
    rotateRight() {
      this.$refs.cropper.rotateRight()
    },
    // 重置大小
    reload() {
      this.$refs.cropper.reload()
    },
    // 重置旋轉
    rotateClear() {
      this.$refs.cropper.rotateClear()
    },
    // 重置所有
    refresh() {
      // this.$refs.cropper.refresh() ;
      this.$refs.cropper.reload()
      this.$refs.cropper.rotateClear()
    },
    // 進度條展示
    showProgress(res) {
      this.$nextTick(() => {
        this.percentage = Math.floor(res.loaded / res.total * 100)
      })
    },
    // 圖檔上傳
    upload(param) {
      this.isShow = true;
      // 具體請求不顯示
      console.log('上傳圖檔');
    },
    // input選擇圖檔
    getFile(e) {
      var vm = this
      console.log(e);
      // let file = this.$refs.imginput.files[0]
      const file = e.target.files[0]
      if (!/image\/\w+/.test(file.type)) {
        this.$message({
          message: '請選擇圖檔',
          type: 'warning'
        })
        // 清空input值
        this.$refs.imginput.value = ''
        return false
      }
      this.param.originalFilename = file.name
      // 建立檔案讀取對象
      var reader = new FileReader()
      reader.readAsDataURL(file)
      // 檔案讀取結束
      reader.onload = function (e) {
        // 此處this === reader
        vm.url = this.result;
        vm.previewUrl = this.result;
      }
    },
    // 圖檔預覽
    realTime(data) {
      console.log(data);
      this.previewHTML = data.html;
    },
  }
}
</script>

<style lang="scss" scoped>
#cropper {
  margin: 0 auto;
  height: 350px;
  width: 850px;

  .vue-cropper {
    width: 300px;
    height: 300px;
    margin: 0 auto;
    .cropper-crop-box {
      transform: translate3d(0px, 0px, 0px);
    }
  }
}
#img-input {
  display: none;
}
</style>