在vue中使用cropperjs,裁剪图片

今天逛网站,发现一篇文章 5分钟搞定图片裁剪,上传,觉得很酷炫,于是便试了试,特此记录一下

cropperjs:github地址

实现效果:

首先项目中引入这个库:npm i cropperjs -S,

在使用的页面中代码(我用了vant组件,然后css中的px2rem是为了手机适配,为了方便调试看效果,你也可以把css中的样式px2rem改为一个具体的px):

<template>
    <input class="imageRead" ref="imageRead" @change="selectImage" accept="image/*" type="file" />
    <div class="photo-wrap mt20">
      <span class="f38 bold">头像</span>
      <span>
        <img @click="clickPhoto" class :src="photoUrl" alt />
      </span>
    </div>
    <van-overlay :show="showCrop">
      <div class="crop-wrapper" @click.stop>
        <div>
          <img id="cropImage" ref="cropImage" src alt />
        </div>
        <div class="crop-options">
          <van-button @click="cancelCrop">取消</van-button>
          <van-button @click="resetCrop">复位</van-button>
          <van-button @click="scaleCrop">反转</van-button>
          <van-button @click="rotateCrop">旋转</van-button>
          <van-button @click="submitCrop">确定</van-button>
        </div>
      </div>
    </van-overlay>
</template>

<script>
import headPortrait from "@/common/images/timg.jpg";
import { Toast, Button, Overlay } from "vant";

import "cropperjs/dist/cropper.css";
import Cropper from "cropperjs";

export default {
  components: {
    vanButton: Button,
    vanOverlay: Overlay,
    pageLayout
  },
  data() {
    return {
      photoUrl: headPortrait,
      showCrop: false,
      myCropper: "",
      flagX: false //裁剪的图片是否反转,默认false(不反转)
    };
  },
  methods: {
    // 点击头像
    clickPhoto() {
      this.$refs["imageRead"].click();
    },
    // 选择图片
    selectImage(e) {
      let targetFile = e.target.files[0];
      console.log(targetFile);
      if (targetFile) {
        this.showCrop = true;
        this.flagX = false;
        let reader = new FileReader();
        /* readAsDataURL 方法会读取指定的 Blob 或 File 对象。
        读取操作完成的时候,readyState 会变成已完成DONE,
        并触发 loadend 事件,同时 result 属性将包含一个data:URL格式的字符串(base64编码)
        以表示所读取文件的内容。*/
        reader.readAsDataURL(targetFile);
        reader.onload = () => {
          let dataURL = reader.result;
          let cropImageDom = document.querySelector("#cropImage");
          cropImageDom.src = dataURL;
          this.myCropper.replace(dataURL);
        };
        // 避免下次选择同一图片不触发
        e.target.value = "";
      }
    },
    // 取消裁剪
    cancelCrop() {
      this.showCrop = false;
    },
    // 复位
    resetCrop() {
      this.flagX = false;
      this.myCropper.reset();
    },
    // 反转
    scaleCrop() {
      if (this.flagX) {
        this.myCropper.scaleX(1), (this.flagX = false);
      } else {
        this.myCropper.scaleX(-1), (this.flagX = true);
      }
    },
    // 旋转
    rotateCrop() {
      this.myCropper.rotate(45);
    },
    // 确定裁剪
    submitCrop() {
      let cas = this.myCropper.getCroppedCanvas();
      let base64 = cas.toDataURL("image/jpeg");
      this.photoUrl = base64;
      this.showCrop = false;
    }
  },
  mounted() {
    // 创建实例,与展示裁剪的img标签绑定
    let cropImageDom = document.querySelector("#cropImage");
    this.myCropper = new Cropper(cropImageDom, {
      aspectRatio: 1 / 1,
      // viewMode: 0,
      // minContainerWidth: 100,
      // minContainerHeight: 100,
      // preview: ".previewBox",
      guides: false, // 裁剪框的虚线(九宫格)
      autoCropArea: 0.5, // 0-1之间的数值,定义自动剪裁区域的大小,默认0.8
      // movable: false, // 是否允许移动图片
      dragCrop: true, // 是否允许移除当前的剪裁框,并通过拖动来新建一个剪裁框区域
      movable: true, // 是否允许移动剪裁框
      resizable: true, // 是否允许改变裁剪框的大小
      // zoomable: false, // 是否允许缩放图片大小
      mouseWheelZoom: false, // 是否允许通过鼠标滚轮来缩放图片
      touchDragZoom: true, // 是否允许通过触摸移动来缩放图片
      rotatable: true, // 是否允许旋转图片
      crop: function(e) {
        // 输出结果数据裁剪图像。
      }
    });
  }
};
</script>
<style lang="scss" scoped>
.crop-wrapper {
  height: 100%;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  & > div {
    width: 100%;
  }
  & > div:first-child {
    height: 80%;
    background: rgb(12, 12, 12);
  }
  & > div:last-child {
    text-align: center;
  }
}
.imageRead {
  display: none;
}
.photo-wrap {
  display: flex;
  justify-content: space-around;
  align-items: center;
  & > span:last-child {
    width: px2rem(200);
    height: px2rem(200);
    border-radius: 50%;
    overflow: hidden;
    background: black;
    box-shadow: 0 0 px2rem(17) gray;
    img {
      width: 100%;
      height: 100%;
      object-fit: contain;
    }
  }
}
</style>

你可能感兴趣的:(vue学习篇)