使用vue-cropper實現最實用的圖片裁剪組件

先上效果圖:

1、安裝vue-cropper

npm install --save vue-cropperjs

2、項目中引入使用:

(1)全局引入man.js

import Vue from 'vue'
import VueCropper from 'vue-cropper'
import 'cropperjs/dist/cropper.css'

Vue.use(VueCropper)

(2)組件中單獨引用

import VueCropper from 'vue-cropper'
import 'cropperjs/dist/cropper.css'

export default {
    components: {
        VueCropper
    }
}

3、封裝組件

crop.vue

<template>
  <section class="crop">
    <el-row>
      <el-col :span="18">
        <div class="cropper-div">
          <vueCropper
            height="562px"
            ref="cropper"
            :img="imgUrl"
            :outputSize="option.size"
            :outputType="option.outputType"
            :info="true"
            :guides="true"
            :high="option.high"
            :fixed="option.fixed"
            :full="option.full"
            :canMove="option.canMove"
            :canMoveBox="option.canMoveBox"
            :original="option.original"
            :autoCrop="option.autoCrop"
            :autoCropWidth="option.autoCropWidth"
            :autoCropHeight="option.autoCropHeight"
            :fixedBox="option.fixedBox"
            :fixedNumber="option.fixedNumber"
            :maxImgSize="option.maxImgSize"
            @realTime="realTime"
            :infoTrue="option.infoTrue"
            @imgLoad="imgLoad"
          />
        </div>
      </el-col>
      <el-col :span="6">
        <div class="oprate-data-div">
          <div class="crop-img-box">
            <img :src="modelSrc" />
          </div>
          <el-input v-model="cropData.offX" size="mini">
            <template slot="prepend">X</template>
            <template slot="append">px</template>
          </el-input>
          <el-input v-model="cropData.offY" size="mini">
            <template slot="prepend">Y</template>
            <template slot="append">px</template>
          </el-input>
          <el-input v-model="cropData.cropW" size="mini">
            <template slot="prepend">Width</template>
            <template slot="append">px</template>
          </el-input>
          <el-input v-model="cropData.cropH" size="mini">
            <template slot="prepend">Height</template>
            <template slot="append">px</template>
          </el-input>
          <div class="finish-btn">
            <el-button type="primary" @click="getPoint">完成截取</el-button>
          </div>
        </div>
      </el-col>
    </el-row>
  </section>
</template>
<script>
export default {
  props: ['imgSrc'],
  data () {
    return {
      modelSrc: '', // 裁剪後的圖片地址
      cropData: {
        offX: '', // 裁剪框相對圖片的x
        offY: '', // 裁剪框相對圖片的y
        cropW: '', // 裁剪框寬度
        cropH: '', // 裁剪框高度
        imgW: '', // 原圖片寬度
        imgH: '' // 原圖片高度
      }, // 裁剪圖片數據
      pointData: {
        x1: '',
        y1: '',
        x2: '',
        y2: ''
      }, // 裁剪框的座標數據
      imgUrl: 'http://cdn.xyxiao.cn/Portrait_1.jpg', // 原圖片的地址
      option: {
        size: 1, // 生成圖片的質量
        full: true, // 是否輸出原圖比例的截圖
        outputType: "png", // 裁剪生成圖片的格式
        canMove: false, // 上傳圖片是否可以移動
        original: false, // 上傳圖片按照原始比例渲染
        canMoveBox: true, // 	截圖框能否拖動
        autoCrop: true, // 是否默認生成截圖框
        high: true, // 是否按照設備的dpr 輸出等比例圖片
        autoCropWidth: 252, // 默認生成截圖框寬度
        autoCropHeight: 140, // 默認生成截圖框高度
        fixedBox: false, // 固定截圖框大小 不允許改變
        infoTrue: false, // true 爲展示真實輸出圖片寬高 false 展示看到的截圖框寬高
        fixed: false, // 是否開啓截圖框寬高固定比例
        downImg: "#", 
        fixedNumber: [4, 3], // 截圖框的寬高比例
        maxImgSize: 3000 // 圖片最大像素
      },
    }
  },
  methods: {
    imgLoad (msg) {
      console.log(msg);
    },

    // 實時預覽函數
    realTime (data) {
      let imgAxis = this.$refs.cropper.getImgAxis()
      let cropAxis = this.$refs.cropper.getCropAxis()
      let cropImgX = cropAxis.x1 - imgAxis.x1,
        cropImgY = cropAxis.y1 - imgAxis.y1,
        imgWidth = imgAxis.x2 - imgAxis.x1,
        imgHeight = imgAxis.y2 - imgAxis.y1
      this.cropData = {
        offX: cropImgX,
        offY: cropImgY,
        cropW: data.w,
        cropH: data.h,
        imgW: imgWidth,
        imgH: imgHeight
      }
      this.getCropImg()
		},
		
		// 獲取裁剪框中的圖片
    getCropImg () {
      if (this.option.outputType === "blob") {
        this.$refs.cropper.getCropBlob(data => {
          var img = window.URL.createObjectURL(data);
          this.modelSrc = img;
        });
      } else {
        this.$refs.cropper.getCropData(data => {
          this.modelSrc = data;
        });
      }
		},
		
		// 獲取裁剪框座標
    getPoint () {
      if (!this.compute()) {
        this.$message({
          message: '選擇區域無效,請重新選擇!',
          type: 'error'
        });
      } else {
        this.pointData = this.compute()
        console.log(this.pointData)
      }
		},
		
		// 判斷裁剪框是否爲有效區域
    compute () {
      let x = this.cropData.offX,
        y = this.cropData.offY,
        w = this.cropData.cropW,
        h = this.cropData.cropH,
        W = this.cropData.imgW,
        H = this.cropData.imgH,
        x1 = (x / W),
        y1 = (y / H),
        x2 = ((x + w) / W),
        y2 = ((y + h) / H)
      if (x < 0) {
        if (w + x < 0) {
          return false
        } else {
          x1 = 0
        }
      }
      if (x > W - w) {
        if (x > W) {
          return false
        } else {
          x2 = 1
        }
      }
      if (y < 0) {
        if (y + h < 0) {
          return fasle
        } else {
          y1 = 0
        }
      }
      if (y > H - h) {
        if (y > H) {
          return false
        } else {
          y2 = 1
        }
      }
      return {
        x1: x1,
        y1: y1,
        x2: x2,
        y2: y2
      }
    }
  }
}
</script>
<style scoped lang="less">
@import "./style.less";
</style>

style.less

.crop {
  padding: 20px;
  .cropper-div {
    margin: 20px auto;
    width: 800px;
    height: 500px;
  }
  .oprate-data-div {
		margin: 20px 50px 0 0;
		.crop-img-box {
			width: 100%;
			height: 100px;
			img {
				max-height: 100%;
				max-width: 100%;
			}
		}
    .el-input {
      margin-top: 10px;
    }
		.finish-btn {
			margin-top: 20px;
			text-align: center;
		}
  }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章