cropperjs裁剪图片(vue+cropperjs+ts),并上传到七牛云

1.安装 :npm i cropperjs

2.如图:
image.png

3.最好写成一个组件,随时调用

<template>
    <div class="v-simple-cropper">
        <input class="file" type="file" accept="image/*" @change="uploadChange" />
        <div class="v-cropper-layer" ref="layer" v-show="showlayer">
            <div class="layer-header">
                <button class="cancel" @click="cancelHandle">取消</button>
                <button class="confirm" @click="confirmHandle">選取</button>
            </div>
            <img ref="cropperImg" />
        </div>
    </div>
</template>
import Cropper from 'cropperjs';
import 'cropperjs/dist/cropper.min.css';
import * as qiniu from 'qiniu-js';
private cropper: any;
// 裁剪板块
private showlayer = false;
// 裁剪参数
private initParam = {
    scale: 1 // 相对手机屏幕放大的倍数
};
// 初始化裁剪插件
private init() {
    const cropperImg = this.$refs.cropperImg as HTMLImageElement;
    this.cropper = new Cropper(cropperImg, {
        aspectRatio: 1 / 1, // 剪裁比例
        dragMode: 'move' // 模式
    });
}
// 选择上传文件
private uploadChange(e) {
    const file = e.target.files[0];
    this.showlayer = true;
    const URL = window.URL || window.webkitURL;
    this.cropper.replace(URL.createObjectURL(file));
}
// 取消上传
private cancelHandle() {
    this.cropper.reset();
    this.showlayer = false;
}
// 确定上传
private confirmHandle() {
    const cropBox = this.cropper.getCropBoxData();
    const scale = this.initParam['scale'] || 1;
    this.cropper
        .getCroppedCanvas({
            width: cropBox.width * scale,
            height: cropBox.height * scale
        })
        //把裁剪的图片转换成blob类型文件,在通过new File(),转换成file文件
        .toBlob(async blob => {
            //重置file的name,以时间戳作为文件名
            const timeString = new Date().getTime();
            const imgFile = new File([blob], `${timeString}.jpg`, { type: 'image/jepg' });
            this.showlayer = false;
            const res = await this.uploadFile(imgFile);
            this.$emit('uploadURL', res);
        });
}
// 请求接口上传图片
private uploadFile(file) {
    return new Promise(resolve => {
        msg.PostQiniu().then(res => {
            const uptoken = res.token;
            const key = file.name;
            const config = {
                useCdnDomain: false, //表示是否使用 cdn 加速域名,为布尔值,true 表示使用,默认为 false。
                region: undefined // 根据具体提示修改上传地区,当为 null 或 undefined 时,自动分析上传域名区域
            };
            const putExtra: any = {
                fname: file.name, //文件原文件名
                params: {}, //用来放置自定义变量
                mimeType: ['image/png', 'image/jpeg', 'image/gif'] //用来限制上传文件类型,为 null 时表示不对文件类型限制;
            };
            const observable = qiniu.upload(file, key, uptoken, putExtra, config);
            observable.subscribe({
                next: result => {
                    // 主要用来展示进度
                    console.warn(result);
                },
                error: () => {
                    this.$toast.show('提交失敗');
                },
                complete: e => {
                    resolve(`${res.domain}${e.key}`);
                }
            });
        });
    });
}

4.样式

<style lang="scss" scoped>
@import '@/assets/style/color.scss';
.v-simple-cropper {
    width: 100%;
    height: 100%;
    position: absolute;
    left: 0;
    top: 0;
    .file {
        width: 100%;
        height: 100%;
        opacity: 0;
    }
    .v-cropper-layer {
        position: fixed;
        width: 100%;
        height: 100%;
        top: 0;
        bottom: 0;
        left: 0;
        right: 0;
        background: #fff;
        z-index: 99999;
        .layer-header {
            position: absolute;
            top: 0;
            left: 0;
            z-index: 99999;
            background: rgba(#fff, 0.5);
            width: 100%;
            height: 0.8rem;
            padding: 0 0.2rem;
            box-sizing: border-box;
        }
        .cancel,
        .confirm {
            line-height: 0.8rem;
            font-size: 0.28rem;
            background: none;
            border: 0;
            outline: 0;
            float: left;
        }
        .confirm {
            float: right;
        }
        img {
            position: inherit !important;
            border-radius: inherit !important;
            float: inherit !important;
        }
    }
}
</style>

5.在页面调用组件

<cropperBox @uploadURL="uploadURL" />
// 上传成功 获取img
private uploadURL(url) {
    console.log(url);
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,941评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,397评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,345评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,851评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,868评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,688评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,414评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,319评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,775评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,945评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,096评论 1 350
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,789评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,437评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,993评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,107评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,308评论 3 372
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,037评论 2 355