|
| 1 | +<template> |
| 2 | + <!-- eslint-disable --> |
| 3 | + <div :class="$options.name"> |
| 4 | + <el-dialog :before-close="handleClose" destroy-on-close :title="title" :visible.sync="dialogVisible" width="660px"> |
| 5 | + <div class="cropper-container"> |
| 6 | + <div class="cropper-el"> |
| 7 | + <vue-cropper ref="cropper" :can-move="option.canMove" :can-move-box="option.canMoveBox" :fixed-box="option.fixedBox" :full="option.full" :img="cropperImg" :info="true" :auto-crop="option.autoCrop" :original="option.original" :auto-crop-width="option.autoCropWidth" :output-size="option.size" :auto-crop-height="option.autoCropHeight" :output-type="option.outputType" :center-box="option.centerBox" :high="option.high" :info-true="option.infoTrue" :enlarge="option.enlarge" :fixed="option.fixed" :fixed-number="option.fixedNumber" @realTime="realTime" /> |
| 8 | + </div> |
| 9 | + <!-- 预览 --> |
| 10 | + <div class="prive-el"> |
| 11 | + 效果预览: |
| 12 | + <div class="prive-style" :style="{ |
| 13 | + width: '300px', |
| 14 | + height: (300 * fixedNumber[1]) / fixedNumber[0] + 'px', |
| 15 | + margin: '0 25px', |
| 16 | + display: 'flex', |
| 17 | + 'align-items': 'center', |
| 18 | + }"> |
| 19 | + <div class="preview" :style="previews.div"> |
| 20 | + <img :src="previews.url" :style="previews.img" /> |
| 21 | + </div> |
| 22 | + </div> |
| 23 | + </div> |
| 24 | + </div> |
| 25 | + <span slot="footer" class="dialog-footer"> |
| 26 | + <el-button @click="handleClose">取 消</el-button> |
| 27 | + <el-button type="primary" @click="saveImg">确 定</el-button> |
| 28 | + </span> |
| 29 | + </el-dialog> |
| 30 | + </div> |
| 31 | +</template> |
| 32 | + |
| 33 | +<script> |
| 34 | +/* eslint-disable */ |
| 35 | +export default { |
| 36 | + name: 'Cropper', |
| 37 | + props: { |
| 38 | + dialogVisible: { |
| 39 | + type: Boolean, |
| 40 | + default: false, |
| 41 | + }, |
| 42 | + imgType: { |
| 43 | + type: String, |
| 44 | + default: 'blob', |
| 45 | + }, |
| 46 | + cropperImg: { |
| 47 | + type: String, |
| 48 | + default: '', |
| 49 | + }, |
| 50 | + title: { |
| 51 | + type: String, |
| 52 | + default: '图片裁剪', |
| 53 | + }, |
| 54 | + fixedNumber: { |
| 55 | + type: Array, |
| 56 | + default: () => [16, 9], |
| 57 | + }, |
| 58 | + }, |
| 59 | + data() { |
| 60 | + return { |
| 61 | + previews: {}, |
| 62 | + option: { |
| 63 | + img: '', // 裁剪图片的地址 |
| 64 | + size: 3000, // 裁剪生成图片的质量 |
| 65 | + full: true, // 是否输出原图比例的截图 默认false |
| 66 | + outputType: 'png', // 裁剪生成图片的格式 默认jpg |
| 67 | + canMove: false, // 上传图片是否可以移动 |
| 68 | + fixedBox: false, // 固定截图框大小 不允许改变 |
| 69 | + original: false, // 上传图片按照原始比例渲染 |
| 70 | + canMoveBox: true, // 截图框能否拖动 |
| 71 | + autoCrop: true, // 是否默认生成截图框 |
| 72 | + // 只有自动截图开启 宽度高度才生效 |
| 73 | + autoCropWidth: 150, // 默认生成截图框宽度 |
| 74 | + autoCropHeight: 150, // 默认生成截图框高度 |
| 75 | + centerBox: true, // 截图框是否被限制在图片里面 |
| 76 | + high: false, // 是否按照设备的dpr 输出等比例图片 |
| 77 | + enlarge: 1, // 图片根据截图框输出比例倍数 |
| 78 | + mode: 'contain', // 图片默认渲染方式 |
| 79 | + maxImgSize: 2000, // 限制图片最大宽度和高度 |
| 80 | + limitMinSize: [100, 120], // 更新裁剪框最小属性 |
| 81 | + infoTrue: false, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高 |
| 82 | + fixed: true, // 是否开启截图框宽高固定比例 (默认:true) |
| 83 | + fixedNumber: this.fixedNumber, // 截图框的宽高比例 |
| 84 | + }, |
| 85 | + } |
| 86 | + }, |
| 87 | + methods: { |
| 88 | + // 裁剪时触发的方法,用于实时预览 |
| 89 | + realTime(data) { |
| 90 | + this.previews = data |
| 91 | + }, |
| 92 | + // 取消关闭弹框 |
| 93 | + handleClose() { |
| 94 | + this.$emit('colse-dialog', false) |
| 95 | + }, |
| 96 | + // 获取裁剪之后的图片,默认blob,也可以获取base64的图片 |
| 97 | + saveImg() { |
| 98 | + if (this.imgType === 'blob') { |
| 99 | + this.$refs.cropper.getCropBlob((data) => { |
| 100 | + this.$emit('upload-img', data) |
| 101 | + }) |
| 102 | + } else { |
| 103 | + this.$refs.cropper.getCropData((data) => { |
| 104 | + this.uploadFile = data |
| 105 | + this.$emit('upload-img', data) |
| 106 | + }) |
| 107 | + } |
| 108 | + }, |
| 109 | + }, |
| 110 | +} |
| 111 | +</script> |
| 112 | + |
| 113 | +<style lang="scss" scoped> |
| 114 | +.Cropper { |
| 115 | + .cropper-el { |
| 116 | + height: 300px; |
| 117 | + width: 300px; |
| 118 | + } |
| 119 | + .cropper-container { |
| 120 | + display: flex; |
| 121 | + justify-content: space-between; |
| 122 | + align-items: flex-end; |
| 123 | + .prive-el { |
| 124 | + width: 300px; |
| 125 | + flex: 1; |
| 126 | + text-align: center; |
| 127 | + .prive-style { |
| 128 | + margin: 0 auto; |
| 129 | + flex: 1; |
| 130 | + -webkit-flex: 1; |
| 131 | + display: flex; |
| 132 | + display: -webkit-flex; |
| 133 | + justify-content: center; |
| 134 | + -webkit-justify-content: center; |
| 135 | + border: 1px solid #eee; |
| 136 | + overflow: hidden; |
| 137 | + margin-left: 40px; |
| 138 | + } |
| 139 | + .preview { |
| 140 | + overflow: hidden; |
| 141 | + } |
| 142 | + .el-button { |
| 143 | + margin-top: 20px; |
| 144 | + } |
| 145 | + } |
| 146 | + } |
| 147 | +} |
| 148 | +</style> |
0 commit comments