vue图片裁剪功能的实现

ps  vue 裁剪框功能分享。 使用vue cropperjs插件

首先 安装插件: cnpm  i  cropperjs -S -D

然后使用插件实例代码封装如下:(不懂留言,css和HTML相关代码根据业务需求编写,可以忽略)

浏览效果:

vue图片裁剪功能的实现

新建组件:pImg。

<template>

  <div id="cropper">

    <div style="text-align:center;margin-bottom:20px;">

      <span v-if="!confirmFlag" style="display: inline-block; width:200px; height:50px;">

        <input type="file" accept="image" @click="fileClick" @change="change" />

      </span>

      <span

        @click="crop"

        v-if="confirmFlag"

        style="

       display: inline-block;

        height: 36px;

        padding: 0 20px;

        line-height: 36px;

        border-radius: 18px;

        margin-right: 20px;

        font-size: 16px;

        font-family: SourceHanSansCN-Regular;

        font-weight: 400;

        background: #045735;

        color: #cfd525;

        text-align: center;

        cursor: pointer;

        "

      >确定裁剪</span>

    </div>

    <!-- 遮罩层 -->

    <div class="container" v-show="panel">

      <div style="width:80%;height:80%; margin:50px auto;">

        <img id="image" :src="url" style="max-width:100%;max-height:100%;margin:0 auto;" />

      </div>

    </div>

  </div>

</template>

 

 

<script>

import Cropper from "cropperjs";

export default {

  name: "p-img-cropper",

  data() {

    return {

      headerImage: "",

      confirmFlag: false,

      saveFlag: false,

      picValue: "",

      cropper: "",

      croppable: false,

      panel: false,

      showFlag: false,

      url: ""

    };

  },

  mounted() {

    //初始化这个裁剪框

    var self = this;

    var image = document.getElementById("image");

    this.cropper = new Cropper(image, {

      aspectRatio: 9 / 5,

      viewMode: 1,

      modal: false,

      ready: function() {

        self.croppable = true;

      }

    });

  },

  methods: {

    fileClick(e) {

      this.saveFlag = false;

    },

    getObjectURL(file) {

      var url = null;

      if (window.createObjectURL != undefined) {

        // basic

        url = window.createObjectURL(file);

      } else if (window.URL != undefined) {

        // mozilla(firefox)

        url = window.URL.createObjectURL(file);

      } else if (window.webkitURL != undefined) {

        // webkit or chrome

        url = window.webkitURL.createObjectURL(file);

      }

      return url;

    },

    change(e) {

      let files = e.target.files || e.dataTransfer.files;

      if (!files.length) return;

      this.panel = true;

      this.picValue = files[0];

      this.showFlag = false;

      this.confirmFlag = true;

      this.url = this.getObjectURL(this.picValue);

      //每次替换图片要重新得到新的url

      if (this.cropper) {

        this.cropper.replace(this.url);

      }

      this.panel = true;

    },

    crop() {

      var croppedCanvas;

      var roundedCanvas;

 

      if (!this.croppable) {

        return;

      }

      // Crop

      croppedCanvas = this.cropper.getCroppedCanvas();

      // Round

      roundedCanvas = this.getRoundedCanvas(croppedCanvas);

 

      this.headerImage = roundedCanvas.toDataURL("image/jpeg", 0.8);

      this.postImg();

    },

    getRoundedCanvas(sourceCanvas) {

      var canvas = document.createElement("canvas");

      var context = canvas.getContext("2d");

      var width = sourceCanvas.width;

      var height = sourceCanvas.height;

 

      canvas.width = width;

      canvas.height = height;

 

      context.imageSmoothingEnabled = true;

      context.drawImage(sourceCanvas, 0, 0, width, height);

      //context.globalCompositeOperation = "destination-in";

      context.beginPath();

      //   context.arc(

      //     width / 2,

      //     height / 2,

      //     Math.min(width, height) / 2,

      //     0,

      //     2 * Math.PI,

      //     true

      //   );

      context.fill();

 

      return canvas;

    },

    postImg() {

      //这边写图片的上传

 

      //console.log(this.headerImage);

      this.save();

    },

    save() {

      let formData = new FormData();

      var base64 = this.headerImage.substring(23, this.headerImage.length);

      formData.append("filedata", base64);

      formData.append("filename", "1.jpg");

      formData.append("base64", "1");

      this.$http

        .post("https://www.tongyi.com/api/upload/image", formData)

        .then(res => {

          this.panel = false;

          this.confirmFlag = false;

          this.$emit("saveHandler", res.data.fileurl);

        })

        .catch(error => {

          console.log(error);

        });

    }

  }

};

