封面图片VueCropper

5 篇文章 0 订阅
5 篇文章 0 订阅
  1. 封面图片
    子组件imageCropper
<template>
  <div class="imageCropper">
    <div class="imageCropper-show"
         :style="{'width': cropperStyle.width + 'px', 'height': cropperStyle.height + 'px'}">
      <img v-if="options.img"
           :src="options.img"
           class="imageCropper-show-img" />
      <div v-if="options.img"
           class="image-tools">
        <span class="image-btn"
              @click="editCropper()"><i class="el-icon-edit"
             title="编辑"></i></span>
        <span class="image-btn"><i class="el-icon-delete"
             title="删除"
             @click="deleteImage()"></i></span>
      </div>
      <div v-else
           class="image-add" @click="editCropper()">
        <i class="el-icon-plus"
           title="添加"
           ></i>
      </div>
    </div>
    <div>请上传格式如<span style="color:#f67979"> jpg/png </span>的图片文件;推荐分辨率为 <span style="color:#f67979"> {{cropperStyle.width+"*"+cropperStyle.height}}</span> </div>
    <!-- 弹框内容 -->
    <el-dialog title="裁剪图片(选择图片后拖动方框或点击左侧操作按钮来裁剪图片)"
               :visible.sync="cropperVisible"
               v-if="cropperVisible"
               append-to-body
               :width="dialogWidth">
      <div class="cropper-box"
           :style="{ 'height': dialogHeight}">
        <div class="cropper-left">
          <vue-cropper ref="cropper"
                       :img="options.img"
                       :info="true"
                       :autoCrop="options.autoCrop"
                       :autoCropWidth="options.autoCropWidth"
                       :autoCropHeight="options.autoCropHeight"
                       :fixedBox="options.fixedBox"
                       :full="options.full"
                       :height="options.height"
                       :infoTrue="options.infoTrue"
                       :enlarge="options.enlarge"
                       :outputSize="options.outputSize"
                       @realTime="realTime" />
          <div class="cropper-tools">
            <el-upload action="#"
                       :http-request="requestUpload"
                       :show-file-list="false"
                       :before-upload="beforeUpload">
              <el-button type="primary"
                         plain>
                <i class="el-icon-upload el-icon--right"></i>
                选择
              </el-button>
            </el-upload>
            <el-button-group class="tools-group">
              <el-button type="primary"
                         plain
                         icon="el-icon-plus"
                         @click="changeScale(1)">放大</el-button>
              <el-button type="primary"
                         plain
                         icon="el-icon-minus"
                         @click="changeScale(-1)">缩小</el-button>
              <el-button type="primary"
                         plain
                         icon="el-icon-refresh-left"
                         @click="rotateLeft()">左旋</el-button>
              <el-button type="primary"
                         plain
                         icon="el-icon-refresh-right"
                         @click="rotateRight()">右旋</el-button>
            </el-button-group>
          </div>
        </div>

        <div class="cropper-right">
          <div class="cropper-tips">预览图片(点击确认上传此图)</div>
          <div class="cropper-preview"
               :style="{'width': previews.w + 'px', 'height': previews.h + 'px',  'overflow': 'hidden', 'margin': '5px'}"
               title="预览图片">
            <div :style="previews.div">
              <img :src="previews.url"
                   :style="previews.img" />
            </div>
          </div>
          <div class="preview-submit">
            <el-button type="primary"
                       @click="uploadImg()">确 认</el-button>
          </div>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { VueCropper } from "vue-cropper"
import * as fileStore from "@/api/base/fileStore";

