123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- <template>
- <popup v-if="src">
- <div class="com-image-cropper">
- <header app-border dir-bottom>
- {{title}}
- <i class="iconfont icon-close" @click="onClose"></i>
- </header>
- <div>
- <vue-cropper
- ref="cropper"
- alt="图片"
- :src="src"
- :view-mode="0"
- :aspect-ratio="options.aspectRatio || 1"
- :ready="ready"
- :min-container-width="(options.minContainerSize && options.minContainerSize.width) || null"
- :min-container-height="(options.minContainerSize && options.minContainerSize.height) || null"
- :container-style="options.containerStyle || containerStyle"
- ></vue-cropper>
- </div>
- <footer>
- <button class="ui-button submit" style="width:120px" @click="cropImage" :class="{disable:isCroping}">确定</button>
- <button class="ui-button cancel" style="width:120px" @click="onClose">取消</button>
- </footer>
- </div>
- </popup>
- </template>
- <script>
- import "cropperjs/dist/cropper.css";
- import VueCropper from "vue-cropperjs";
- import Popup from "./popup";
- import { base64ToDataURL, base64ToBlob } from "@/utils/file";
- import CompressImg from "@/utils/CompressImg";
- export default {
- name: "com-image-cropper",
- components: { Popup, VueCropper },
- props: {
- src: String,
- radius: Number,
- title: {
- type: String,
- default: ""
- },
- options: {
- type: Object,
- default() {
- return {};
- }
- },
- compress: Boolean,
- containerStyle: { height: "300px" }
- },
- data(){
- return{
- isCroping:false
- }
- },
- watch: {
- src(newVal, oldVal) {
- if (!newVal && oldVal) {
- this.$refs.cropper.destroy();
- }
- }
- },
- methods: {
- ready() {
- if (this.radius > 0) {
- this.$el.querySelector(".cropper-view-box").style.borderRadius =
- this.radius + "%";
- }
- },
- cropImage() {
- this.isCroping = true
- let base64 = this.$refs.cropper.getCroppedCanvas().toDataURL();
- this.dataURL && window.URL.revokeObjectURL(this.dataURL);
- if (this.compress) {
- const img = new Image();
- img.src = base64;
- img.onload = () => {
- const blob = base64ToBlob(base64);
- const simg = CompressImg(img, {
- weight: blob.size,
- maxWeight: 0.4 * 1024 * 1024,
- maxSize: 200
- });
- this.dataURL = simg.src;
- this.$emit("crop-blob", this.dataURL, simg.base64Src);
- this.onClose();
- };
- } else {
- this.dataURL = base64ToDataURL(base64);
- this.$emit("crop-blob", this.dataURL, base64);
- this.onClose();
- }
- },
- onClose() {
- this.isCroping = false
- this.$emit("close");
- }
- }
- };
- </script>
- <style lang="less" scoped>
- .com-image-cropper {
- width: 600px;
- min-width: 600px;
- background-color: #262729;
- font-size: 14px;
- color: #fff;
- overflow: hidden;
- border-radius: 9px;
- box-shadow: 0 0px 35px rgba(0, 0, 0, 0.3);
- header {
- padding: 10px 16px;
- height: 40px;
- i {
- float: right;
- cursor: pointer;
- }
- }
- footer {
- display: flex;
- align-items: center;
- justify-content: center;
- height: 80px;
- button {
- margin: 0 10px;
- }
- }
- > div {
- padding: 30px;
- padding-bottom: 0;
- display: flex;
- align-items: center;
- justify-content: center;
- }
- }
- </style>
- <style lang="less">
- .cropper-view-box {
- border: 1px solid rgba(2, 200, 174, 0.54);
- outline: 1px solid @color !important;
- outline-color: rgba(2, 200, 174, 0.75) !important;
- }
- .cropper-point {
- background-color: @color !important;
- }
- </style>
|