@@ -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> |