| @@ -1,377 +0,0 @@ | |||
| <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) => { | |||
| canvas.width = img.width; | |||
| canvas.height = img.height; | |||
| img.onload = function () { | |||
| context.drawImage(img, 0, 0); | |||
| canvas.toBlob( | |||
| function (compressedBlob) { | |||
| resolve(compressedBlob); | |||
| }, | |||
| 'png', | |||
| 0.5 | |||
| ); // 指定导出的图像类型和压缩质量 | |||
| }; | |||
| }); | |||
| 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> | |||
| @@ -1,364 +0,0 @@ | |||
| <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, '上传图片数据'); | |||
| let formData = new FormData(); | |||
| formData.append('file', data, timestamp + '.png'); | |||
| let file = formData.get('file'); | |||
| // 转为 base64 | |||
| // let reader = new FileReader(); | |||
| // const base64Data = await new Promise((resolve, reject) => { | |||
| // reader.onload = () => { | |||
| // resolve(reader.result); | |||
| // }; | |||
| // reader.readAsDataURL(file); | |||
| // }); | |||
| // let imgBinary = await that.base64ToBinary(base64Data.substring(23)); | |||
| // // base64结果 | |||
| // that.ImgUrl = base64Data; | |||
| that.loading = false; | |||
| // console.log(that.ImgUrl, 'dasdasd') | |||
| // 发请求 | |||
| const AccessToken = localStorage.getItem('AccessToken'); | |||
| that | |||
| .$axios({ | |||
| method: 'post', | |||
| // url: `https://smapitest.malls.iformall.com/C/api/upload/awsImgUpload`, | |||
| // url: `http://m.metavatar.cc/C/api/upload/awsImgUpload`, | |||
| 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> | |||
| @@ -1,376 +1,419 @@ | |||
| <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> | |||
| <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) => { | |||
| if (res.data.code == 200) { | |||
| Toast.success("上传成功"); | |||
| } else { | |||
| Toast.fail(res.data.message); | |||
| } | |||
| that.loadingShow = false; | |||
| that.showCropper = false; | |||
| // console.log(res.data.data.url) | |||
| const res1 = await saveImgApi({ | |||
| type: that.type, | |||
| videoType: that.videoType, | |||
| material: res.data.data.url, | |||
| }); | |||
| // 重新获取列表 | |||
| that.$parent.$parent.$parent.pageNum2 = 1; | |||
| that.$parent.$parent.$parent.pageNum4 = 1; | |||
| that.$parent.$parent.$parent.finished2 = false; | |||
| that.$parent.$parent.$parent.finished4 = false; | |||
| that.$parent.$parent.$parent.myBGIList = []; | |||
| that.$parent.$parent.$parent.myScList = []; | |||
| await that.$parent.$parent.$parent.getMyScListApi("reset"); | |||
| await that.$parent.$parent.$parent.getMyBGIListApi("reset"); | |||
| console.log(that.$parent.$parent.$parent.pageNum4, "444"); | |||
| if (this.type == 4) { | |||
| that.$parent.$parent.$parent.changeShowBGIList(1); | |||
| } | |||
| if (this.type == 5) { | |||
| that.$parent.$parent.$parent.changeShowBGIList(3); | |||
| } | |||
| that.loadingShow = false; | |||
| that.showCropper = false; | |||
| console.log(res); | |||
| }); | |||
| }); | |||
| }, | |||
| // 点击取消 | |||
| 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> | |||
| @@ -1,137 +1,132 @@ | |||
| import Vue from 'vue' | |||
| import VueRouter from 'vue-router' | |||
| Vue.use(VueRouter) | |||
| // 解决ElementUI导航栏中的vue-router在3.0版本以上重复点菜单报错问题 | |||
| const originalPush = VueRouter.prototype.push | |||
| VueRouter.prototype.push = function push(location) { | |||
| return originalPush.call(this, location).catch(err => err) | |||
| } | |||
| const routes = [ | |||
| { | |||
| path: '/', | |||
| name: 'Home', | |||
| // component: Home | |||
| component: () => import("../components/home/home"), | |||
| }, | |||
| { | |||
| path: '/aboutUs', | |||
| name: 'aboutUs', | |||
| component: () => import("../components/aboutUs/aboutUs"), | |||
| }, | |||
| // 登录 | |||
| { | |||
| path: '/login', | |||
| name: 'login', | |||
| component: () => import("../views/login/login"), | |||
| }, | |||
| // 创作中心首页 | |||
| { | |||
| path: '/myPage', | |||
| name: 'myPage', | |||
| component: () => import("../views/myPage/myPage"), | |||
| }, | |||
| // 选择模板 | |||
| { | |||
| path: '/chooseModel', | |||
| name: 'chooseModel', | |||
| component: () => import("../views/model/chooseModel"), | |||
| }, | |||
| // 模板预览new | |||
| { | |||
| path: '/previewModel', | |||
| name: 'previewModel', | |||
| component: () => import("../views/model/previewModel"), | |||
| }, | |||
| // 编辑模板new | |||
| { | |||
| path: '/editModel', | |||
| name: 'editModel', | |||
| component: () => import("../views/model/editModel"), | |||
| }, | |||
| // 编辑位置new | |||
| { | |||
| path: '/editPosition', | |||
| name: 'editPosition', | |||
| component: () => import("../views/model/editPosition"), | |||
| }, | |||
| // 编辑位置new | |||
| { | |||
| path: '/editPosition-chatgpt', | |||
| name: 'editPosition-chatgpt', | |||
| component: () => import("../views/model/editPosition-chatgpt"), | |||
| }, | |||
| // 下载预览视频页 | |||
| { | |||
| path: '/videoDownload', | |||
| name: 'videoDownload', | |||
| component: () => import("../views/videoDownload/videoDownload"), | |||
| } | |||
| , | |||
| //视频生成中页 | |||
| { | |||
| path: '/videoCreate', | |||
| name: 'videoCreate', | |||
| component: () => import("../views/model/videoCreate"), | |||
| }, | |||
| , | |||
| //视频生成失败 | |||
| { | |||
| path: '/videoFail', | |||
| name: 'videoFail', | |||
| component: () => import("../views/model/videoFail"), | |||
| }, | |||
| // 聊天首页new | |||
| { | |||
| path: '/chat', | |||
| name: 'chat', | |||
| component: () => import("@/views/chat/chat"), | |||
| }, | |||
| , | |||
| // 聊天首页new | |||
| { | |||
| path: '/chatgpt', | |||
| name: 'chatgpt', | |||
| component: () => import("@/views/chatgpt/chatgpt"), | |||
| }, | |||
| { | |||
| path: '/chatgpt-getmp3', | |||
| name: 'chatgpt-getmp3', | |||
| component: () => import("@/views/chatgpt/chatgpt-getmp3"), | |||
| }, | |||
| , | |||
| // 音频new | |||
| { | |||
| path: '/audio', | |||
| name: 'audio', | |||
| component: () => import("@/views/audio/audio"), | |||
| }, | |||
| // 录入文案 | |||
| { | |||
| path: '/getPaper', | |||
| name: 'getPaper', | |||
| component: () => import("../views/model/getPaper"), | |||
| }, | |||
| // 合成视频 | |||
| { | |||
| path: '/generateVideo', | |||
| name: 'generateVideo', | |||
| component: () => import("../views/model/generateVideo"), | |||
| }, | |||
| // 下载视频 | |||
| { | |||
| path: '/downloadVideo', | |||
| name: 'downloadVideo', | |||
| component: () => import("../views/model/downloadVideo"), | |||
| }, | |||
| ] | |||
| const router = new VueRouter({ | |||
| // mode: 'history', | |||
| base: process.env.BASE_URL, | |||
| routes | |||
| }) | |||
| export default router | |||
| import Vue from 'vue' | |||
| import VueRouter from 'vue-router' | |||
| Vue.use(VueRouter) | |||
| // 解决ElementUI导航栏中的vue-router在3.0版本以上重复点菜单报错问题 | |||
| const originalPush = VueRouter.prototype.push | |||
| VueRouter.prototype.push = function push(location) { | |||
| return originalPush.call(this, location).catch(err => err) | |||
| } | |||
| const routes = [ | |||
| { | |||
| path: '/', | |||
| name: 'Home', | |||
| // component: Home | |||
| component: () => import("../components/home/home"), | |||
| }, | |||
| { | |||
| path: '/aboutUs', | |||
| name: 'aboutUs', | |||
| component: () => import("../components/aboutUs/aboutUs"), | |||
| }, | |||
| // 登录 | |||
| { | |||
| path: '/login', | |||
| name: 'login', | |||
| component: () => import("../views/login/login"), | |||
| }, | |||
| // 创作中心首页 | |||
| { | |||
| path: '/myPage', | |||
| name: 'myPage', | |||
| component: () => import("../views/myPage/myPage"), | |||
| }, | |||
| // 选择模板 | |||
| { | |||
| path: '/chooseModel', | |||
| name: 'chooseModel', | |||
| component: () => import("../views/model/chooseModel"), | |||
| }, | |||
| // 模板预览new | |||
| { | |||
| path: '/previewModel', | |||
| name: 'previewModel', | |||
| component: () => import("../views/model/previewModel"), | |||
| }, | |||
| // 编辑模板new | |||
| { | |||
| path: '/editModel', | |||
| name: 'editModel', | |||
| component: () => import("../views/model/editModel"), | |||
| }, | |||
| // 编辑位置new | |||
| { | |||
| path: '/editPosition', | |||
| name: 'editPosition', | |||
| component: () => import("../views/model/editPosition"), | |||
| }, | |||
| // 下载预览视频页 | |||
| { | |||
| path: '/videoDownload', | |||
| name: 'videoDownload', | |||
| component: () => import("../views/videoDownload/videoDownload"), | |||
| } | |||
| , | |||
| //视频生成中页 | |||
| { | |||
| path: '/videoCreate', | |||
| name: 'videoCreate', | |||
| component: () => import("../views/model/videoCreate"), | |||
| }, | |||
| , | |||
| //视频生成失败 | |||
| { | |||
| path: '/videoFail', | |||
| name: 'videoFail', | |||
| component: () => import("../views/model/videoFail"), | |||
| }, | |||
| // 聊天首页new | |||
| { | |||
| path: '/chat', | |||
| name: 'chat', | |||
| component: () => import("@/views/chat/chat"), | |||
| }, | |||
| , | |||
| // 聊天首页new | |||
| { | |||
| path: '/chatgpt', | |||
| name: 'chatgpt', | |||
| component: () => import("@/views/chatgpt/chatgpt"), | |||
| }, | |||
| { | |||
| path: '/chatgpt-getmp3', | |||
| name: 'chatgpt-getmp3', | |||
| component: () => import("@/views/chatgpt/chatgpt-getmp3"), | |||
| }, | |||
| , | |||
| // 音频new | |||
| { | |||
| path: '/audio', | |||
| name: 'audio', | |||
| component: () => import("@/views/audio/audio"), | |||
| }, | |||
| // 录入文案 | |||
| { | |||
| path: '/getPaper', | |||
| name: 'getPaper', | |||
| component: () => import("../views/model/getPaper"), | |||
| }, | |||
| // 合成视频 | |||
| { | |||
| path: '/generateVideo', | |||
| name: 'generateVideo', | |||
| component: () => import("../views/model/generateVideo"), | |||
| }, | |||
| // 下载视频 | |||
| { | |||
| path: '/downloadVideo', | |||
| name: 'downloadVideo', | |||
| component: () => import("../views/model/downloadVideo"), | |||
| }, | |||
| ] | |||
| const router = new VueRouter({ | |||
| // mode: 'history', | |||
| base: process.env.BASE_URL, | |||
| routes | |||
| }) | |||
| export default router | |||
| @@ -1,280 +0,0 @@ | |||
| <template> | |||
| <div class="uploder"> | |||
| <div class="change-photo-setter"> | |||
| <van-uploader | |||
| class="sett-item" | |||
| :before-read="beforeRead" | |||
| accept="image/*" | |||
| > | |||
| <div>照片图库</div> | |||
| <img src="https://img01.yzcdn.cn/vant/leaf.jpg" alt="" /> | |||
| </van-uploader> | |||
| <van-uploader | |||
| class="sett-item" | |||
| :before-read="beforeRead" | |||
| capture="camera" | |||
| > | |||
| <div>拍照</div> | |||
| <img src="https://img01.yzcdn.cn/vant/leaf.jpg" alt="" /> | |||
| </van-uploader> | |||
| <van-uploader class="sett-item" :before-read="beforeRead"> | |||
| <div>选取文件</div> | |||
| <img src="https://img01.yzcdn.cn/vant/leaf.jpg" alt="" /> | |||
| </van-uploader> | |||
| </div> | |||
| <div class="uploadava"> | |||
| <!-- <van-overlay :show="show" @click="$emit('update:showAta', false),show = false"> | |||
| <div class="update-avatar"> | |||
| <ul class="avatar-select-type" @click.stop> | |||
| <van-uploader :before-read="beforeRead" capture="camera"> | |||
| <li class="select-type-photo upload-avator">拍摄</li> | |||
| </van-uploader> | |||
| <li class="update-avatar-line"></li> | |||
| <van-uploader :before-read="beforeRead"> | |||
| <li class="select-type-album upload-avator">从手机相册选择</li> | |||
| </van-uploader> | |||
| </ul> | |||
| <p @click.stop="show = false,$emit('update:showAta', false)">取消</p> | |||
| </div> | |||
| </van-overlay> --> | |||
| <van-popup | |||
| duration="0" | |||
| v-model="showCropper" | |||
| position="top" | |||
| :style="{ height: '100%' }" | |||
| > | |||
| <div class="cropper-container"> | |||
| <van-loading | |||
| v-show="loadingShow" | |||
| size="50" | |||
| color="#fff" | |||
| vertical | |||
| text-color="#fff" | |||
| >上传中...</van-loading | |||
| > | |||
| <vueCropper | |||
| 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" | |||
| /> | |||
| <van-nav-bar | |||
| left-text="取消" | |||
| right-text="选择" | |||
| @click-left="onClickLeft" | |||
| @click-right="getCropBlob" | |||
| /> | |||
| </div> | |||
| </van-popup> | |||
| </div> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| import { VueCropper } from 'vue-cropper' | |||
| export default { | |||
| name: 'uploadAva', | |||
| components: { | |||
| VueCropper | |||
| }, | |||
| props: { | |||
| showAta: { | |||
| default: false, | |||
| type: Boolean | |||
| }, | |||
| avaUrl: { | |||
| default: '', | |||
| type: String | |||
| } | |||
| }, | |||
| data() { | |||
| return { | |||
| show: true, // 上传类型的弹窗 | |||
| imageFileName: '', | |||
| showCropper: false, // 裁剪的弹窗 | |||
| option: { | |||
| img: '', | |||
| outputSize: 0.8, | |||
| info: false, // 裁剪框的大小信息 | |||
| outputType: 'jpeg', // 裁剪生成图片的格式 | |||
| canScale: true, // 图片是否允许滚轮缩放 | |||
| autoCrop: true, // 是否默认生成截图框 | |||
| autoCropWidth: window.innerWidth - 100 + 'px', // 默认生成截图框宽度 | |||
| autoCropHeight: window.innerWidth - 100 + 'px', // 默认生成截图框高度 | |||
| high: true, // 是否按照设备的dpr 输出等比例图片 | |||
| fixedBox: false, // 固定截图框大小 不允许改变 | |||
| fixed: true, // 是否开启截图框宽高固定比例 | |||
| fixedNumber: [1, 1], // 截图框的宽高比例 | |||
| full: true, // 是否输出原图比例的截图 | |||
| canMoveBox: true, // 截图框能否拖动 | |||
| original: false, // 上传图片按照原始比例渲染 | |||
| centerBox: true, // 截图框是否被限制在图片里面 | |||
| infoTrue: false, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高 | |||
| mode: '100% auto' // 图片默认渲染方式 | |||
| }, | |||
| loadingShow: false // 是否展示loading | |||
| } | |||
| }, | |||
| methods: { | |||
| // 点击上传按钮 | |||
| beforeRead(file) { | |||
| console.log(file, '111') | |||
| if (file.type !== 'image/jpeg' && file.type !== 'image/png') { | |||
| this.$toast('请上传 jpg/png 格式图片') | |||
| return false | |||
| } | |||
| console.log(111, file) | |||
| this.showCropper = true | |||
| this.imageToBase64(file) | |||
| this.imageFileName = file.name | |||
| }, | |||
| // 转64 | |||
| imageToBase64(file) { | |||
| let reader = new FileReader() | |||
| console.log(reader) | |||
| reader.readAsDataURL(file) | |||
| reader.onload = () => { | |||
| console.log(reader.result, '222') | |||
| this.option.img = reader.result | |||
| } | |||
| }, | |||
| // 处理图片, | |||
| getCropBlob() { | |||
| // let formData = new FormData() | |||
| this.loadingShow = true | |||
| console.log(this.option) | |||
| console.log(this.$refs.cropper) | |||
| // cropper插件上的getCropBlob()方法,data就是截图的图片 | |||
| this.$refs.cropper.getCropBlob((data) => { | |||
| // formData.append('headFile', data, this.imageFileName) | |||
| // formData.append('id', this.$store.getters.user.userId) | |||
| console.log(data) | |||
| // uploadAva(formData).then((res) => { | |||
| // this.showCropper = false | |||
| this.$emit('update:showAta', false) | |||
| // this.$emit('update:avaUrl', res.data) | |||
| // }) | |||
| }) | |||
| }, | |||
| onClickLeft() { | |||
| this.loadingShow = false | |||
| this.showCropper = false | |||
| this.$parent.showPhotoUploader = false | |||
| } | |||
| } | |||
| } | |||
| </script> | |||
| <style lang="scss" scoped> | |||
| // .uploder{ | |||
| // overflow: hidden; | |||
| // } | |||
| /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; | |||
| } | |||
| .change-photo-setter { | |||
| width: 400px; | |||
| background: #fff; | |||
| position: absolute; | |||
| top: 11%; | |||
| left: 40px; | |||
| z-index: 300; | |||
| .sett-item { | |||
| width: 100%; | |||
| } | |||
| /deep/.van-uploader__input-wrapper { | |||
| width: 100%; | |||
| display: flex; | |||
| flex-direction: row; | |||
| align-items: center; | |||
| justify-content: space-between; | |||
| padding: 15px; | |||
| img { | |||
| width: 40px; | |||
| height: 40px; | |||
| display: block; | |||
| } | |||
| } | |||
| .sett-item:first-child { | |||
| border-bottom: 2px solid #ccc; | |||
| } | |||
| } | |||
| .uploadava { | |||
| .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 { | |||
| height: 94vh; | |||
| .van-nav-bar { | |||
| background-color: rgba(0, 0, 0, 0.87); | |||
| :global(.van-nav-bar__text) { | |||
| color: #fff; | |||
| // 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; | |||
| height: 100%; | |||
| padding-top: 46px; | |||
| box-sizing: border-box; | |||
| } | |||
| } | |||
| </style> | |||
| @@ -1,267 +0,0 @@ | |||
| <template> | |||
| <div :class="inPage ? 'page active' : 'page'"> | |||
| <div id="top"></div> | |||
| <div class="content" ref="fatherBox"> | |||
| <!-- 控制框 --> | |||
| <div class="control"> | |||
| <div @click="controlImg(1)">放大</div> | |||
| <div @click="controlImg(2)">缩小</div> | |||
| <div @click="controlImg(3)">上移一层</div> | |||
| <div @click="controlImg(4)">下移一层</div> | |||
| </div> | |||
| <div | |||
| :id="'item' + index" | |||
| @touchmove="onMouseMove(index)" | |||
| @touchstart="onMouseDown(index)" | |||
| @touchend="onMouseUp(index)" | |||
| v-for="(item, index) in materialList" | |||
| :key="index" | |||
| class="material" | |||
| :style="{ | |||
| transform: 'scale(' + item.scale + ') ', | |||
| zIndex: item.zIndex, | |||
| top: item.y + 'px', | |||
| left: item.x + 'px' | |||
| }" | |||
| > | |||
| <div>{{ item.text }}</div> | |||
| <img :src="item.url" alt="" /> | |||
| <!-- 边框 --> | |||
| <div :class="domIndex == index ? 'active' : ''"></div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| // 组件 | |||
| import Vue from 'vue' | |||
| import { Toast } from 'vant' | |||
| import { mapState, mapActions } from 'vuex' | |||
| // 工具 | |||
| import { scrollToID } from '../../utils' | |||
| Vue.use(Toast) | |||
| export default { | |||
| data() { | |||
| return { | |||
| inPage: false, | |||
| dragging: false, | |||
| startX: 0, | |||
| startY: 0, // 鼠标位置x y | |||
| windowWidth: 0, | |||
| windowHeight: 0, | |||
| scale: 1, | |||
| domIndex: -1, //当前点击的图片 | |||
| materialList: [ | |||
| { | |||
| text: '小div1', | |||
| url: 'img/BG@2x.b0cf224b.png', | |||
| x: 300, // 相对左上角XY坐标 | |||
| y: 300, | |||
| scale: 1, //缩放 | |||
| zIndex: 3 //层级 | |||
| }, | |||
| { | |||
| text: '小div2', | |||
| url: 'img/BG@2x.b0cf224b.png', | |||
| x: 100, | |||
| y: 0, | |||
| scale: 1, | |||
| zIndex: 13 | |||
| }, | |||
| { | |||
| text: '小div3', | |||
| url: '@/assets/icon/icon-trash', | |||
| x: 0, | |||
| y: 100, | |||
| scale: 1, | |||
| zIndex: 11 | |||
| }, | |||
| { | |||
| text: '小div4', | |||
| url: '../../assets/icon/icon-trash', | |||
| x: 100, | |||
| y: 100, | |||
| scale: 1, | |||
| zIndex: 10 | |||
| }, | |||
| { | |||
| text: '小div5', | |||
| url: '@/assets/icon/icon-trash', | |||
| x: 200, | |||
| y: 200, | |||
| scale: 1, | |||
| zIndex: 4 | |||
| } | |||
| ] | |||
| } | |||
| }, | |||
| computed: { | |||
| ...mapState({ | |||
| characters: (state) => state.publicObj.characters | |||
| }) | |||
| // imageStyles() { | |||
| // return this.images.map((image, index) => { | |||
| // return { | |||
| // zIndex: index, | |||
| // width: `${image.width}px`, | |||
| // height: `${image.height}px`, | |||
| // position: 'absolute', | |||
| // top: `${image.y}px`, | |||
| // left: `${image.x}px`, | |||
| // }; | |||
| // }); | |||
| // }, | |||
| }, | |||
| methods: { | |||
| ...mapActions(['setCharacters']), | |||
| // 鼠标按下事件 | |||
| onMouseDown(index) { | |||
| this.dragging = true | |||
| this.domIndex = index | |||
| // 记录点击瞬间的鼠标坐标 | |||
| this.startX = event.touches[0].clientX | |||
| this.startY = event.touches[0].clientY | |||
| }, | |||
| // 鼠标抬起 | |||
| onMouseUp(index) { | |||
| this.dragging = false | |||
| // this.domIndex = -1 | |||
| }, | |||
| // 鼠标在父盒子移动时,判断是否按下,然后再走逻辑 | |||
| onMouseMove(index) { | |||
| // 禁止默认事件--下拉 | |||
| event.preventDefault() | |||
| if (!this.dragging) return | |||
| if (this.domIndex != index) return | |||
| console.log(event.touches[0]) | |||
| const deltaX = event.touches[0].clientX - this.startX | |||
| const deltaY = event.touches[0].clientY - this.startY | |||
| console.log(deltaX) | |||
| this.materialList[index].x += deltaX | |||
| this.materialList[index].y += deltaY | |||
| this.startX = event.touches[0].clientX | |||
| this.startY = event.touches[0].clientY | |||
| // 得到父子盒子信息 | |||
| const fatherRect = this.$refs.fatherBox.getBoundingClientRect() | |||
| const sonRect = document | |||
| .getElementById(`item${index}`) | |||
| .getBoundingClientRect() | |||
| // 限制X轴 | |||
| if (this.materialList[index].x < 0) { | |||
| this.materialList[index].x = 0 | |||
| } | |||
| if (sonRect.left > fatherRect.width - sonRect.width / 2) { | |||
| this.materialList[index].x = fatherRect.width - sonRect.width | |||
| this.exceed() | |||
| } | |||
| // 限制Y轴 | |||
| if (this.materialList[index].y < 0) { | |||
| this.materialList[index].y = 0 | |||
| } | |||
| if (sonRect.top > fatherRect.height - sonRect.height / 2) { | |||
| this.materialList[index].y = fatherRect.height - sonRect.height | |||
| this.exceed() | |||
| } | |||
| }, | |||
| // 控制台 | |||
| controlImg(type) { | |||
| if (this.domIndex == -1) { | |||
| Toast('请选择素材') | |||
| } | |||
| if (type == 1) { | |||
| this.materialList[this.domIndex].scale += 0.1 | |||
| } | |||
| if (type == 2) { | |||
| this.materialList[this.domIndex].scale -= 0.1 | |||
| } | |||
| if (type == 3) { | |||
| this.materialList[this.domIndex].zIndex += 1 | |||
| } | |||
| if (type == 4) { | |||
| this.materialList[this.domIndex].zIndex -= 1 | |||
| } | |||
| }, | |||
| // 素材超出显示范围 | |||
| exceed() { | |||
| Toast('素材超出显示范围') | |||
| }, | |||
| go(url) { | |||
| this.$router.push(url) | |||
| } | |||
| }, | |||
| created() {}, | |||
| mounted() { | |||
| this.inPage = true | |||
| scrollToID('top') | |||
| } | |||
| } | |||
| </script> | |||
| <style lang="scss" scoped> | |||
| * { | |||
| box-sizing: content-box !important; | |||
| } | |||
| .control { | |||
| position: absolute; | |||
| top: 0; | |||
| left: 50%; | |||
| transform: translateX(-50%); | |||
| display: flex; | |||
| justify-content: space-around; | |||
| width: 200px; | |||
| height: 30px; | |||
| text-align: center; | |||
| line-height: 30px; | |||
| background-color: #fff; | |||
| z-index: 999999; | |||
| } | |||
| .page { | |||
| transform: translateX(30%); | |||
| opacity: 0; | |||
| transition: all 0.5s; // global-transition | |||
| &.active { | |||
| opacity: 1; | |||
| transform: translateX(0); | |||
| } | |||
| height: 100%; | |||
| width: 100%; | |||
| position: fixed; | |||
| top: 0; | |||
| left: 0; | |||
| } | |||
| .content { | |||
| position: relative; | |||
| width: 100vw; | |||
| height: 100vh; | |||
| background-color: green; | |||
| overflow: hidden; | |||
| .active { | |||
| position: absolute; | |||
| top: -10px; | |||
| left: -10px; | |||
| width: 100%; | |||
| height: 100%; | |||
| border: 10px solid rgba(0, 0, 0, 0.5); | |||
| } | |||
| .material { | |||
| position: absolute; | |||
| top: 0; | |||
| left: 0; | |||
| width: 150px; | |||
| height: 140px; | |||
| background-color: red; | |||
| img { | |||
| width: 30px; | |||
| height: 30px; | |||
| // background-color: red; | |||
| } | |||
| } | |||
| } | |||
| </style> | |||