</script>  

  

<style>

* {

  margin: 0;

  padding: 0;

}

#demo #button {

  position: absolute;

  right: 10px;

  top: 10px;

  width: 80px;

  height: 40px;

  border: none;

  border-radius: 5px;

  background: white;

}

#demo .show {

  width: 600px;

  height: 500px;

  position: relative;

 

  border: 1px solid #d5d5d5;

}

#demo .picture {

  width: 500px;

  height: 500px;

  overflow: hidden;

  background-position: center center;

  background-repeat: no-repeat;

  background-size: cover;

}

#demo .container {

  width: 600px;

  height: 500px;

  z-index: 99;

  position: fixed;

  left: 0;

  top: 0;

  right: 0;

  bottom: 0;

  background: rgba(0, 0, 0, 1);

}

 

#demo #image {

  width: 500px;

}

 

/*!  

 * Cropper.js v1.0.0-rc  

 * https://github.com/fengyuanchen/cropperjs  

 *  

 * Copyright (c) 2017 Fengyuan Chen  

 * Released under the MIT license  

 *  

 * Date: 2017-03-25T12:02:21.062Z  

 */

 

.cropper-container {

  font-size: 0;

  line-height: 0;

  width: 851px;

  height: 855px;

  position: relative;

 

  -webkit-user-select: none;

 

  -moz-user-select: none;

 

  -ms-user-select: none;

 

  user-select: none;

 

  direction: ltr;

  -ms-touch-action: none;

  touch-action: none;

}

 

.cropper-container img {

  /* Avoid margin top issue (Occur only when margin-top <= -height) */

  display: block;

  min-width: 0 !important;

  max-width: none !important;

  min-height: 0 !important;

  max-height: none !important;

  image-orientation: 0deg;

}

 

.cropper-wrap-box,

.cropper-canvas,

.cropper-drag-box,

.cropper-crop-box,

.cropper-modal {

  position: absolute;

  top: 0;

  right: 0;

  bottom: 0;

  left: 0;

}

.cropper-crop-box {

  width: 405px;

  height: 280px;

}

 

.cropper-wrap-box {

  overflow: hidden;

}

 

.cropper-drag-box {

  opacity: 0;

  background-color: #fff;

}

 

.cropper-modal {

  opacity: 0.5;

  background-color: #000;

}

 

.cropper-view-box {

  display: block;

  overflow: hidden;

  width: 100%;

  height: 100%;

 

  outline: 1px solid #39f;

  outline-color: rgba(51, 153, 255, 0.75);

}

 

.cropper-dashed {

  position: absolute;

 

  display: block;

 

  opacity: 0.5;

  border: 0 dashed #eee;

}

 

.cropper-dashed.dashed-h {

  top: 33.33333%;

  left: 0;

  width: 100%;

  height: 33.33333%;

  border-top-width: 1px;

  border-bottom-width: 1px;

}

 

.cropper-dashed.dashed-v {

  top: 0;

  left: 33.33333%;

  width: 33.33333%;

  height: 100%;

  border-right-width: 1px;

  border-left-width: 1px;

}

 

.cropper-center {

  position: absolute;

  top: 50%;

  left: 50%;

 

  display: block;

 

  width: 0;

  height: 0;

 

  opacity: 0.75;

}

 

.cropper-center:before,

