forked from natuka/web.puabadge.com
新增徽章形状,裁剪优化
This commit is contained in:
1 parent
53add7b47a
commit
e330ba2ce8
9 files changed
+435
-47
No files matched your search
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
VITE_APP_PREVIEW=true
|
VITE_APP_PREVIEW=true
|
||||||
# VITE_APP_API_BASE_URL=http://172.16.0.47:8166/web/
|
# VITE_APP_API_BASE_URL=http://172.16.0.47:8166/web/
|
||||||
# VITE_APP_API_BASE_URL=https://wechat-test.api.puabadge.com/web/
|
VITE_APP_API_BASE_URL=https://wechat-test.api.puabadge.com/web/
|
||||||
VITE_APP_API_BASE_URL=https://wechat.api.puabadge.com/web/
|
# VITE_APP_API_BASE_URL=https://wechat.api.puabadge.com/web/
|
||||||
# VITE_APP_API_WX_URL=https://wechat.api.puabadge.com/web/
|
# VITE_APP_API_WX_URL=https://wechat.api.puabadge.com/web/
|
||||||
# http://web.suwa3d.dev:28499/
|
# http://web.suwa3d.dev:28499/
|
||||||
VITE_HTTP_MOCK=true
|
VITE_HTTP_MOCK=true
|
||||||
|
|||||||
Vendored
-1
@@ -24,7 +24,6 @@ declare module '@vue/runtime-core' {
|
|||||||
VanDivider: typeof import('vant/es')['Divider']
|
VanDivider: typeof import('vant/es')['Divider']
|
||||||
VanField: typeof import('vant/es')['Field']
|
VanField: typeof import('vant/es')['Field']
|
||||||
VanIcon: typeof import('vant/es')['Icon']
|
VanIcon: typeof import('vant/es')['Icon']
|
||||||
VanImage: typeof import('vant/es')['Image']
|
|
||||||
VanList: typeof import('vant/es')['List']
|
VanList: typeof import('vant/es')['List']
|
||||||
VanPullRefresh: typeof import('vant/es')['PullRefresh']
|
VanPullRefresh: typeof import('vant/es')['PullRefresh']
|
||||||
VanStepper: typeof import('vant/es')['Stepper']
|
VanStepper: typeof import('vant/es')['Stepper']
|
||||||
|
|||||||
@@ -127,3 +127,27 @@ export const faceCheck = (params: any) => {
|
|||||||
params,
|
params,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取形状列表
|
||||||
|
export const getShapeList = (params: any) => {
|
||||||
|
return request('products/shapeList', {
|
||||||
|
method: 'GET',
|
||||||
|
params,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取形状类别列表
|
||||||
|
export const getTypesList = (params: any) => {
|
||||||
|
return request('products/typesList', {
|
||||||
|
method: 'GET',
|
||||||
|
params,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上传合成图
|
||||||
|
export const composite = (data: any) => {
|
||||||
|
return request('uploads/composite', {
|
||||||
|
method: 'POST',
|
||||||
|
data,
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: "chinese";
|
||||||
|
src: url('jingnan-Nunito.ttf');
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -7,6 +7,7 @@ import router from './router'
|
|||||||
|
|
||||||
import './app.less'
|
import './app.less'
|
||||||
import './assets/icon/iconfont.css'
|
import './assets/icon/iconfont.css'
|
||||||
|
import "./assets/font/font.css";
|
||||||
|
|
||||||
// import I18n from "@/lang/i18n"
|
// import I18n from "@/lang/i18n"
|
||||||
import I18NextVue from 'i18next-vue'
|
import I18NextVue from 'i18next-vue'
|
||||||
|
|||||||
+20
-10
@@ -12,10 +12,15 @@ const show = ref(false)
|
|||||||
const imgShow = ref(false)
|
const imgShow = ref(false)
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const option = ref({
|
const option = ref({
|
||||||
|
canScale: true,
|
||||||
autoCropWidth: 1024,
|
autoCropWidth: 1024,
|
||||||
autoCropHeight: 1024,
|
autoCropHeight: 1024,
|
||||||
ceilbutton: false,
|
ceilbutton: false,
|
||||||
infoTrue: true,
|
infoTrue: true,
|
||||||
|
fixed: false,
|
||||||
|
fixedNumber: [3, 4],
|
||||||
|
fixedBox: false,
|
||||||
|
canMoveBox: true,
|
||||||
enlarge: 6
|
enlarge: 6
|
||||||
})
|
})
|
||||||
const options = ref({
|
const options = ref({
|
||||||
@@ -135,20 +140,24 @@ function getbase64Data(data) {
|
|||||||
img.onload = () => {
|
img.onload = () => {
|
||||||
imageWidth.value = img.naturalWidth;
|
imageWidth.value = img.naturalWidth;
|
||||||
imageHeight.value = img.naturalHeight;
|
imageHeight.value = img.naturalHeight;
|
||||||
if (imageWidth.value < 800 || imageHeight.value < 800) {
|
if (imageWidth.value < 500 || imageHeight.value < 500) {
|
||||||
showToast('请上传尺寸大于800*800像素的照片')
|
showToast('请上传尺寸大于500*500像素的照片')
|
||||||
return
|
imgurl.value = null
|
||||||
}
|
picture.value = null
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
const blob = base64ToBlob(data);
|
const blob = base64ToBlob(data);
|
||||||
if (blob.size > 1024 * 1024 * 10) {
|
if (blob.size > 1024 * 1024 * 10) {
|
||||||
showToast('照片大小不能超过10M')
|
showToast('照片大小不能超过10M')
|
||||||
return
|
imgurl.value = null
|
||||||
|
picture.value = null
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
imgurl.value = blob;
|
imgurl.value = blob;
|
||||||
if (prodId.value == 7) {
|
if (prodId.value == 7) {
|
||||||
getUploadUrl()
|
getUploadUrl()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function base64ToBlob(base64) {
|
function base64ToBlob(base64) {
|
||||||
@@ -172,8 +181,8 @@ function imgorigoinf(data) {
|
|||||||
img.onload = () => {
|
img.onload = () => {
|
||||||
imageWidth.value = img.naturalWidth;
|
imageWidth.value = img.naturalWidth;
|
||||||
imageHeight.value = img.naturalHeight;
|
imageHeight.value = img.naturalHeight;
|
||||||
if (imageWidth.value < 800 || imageHeight.value < 800) {
|
if (imageWidth.value < 500 || imageHeight.value < 500) {
|
||||||
showToast('请上传尺寸大于800*800像素的照片')
|
showToast('请上传尺寸大于500*500像素的照片')
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const btn = document.querySelector('.btn')
|
const btn = document.querySelector('.btn')
|
||||||
if (btn) {
|
if (btn) {
|
||||||
@@ -795,7 +804,7 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
.step-title {
|
.step-title {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
color: #808080;;
|
color: #808080;
|
||||||
}
|
}
|
||||||
.step-desc {
|
.step-desc {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
@@ -808,6 +817,7 @@ onMounted(() => {
|
|||||||
width: 80vw;
|
width: 80vw;
|
||||||
height: 80vw;
|
height: 80vw;
|
||||||
margin: 16px auto 0 auto;
|
margin: 16px auto 0 auto;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
.photo-upload-box {
|
.photo-upload-box {
|
||||||
margin: 16px auto 0 auto;
|
margin: 16px auto 0 auto;
|
||||||
@@ -833,8 +843,8 @@ onMounted(() => {
|
|||||||
right: 0;
|
right: 0;
|
||||||
}
|
}
|
||||||
.photo-upload-img {
|
.photo-upload-img {
|
||||||
width: 80vw;
|
max-width: 80vw;
|
||||||
height: 80vw;
|
max-height: 80vw;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
}
|
}
|
||||||
.photo-upload-header {
|
.photo-upload-header {
|
||||||
|
|||||||
@@ -5,8 +5,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="order-status">
|
<div class="order-status">
|
||||||
<div class="avatar-wrapper">
|
<div class="avatar-wrapper">
|
||||||
<img class="avatar-img" :src="order.path" :alt="order.kind_name" />
|
<!-- <img v-if="shapeImage" class="avatar-back-img" :src="shapeImage" alt=""> -->
|
||||||
<div class="progress-image-item-shadow"></div>
|
<div class="avatar-front-box">
|
||||||
|
<img class="avatar-font-img" :src="imageUrl" :alt="order.kind_name" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="status-info">
|
<div class="status-info">
|
||||||
@@ -29,6 +31,10 @@
|
|||||||
<span class="product-label">尺寸</span>
|
<span class="product-label">尺寸</span>
|
||||||
<span class="product-value">{{order.model_size}}</span>
|
<span class="product-value">{{order.model_size}}</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="product-row" v-if="shape_name">
|
||||||
|
<span class="product-label">形状</span>
|
||||||
|
<span class="product-value">{{shape_name}}</span>
|
||||||
|
</div>
|
||||||
<div class="product-row">
|
<div class="product-row">
|
||||||
<span class="product-label">购买数量</span>
|
<span class="product-label">购买数量</span>
|
||||||
<span class="product-value">{{order.count}}</span>
|
<span class="product-value">{{order.count}}</span>
|
||||||
@@ -80,13 +86,42 @@ onMounted(() => {
|
|||||||
id.value = route.query.id
|
id.value = route.query.id
|
||||||
getOrderDetail()
|
getOrderDetail()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const shapeImage = ref('')
|
||||||
|
const imageUrl = ref('')
|
||||||
|
const getStyle = ref('')
|
||||||
|
const shape_name = ref('')
|
||||||
|
|
||||||
function getOrderDetail() {
|
function getOrderDetail() {
|
||||||
badgeApi.getOrderDetail({
|
badgeApi.getOrderDetail({
|
||||||
id: id.value,
|
id: id.value,
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
order.value = res
|
order.value = res
|
||||||
|
imageUrl.value = res.path
|
||||||
|
shapeImage.value = res.shape_details.frame_path
|
||||||
|
shape_name.value = res.shape_details.name
|
||||||
|
// if (res.shape_details) {
|
||||||
|
// ImageShow(res.shape_details)
|
||||||
|
// }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ImageShow = (item: any) => {
|
||||||
|
const scale = 0.6
|
||||||
|
const img = new Image()
|
||||||
|
img.src = item.frame_path
|
||||||
|
img.onload = () => {
|
||||||
|
console.log('img', img)
|
||||||
|
const ratioWidth = 320 / img.width;
|
||||||
|
const ratioHeight = 320 / img.height;
|
||||||
|
const x = item.axisx * ratioWidth * scale;
|
||||||
|
const y = item.axisy * ratioHeight * scale;
|
||||||
|
const path_width = item.width * ratioWidth * scale;
|
||||||
|
const path_height = item.height * ratioHeight * scale;
|
||||||
|
getStyle.value = `left: ${x}px;top: ${y}px;width: ${path_width}px;height: ${path_height}px;transform: rotate3D(1, 1, 0, 0deg)`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
function goBack() {
|
function goBack() {
|
||||||
router.back()
|
router.back()
|
||||||
@@ -121,23 +156,38 @@ function getStatus(status: number) {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.order-status {
|
.order-status {
|
||||||
|
margin: 0 auto;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vw;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-top: 32px;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
.avatar-wrapper {
|
.avatar-wrapper {
|
||||||
width: 85vw;
|
|
||||||
height: 85vw;
|
|
||||||
border-radius: 50%;
|
|
||||||
margin-bottom: 24px;
|
|
||||||
background: #fff;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
|
width: 320px;
|
||||||
|
height: 320px;
|
||||||
|
}
|
||||||
|
.avatar-back-img {
|
||||||
|
position: absolute;
|
||||||
|
width: 320px;
|
||||||
|
height: 320px;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
.avatar-front-box {
|
||||||
|
width: 320px;
|
||||||
|
height: 320px;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
.avatar-font-img {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-image-item-shadow {
|
.progress-image-item-shadow {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
|||||||
+321
-21
@@ -27,18 +27,16 @@
|
|||||||
<div class="progress-text">{{progressText}} {{progress}}%</div>
|
<div class="progress-text">{{progressText}} {{progress}}%</div>
|
||||||
<div class="progress-desc">总计大约需要90秒,请耐心等待...</div>
|
<div class="progress-desc">总计大约需要90秒,请耐心等待...</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="progress-section">
|
<div v-else class="progress-section-picture" style="width: 320px;height: 320px;">
|
||||||
<!-- <van-swipe v-model="currentIndex" class="progress-section-img" :autoplay="3000" :show-indicators="false">
|
<div class="progress-section-img" style="width: 320px;height: 320px;">
|
||||||
<van-swipe-item v-for="item in imageList" :key="item.id">
|
<img v-if="shapeImage" class="box1-back-image" :src="shapeImage" style="width: 320px;height: 320px;" alt="">
|
||||||
<img class="progress-section-img" :src="item.origin_url" alt="">
|
<div class="box1-front-box" :style="getStyle">
|
||||||
<div class="progress-image-item-shadow"></div>
|
<img class="box1-front-image" :class="{ 'box1-round-image': shapeId == 1 && shapeImage == '' }" :src="imageUrl" alt="">
|
||||||
</van-swipe-item>
|
<div class="box1-round-shadow" v-if="shapeId == 1 && shapeImage == ''" style="width: 320px;height: 320px;"></div>
|
||||||
</van-swipe> -->
|
|
||||||
<div class="progress-section-img">
|
|
||||||
<img class="progress-section-img-item" :src="imageUrl" alt="">
|
|
||||||
<div class="progress-image-item-shadow"></div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="image-list-box">
|
<div class="shape-text" :style="shapeTextStyle" v-if="shapeText">{{shapeText}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="image-list-box" v-if="imageList.length > 1">
|
||||||
<div class="image-list-item" v-for="item in imageList" :key="item.key">
|
<div class="image-list-item" v-for="item in imageList" :key="item.key">
|
||||||
<img v-if="item.status == 1" class="image-list-item-img" :class="{ imgActive: item.key == imgKey }" :src="item.origin_url" alt="" @click="changeImage(item)">
|
<img v-if="item.status == 1" class="image-list-item-img" :class="{ imgActive: item.key == imgKey }" :src="item.origin_url" alt="" @click="changeImage(item)">
|
||||||
<div v-else-if="item.status == 0" class="image-list-item-loading">
|
<div v-else-if="item.status == 0" class="image-list-item-loading">
|
||||||
@@ -64,6 +62,23 @@
|
|||||||
<div class="info-content">材料</div>
|
<div class="info-content">材料</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="shape-body">
|
||||||
|
<div class="shape-type">
|
||||||
|
<div class="shape-type-item" :class="{ 'shape-active': item.id == typeId }" v-for="item in typesList" :key="item.id" @click="typeChange(item.id)">{{item.name}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="shape-box">
|
||||||
|
<div class="shape-item" v-for="item in shapeList" :key="item.id" @click="shapeChange(item)">
|
||||||
|
<div class="shape-item-list">
|
||||||
|
<img class="shape-item-image" :src="item.cover_path || imageUrl"/>
|
||||||
|
<van-icon v-if="item.id == shapeId" class="shape-icon" color="#15CF5F" name="checked" size="18px" />
|
||||||
|
</div>
|
||||||
|
<div class="shape-item-text">{{item.name}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="shape-box-input" v-if="custom_switch == 1">
|
||||||
|
<input class="shape-box-input-text" type="text" placeholder="请输入文字" v-model="shapeText" @change="changeShapeText" @input="changeShapeText" @onBlur="changeShapeText" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<!-- <div class="info-desc">
|
<!-- <div class="info-desc">
|
||||||
下单后预计需要7天完成生产发货。<br>
|
下单后预计需要7天完成生产发货。<br>
|
||||||
实物3D打印色彩与图片有合理色差,如对产品有疑问,可以联系客服咨询。
|
实物3D打印色彩与图片有合理色差,如对产品有疑问,可以联系客服咨询。
|
||||||
@@ -141,7 +156,8 @@ function compare() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function sureReload() {
|
function sureReload() {
|
||||||
if (payAmount.value <= 0) {
|
console.log('orderStat', orderStat.value)
|
||||||
|
if (orderStat.value.remain_count <= 0) {
|
||||||
showToast('当前次数已用完,请重新购买')
|
showToast('当前次数已用完,请重新购买')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -255,6 +271,7 @@ const confirm = () => {
|
|||||||
showToast('请先选择下单数量')
|
showToast('请先选择下单数量')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
getPosition()
|
||||||
loading.value = true
|
loading.value = true
|
||||||
showConfirmDialog({
|
showConfirmDialog({
|
||||||
title: '确认下单',
|
title: '确认下单',
|
||||||
@@ -267,7 +284,9 @@ const confirm = () => {
|
|||||||
key: imgKey.value,
|
key: imgKey.value,
|
||||||
pay_amount: payAmount.value,
|
pay_amount: payAmount.value,
|
||||||
products: sizeList.value,
|
products: sizeList.value,
|
||||||
prod_id: prodId.value
|
prod_id: prodId.value,
|
||||||
|
shape_id: shapeId.value,
|
||||||
|
custom_text: shapeText.value
|
||||||
}
|
}
|
||||||
badgeApi.creatOrder(parms).then((res: any) => {
|
badgeApi.creatOrder(parms).then((res: any) => {
|
||||||
console.log('creatOrder', res)
|
console.log('creatOrder', res)
|
||||||
@@ -297,6 +316,21 @@ const confirm = () => {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getPosition = () => {
|
||||||
|
badgeApi.composite({
|
||||||
|
pid: pid.value,
|
||||||
|
num: imgKey.value,
|
||||||
|
custom_text: shapeText.value,
|
||||||
|
shape_id: shapeId.value,
|
||||||
|
}).then((res: any) => {
|
||||||
|
console.log('getPosition', res)
|
||||||
|
}).catch((err) => {
|
||||||
|
console.log('getPosition', err)
|
||||||
|
}).finally((err) => {
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const imageUrl = ref('')
|
const imageUrl = ref('')
|
||||||
const group = ref(1);
|
const group = ref(1);
|
||||||
// 轮询获取图片
|
// 轮询获取图片
|
||||||
@@ -426,15 +460,165 @@ const getImageList = () => {
|
|||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const typeId = ref(1)
|
||||||
|
const typesList = ref([])
|
||||||
|
const getTypesList = () => {
|
||||||
|
badgeApi.getTypesList({}).then((res: any) => {
|
||||||
|
console.log('getTypesList', res)
|
||||||
|
typesList.value = res.list
|
||||||
|
typeId.value = res.list[0].id
|
||||||
|
getShapeList()
|
||||||
|
}).catch((err) => {
|
||||||
|
console.log('getTypesList', err)
|
||||||
|
}).finally((err) => {
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const shapeId = ref(1)
|
||||||
|
const shapeImage = ref('')
|
||||||
|
|
||||||
|
const shapeList = ref([])
|
||||||
|
const custom_switch = ref(0)
|
||||||
|
const limitCount = ref(10)
|
||||||
|
const getShapeList = () => {
|
||||||
|
badgeApi.getShapeList({
|
||||||
|
type_id: typeId.value,
|
||||||
|
prod_id: prodId.value
|
||||||
|
}).then((res: any) => {
|
||||||
|
console.log('getShapeList', res)
|
||||||
|
shapeList.value = res.list
|
||||||
|
shapeId.value = res.list[0].id
|
||||||
|
shapeImage.value = res.list[0]?.frame_path
|
||||||
|
custom_switch.value = res.list[0]?.custom_switch
|
||||||
|
limitCount.value = res.list[0]?.text_limit_max
|
||||||
|
ImageShow(res.list[0])
|
||||||
|
if (custom_switch.value == 1) {
|
||||||
|
textShow(res.list[0])
|
||||||
|
}
|
||||||
|
}).catch((err) => {
|
||||||
|
console.log('getShapeList', err)
|
||||||
|
}).finally((err) => {
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const getStyle = ref('')
|
||||||
|
const ImageShow = (item: any) => {
|
||||||
|
const scale = 0.6;
|
||||||
|
const img = new Image()
|
||||||
|
img.src = item.frame_path
|
||||||
|
img.onload = () => {
|
||||||
|
console.log('img', img)
|
||||||
|
const ratioWidth = 320 / img.width;
|
||||||
|
const ratioHeight = 320 / img.height;
|
||||||
|
const x = item.axisx * ratioWidth * scale;
|
||||||
|
const y = item.axisy * ratioHeight * scale;
|
||||||
|
const path_width = item.width * ratioWidth * scale;
|
||||||
|
const path_height = item.height * ratioHeight * scale;
|
||||||
|
getStyle.value = `left: ${x}px;top: ${y}px;width: ${path_width}px;height: ${path_height}px;`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const shapeTextStyle = ref('')
|
||||||
|
const textShow = (item: any) => {
|
||||||
|
const scale = 0.6;
|
||||||
|
const img = new Image()
|
||||||
|
img.src = item.frame_path
|
||||||
|
img.onload = () => {
|
||||||
|
console.log('img', img)
|
||||||
|
const ratioWidth = 320 / img.width;
|
||||||
|
const ratioHeight = 320 / img.height;
|
||||||
|
const x = item.text_axisx * ratioWidth * scale;
|
||||||
|
const y = item.text_axisy * ratioHeight * scale;
|
||||||
|
const path_width = item.text_width * ratioWidth * scale;
|
||||||
|
const path_height = item.text_height * ratioHeight * scale;
|
||||||
|
const text_size = item.font_size * Math.min(ratioWidth * scale, ratioHeight * scale);
|
||||||
|
shapeTextStyle.value = `left: ${x}px;top: ${y}px;width: ${path_width}px;height: ${path_height}px;text-align: center;line-height: ${path_height}px;font-size: ${text_size}px;color: ${item.font_color};font-weight: ${item.font_weight};`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const shapeText = ref('')
|
||||||
|
const changeShapeText = (e: any) => {
|
||||||
|
console.log('changeShapeText', e.target.value)
|
||||||
|
handleInput(e.target.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleInput = (value: string) => {
|
||||||
|
let byteLength = calculateByteLength(value);
|
||||||
|
// 如果超过最大字节数,禁止继续输入
|
||||||
|
console.log('byteLength', byteLength, limitCount.value)
|
||||||
|
if (byteLength > limitCount.value) {
|
||||||
|
// 超出字节数,直接截断到允许的最大字节数
|
||||||
|
let validValue = '';
|
||||||
|
let currentBytes = 0;
|
||||||
|
for (let i = 0; i < value.length; i++) {
|
||||||
|
const char = value.charAt(i);
|
||||||
|
const charBytes = char.charCodeAt(0) > 255 ? 2 : 1;
|
||||||
|
if (currentBytes + charBytes <= limitCount.value) {
|
||||||
|
validValue += char;
|
||||||
|
currentBytes += charBytes;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
shapeText.value = validValue;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 未超过最大字节数,正常更新
|
||||||
|
shapeText.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
const calculateByteLength = (str: string) => {
|
||||||
|
let len = 0;
|
||||||
|
for (let i = 0; i < str.length; i++) {
|
||||||
|
const code = str.charCodeAt(i);
|
||||||
|
// 中文字符和特殊符号占2字节,英文占1字节
|
||||||
|
len += code > 255 ? 2 : 1;
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
const typeChange = (id: number) => {
|
||||||
|
console.log('typeChange', id)
|
||||||
|
typeId.value = id;
|
||||||
|
shapeList.value = [];
|
||||||
|
shapeImage.value = '';
|
||||||
|
getStyle.value = '';
|
||||||
|
getShapeList()
|
||||||
|
}
|
||||||
|
|
||||||
|
const shapeChange = (item: any) => {
|
||||||
|
shapeText.value = '';
|
||||||
|
shapeId.value = item.id
|
||||||
|
shapeImage.value = item.frame_path
|
||||||
|
custom_switch.value = item.custom_switch
|
||||||
|
limitCount.value = item.text_limit_max
|
||||||
|
ImageShow(item)
|
||||||
|
if (custom_switch.value == 1) {
|
||||||
|
textShow(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const trialCode = ref(false)
|
const trialCode = ref(false)
|
||||||
const getTrialCode = () => {
|
const getTrialCode = () => {
|
||||||
const value = localStorage.get('trialCode')
|
const value = localStorage.get('trialCode')
|
||||||
if (value) {
|
if (value) {
|
||||||
trialCode.value = true
|
trialCode.value = true
|
||||||
} else {
|
} else {
|
||||||
|
getOrderStat()
|
||||||
getSizeList()
|
getSizeList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const orderStat = ref({})
|
||||||
|
const getOrderStat = () => {
|
||||||
|
badgeApi.getOrderStat({}).then((res: any) => {
|
||||||
|
console.log('getOrderStat', res)
|
||||||
|
orderStat.value = res
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
function handleBeforeUnload(_event: BeforeUnloadEvent) {
|
function handleBeforeUnload(_event: BeforeUnloadEvent) {
|
||||||
localStorage.remove('code')
|
localStorage.remove('code')
|
||||||
localStorage.remove('trialCode')
|
localStorage.remove('trialCode')
|
||||||
@@ -460,6 +644,7 @@ onMounted(() => {
|
|||||||
// pid.value = 281505;
|
// pid.value = 281505;
|
||||||
// group.value = 1;
|
// group.value = 1;
|
||||||
// prodId.value = 7;
|
// prodId.value = 7;
|
||||||
|
getTypesList()
|
||||||
getImageList()
|
getImageList()
|
||||||
progressList()
|
progressList()
|
||||||
getCompareImage()
|
getCompareImage()
|
||||||
@@ -594,22 +779,54 @@ onUnmounted(() => {
|
|||||||
.progress-section {
|
.progress-section {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
width: 80vw;
|
width: 100vw;
|
||||||
min-height: 80vw;
|
height: 100vw;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.progress-section-picture {
|
||||||
|
width: 320px;
|
||||||
|
height: 320px;
|
||||||
|
position: relative;
|
||||||
|
margin: 0 auto;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
.progress-section-img {
|
.progress-section-img {
|
||||||
width: 80vw;
|
|
||||||
height: 80vw;
|
|
||||||
border-radius: 50%;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
.progress-section-img-item {
|
.box1-back-image {
|
||||||
width: 80vw;
|
position: absolute;
|
||||||
height: 80vw;
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 2;
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
.box1-front-box {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
.box1-front-image {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
.box1-round-shadow {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 320px;
|
||||||
|
height: 320px;
|
||||||
|
border-radius: 50%;
|
||||||
|
box-shadow: 2px 2px 4px #00000042,inset -2px -2px 4px #00000048,inset 2px 2px 4px #ffffffb4;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
.box1-round-image {
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
.progress-bar-bg {
|
.progress-bar-bg {
|
||||||
@@ -904,4 +1121,87 @@ onUnmounted(() => {
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #999;
|
color: #999;
|
||||||
}
|
}
|
||||||
|
.shape-body {
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 0 20px;
|
||||||
|
}
|
||||||
|
.shape-box {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.shape-title {
|
||||||
|
padding-bottom: 12px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.shape-item {
|
||||||
|
position: relative;
|
||||||
|
flex: 0 0 24%;
|
||||||
|
margin-right: calc(4% / 3);
|
||||||
|
margin-bottom: calc(4% / 2);
|
||||||
|
}
|
||||||
|
.shape-item:nth-child(4n){
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
.shape-item:last-child{
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
.shape-item-image {
|
||||||
|
width: 20vw;
|
||||||
|
height: 20vw;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
.shape-icon {
|
||||||
|
position: absolute;
|
||||||
|
right: 6px;
|
||||||
|
bottom: 24px;
|
||||||
|
}
|
||||||
|
.shape-item-text {
|
||||||
|
font-size: 12px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.shape-type {
|
||||||
|
display: -webkit-box;
|
||||||
|
overflow-x: scroll;
|
||||||
|
scrollbar-width: none;
|
||||||
|
-ms-overflow-style: none;
|
||||||
|
padding-bottom: 16px;
|
||||||
|
}
|
||||||
|
.shape-type-item {
|
||||||
|
background: #F0F2F5;
|
||||||
|
font-size: 12px;
|
||||||
|
height: 7vw;
|
||||||
|
padding: 0px 16px;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-right: 8px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.shape-active {
|
||||||
|
background: #15CF5F;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.shape-box-input {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
.shape-box-input-text {
|
||||||
|
width: 100%;
|
||||||
|
height: 40px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
.shape-text {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 2;
|
||||||
|
font-family: chinese;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
Reference in new issue
Block a user