# 图片裁剪

# 介绍

cropperjs 是一款 js 图片裁剪插件,在用户头上上传等地方经常使用到。

官网地址:https://fengyuanchen.github.io/cropperjs/ (opens new window)

# 使用

本项目在用户头像上传时使用了该插件

<m-cell title="头像">
  <image-upload :src="user.avatar" @on-change="submitAvatar" />
</m-cell>

# 目录结构

└─ src                          
   └─ components                
      └─ ImageUpload                # 图片上传组件
        ├─ src
        │  ├─ CropImage.vue         # 图片裁剪
        │  ├─ index.vue             # 图片上传
        └─ index.js                 # 入口文件

# CropImage 组件介绍

<div class="camera">
  <!-- 图片裁剪区域 -->
  <div class="camera-photo">
    <!-- 被裁剪图片 -->
    <img id="image" ref="img" :src="img" />
  </div>

  <div class="tool">
    <m-button type="info" size="small" @click="cancle()">取 消</m-button>
    <m-button type="primary" size="small" @click="clipImage()">保 存</m-button>
  </div>
</div>
import Cropper from "cropperjs";            // 引入裁剪插件
import "cropperjs/dist/cropper.min.css";    // 引入裁剪插件样式文件

export default {
  name: "CropImage",
  props: {
    // 传入图片地址
    img: {
        type: String,
        default: null,
    },
  },

  data() {
    return {
      cropper: null,
      imgUrl: "",
    };
  },

  watch: {
    //   如果存在图片地址,则初始化裁剪插件实例,若不存在,则销毁实例
    img(val) {
      if (val === "" && this.cropper) {
        this.cropper.destroy();
      }

      // 不存在则实例化
      if (!this.cropper) {
        this.initCropper();
      } else {
        if (val) {
          this.cropper.replace(val);
        }
      }
    },
  },

  mounted() {
    this.initCropper();
  },

  methods: {
    // 初始化裁剪
    initCropper() {
      this.$nextTick(() => {
        this.cropper = new Cropper(this.$refs.img, {
          aspectRatio: 1 / 1,
          viewMode: 1,
          guides: true, // 显示裁剪框的虚线(九宫格)
          autoCropArea: 1,
          zoomable: true,
          zoomOnTouch: true,
          initialAspectRatio: 0.9,
          // dragMode: 'move',
          // cropBoxMovable: false,
          minCropBoxWidth: 200,
        });
      });
    },

    // 取消
    cancle() {
      this.$router.back();
    },

    // 图片裁剪完成后,将裁剪画布 `canvas` 转为图片信息流 `blob`,
    // 以便将图片信息流上传至服务器
    clipImage() {
      this.$nextTick(() => {
        let canvas = this.cropper.getCroppedCanvas({
          maxWidth: 300,
          maxHeight: 300,
        });

        // canvas 转 blob
        canvas.toBlob((blob) => {
          this.$emit("on-change", blob);
        });
      });
    },
  },
};

警告

cropper.getCroppedCanvas 设置的最大宽高不建议超过2000,否则手机上容易出现内存占用过大被浏览器杀掉进程导致黑屏问题。

上次更新: 6/27/2022, 5:48:02 PM
示例展示,因PC端无touch事件,请在手机上进行浏览