export default {
  name: "imageCropper",
  components: { VueCropper },
  props: {
    imgUrl: {
      type: String
    },
    cropperStyle: {
      type: Object,
      default: () => {
        return {
          width: 300,
          height: 200
        }
      }
    }
  },
  watch: {
    imgUrl(params) {
      this.options.img = params
    }
  },
  computed: {
    dialogWidth() {
      if (
        this.cropperStyle.width * 2 <
        Number(document.body.clientWidth) * 0.66
      ) {
        return "66vw"
      } else {
        return "100vw"
      }
    },
    dialogHeight() {
      if (this.cropperStyle.height > Number(document.body.clientWidth) * 0.8) {
        return "100vh"
      } else {
        return this.cropperStyle.height + 100 + "px"
      }
    }
  },
  data() {
    return {
      // 是否显示弹出层
      cropperVisible: false,
      // 是否显示cropper
      visible: false,
      options: {
        img: "", //裁剪图片的地址
        autoCrop: true, // 是否默认生成截图框
        autoCropWidth: 400, // 默认生成截图框宽度
        autoCropHeight: 300, // 默认生成截图框高度
        fixedBox: true, // 固定截图框大小 不允许改变
        // fixed: true,         //是否开启截图框宽高固定比例
        // fixedNumber: [1.53, 1], //截图框的宽高比例
        height: true,        //是否按照设备的dpr 输出等比例图片
        full: false,         //false按原比例裁切图片,不失真
        infoTrue: false,     //true为展示真实输出图片宽高,false展示看到的截图框宽高
        enlarge: 1,          //图片根据截图框输出比例倍数
        outputSize: 1,       //裁剪生成图片的质量(可选0.1 - 1)
      },
      previews: {},
      fileName: ''
    }
  },
  created() {
    this.options.autoCropWidth = this.cropperStyle.width
    this.options.autoCropHeight = this.cropperStyle.height
    if(this.imgUrl){
      this.options.img = this.imgUrl
    }
  },
  methods: {
    deleteAction() {
      this.options.img = "";
    },
    deleteImage() {
      this.$emit("deleteImage", "")
    },
    // 编辑图片
    editCropper() {
      this.cropperVisible = true
    },
    // 覆盖默认的上传行为
    requestUpload() {},
    // 向左旋转
    rotateLeft() {
      this.$refs.cropper.rotateLeft()
    },
    // 向右旋转
    rotateRight() {
      this.$refs.cropper.rotateRight()
    },
    // 图片缩放
    changeScale(num) {
      num = num || 1
      this.$refs.cropper.changeScale(num)
    },
    // 上传预处理
    beforeUpload(file) {
      this.fileName = file.name;
      if (file.type.indexOf("image/") == -1) {
        this.$modal.msgError(
          "文件格式错误,请上传图片类型,如:JPG,PNG后缀的文件。"
        )
      } else {
        const reader = new FileReader()
        reader.readAsDataURL(file)
        reader.onload = () => {
          this.options.img = reader.result
        }
      }
    },
    // 上传图片
    uploadImg() {
      this.$refs.cropper.getCropBlob((data) => {
        var file = new File([data], this.fileName);
        let form = new FormData();
        form.append("file", file);
        fileStore.uploadFiles(form).then((response) => {
          this.cropperVisible = false
          this.options.img = fileStore.getImgUrl(response.data.fileId)
          //data: {fileId: "6377403363e4ef65532be317", filename: "234.png", length: 68100,…}
          this.$emit("changeImg", response.data.fileId, response.data.type)
          this.$message.success("提交成功")
        })
      })
    },
    // 实时预览
    realTime(data) {
      console.log(data, '======')
     	 //div: Object
     	 //h: 256
		//html: "\n      <div class=\"show-preview\" style=\"width: 521.359px; height: 256px,; overflow: hidden\">\n        <div style=\"width: 521.359px; height: 256px\">\n          <img src=blob:http://localhost:8080/2c1310d7-5b09-4d18-b591-3baf14ae6e97 style=\"width: 718px; height: 211px; transform:\n          scale(0.7261267409470753)translate3d(-135.40404788255304px, 30.986326120772823px, 0px)rotateZ(0deg)\">\n        </div>\n      </div>"
		//img: Object
		//url: "blob:http://localhost:8080/2c1310d7-5b09-4d18-b591-3baf14ae6e97"
      this.previews = data
    }
  }
}
</script>
<style scoped lang="less">
.imageCropper {
  width: 100%;
  height: 100%;
  overflow: hidden;
}
.imageCropper-show {
  position: relative;
  border: 1px solid #c0c4cc;
  cursor: pointer;
  .imageCropper-show-img {
    width: 100%;
    height: 100%;
  }
  .image-tools {
    position: absolute;
    width: 100%;
    height: 100%;
    left: 0;
    top: 0;
    cursor: default;
    text-align: center;
    color: #fff;
    opacity: 0;
    font-size: 25px;
    background-color: rgba(0, 0, 0, 0.5);
    transition: opacity 0.3s;
    display: flex;
    justify-content: center;
    align-items: center;
    &:hover {
      opacity: 1;
    }
    .image-btn {
      display: inline-block;
      padding: 0 10px;
      cursor: pointer;
    }
  }
  .image-add {
    width: 100%;
    height: 100%;
    font-size: 20px;
    display: flex;
    justify-content: center;
    align-items: center;
    .el-icon-plus {
      font-size: 30px;
      font-weight: 600;
    }
  }
}

.cropper-box {
  min-height: 400px;
  display: flex;
  justify-content: space-around;
  .cropper-left {
    width: 49%;
    height: calc(100% - 60px);
    position: relative;
  }
  .cropper-right {
    width: 49%;
    height: calc(100% - 60px);
    border: 2px dashed #1890ff;
    text-align: center;
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    .cropper-preview {
      background: #000000;
      z-index: 2;
    }
    .cropper-tips {
      z-index: 1;
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      font-size: 1.2rem;
      color: #1890ff;
    }
  }
}
.cropper-tools {
  width: 100%;
  height: 50px;
  position: absolute;
  left: 0;
  bottom: -60px;
  display: flex;
  .tools-group {
    margin-left: 10px;
  }
}
.preview-submit {
  width: 100%;
  height: 50px;
  text-align: center;
  position: absolute;
  right: 0;
  bottom: -60px;
}
</style>
  1. 父组件应用
<el-col :span="24">
  <el-form-item label="图片" prop="img">
    <imageCropper ref="imageCropper" 
	:cropperStyle="cropperStyle"
    :imgUrl.sync="form.img"
    @changeImg="changeImg" 
    @deleteImage="deleteImage"/>
  </el-form-item>
</el-col>

import imageCropper from "@/components/imageCropper/index.vue"

data(){
	return{
	cropperStyle:{
	        width:592,
	        height:256,
	      },
	  form:{
	 		 img:'',
	 		 pictures :'',
	 		 fileType :'',
	 		 
	  }
    },
    methods:{
     changeImg(fileId, type) {
     	this.form.pictures = fileId;
      	this.form.fileType = type;
     	 console.log(fileId, type)//61534641152151654895  , .png
    },
    deleteImage() {
     	 this.form.pictures = '';
     	 this.form.fileType = '';
     	 this.$refs.imageCropper.deleteAction();
    },
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值