|
- <template>
- <div class="uploder">
- <div class="change-photo-setter" style="height: 240px; width: 160px">
- <van-uploader ref="uploader" class="sett-item" :before-read="beforeRead" style="height: 240px; width: 160px">
- <div style="height: 240px; width: 160px">
- <!-- <img :src="ImgUrl" alt="" /> -->
- </div>
- </van-uploader>
- </div>
- <div class="uploadava">
- <!-- van-popup有bug,某些1情况需要绑定app为根 -->
- <van-popup :get-container="this.isAndroid ? '' : '#app'" class="vanPopup" duration="0" v-model="showCropper" position="top" :style="{ height: '100%' }">
- <div class="cropper-container" :style="{ height: '92vh', position: 'relative' }">
- <van-loading v-show="loadingShow" size="50" color="#fff" vertical text-color="#fff">上传中...</van-loading>
- <!-- 切图组件 -->
- <!-- :outputSize="option.outputSize" -->
- <vueCropper
- :style="{ backgroundImage: 'none', height: '92vh' }"
- ref="cropper"
- :img="option.img"
- :outputSize="option.outputSize"
- :outputType="option.outputType"
- :info="option.info"
- :full="option.full"
- :autoCropWidth="option.autoCropWidth"
- :autoCropHeight="option.autoCropHeight"
- :canMove="option.canMove"
- :canMoveBox="option.canMoveBox"
- :original="option.original"
- :autoCrop="option.autoCrop"
- :fixed="option.fixed"
- :fixedNumber="option.fixedNumber"
- :centerBox="option.centerBox"
- :infoTrue="option.infoTrue"
- :fixedBox="option.fixedBox"
- :high="option.high"
- :mode="option.mode" />
- <!-- <div style="display: flex; justify-content: space-between; padding: 10px; height: 8vh">
- <div @click="onClickLeft">取消</div>
- <div @click="onClickRight">确定</div>
- </div> -->
- <van-nav-bar :style="{ height: '8vh', width: '100%', position: 'absolute' }" left-text="取消" right-text="确定" @click-left="onClickLeft" @click-right="onClickRight" />
- </div>
- </van-popup>
- </div>
- </div>
- </template>
-
- <script>
- import { awsImgUpload } from '@/api/editModel';
- import { Toast } from 'vant';
- import { VueCropper } from 'vue-cropper';
- import { scrollToID, getDeviceType } from '../utils';
- import { saveImgApi } from '../api/editModel';
- import { watch } from 'vue';
- export default {
- name: 'uploadAva',
- components: {
- VueCropper
- },
- props: {
- showAta: {
- default: false,
- type: Boolean
- },
- avaUrl: {
- default: '',
- type: String
- },
- type: {
- default: '',
- type: Number
- },
- videoType: {
- default: null,
- type: Number
- }
- },
- data() {
- return {
- isAndroid: false, //判断是不是ios
- aaa: null,
- ImgUrl: '',
- show: true, // 上传类型的弹窗
- imageFileName: '',
- showCropper: false, // 裁剪的弹窗
- option: {
- img: '',
- outputSize: 0.5, //图片质量
- info: false, // 裁剪框的大小信息
- // outputType: 'jpeg', // 裁剪生成图片的格式
- outputType: 'png', // 裁剪生成图片的格式
- canScale: true, // 图片是否允许滚轮缩放
- autoCrop: true, // 是否默认生成截图框
- autoCropWidth: window.innerWidth - 100 + 'px', // 默认生成截图框宽度
- autoCropHeight: window.innerWidth - 100 + 'px', // 默认生成截图框高度
- high: true, // 是否按照设备的dpr 输出等比例图片
- fixedBox: false, // 固定截图框大小 不允许改变
- fixed: false, // 是否开启截图框宽高固定比例
- // fixedNumber: [1, 1], // 截图框的宽高比例
- full: true, // 是否输出原图比例的截图
- canMoveBox: true, // 截图框能否拖动
- original: false, // 上传图片按照原始比例渲染
- centerBox: true, // 截图框是否被限制在图片里面
- infoTrue: false, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
- mode: '100% auto' // 图片默认渲染方式
- },
- loadingShow: false // 是否展示loading
- };
- },
- created() {
- const deviceType = getDeviceType();
- this.isAndroid = false;
- if (!deviceType) {
- // 设备类型为pc
- this.isAndroid = false;
- } else {
- if (deviceType[0] == 'Android') {
- // 设备类型为安卓
- this.isAndroid = true;
- } else {
- // 其他设备
- this.isAndroid = false;
- }
- }
- if (this.type == 4 && this.videoType == 1) {
- this.option.autoCropWidth = 1080 + 'px'; // 默认生成截图框宽度
- this.option.autoCropHeight = 1920 + 'px'; // 默认生成截图框高度
- this.option.fixed = true;
- this.option.fixedNumber = [1080, 1920];
- }
- if (this.type == 4 && this.videoType == 2) {
- this.option.autoCropWidth = 1920 + 'px'; // 默认生成截图框宽度
- this.option.autoCropHeight = 1080 + 'px'; // 默认生成截图框高度
- this.option.fixed = true;
- this.option.fixedNumber = [1920, 1080];
- }
- },
- methods: {
- beforeRead(file) {
- // console.log(file)
- if (file.type !== 'image/jpeg' && file.type !== 'image/png') {
- this.$toast('请上传 jpg/png 格式图片');
- return false;
- }
- // let data = window.URL.createObjectURL(new Blob([file]));
- let data = window.URL.createObjectURL(file);
- console.log(data);
- this.option.img = data; //给裁剪图片的路径
- this.showCropper = true;
- return false;
- },
- // 点击裁剪的选择
- onClickRight() {
- const timestamp = Date.now();
- let that = this;
- this.loadingShow = true;
- // console.log(this.$refs.cropper);
- this.$refs.cropper.getCropData(data => {
- // do something
- // console.log(data, 'base64');
- });
- this.$refs.cropper.getCropBlob(async data => {
- console.log(data, '上传图片数据');
- // 利用canvas压缩图片
- const img = new Image();
- img.src = URL.createObjectURL(data);
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
- const getCanvasData = new Promise((resolve, reject) => {
- img.onload = function () {
- canvas.width = img.width;
- canvas.height = img.height;
- context.drawImage(img, 0, 0);
- canvas.toBlob(
- function (compressedBlob) {
- resolve(compressedBlob);
- },
-
- 0.5
- ); // 指定导出的图像类型和压缩质量
- };
- });
- // img.src = URL.createObjectURL(data);
- const canvasData = await getCanvasData;
- // ---------------------------------------------
- let formData = new FormData();
- // formData.append('file', data, timestamp + '.png');
- console.log(canvasData, '压缩图片数据');
- formData.append('file', canvasData, timestamp + '.png');
-
- that.loading = false;
- // console.log(that.ImgUrl, 'dasdasd')
- // 发请求
- const AccessToken = localStorage.getItem('AccessToken');
- that
- .$axios({
- method: 'post',
-
- url: process.env.VUE_APP_API_ROOT + `/api/upload/awsImgUpload`,
- headers: {
- 'content-type': 'multipart/form-data',
- token: AccessToken,
- 'Access-Control-Allow-Credentials': true
- },
- data: formData
- })
- .then(async res => {
- // console.log(res.data.data.url)
- const res1 = await saveImgApi({
- type: that.type,
- videoType: that.videoType,
- material: res.data.data.url
- });
- // 重新获取列表
- await that.$parent.$parent.getMyBGIListApi();
- await that.$parent.$parent.getMyScListApi();
- if (this.type == 4) {
- that.$parent.$parent.changeShowBGIList(1);
- }
- if (this.type == 5) {
- that.$parent.$parent.changeShowBGIList(3);
- }
- that.loadingShow = false;
- that.showCropper = false;
- Toast.success('上传成功');
- });
- });
- },
-
- // 点击取消
- onClickLeft() {
- this.loadingShow = false;
- this.showCropper = false;
- this.$parent.showPhotoUploader = false;
- },
- // 上传图片
- async pushImg(data) {
- try {
- const res = await awsImgUpload(data);
- this.loadingShow = false;
- this.showCropper = false;
- Toast.success('上传成功');
- } catch (error) {
- console.log(error, 'error');
- Toast.fail(error.message);
- }
- },
- //图片转base64,异步
- toBase64(file) {
- let that = this;
- return new Promise((resolve, reject) => {
- const reader = new FileReader();
- reader.onload = () => {
- // base64结果
- that.ImgUrl = this.result;
- that.loading = false;
- };
- reader.onerror = reject;
- reader.readAsDataURL(file);
- });
- },
- // base64 转二进制
- base64ToBinary(base64) {
- const binaryStr = window.atob(base64);
- const len = binaryStr.length;
- const bytes = new Uint8Array(len);
- for (let i = 0; i < len; ++i) {
- bytes[i] = binaryStr.charCodeAt(i);
- }
- return bytes;
- }
- },
- mounted() {}
- };
- </script>
-
- <style lang="scss" scoped>
- // /deep/.cropper-container {
- // z-index: 2005 !important;
- // }
- // .uploder{
- // overflow: hidden;
- // }
-
- /deep/.van-nav-bar__content {
- height: 8vh;
- background-color: #ccc;
- }
- /deep/.van-hairline--bottom::after {
- // height: 8vh;
- }
- /deep/.cropper-view-box {
- outline: 2px dashed #fff !important;
- }
- /deep/.crop-point {
- background-color: auto !important;
- }
-
- /deep/.van-loading {
- position: absolute;
- // color: red;
- z-index: 9999;
- left: 50%;
- top: 50%;
- margin-left: -55px;
- margin-top: -30px;
- background: rgba(0, 0, 0, 0.3);
- padding: 10px 30px;
- border-radius: 25px;
- }
-
- .uploadava {
- // width: 100%;
- // width: 100vw;
- height: 94vh;
- .update-avatar {
- height: 100%;
- text-align: center;
- .update-avatar-line {
- width: 100%;
- height: 1px;
- background-color: #979797;
- }
- .avatar-select-type {
- background-color: #fff;
- width: 346px;
- border-radius: 12px;
- padding-bottom: 4px;
- .upload-avator {
- padding: 14px;
- }
- }
- p {
- margin: 15px 0 30px;
- background-color: #fff;
- width: 346px;
- border-radius: 12px;
- padding: 15px 0 18px;
- }
- }
- .cropper-container {
- position: relative;
- width: 100%;
- height: 94vh;
- // height: 100%;
- /deep/ .van-nav-bar {
- position: absolute;
- z-index: 999;
- width: 100%;
- bottom: 0px;
- left: 0px;
- height: 6vh;
- background-color: rgba(0, 0, 0, 0.87);
- :global(.van-nav-bar__text) {
- color: #000;
- // font-size: $font-size-normal-x;
- }
- :global(.van-nav-bar__text:nth-child(2)) {
- color: #000;
- font-weight: 500;
- }
- // :global(.van-icon) {
- // color: red;
- // }
- }
- }
- .vue-cropper {
- background: #000;
- width: 100%;
- height: 88vh;
- padding-top: 46px;
- box-sizing: border-box;
- }
- }
- </style>
|