.cropper-center:after {

  position: absolute;

  display: block;

  content: " ";

  background-color: #eee;

}

 

.cropper-center:before {

  top: 0;

  left: -3px;

  width: 7px;

  height: 1px;

}

 

.cropper-center:after {

  top: -3px;

  left: 0;

  width: 1px;

  height: 7px;

}

 

.cropper-face,

.cropper-line,

.cropper-point {

  position: absolute;

 

  display: block;

 

  width: 100%;

  height: 100%;

 

  opacity: 0.1;

}

 

.cropper-face {

  top: 0;

  left: 0;

 

  background-color: #fff;

}

 

.cropper-line {

  background-color: #39f;

}

 

.cropper-line.line-e {

  top: 0;

  right: -3px;

  width: 5px;

  cursor: e-resize;

}

 

.cropper-line.line-n {

  top: -3px;

  left: 0;

  height: 5px;

  cursor: n-resize;

}

 

.cropper-line.line-w {

  top: 0;

  left: -3px;

  width: 5px;

  cursor: w-resize;

}

 

.cropper-line.line-s {

  bottom: -3px;

  left: 0;

  height: 5px;

  cursor: s-resize;

}

 

.cropper-point {

  width: 5px;

  height: 5px;

 

  opacity: 0.75;

  background-color: #39f;

}

 

.cropper-point.point-e {

  top: 50%;

  right: -3px;

  margin-top: -3px;

  cursor: e-resize;

}

 

.cropper-point.point-n {

  top: -3px;

  left: 50%;

  margin-left: -3px;

  cursor: n-resize;

}

 

.cropper-point.point-w {

  top: 50%;

  left: -3px;

  margin-top: -3px;

  cursor: w-resize;

}

 

.cropper-point.point-s {

  bottom: -3px;

  left: 50%;

  margin-left: -3px;

  cursor: s-resize;

}

 

.cropper-point.point-ne {

  top: -3px;

  right: -3px;

  cursor: ne-resize;

}

 

.cropper-point.point-nw {

  top: -3px;

  left: -3px;

  cursor: nw-resize;

}

 

.cropper-point.point-sw {

  bottom: -3px;

  left: -3px;

  cursor: sw-resize;

}

 

.cropper-point.point-se {

  right: -3px;

  bottom: -3px;

  width: 20px;

  height: 20px;

  cursor: se-resize;

  opacity: 1;

}

 

@media (min-width: 768px) {

  .cropper-point.point-se {

    width: 15px;

    height: 15px;

  }

}

 

@media (min-width: 992px) {

  .cropper-point.point-se {

    width: 10px;

    height: 10px;

  }

}

 

@media (min-width: 1200px) {

  .cropper-point.point-se {

    width: 5px;

    height: 5px;

    opacity: 0.75;

  }

}

 

.cropper-point.point-se:before {

  position: absolute;

  right: -50%;

  bottom: -50%;

  display: block;

  width: 200%;

  height: 200%;

  content: " ";

  opacity: 0;

  background-color: #39f;

}

 

.cropper-invisible {

  opacity: 0;

}

 

.cropper-bg {

  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC");

}

 

.cropper-hide {

  position: absolute;

 

  display: block;

 

  width: 0;

  height: 0;

}

 

.cropper-hidden {

  display: none !important;

}

 

.cropper-move {

  cursor: move;

}

 

.cropper-crop {

  cursor: crosshair;

}

 

.cropper-disabled .cropper-drag-box,

.cropper-disabled .cropper-face,

.cropper-disabled .cropper-line,

.cropper-disabled .cropper-point {

  cursor: not-allowed;

}

</style>  

使用组件 :

import pImg from "@/page/components/pimg.vue";

 <p-img @saveHandler="saveHandler" v-if="dialogVisible" />

 

方法 :saveHandler 为保存成功回调。

    saveHandler(data) {

      this.imageUrl = data;

    }

<!-- 欢迎参考,如有缺陷请留言 ,欢迎打赏 !bye~  -->