Merge branch 'dev_vite' of http://18.167.251.121:10003/aidlab/aida_front into dev_vite
This commit is contained in:
1
src/assets/icons/CFile.svg
Normal file
1
src/assets/icons/CFile.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg focusable="false" class="" data-icon="paper-clip" width="1em" height="1em" fill="#00000073" aria-hidden="true" viewBox="64 64 896 896"><path d="M779.3 196.6c-94.2-94.2-247.6-94.2-341.7 0l-261 260.8c-1.7 1.7-2.6 4-2.6 6.4s.9 4.7 2.6 6.4l36.9 36.9a9 9 0 0012.7 0l261-260.8c32.4-32.4 75.5-50.2 121.3-50.2s88.9 17.8 121.2 50.2c32.4 32.4 50.2 75.5 50.2 121.2 0 45.8-17.8 88.8-50.2 121.2l-266 265.9-43.1 43.1c-40.3 40.3-105.8 40.3-146.1 0-19.5-19.5-30.2-45.4-30.2-73s10.7-53.5 30.2-73l263.9-263.8c6.7-6.6 15.5-10.3 24.9-10.3h.1c9.4 0 18.1 3.7 24.7 10.3 6.7 6.7 10.3 15.5 10.3 24.9 0 9.3-3.7 18.1-10.3 24.7L372.4 653c-1.7 1.7-2.6 4-2.6 6.4s.9 4.7 2.6 6.4l36.9 36.9a9 9 0 0012.7 0l215.6-215.6c19.9-19.9 30.8-46.3 30.8-74.4s-11-54.6-30.8-74.4c-41.1-41.1-107.9-41-149 0L463 364 224.8 602.1A172.22 172.22 0 00174 724.8c0 46.3 18.1 89.8 50.8 122.5 33.9 33.8 78.3 50.7 122.7 50.7 44.4 0 88.8-16.9 122.6-50.7l309.2-309C824.8 492.7 850 432 850 367.5c.1-64.6-25.1-125.3-70.7-170.9z"></path></svg>
|
||||||
|
After Width: | Height: | Size: 985 B |
BIN
src/assets/images/award/upload_video_icon.png
Normal file
BIN
src/assets/images/award/upload_video_icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.7 KiB |
@@ -89,8 +89,8 @@
|
|||||||
<img crossOrigin="anonymous" :src="item?.path" :style="{transform:`rotateZ(${item.pattern?.transform?.rotateZ}deg)`}" class="designOpenrtion_imgItme" draggable="false">
|
<img crossOrigin="anonymous" :src="item?.path" :style="{transform:`rotateZ(${item.pattern?.transform?.rotateZ}deg)`}" class="designOpenrtion_imgItme" draggable="false">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<img :src="selectDetail.path" alt="" class="designOpenrtion_sketch" ref="sketchImg">
|
<!-- <img :src="selectDetail.path" alt="" class="designOpenrtion_sketch" ref="sketchImg" @load="()=>isSketchLoad = true"> -->
|
||||||
<!-- <img :src="stateOverallSingle == 'single'?(selectDetail.undividedLayer||selectDetail.path):(selectDetail.undividedLayerColor || selectDetail.path)" alt="" class="designOpenrtion_sketch" ref="sketchImg" @load="()=>isSketchLoad = true"> -->
|
<img :src="(selectDetail.path)" alt="" class="designOpenrtion_sketch" ref="sketchImg" @load="()=>isSketchLoad = true">
|
||||||
<img :src="selectDetail.sketchMask" alt="" class="designOpenrtion_sketchMask" ref="sketchMask">
|
<img :src="selectDetail.sketchMask" alt="" class="designOpenrtion_sketchMask" ref="sketchMask">
|
||||||
<div class="designOpenrtion_btn" v-if="stateOverallSingle == 'single'" >
|
<div class="designOpenrtion_btn" v-if="stateOverallSingle == 'single'" >
|
||||||
<ul v-for="item,index in printStyleList[type][stateOverallSingle]" :key="item" :class="{active:item?.pattern.designOpenrtionBtn?item?.pattern.designOpenrtionBtn:false}" class="designOpenrtion_Mousingle" :style="item?.pattern.style" @mousedown.stop="itemMoveMousedown(index,getMousePosition($event,false))" @touchstart.passive="itemMoveMousedown(index,getMousePosition($event,true))">
|
<ul v-for="item,index in printStyleList[type][stateOverallSingle]" :key="item" :class="{active:item?.pattern.designOpenrtionBtn?item?.pattern.designOpenrtionBtn:false}" class="designOpenrtion_Mousingle" :style="item?.pattern.style" @mousedown.stop="itemMoveMousedown(index,getMousePosition($event,false))" @touchstart.passive="itemMoveMousedown(index,getMousePosition($event,true))">
|
||||||
@@ -160,7 +160,6 @@ export default defineComponent({
|
|||||||
selectDetail:computed(()=>store.state.DesignDetail.selectDetail),
|
selectDetail:computed(()=>store.state.DesignDetail.selectDetail),
|
||||||
currentDetailType:computed(()=>store.state.DesignDetail.currentDetailType),
|
currentDetailType:computed(()=>store.state.DesignDetail.currentDetailType),
|
||||||
currentPrintElement:computed(()=>store.state.DesignDetail.currentPrintElement),
|
currentPrintElement:computed(()=>store.state.DesignDetail.currentPrintElement),
|
||||||
systemDesignerPercentage:0,
|
|
||||||
printStyleList:{
|
printStyleList:{
|
||||||
print:{
|
print:{
|
||||||
single:[],
|
single:[],
|
||||||
@@ -224,6 +223,7 @@ export default defineComponent({
|
|||||||
img.onload = ()=>{
|
img.onload = ()=>{
|
||||||
let imgScale = img.width / img.height
|
let imgScale = img.width / img.height
|
||||||
let zoom = 2
|
let zoom = 2
|
||||||
|
console.log(editPrintElementData.sketchWH)
|
||||||
let width = editPrintElementData.sketchWH.width / zoom
|
let width = editPrintElementData.sketchWH.width / zoom
|
||||||
let height = width / editPrintElementData.sketchWH.height
|
let height = width / editPrintElementData.sketchWH.height
|
||||||
|
|
||||||
@@ -233,30 +233,43 @@ export default defineComponent({
|
|||||||
let sketchH = editPrintElementData.sketchWH.height * editPrintElementData.sketchWH.scale[1]
|
let sketchH = editPrintElementData.sketchWH.height * editPrintElementData.sketchWH.scale[1]
|
||||||
let x = sketchW / 2 - (sketchW * (width / editPrintElementData.sketchWH.width)/2)
|
let x = sketchW / 2 - (sketchW * (width / editPrintElementData.sketchWH.width)/2)
|
||||||
let y = sketchH / 2 -(sketchH * height/2)
|
let y = sketchH / 2 -(sketchH * height/2)
|
||||||
if(!editPrintElementData.stateOverallSingle == 'single'){
|
if(editPrintElementData.stateOverallSingle !== 'single'){
|
||||||
x = sketchW / 2
|
x = sketchW / 2
|
||||||
y = sketchH / 2
|
y = sketchH / 2
|
||||||
}
|
}
|
||||||
let location = [x,y]
|
let location = [x,y]
|
||||||
resolve({scale,location})
|
resolve({scale,location})
|
||||||
}
|
}
|
||||||
img.src = item.url
|
img.src = item.url || item.path
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
const addPrintELement = async (data:any)=>{
|
const addPrintELement = async (data:any)=>{
|
||||||
if(!editPrintElementData.isSketchLoad)return
|
if(!editPrintElementData.isSketchLoad)return
|
||||||
let {scale,location} = await setScaleLocation(data)
|
let {scale,location} = await setScaleLocation(data)
|
||||||
let allElementPrint = [
|
let printIndex = 1
|
||||||
...(editPrintElementData.selectDetail.printObject.prints || []),
|
let allElementPrint = []
|
||||||
...(editPrintElementData.selectDetail.trims.prints || []),
|
if(props.type == 'print'){
|
||||||
]
|
allElementPrint = [
|
||||||
let printIndex = Math.max(...allElementPrint.map(item => item.priority)) + 1
|
...(editPrintElementData.printStyleList.print.single || []),
|
||||||
|
...(editPrintElementData.printStyleList.print.overall || []),
|
||||||
|
...(editPrintElementData.selectDetail.trims.prints || []),
|
||||||
|
]
|
||||||
|
}else{
|
||||||
|
allElementPrint = [
|
||||||
|
...(editPrintElementData.printStyleList.element.single || []),
|
||||||
|
...(editPrintElementData.selectDetail.printObject.prints || []),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
if(allElementPrint.length >= 1){
|
||||||
|
printIndex = Math.max(...allElementPrint.map(item => Number(item.priority))) + 1
|
||||||
|
}
|
||||||
let item = {
|
let item = {
|
||||||
angle:0,
|
angle:0,
|
||||||
designType:data.designType,
|
designType:data.designType,
|
||||||
ifSingle:editPrintElementData.stateOverallSingle == 'single',
|
ifSingle:editPrintElementData.stateOverallSingle == 'single',
|
||||||
level2Type:data.level2Type,
|
level2Type:data.level2Type,
|
||||||
location:editPrintElementData.stateOverallSingle == 'single'?location:[0,0],
|
location:location,
|
||||||
|
// location:editPrintElementData.stateOverallSingle == 'single'?location:[0,0],
|
||||||
minIOPath:data.minIOPath || data.originalUrl,
|
minIOPath:data.minIOPath || data.originalUrl,
|
||||||
path:data.url,
|
path:data.url,
|
||||||
priority:printIndex,
|
priority:printIndex,
|
||||||
@@ -344,10 +357,9 @@ export default defineComponent({
|
|||||||
top = item.location[1] / editPrintElementData.sketchWH.scale[1]
|
top = item.location[1] / editPrintElementData.sketchWH.scale[1]
|
||||||
}else{
|
}else{
|
||||||
//overall
|
//overall
|
||||||
editPrintElementData.systemDesignerPercentage = item.scale[0]*1000
|
|
||||||
left = item.location[0] / editPrintElementData.sketchWH.scale[0]
|
left = item.location[0] / editPrintElementData.sketchWH.scale[0]
|
||||||
top = item.location[1] / editPrintElementData.sketchWH.scale[1]
|
top = item.location[1] / editPrintElementData.sketchWH.scale[1]
|
||||||
editPrintElementData.systemDesignerPercentage = item.scale?.[0]?item.scale[0]*100:30
|
item.scale = [1,1]
|
||||||
}
|
}
|
||||||
let pattern = {
|
let pattern = {
|
||||||
centers:{left:0,top:0},
|
centers:{left:0,top:0},
|
||||||
@@ -407,51 +419,49 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const setPosition = ()=>{
|
const setPosition = async ()=>{
|
||||||
nextTick(()=>{
|
await new Promise<void>((resolve, reject) => {
|
||||||
let img = new Image
|
nextTick(()=>{
|
||||||
img.onload = ()=>{
|
let img = new Image
|
||||||
// let sketchScale = editPrintElementData.selectDetail.layersObject[0].scale
|
img.onload = ()=>{
|
||||||
let sketchScale = [1,1]
|
// let sketchScale = editPrintElementData.selectDetail.layersObject[0].scale
|
||||||
let scaleX = img.width * sketchScale[0] / editPrintElementDom.sketchImg.offsetWidth
|
let sketchScale = [1,1]
|
||||||
let scaleY = img.height * sketchScale[1] / editPrintElementDom.sketchImg.offsetHeight
|
let scaleX = img.width * sketchScale[0] / editPrintElementDom.sketchImg.offsetWidth
|
||||||
|
let scaleY = img.height * sketchScale[1] / editPrintElementDom.sketchImg.offsetHeight
|
||||||
|
|
||||||
editPrintElementData.sketchWH = {
|
editPrintElementData.sketchWH = {
|
||||||
width:editPrintElementDom.sketchImg.offsetWidth,
|
width:editPrintElementDom.sketchImg.offsetWidth,
|
||||||
height:editPrintElementDom.sketchImg.offsetHeight,
|
height:editPrintElementDom.sketchImg.offsetHeight,
|
||||||
scale:[scaleX,scaleY],
|
scale:[scaleX,scaleY],
|
||||||
|
}
|
||||||
|
if(!editPrintElementData.selectDetail.printObject.prints)return
|
||||||
|
let state = true
|
||||||
|
// editPrintElementData.stateOverallSingle = 'single'
|
||||||
|
let arr:any = editPrintElementData.selectDetail.printObject.prints
|
||||||
|
if(props.type == 'element'){
|
||||||
|
arr = editPrintElementData.selectDetail.trims.prints
|
||||||
|
}
|
||||||
|
// if(editPrintElementData.selectDetail.newDetail?.[editPrintElementData.currentDetailType]){
|
||||||
|
// arr = editPrintElementData.selectDetail.newDetail[editPrintElementData.currentDetailType]
|
||||||
|
// }
|
||||||
|
if(arr && arr.length > 0){
|
||||||
|
editPrintElementData.printStyleList[props.type].single = []
|
||||||
|
editPrintElementData.printStyleList[props.type].overall = []
|
||||||
|
arr.forEach((item:any)=>{
|
||||||
|
// if(!item.ifSingle){
|
||||||
|
// editPrintElementData.stateOverallSingle = 'overall',
|
||||||
|
// state = false
|
||||||
|
// }
|
||||||
|
getItemPosition(item)
|
||||||
|
})
|
||||||
|
setItemPosition()
|
||||||
|
}
|
||||||
|
resolve('')
|
||||||
}
|
}
|
||||||
if(!editPrintElementData.selectDetail.printObject.prints)return
|
img.src = editPrintElementData.selectDetail.path
|
||||||
let state = true
|
})
|
||||||
// editPrintElementData.stateOverallSingle = 'single'
|
|
||||||
let arr:any = editPrintElementData.selectDetail.printObject.prints
|
|
||||||
if(props.type == 'element'){
|
|
||||||
arr = editPrintElementData.selectDetail.trims.prints
|
|
||||||
}
|
|
||||||
// if(editPrintElementData.selectDetail.newDetail?.[editPrintElementData.currentDetailType]){
|
|
||||||
// arr = editPrintElementData.selectDetail.newDetail[editPrintElementData.currentDetailType]
|
|
||||||
// }
|
|
||||||
if(arr && arr.length > 0){
|
|
||||||
editPrintElementData.printStyleList[props.type].single = []
|
|
||||||
editPrintElementData.printStyleList[props.type].overall = []
|
|
||||||
arr.forEach((item:any)=>{
|
|
||||||
// if(!item.ifSingle){
|
|
||||||
// editPrintElementData.stateOverallSingle = 'overall',
|
|
||||||
// state = false
|
|
||||||
// }
|
|
||||||
getItemPosition(item)
|
|
||||||
})
|
|
||||||
setItemPosition()
|
|
||||||
}
|
|
||||||
// if(props.type == 'print'){
|
|
||||||
// editPrintElementData.overallSingle = state
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
// undividedLayer
|
|
||||||
//计算宽高使用editPrintElementData.selectDetail.path
|
|
||||||
// img.src = editPrintElementData.selectDetail.path
|
|
||||||
img.src = editPrintElementData.selectDetail.undividedLayer?editPrintElementData.selectDetail.undividedLayer:editPrintElementData.selectDetail.path
|
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
// watch(()=>editPrintElementData.selectDetail?.id,(newVal)=>{
|
// watch(()=>editPrintElementData.selectDetail?.id,(newVal)=>{
|
||||||
// if(!newVal)return
|
// if(!newVal)return
|
||||||
@@ -862,7 +872,6 @@ export default defineComponent({
|
|||||||
let arr:any = editPrintElementData.printStyleList[props.type][editPrintElementData.stateOverallSingle]
|
let arr:any = editPrintElementData.printStyleList[props.type][editPrintElementData.stateOverallSingle]
|
||||||
|
|
||||||
arr.forEach((item,index) => {item.uniqueId = `${Date.now()}_${index}`});
|
arr.forEach((item,index) => {item.uniqueId = `${Date.now()}_${index}`});
|
||||||
console.log(arr)
|
|
||||||
const sortedArray = [...arr].sort((a, b) => a.priority - b.priority);
|
const sortedArray = [...arr].sort((a, b) => a.priority - b.priority);
|
||||||
const sortMap = {} as any;
|
const sortMap = {} as any;
|
||||||
sortedArray.forEach((item, index) => {
|
sortedArray.forEach((item, index) => {
|
||||||
|
|||||||
@@ -13,7 +13,10 @@
|
|||||||
<div class="desc">AiDA Users Only</div>
|
<div class="desc">AiDA Users Only</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Success :isExpired="isExpired" v-if="isCompleted || isExpired" />
|
<Success
|
||||||
|
:isExpired="isExpired"
|
||||||
|
v-if="isCompleted || isExpired"
|
||||||
|
/>
|
||||||
<div
|
<div
|
||||||
class="form-container"
|
class="form-container"
|
||||||
v-if="!isCompleted && !isExpired"
|
v-if="!isCompleted && !isExpired"
|
||||||
@@ -36,6 +39,7 @@
|
|||||||
<div class="email-wrapper flex align-center">
|
<div class="email-wrapper flex align-center">
|
||||||
<a-input v-model:value="form.email" />
|
<a-input v-model:value="form.email" />
|
||||||
<div
|
<div
|
||||||
|
v-if="!hasValidEmail"
|
||||||
class="code-btn"
|
class="code-btn"
|
||||||
:class="{ disabled: isCountingDown }"
|
:class="{ disabled: isCountingDown }"
|
||||||
@click="handleSendCode"
|
@click="handleSendCode"
|
||||||
@@ -78,19 +82,29 @@
|
|||||||
:disabled="readOnly"
|
:disabled="readOnly"
|
||||||
v-model:value="form[item.key]"
|
v-model:value="form[item.key]"
|
||||||
/>
|
/>
|
||||||
<a-select
|
<div
|
||||||
|
class="select-container"
|
||||||
v-if="item.type === 'select'"
|
v-if="item.type === 'select'"
|
||||||
:disabled="readOnly"
|
|
||||||
v-model:value="form[item.key]"
|
|
||||||
:options="genderOptions"
|
|
||||||
>
|
>
|
||||||
<template #suffixIcon>
|
<a-select
|
||||||
|
:disabled="readOnly"
|
||||||
|
v-model:value="form[item.key]"
|
||||||
|
:options="genderOptions"
|
||||||
|
>
|
||||||
|
<template #suffixIcon>
|
||||||
|
<!-- <img
|
||||||
|
class="arrow-down-icon"
|
||||||
|
src="@/assets/images/award/arrow_down.svg"
|
||||||
|
/> -->
|
||||||
|
</template>
|
||||||
|
</a-select>
|
||||||
|
<div class="arrow-wrapper flex flex-center">
|
||||||
<img
|
<img
|
||||||
class="arrow-down-icon"
|
class="arrow-down-icon"
|
||||||
src="@/assets/images/award/arrow_down.svg"
|
src="@/assets/images/award/arrow_down.svg"
|
||||||
/>
|
/>
|
||||||
</template>
|
</div>
|
||||||
</a-select>
|
</div>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
@@ -157,19 +171,15 @@
|
|||||||
:validate-trigger="[]"
|
:validate-trigger="[]"
|
||||||
label="How will you use AiDA in your design process?"
|
label="How will you use AiDA in your design process?"
|
||||||
>
|
>
|
||||||
<div
|
<div>
|
||||||
v-if="
|
|
||||||
pdfUploadStatus === 'idle' ||
|
|
||||||
pdfUploadStatus === 'error'
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<a-upload-dragger
|
<a-upload-dragger
|
||||||
v-model:fileList="pdfList"
|
v-model:fileList="pdfList"
|
||||||
:disabled="readOnly"
|
:disabled="readOnly"
|
||||||
:showUploadList="false"
|
:maxCount="1"
|
||||||
@change="info => handleFileChange(info, 'pdf')"
|
@change="info => handleFileChange(info, 'pdf')"
|
||||||
:customRequest="handleUploadPdf"
|
:customRequest="handleUploadPdf"
|
||||||
:beforeUpload="beforeUploadPdf"
|
:beforeUpload="beforeUploadPdf"
|
||||||
|
@remove="handleRemoveFile('pdf')"
|
||||||
accept=".pdf"
|
accept=".pdf"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
@@ -179,25 +189,48 @@
|
|||||||
/>
|
/>
|
||||||
<p class="desc">Click to upload or drag and drop</p>
|
<p class="desc">Click to upload or drag and drop</p>
|
||||||
<p class="limit">PDF file, max 20MB</p>
|
<p class="limit">PDF file, max 20MB</p>
|
||||||
|
<template #itemRender="{ file, actions }">
|
||||||
|
<div
|
||||||
|
class="custom-upload-list flex align-center space-between"
|
||||||
|
>
|
||||||
|
<div class="flex align-center">
|
||||||
|
<SvgIcon name="CFile" />
|
||||||
|
{{ file.name }}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
@click="actions.remove"
|
||||||
|
class="delete-file"
|
||||||
|
title="delete file"
|
||||||
|
>
|
||||||
|
<SvgIcon
|
||||||
|
name="CDelete"
|
||||||
|
color="red"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</a-upload-dragger>
|
</a-upload-dragger>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-else
|
v-show="
|
||||||
|
pdfUploadStatus === 'uploading' ||
|
||||||
|
pdfUploadStatus === 'success'
|
||||||
|
"
|
||||||
class="uploading-container"
|
class="uploading-container"
|
||||||
>
|
>
|
||||||
<UploadStatus
|
<UploadStatus
|
||||||
:status="pdfUploadStatus"
|
:status="pdfUploadStatus"
|
||||||
type="pdf"
|
type="pdf"
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="progress-bar-container"
|
|
||||||
v-if="pdfUploadStatus === 'uploading'"
|
|
||||||
>
|
|
||||||
<div
|
<div
|
||||||
class="progress-bar"
|
class="progress-bar-container"
|
||||||
:style="{ width: `${uploadProgressPdf}%` }"
|
v-if="pdfUploadStatus === 'uploading'"
|
||||||
></div>
|
>
|
||||||
|
<div
|
||||||
|
class="progress-bar"
|
||||||
|
:style="{ width: `${uploadProgressPdf}%` }"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</div>
|
</div>
|
||||||
@@ -209,23 +242,19 @@
|
|||||||
:validate-trigger="[]"
|
:validate-trigger="[]"
|
||||||
label="How will you use AiDA in your design process?"
|
label="How will you use AiDA in your design process?"
|
||||||
>
|
>
|
||||||
<div
|
<div>
|
||||||
v-if="
|
|
||||||
videoUploadStatus === 'idle' ||
|
|
||||||
videoUploadStatus === 'error'
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<a-upload-dragger
|
<a-upload-dragger
|
||||||
v-model:fileList="videoList"
|
v-model:fileList="videoList"
|
||||||
:showUploadList="false"
|
|
||||||
:disabled="readOnly"
|
:disabled="readOnly"
|
||||||
|
:maxCount="1"
|
||||||
@change="info => handleFileChange(info, 'video')"
|
@change="info => handleFileChange(info, 'video')"
|
||||||
:customRequest="handleUploadVideo"
|
:customRequest="handleUploadVideo"
|
||||||
:beforeUpload="beforeUploadVideo"
|
:beforeUpload="beforeUploadVideo"
|
||||||
|
@remove="handleRemoveFile('video')"
|
||||||
accept=".mp4,.mov"
|
accept=".mp4,.mov"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
src="@/assets/images/award/upload.png"
|
src="@/assets/images/award/upload_video_icon.png"
|
||||||
alt=""
|
alt=""
|
||||||
class="upload-icon"
|
class="upload-icon"
|
||||||
/>
|
/>
|
||||||
@@ -233,25 +262,48 @@
|
|||||||
<p class="limit">
|
<p class="limit">
|
||||||
Video file (MP4, MOV), 1080p, max 100MB
|
Video file (MP4, MOV), 1080p, max 100MB
|
||||||
</p>
|
</p>
|
||||||
|
<template #itemRender="{ file, actions }">
|
||||||
|
<div
|
||||||
|
class="custom-upload-list flex align-center space-between"
|
||||||
|
>
|
||||||
|
<div class="flex align-center">
|
||||||
|
<SvgIcon name="CFile" />
|
||||||
|
{{ file.name }}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
@click="actions.remove"
|
||||||
|
class="delete-file"
|
||||||
|
title="delete file"
|
||||||
|
>
|
||||||
|
<SvgIcon
|
||||||
|
name="CDelete"
|
||||||
|
color="red"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</a-upload-dragger>
|
</a-upload-dragger>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-else
|
v-show="
|
||||||
|
videoUploadStatus === 'success' ||
|
||||||
|
videoUploadStatus === 'uploading'
|
||||||
|
"
|
||||||
class="uploading-container"
|
class="uploading-container"
|
||||||
>
|
>
|
||||||
<UploadStatus
|
<UploadStatus
|
||||||
:status="videoUploadStatus"
|
:status="videoUploadStatus"
|
||||||
type="video"
|
type="video"
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="progress-bar-container"
|
|
||||||
v-if="videoUploadStatus === 'uploading'"
|
|
||||||
>
|
|
||||||
<div
|
<div
|
||||||
class="progress-bar"
|
class="progress-bar-container"
|
||||||
:style="{ width: `${uploadProgressVideo}%` }"
|
v-if="videoUploadStatus === 'uploading'"
|
||||||
></div>
|
>
|
||||||
|
<div
|
||||||
|
class="progress-bar"
|
||||||
|
:style="{ width: `${uploadProgressVideo}%` }"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</div>
|
</div>
|
||||||
@@ -342,7 +394,7 @@
|
|||||||
import { ref, onUnmounted, onMounted, computed } from 'vue'
|
import { ref, onUnmounted, onMounted, computed } from 'vue'
|
||||||
import { debounce } from 'lodash-es'
|
import { debounce } from 'lodash-es'
|
||||||
import type { Rule } from 'ant-design-vue/es/form'
|
import type { Rule } from 'ant-design-vue/es/form'
|
||||||
import { message } from 'ant-design-vue'
|
import { message, Upload } from 'ant-design-vue'
|
||||||
import { Https } from '@/tool/https'
|
import { Https } from '@/tool/https'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import type { UploadChangeParam } from 'ant-design-vue'
|
import type { UploadChangeParam } from 'ant-design-vue'
|
||||||
@@ -359,7 +411,7 @@
|
|||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const isCompleted = ref(false)
|
const isCompleted = ref(false)
|
||||||
const hasValidEmail = ref(false)
|
|
||||||
const readOnly = computed(() => {
|
const readOnly = computed(() => {
|
||||||
if (route.query.id && !hasValidEmail.value) {
|
if (route.query.id && !hasValidEmail.value) {
|
||||||
return true
|
return true
|
||||||
@@ -383,7 +435,10 @@
|
|||||||
designDescription: '',
|
designDescription: '',
|
||||||
pdfPath: '',
|
pdfPath: '',
|
||||||
videoPath: '',
|
videoPath: '',
|
||||||
secureToken: null
|
secureToken: ''
|
||||||
|
})
|
||||||
|
const hasValidEmail = computed(() => {
|
||||||
|
return !!form.value.secureToken
|
||||||
})
|
})
|
||||||
|
|
||||||
// 验证码输入组件引用
|
// 验证码输入组件引用
|
||||||
@@ -620,7 +675,6 @@
|
|||||||
console.log('coderes', res)
|
console.log('coderes', res)
|
||||||
|
|
||||||
form.value.secureToken = res.data.secureToken
|
form.value.secureToken = res.data.secureToken
|
||||||
hasValidEmail.value = true
|
|
||||||
|
|
||||||
message.success('Verification successful!')
|
message.success('Verification successful!')
|
||||||
showModal.value = false
|
showModal.value = false
|
||||||
@@ -675,7 +729,7 @@
|
|||||||
const beforeUploadFile = (type: FileType, file: File) => {
|
const beforeUploadFile = (type: FileType, file: File) => {
|
||||||
if (!hasValidEmail.value) {
|
if (!hasValidEmail.value) {
|
||||||
message.error('Please verify your email first')
|
message.error('Please verify your email first')
|
||||||
return false
|
return Upload.LIST_IGNORE
|
||||||
}
|
}
|
||||||
let maxSize: number
|
let maxSize: number
|
||||||
let allowedExtensions: string[]
|
let allowedExtensions: string[]
|
||||||
@@ -693,7 +747,7 @@
|
|||||||
allowedMimeTypes = ['video/mp4', 'video/quicktime']
|
allowedMimeTypes = ['video/mp4', 'video/quicktime']
|
||||||
errorMessage = 'Please upload a MP4 or MOV file only.'
|
errorMessage = 'Please upload a MP4 or MOV file only.'
|
||||||
} else {
|
} else {
|
||||||
return false
|
return Upload.LIST_IGNORE
|
||||||
}
|
}
|
||||||
|
|
||||||
// 验证文件类型
|
// 验证文件类型
|
||||||
@@ -705,18 +759,18 @@
|
|||||||
if (!isValidType) {
|
if (!isValidType) {
|
||||||
message.error(errorMessage)
|
message.error(errorMessage)
|
||||||
// 从文件列表中移除
|
// 从文件列表中移除
|
||||||
if (type === 'pdf') {
|
// if (type === 'pdf') {
|
||||||
const index = pdfList.value.findIndex(item => item.uid === file.uid)
|
// const index = pdfList.value.findIndex(item => item.uid === file.uid)
|
||||||
if (index > -1) {
|
// if (index > -1) {
|
||||||
pdfList.value.splice(index, 1)
|
// pdfList.value.splice(index, 1)
|
||||||
}
|
// }
|
||||||
} else {
|
// } else {
|
||||||
const index = videoList.value.findIndex(item => item.uid === file.uid)
|
// const index = videoList.value.findIndex(item => item.uid === file.uid)
|
||||||
if (index > -1) {
|
// if (index > -1) {
|
||||||
videoList.value.splice(index, 1)
|
// videoList.value.splice(index, 1)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
return false // 阻止上传
|
return Upload.LIST_IGNORE
|
||||||
}
|
}
|
||||||
|
|
||||||
// 验证文件大小
|
// 验证文件大小
|
||||||
@@ -726,21 +780,21 @@
|
|||||||
`File size exceeds ${sizeLimit} limit. Please upload a smaller file.`
|
`File size exceeds ${sizeLimit} limit. Please upload a smaller file.`
|
||||||
)
|
)
|
||||||
// 从文件列表中移除
|
// 从文件列表中移除
|
||||||
if (type === 'pdf') {
|
// if (type === 'pdf') {
|
||||||
const index = pdfList.value.findIndex(item => item.uid === file.uid)
|
// const index = pdfList.value.findIndex(item => item.uid === file.uid)
|
||||||
if (index > -1) {
|
// if (index > -1) {
|
||||||
pdfList.value.splice(index, 1)
|
// pdfList.value.splice(index, 1)
|
||||||
}
|
// }
|
||||||
} else {
|
// } else {
|
||||||
const index = videoList.value.findIndex(item => item.uid === file.uid)
|
// const index = videoList.value.findIndex(item => item.uid === file.uid)
|
||||||
if (index > -1) {
|
// if (index > -1) {
|
||||||
videoList.value.splice(index, 1)
|
// videoList.value.splice(index, 1)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
return false // 阻止上传
|
return Upload.LIST_IGNORE
|
||||||
}
|
}
|
||||||
|
|
||||||
return true // 允许上传
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// PDF文件上传前验证
|
// PDF文件上传前验证
|
||||||
@@ -822,18 +876,22 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const completeChunkUpload = async (type: FileType, file: File) => {
|
const completeChunkUpload = async (type: FileType, file: File) => {
|
||||||
const endpoint =
|
try {
|
||||||
type === 'pdf'
|
const endpoint =
|
||||||
? Https.httpUrls.uploadPDFComplete
|
type === 'pdf'
|
||||||
: Https.httpUrls.uploadVideoComplete
|
? Https.httpUrls.uploadPDFComplete
|
||||||
|
: Https.httpUrls.uploadVideoComplete
|
||||||
|
|
||||||
return Https.axiosPost(endpoint, {
|
return Https.axiosPost(endpoint, {
|
||||||
uploadId: chunkUploadState[type].uploadId,
|
uploadId: chunkUploadState[type].uploadId,
|
||||||
email: form.value.email,
|
email: form.value.email,
|
||||||
fileName: file.name,
|
fileName: file.name,
|
||||||
totalSize: file.size,
|
totalSize: file.size,
|
||||||
secureToken: form.value.secureToken
|
secureToken: form.value.secureToken
|
||||||
})
|
})
|
||||||
|
} catch (error) {
|
||||||
|
console.log('complete错误', error)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type FileType = 'pdf' | 'video'
|
type FileType = 'pdf' | 'video'
|
||||||
@@ -922,10 +980,12 @@
|
|||||||
isUploadingPdf.value = false
|
isUploadingPdf.value = false
|
||||||
uploadProgressPdf.value = 0
|
uploadProgressPdf.value = 0
|
||||||
pdfUploadStatus.value = 'error'
|
pdfUploadStatus.value = 'error'
|
||||||
|
pdfList.value = []
|
||||||
} else {
|
} else {
|
||||||
isUploadingVideo.value = false
|
isUploadingVideo.value = false
|
||||||
uploadProgressVideo.value = 0
|
uploadProgressVideo.value = 0
|
||||||
videoUploadStatus.value = 'error'
|
videoUploadStatus.value = 'error'
|
||||||
|
videoList.value = []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -940,6 +1000,18 @@
|
|||||||
return handleUploadFile(option, 'video')
|
return handleUploadFile(option, 'video')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleRemoveFile = (type: 'video' | 'pdf') => {
|
||||||
|
if (type === 'pdf') {
|
||||||
|
form.value.pdfPath = ''
|
||||||
|
pdfUploadStatus.value = 'idle'
|
||||||
|
uploadProgressPdf.value = 0
|
||||||
|
} else if (type === 'video') {
|
||||||
|
form.value.videoPath = ''
|
||||||
|
videoUploadStatus.value = 'idle'
|
||||||
|
uploadProgressVideo.value = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const conditionsList = ref([
|
const conditionsList = ref([
|
||||||
{
|
{
|
||||||
check: false,
|
check: false,
|
||||||
@@ -1137,14 +1209,26 @@
|
|||||||
line-height: 6rem;
|
line-height: 6rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
:deep(.ant-select-arrow) {
|
// :deep(.ant-select-arrow) {
|
||||||
height: 4rem;
|
|
||||||
width: 6.2rem;
|
// justify-content: center;
|
||||||
justify-content: center;
|
// display: flex;
|
||||||
display: flex;
|
// align-items: center;
|
||||||
align-items: center;
|
// }
|
||||||
border-left: 0.1rem solid #d5d5d5;
|
}
|
||||||
}
|
}
|
||||||
|
.select-container {
|
||||||
|
position: relative;
|
||||||
|
.arrow-wrapper {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
width: 6rem;
|
||||||
|
height: 4rem;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-left: 0.1rem solid #d5d5d5;
|
||||||
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1238,9 +1322,10 @@
|
|||||||
|
|
||||||
.upload-container {
|
.upload-container {
|
||||||
margin-top: 6rem;
|
margin-top: 6rem;
|
||||||
|
position: relative;
|
||||||
:deep(.ant-upload-drag) {
|
:deep(.ant-upload-drag) {
|
||||||
height: 32rem;
|
height: 32rem;
|
||||||
|
border-radius: 0.8rem;
|
||||||
|
|
||||||
.ant-upload-btn {
|
.ant-upload-btn {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
@@ -1276,9 +1361,13 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
border: 0.2rem solid #d5d5d5;
|
border: 0.2rem dashed #d5d5d5;
|
||||||
border-radius: 0.8rem;
|
border-radius: 0.8rem;
|
||||||
background-color: #fafafa;
|
background-color: #fafafa;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
.uploading-text {
|
.uploading-text {
|
||||||
color: #585858;
|
color: #585858;
|
||||||
@@ -1306,7 +1395,20 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.custom-upload-list {
|
||||||
|
padding: 0.4rem 1rem;
|
||||||
|
margin-top: 1rem;
|
||||||
|
&:hover {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
border-radius: 0.4rem;
|
||||||
|
}
|
||||||
|
.c-svg {
|
||||||
|
width: fit-content;
|
||||||
|
}
|
||||||
|
.delete-file {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
.conditions {
|
.conditions {
|
||||||
margin-top: 12rem;
|
margin-top: 12rem;
|
||||||
|
|
||||||
@@ -1462,9 +1564,12 @@
|
|||||||
</style>
|
</style>
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
.code-modal {
|
.code-modal {
|
||||||
.ant-modal-content .ant-modal-body {
|
.ant-modal-content {
|
||||||
padding: 0;
|
width: 60rem;
|
||||||
// width: 60rem;
|
height: 49.4rem;
|
||||||
|
.ant-modal-body {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -463,7 +463,7 @@
|
|||||||
.item-desc {
|
.item-desc {
|
||||||
font-family: 'Instrument';
|
font-family: 'Instrument';
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-size: 24px;
|
font-size: 2.4rem;
|
||||||
color: #585858;
|
color: #585858;
|
||||||
&.indent {
|
&.indent {
|
||||||
padding-left: 3.8rem;
|
padding-left: 3.8rem;
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
return {
|
return {
|
||||||
icon: expiredIcon,
|
icon: expiredIcon,
|
||||||
title: 'Application Deadline Passed',
|
title: 'Application Deadline Passed',
|
||||||
desc: 'The submission deadline for AIDA Global Fashion Award 2026 has ended.\nWe are no longer accepting new applications. '
|
desc: 'The submission deadline for AiDA Global Fashion Award 2026 has ended.\nWe are no longer accepting new applications. '
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -5,10 +5,14 @@
|
|||||||
>
|
>
|
||||||
<div class="timeline-title">Competition Timeline</div>
|
<div class="timeline-title">Competition Timeline</div>
|
||||||
<div class="desc">Shaping the Future</div>
|
<div class="desc">Shaping the Future</div>
|
||||||
<div class="timeline-point">
|
<div
|
||||||
<div class="labels-row flex align-center">
|
class="timeline-point"
|
||||||
|
ref="timelineRef"
|
||||||
|
>
|
||||||
|
<!-- 顶部标签行 -->
|
||||||
|
<div class="grid-row labels-row">
|
||||||
<div
|
<div
|
||||||
class="item-label flex flex-col"
|
class="grid-cell label-cell"
|
||||||
v-for="item in points"
|
v-for="item in points"
|
||||||
:key="'label-' + item.time"
|
:key="'label-' + item.time"
|
||||||
>
|
>
|
||||||
@@ -21,31 +25,35 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- Icons row -->
|
<!-- 图标行 -->
|
||||||
<div class="icons-row flex align-center">
|
<div class="grid-row icons-row">
|
||||||
<div class="timeline-line"></div>
|
<div class="timeline-line"></div>
|
||||||
<img
|
<div
|
||||||
src="@/assets/images/award/point.png"
|
class="grid-cell icon-cell"
|
||||||
class="point-icon"
|
|
||||||
v-for="item in points"
|
v-for="item in points"
|
||||||
:key="'icon-' + item.time"
|
:key="'icon-' + item.time"
|
||||||
/>
|
>
|
||||||
|
<img
|
||||||
|
src="@/assets/images/award/point.png"
|
||||||
|
class="point-icon"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- 时间行 -->
|
||||||
<!-- Times row -->
|
<div class="grid-row times-row">
|
||||||
<div class="times-row flex align-center">
|
|
||||||
<div
|
<div
|
||||||
class="item-time"
|
class="grid-cell time-cell"
|
||||||
v-for="item in points"
|
v-for="item in points"
|
||||||
:key="'time-' + item.time"
|
:key="'time-' + item.time"
|
||||||
>
|
>
|
||||||
{{ item.time }}
|
{{ item.time }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- Descriptions row -->
|
|
||||||
<div class="descs-row flex align-center">
|
<!-- 描述行 -->
|
||||||
|
<div class="grid-row descs-row">
|
||||||
<div
|
<div
|
||||||
class="item-desc flex justify-center"
|
class="grid-cell desc-cell"
|
||||||
v-for="item in points"
|
v-for="item in points"
|
||||||
:key="'desc-' + item.time"
|
:key="'desc-' + item.time"
|
||||||
>
|
>
|
||||||
@@ -63,12 +71,13 @@
|
|||||||
import { gsap } from 'gsap'
|
import { gsap } from 'gsap'
|
||||||
|
|
||||||
const containerRef = ref<HTMLElement | null>(null)
|
const containerRef = ref<HTMLElement | null>(null)
|
||||||
|
const timelineRef = ref<HTMLElement | null>(null)
|
||||||
const hasAnimated = ref(false)
|
const hasAnimated = ref(false)
|
||||||
|
|
||||||
const points = ref([
|
const points = ref([
|
||||||
{
|
{
|
||||||
label: 'Application',
|
label: 'Application',
|
||||||
subLabel:'Deadline',
|
subLabel: 'Deadline',
|
||||||
time: 'Jul 15',
|
time: 'Jul 15',
|
||||||
desc: 'Application deadline and\nentry review process\nbegins.'
|
desc: 'Application deadline and\nentry review process\nbegins.'
|
||||||
},
|
},
|
||||||
@@ -86,16 +95,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Receiving Outfits',
|
label: 'Receiving Outfits',
|
||||||
subLabel:'from Finallists',
|
subLabel: 'from Finallists',
|
||||||
time: 'October',
|
time: 'October',
|
||||||
desc: 'AiDA receives physical\noutfits from all 20\nfinalists.'
|
desc: 'AiDA receives physical\noutfits from all 20\nfinalists.'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Award',
|
label: 'Award',
|
||||||
subLabel:'Ceremony',
|
subLabel: 'Ceremony',
|
||||||
time: 'Nov 12',
|
time: 'Nov 12',
|
||||||
desc: 'Award Ceremony &\nCommunity Gathering\n– Soho House.'
|
desc: 'Award Ceremony &\nCommunity Gathering\n– Soho House.'
|
||||||
},
|
}
|
||||||
])
|
])
|
||||||
|
|
||||||
const playAnimation = () => {
|
const playAnimation = () => {
|
||||||
@@ -120,7 +129,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
clipPath: 'inset(0 0% 0 0)',
|
clipPath: 'inset(0 0% 0 0)',
|
||||||
duration: 1.6,
|
duration: 1.3,
|
||||||
ease: 'power1.out'
|
ease: 'power1.out'
|
||||||
},
|
},
|
||||||
'start'
|
'start'
|
||||||
@@ -157,16 +166,14 @@
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 行内文字(标签、时间、描述)与 start 同步开始
|
// 行内文字(标签、时间、描述、图标)与 start 同步开始
|
||||||
const textItems = containerRef.value.querySelectorAll(
|
const textItems = containerRef.value.querySelectorAll('.grid-cell')
|
||||||
'.item-label, .item-time, .item-desc .txt'
|
|
||||||
)
|
|
||||||
if (textItems && textItems.length) {
|
if (textItems && textItems.length) {
|
||||||
tl.from(
|
tl.from(
|
||||||
textItems,
|
textItems,
|
||||||
{
|
{
|
||||||
autoAlpha: 0.5,
|
// autoAlpha: 0.5,
|
||||||
duration: 0.6,
|
duration: 0.7,
|
||||||
stagger: 0.08,
|
stagger: 0.08,
|
||||||
ease: 'power2.out'
|
ease: 'power2.out'
|
||||||
},
|
},
|
||||||
@@ -174,22 +181,6 @@
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 所有文字与线条完成后,立即开始点图标动画(按顺序出现)
|
|
||||||
const icons = containerRef.value.querySelectorAll('.point-icon')
|
|
||||||
if (icons && icons.length) {
|
|
||||||
// 与 'start' 标签同步开始:改为纯淡入动画(移除缩放)
|
|
||||||
tl.from(
|
|
||||||
icons,
|
|
||||||
{
|
|
||||||
autoAlpha: 0,
|
|
||||||
duration: 2,
|
|
||||||
stagger: 0.12,
|
|
||||||
ease: 'power2.out'
|
|
||||||
},
|
|
||||||
'start+=0.3'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
hasAnimated.value = true
|
hasAnimated.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,8 +190,8 @@
|
|||||||
await nextTick()
|
await nextTick()
|
||||||
if (!containerRef.value) return
|
if (!containerRef.value) return
|
||||||
observer = new IntersectionObserver(
|
observer = new IntersectionObserver(
|
||||||
(entries) => {
|
entries => {
|
||||||
entries.forEach((entry) => {
|
entries.forEach(entry => {
|
||||||
if (entry.isIntersecting) {
|
if (entry.isIntersecting) {
|
||||||
playAnimation()
|
playAnimation()
|
||||||
}
|
}
|
||||||
@@ -224,7 +215,7 @@
|
|||||||
background: url('@/assets/images/award/timeline_bg.png') no-repeat;
|
background: url('@/assets/images/award/timeline_bg.png') no-repeat;
|
||||||
background-size: 100% 100%;
|
background-size: 100% 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
padding-top: 12.8rem;
|
padding: 12.8rem 0 15.9rem;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
.timeline-title {
|
.timeline-title {
|
||||||
@@ -248,42 +239,45 @@
|
|||||||
will-change: clip-path;
|
will-change: clip-path;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-top: 12rem;
|
margin-top: 11rem;
|
||||||
padding: 0 21.2rem 0 22rem;
|
padding: 0 13.8rem;
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
|
|
||||||
.labels-row {
|
// 主网格布局:5列
|
||||||
position: relative;
|
display: grid;
|
||||||
z-index: 2;
|
grid-template-columns: repeat(5, 1fr);
|
||||||
margin-bottom: 8rem;
|
grid-template-rows: auto auto auto auto;
|
||||||
.item-label {
|
grid-column-gap: 0;
|
||||||
flex: 1;
|
grid-row-gap: 0;
|
||||||
color: #fff;
|
|
||||||
font-family: 'PoppinsBold';
|
// 所有 grid 子行的通用样式
|
||||||
font-weight: 600;
|
.grid-row {
|
||||||
font-size: 2.8rem;
|
display: grid;
|
||||||
text-align: center;
|
grid-template-columns: repeat(5, 1fr);
|
||||||
white-space: pre-line;
|
grid-column: 1 / -1;
|
||||||
// height: 6rem;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.grid-cell {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 图标行
|
||||||
.icons-row {
|
.icons-row {
|
||||||
margin-bottom: 1.6rem;
|
align-items: center;
|
||||||
|
height: 6.4rem;
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
.point-icon {
|
margin-bottom: 1.6rem;
|
||||||
width: 6.4rem;
|
|
||||||
height: 6.4rem;
|
|
||||||
display: block;
|
|
||||||
margin: 0 auto;
|
|
||||||
z-index: 2;
|
|
||||||
}
|
|
||||||
.timeline-line {
|
.timeline-line {
|
||||||
width: calc(100% + 22rem + 21.2rem);
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
left: -22rem;
|
left: -22rem;
|
||||||
|
right: -21.2rem;
|
||||||
height: 0.15rem;
|
height: 0.15rem;
|
||||||
background: linear-gradient(
|
background: linear-gradient(
|
||||||
90deg,
|
90deg,
|
||||||
@@ -293,40 +287,78 @@
|
|||||||
rgba(199, 52, 44, 0.762376) 75.96%,
|
rgba(199, 52, 44, 0.762376) 75.96%,
|
||||||
rgba(199, 52, 44, 0) 100%
|
rgba(199, 52, 44, 0) 100%
|
||||||
);
|
);
|
||||||
position: absolute;
|
|
||||||
bottom: 50%;
|
|
||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-cell {
|
||||||
|
position: relative;
|
||||||
|
.point-icon {
|
||||||
|
width: 6.4rem;
|
||||||
|
height: 6.4rem;
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 标签行
|
||||||
|
.labels-row {
|
||||||
|
margin-bottom: 8rem;
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
.label-cell {
|
||||||
|
flex-direction: column;
|
||||||
|
color: #fff;
|
||||||
|
font-family: 'PoppinsBold';
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 2.8rem;
|
||||||
|
white-space: pre-line;
|
||||||
|
justify-content: center;
|
||||||
|
min-height: 6rem;
|
||||||
|
|
||||||
|
// .sub-label {
|
||||||
|
// font-family: 'Arial';
|
||||||
|
// font-weight: 400;
|
||||||
|
// font-size: 1.4rem;
|
||||||
|
// color: rgba(255, 255, 255, 0.8);
|
||||||
|
// margin-top: 0.4rem;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 时间行
|
||||||
.times-row {
|
.times-row {
|
||||||
margin-bottom: 6rem;
|
margin-bottom: 6rem;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
position: relative;
|
position: relative;
|
||||||
.item-time {
|
.time-cell {
|
||||||
flex: 1;
|
|
||||||
color: #f95750;
|
color: #f95750;
|
||||||
font-family: 'Arial';
|
font-family: 'Arial';
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-size: 2.8rem;
|
font-size: 2.8rem;
|
||||||
line-height: 4.5rem;
|
line-height: 4.5rem;
|
||||||
text-align: center;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 描述行
|
||||||
.descs-row {
|
.descs-row {
|
||||||
.item-desc {
|
.desc-cell {
|
||||||
flex: 1;
|
|
||||||
.txt {
|
.txt {
|
||||||
font-family: 'Arial';
|
font-family: 'Arial';
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-size: 2rem;
|
font-size: 2rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: #e0e0e0;
|
color: #e0e0e0;
|
||||||
width: 31.2rem;
|
width: 100%;
|
||||||
height: 10.2rem;
|
max-width: 31.2rem;
|
||||||
|
min-height: 10.2rem;
|
||||||
white-space: pre-line;
|
white-space: pre-line;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,7 +63,7 @@
|
|||||||
height: 2.4rem;
|
height: 2.4rem;
|
||||||
}
|
}
|
||||||
.banner {
|
.banner {
|
||||||
height: 108rem;
|
height: 100rem;
|
||||||
// background: url('@/assets/images/award/banner.png') no-repeat;
|
// background: url('@/assets/images/award/banner.png') no-repeat;
|
||||||
// background-size: cover;
|
// background-size: cover;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|||||||
Reference in New Issue
Block a user