|
@@ -77,12 +77,13 @@
|
|
|
@dragstart.prevent
|
|
|
>
|
|
|
<HotSpot
|
|
|
- v-if="[3].includes(tourState) || ([0].includes(tourState) && maskOpacity === 0)"
|
|
|
+ v-if="[3].includes(tourState) || ([0].includes(tourState))"
|
|
|
class="hot-spot"
|
|
|
@click="onClickPeopleFarHotSpot"
|
|
|
/>
|
|
|
</div>
|
|
|
<div
|
|
|
+ ref="people-near-wrap"
|
|
|
class="people-near-wrap"
|
|
|
:style="{
|
|
|
left: peopleNearPositionLeft,
|
|
@@ -99,7 +100,7 @@
|
|
|
@click="onClickPeopleNearHotSpot"
|
|
|
/>
|
|
|
<img
|
|
|
- v-show="[0, 1].includes(tourState)"
|
|
|
+ v-if="[0, 3].includes(tourState) || ([0].includes(tourState) && maskOpacity === 0)"
|
|
|
ref="treasure"
|
|
|
class="treasure"
|
|
|
:style="{
|
|
@@ -122,7 +123,7 @@
|
|
|
>
|
|
|
|
|
|
<div
|
|
|
- v-if="[0, 1, 2].includes(tourState) && maskOpacity !== 0"
|
|
|
+ v-if="[0, 1, 2].includes(tourState)"
|
|
|
class="fade-mask"
|
|
|
:style="{
|
|
|
opacity: maskOpacity,
|
|
@@ -151,29 +152,21 @@
|
|
|
@load="onTreasureFrameLoad(index - 1)"
|
|
|
@error="onTreasureFrameError(index - 1)"
|
|
|
>
|
|
|
- <div
|
|
|
- class="text1"
|
|
|
- :style="{opacity: text1Opacity}"
|
|
|
- >
|
|
|
- <span class="title">宋清瓷团花粉盒</span><br>
|
|
|
- <span>约公元前1220年<br>口径13.5cm 底径8cm 高6cm</span>
|
|
|
- </div>
|
|
|
- <div
|
|
|
- class="text2"
|
|
|
- :style="{opacity: text2Opacity}"
|
|
|
- >
|
|
|
- 此展品为宋代文物。子母口,浅腹,平底,盖面平;盒为子口,内有三个小碟;胎灰白,坚硬,施青色釉,口沿与底部无釉。现收藏于松阳县博物馆。
|
|
|
- </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
+import TWEEN from '@tweenjs/tween.js'
|
|
|
+
|
|
|
+const initialLandscapePositionLeft = '18.491%'
|
|
|
const initialCloud2PositionLeft = '35%'
|
|
|
const initialCloud1PositionLeft = '0%'
|
|
|
const initialCloud3PositionLeft = '55%'
|
|
|
+const initialPeopleFarPositionRight = '15%'
|
|
|
const initialPeopleNearPositionLeft = '25%'
|
|
|
-const initPeopleFarPositionRight = '15%'
|
|
|
+const initialIntroducePositionLeft = '3.347%'
|
|
|
+
|
|
|
const landscapeSpeedRate = 0.02
|
|
|
const cloud2SpeedRate = 0.25
|
|
|
const cloud1SpeedRate = 0.4
|
|
@@ -181,11 +174,14 @@ const cloud3SpeedRate = 0.4
|
|
|
const peopleFarSpeedRate = 0.4
|
|
|
const peopleNearSpeedRate = 0.6
|
|
|
const introduceSpeedRate = 0.6
|
|
|
+
|
|
|
const translateLengthRightBorder = 9000
|
|
|
-const treasureFadeInProgressRightBorder = 3000
|
|
|
-const treasureDisplayProgressRightBorder = 6000
|
|
|
-const treasureFadeOutProgressRightBorder = 2000
|
|
|
+
|
|
|
+const treasureFadeInDuration = 3000
|
|
|
+const treasureFadeOutDuration = 2000
|
|
|
+
|
|
|
const treasureFrameTotalNum = 125
|
|
|
+
|
|
|
const treasureInitialHeightPercent = 9
|
|
|
const treasureFinalHeightPercent = 116
|
|
|
|
|
@@ -209,32 +205,36 @@ export default {
|
|
|
// 镜头平移相关
|
|
|
translateLength: 0,
|
|
|
paperPositionLeft: 0,
|
|
|
- landscapePositionLeft: '18.491%',
|
|
|
+ landscapePositionLeft: initialLandscapePositionLeft,
|
|
|
cloud2PositionLeft: initialCloud2PositionLeft,
|
|
|
cloud1PositionLeft: initialCloud1PositionLeft,
|
|
|
cloud3PositionLeft: initialCloud3PositionLeft,
|
|
|
- peopleFarPositionRight: initPeopleFarPositionRight,
|
|
|
+ peopleFarPositionRight: initialPeopleFarPositionRight,
|
|
|
peopleNearPositionLeft: initialPeopleNearPositionLeft,
|
|
|
- introducePositionLeft: '3.347%',
|
|
|
+ introducePositionLeft: initialIntroducePositionLeft,
|
|
|
|
|
|
// 文物淡入相关
|
|
|
- treasureFadeInProgress: 0,
|
|
|
- treasureFadeInProgressRightBorder,
|
|
|
+ treasureFadeInProgress: {
|
|
|
+ value: 0,
|
|
|
+ },
|
|
|
treasureFadeInInitialLeft: 0,
|
|
|
treasureFadeInInitialTop: 0,
|
|
|
treasureFadeInFinalLeft: 0,
|
|
|
treasureFadeInFinalTop: 0,
|
|
|
treasureInitialHeightPercent,
|
|
|
+ treasureFadeInTween: null,
|
|
|
|
|
|
// 文物展示相关
|
|
|
- treasureDisplayProgress: 0,
|
|
|
treasureFrameTotalNum,
|
|
|
treasureFrameCurNum: 0,
|
|
|
treasureFrameStateList: new Array(treasureFrameTotalNum),
|
|
|
+ treasureFrameIntervalId: null,
|
|
|
|
|
|
// 文物淡出相关
|
|
|
- treasureFadeOutProgress: 0,
|
|
|
- treasureFadeOutProgressRightBorder,
|
|
|
+ treasureFadeOutProgress: {
|
|
|
+ value: 0,
|
|
|
+ },
|
|
|
+ treasureFadeOutTween: null,
|
|
|
|
|
|
// 远处人物变色相关
|
|
|
peopleFarColorStatus: 'no-color', // 'no-color', 'color'
|
|
@@ -244,16 +244,16 @@ export default {
|
|
|
computed: {
|
|
|
treasureOpacity() {
|
|
|
if (this.tourState === 0) {
|
|
|
- if (this.treasureFadeInProgress > treasureFadeInProgressRightBorder / 2) {
|
|
|
+ if (this.treasureFadeInProgress.value > 50) {
|
|
|
return 1
|
|
|
} else {
|
|
|
- return this.treasureFadeInProgress / (treasureFadeInProgressRightBorder / 2)
|
|
|
+ return this.treasureFadeInProgress.value / 50
|
|
|
}
|
|
|
} else if (this.tourState === 2) {
|
|
|
- if (this.treasureFadeOutProgress < treasureFadeOutProgressRightBorder / 2) {
|
|
|
+ if (this.treasureFadeOutProgress.value < 50) {
|
|
|
return 1
|
|
|
} else {
|
|
|
- return 1 - (this.treasureFadeOutProgress - treasureFadeOutProgressRightBorder / 2) / (treasureFadeOutProgressRightBorder / 2)
|
|
|
+ return 1 - (this.treasureFadeOutProgress.value - 50) / 50
|
|
|
}
|
|
|
} else {
|
|
|
return 0
|
|
@@ -261,62 +261,53 @@ export default {
|
|
|
},
|
|
|
maskOpacity() {
|
|
|
if (this.tourState === 0) {
|
|
|
- if (this.treasureFadeInProgress > treasureFadeInProgressRightBorder / 2) {
|
|
|
+ if (this.treasureFadeInProgress.value > 50) {
|
|
|
return 1
|
|
|
} else {
|
|
|
- return this.treasureFadeInProgress / (treasureFadeInProgressRightBorder / 2)
|
|
|
+ return this.treasureFadeInProgress.value / 50
|
|
|
}
|
|
|
} else if (this.tourState === 2) {
|
|
|
- if (this.treasureFadeOutProgress < treasureFadeOutProgressRightBorder / 2) {
|
|
|
- return 1
|
|
|
- } else {
|
|
|
- return 1 - (this.treasureFadeOutProgress - treasureFadeOutProgressRightBorder / 2) / (treasureFadeOutProgressRightBorder / 2)
|
|
|
- }
|
|
|
- } else {
|
|
|
- return 1
|
|
|
- }
|
|
|
- },
|
|
|
- text1Opacity() {
|
|
|
- if (this.tourState === 1) {
|
|
|
- if (this.treasureDisplayProgress < treasureDisplayProgressRightBorder * 0.1) {
|
|
|
- return this.treasureDisplayProgress / (treasureDisplayProgressRightBorder * 0.1)
|
|
|
- } else if (this.treasureDisplayProgress >= treasureDisplayProgressRightBorder * 0.1 && this.treasureDisplayProgress < treasureDisplayProgressRightBorder * 0.4) {
|
|
|
- return 1
|
|
|
- } else if (this.treasureDisplayProgress >= treasureDisplayProgressRightBorder * 0.4 && this.treasureDisplayProgress < treasureDisplayProgressRightBorder * 0.5) {
|
|
|
- return 1 - (this.treasureDisplayProgress - treasureDisplayProgressRightBorder * 0.4) / (treasureDisplayProgressRightBorder * (0.5 - 0.4))
|
|
|
- } else {
|
|
|
- return 0
|
|
|
- }
|
|
|
+ return (100 - this.treasureFadeOutProgress.value) / 100
|
|
|
} else {
|
|
|
return 0
|
|
|
}
|
|
|
},
|
|
|
- text2Opacity() {
|
|
|
- if (this.tourState === 1) {
|
|
|
- if (this.treasureDisplayProgress < treasureDisplayProgressRightBorder * 0.5) {
|
|
|
- return 0
|
|
|
- } else if (this.treasureDisplayProgress >= treasureDisplayProgressRightBorder * 0.5 && this.treasureDisplayProgress < treasureDisplayProgressRightBorder * 0.6) {
|
|
|
- return (this.treasureDisplayProgress - treasureDisplayProgressRightBorder * 0.5) / (treasureDisplayProgressRightBorder * (0.6 - 0.5))
|
|
|
- } else if (this.treasureDisplayProgress >= treasureDisplayProgressRightBorder * 0.6 && this.treasureDisplayProgress < treasureDisplayProgressRightBorder * 0.9) {
|
|
|
- return 1
|
|
|
- } else {
|
|
|
- return 1 - (this.treasureDisplayProgress - treasureDisplayProgressRightBorder * 0.9) / (treasureDisplayProgressRightBorder * (1 - 0.9))
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ tourState: {
|
|
|
+ handler(vNew, vOld) {
|
|
|
+ if (vOld === 0 && vNew === 1) {
|
|
|
+ this.treasureFrameIntervalId = setInterval(() => {
|
|
|
+ const frameNumBackup = this.treasureFrameCurNum
|
|
|
+ this.treasureFrameCurNum++
|
|
|
+ if (this.treasureFrameCurNum === this.treasureFrameTotalNum) {
|
|
|
+ clearInterval(this.treasureFrameIntervalId)
|
|
|
+ this.treasureFrameCurNum = 0
|
|
|
+ this.tourState = 2
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ while (this.treasureFrameStateList[this.treasureFrameCurNum] === false) {
|
|
|
+ this.treasureFrameCurNum++
|
|
|
+ }
|
|
|
+ if (this.treasureFrameStateList[this.treasureFrameCurNum] === undefined) {
|
|
|
+ this.treasureFrameCurNum = frameNumBackup
|
|
|
+ }
|
|
|
+ }, 41)
|
|
|
+ } else if (vOld === 1 && vNew === 2) {
|
|
|
+ this.treasureFadeOutTween.start()
|
|
|
}
|
|
|
- } else {
|
|
|
- return 0
|
|
|
}
|
|
|
},
|
|
|
- },
|
|
|
- watch: {
|
|
|
- treasureFadeInProgress: {
|
|
|
+ 'treasureFadeInProgress.value': {
|
|
|
handler(vNew, vOld) {
|
|
|
- if (vOld < this.treasureFadeInProgressRightBorder && vNew >= this.treasureFadeInProgressRightBorder && this.tourState === 0) {
|
|
|
+ if (vOld < 100 && vNew === 100 && this.tourState === 0) {
|
|
|
this.tourState = 1
|
|
|
}
|
|
|
- if (this.treasureFadeInProgress > treasureFadeInProgressRightBorder / 2) {
|
|
|
- this.$refs.treasure.style.left = this.treasureFadeInInitialLeft + (this.treasureFadeInProgress - treasureFadeInProgressRightBorder / 2) / (treasureFadeInProgressRightBorder / 2) * (this.treasureFadeInFinalLeft - this.treasureFadeInInitialLeft) + 'px'
|
|
|
- this.$refs.treasure.style.top = this.treasureFadeInInitialTop + (this.treasureFadeInProgress - treasureFadeInProgressRightBorder / 2) / (treasureFadeInProgressRightBorder / 2) * (this.treasureFadeInFinalTop - this.treasureFadeInInitialTop) + 'px'
|
|
|
- this.$refs.treasure.style.transform = `translate(-50%, -50%) scale(${1 + (this.treasureFadeInProgress - treasureFadeInProgressRightBorder / 2) / (treasureFadeInProgressRightBorder / 2) * (treasureFinalHeightPercent / this.treasureInitialHeightPercent - 1)})`
|
|
|
+ if (this.treasureFadeInProgress.value > 50) {
|
|
|
+ this.$refs.treasure.style.left = this.treasureFadeInInitialLeft + (this.treasureFadeInProgress.value - 50) / 50 * (this.treasureFadeInFinalLeft - this.treasureFadeInInitialLeft) + 'px'
|
|
|
+ this.$refs.treasure.style.top = this.treasureFadeInInitialTop + (this.treasureFadeInProgress.value - 50) / 50 * (this.treasureFadeInFinalTop - this.treasureFadeInInitialTop) + 'px'
|
|
|
+ this.$refs.treasure.style.transform = `translate(-50%, -50%) scale(${1 + (this.treasureFadeInProgress.value - 50) / 50 * (treasureFinalHeightPercent / this.treasureInitialHeightPercent - 1)})`
|
|
|
} else {
|
|
|
this.$refs.treasure.style.left = this.treasureFadeInInitialLeft + 'px'
|
|
|
this.$refs.treasure.style.top = this.treasureFadeInInitialTop + 'px'
|
|
@@ -324,49 +315,42 @@ export default {
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
- treasureDisplayProgress: {
|
|
|
+ 'treasureFadeOutProgress.value': {
|
|
|
handler(vNew, vOld) {
|
|
|
- // 更新toureState
|
|
|
- if (vOld > 0 && vNew <= 0 && this.tourState === 1) {
|
|
|
- this.tourState = 0
|
|
|
- } else if (vOld < treasureDisplayProgressRightBorder && vNew >= treasureDisplayProgressRightBorder && this.tourState === 1) {
|
|
|
- this.tourState = 2
|
|
|
- }
|
|
|
-
|
|
|
- let idealCurNum = Math.round(this.treasureDisplayProgress / treasureDisplayProgressRightBorder * treasureFrameTotalNum)
|
|
|
-
|
|
|
- while (this.treasureFrameStateList[idealCurNum] === false) {
|
|
|
- idealCurNum--
|
|
|
- }
|
|
|
- this.treasureFrameCurNum = idealCurNum
|
|
|
- }
|
|
|
- },
|
|
|
- treasureFadeOutProgress: {
|
|
|
- handler(vNew, vOld) {
|
|
|
- if (vOld > 0 && vNew <= 0 && this.tourState === 2) {
|
|
|
- this.tourState = 1
|
|
|
- } else if (vOld < this.treasureFadeOutProgressRightBorder && vNew >= this.treasureFadeOutProgressRightBorder && this.tourState === 2) {
|
|
|
+ if (vOld < 100 && vNew >= 100 && this.tourState === 2) {
|
|
|
this.tourState = 3
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
translateLength: {
|
|
|
handler(vNew, vOld) {
|
|
|
- // const rightBorder = window.innerWidth * 2
|
|
|
-
|
|
|
this.paperPositionLeft = `${vNew * landscapeSpeedRate}px`
|
|
|
this.landscapePositionLeft = `calc(18.491% + ${vNew * landscapeSpeedRate}px)`
|
|
|
this.cloud2PositionLeft = `calc(${initialCloud2PositionLeft} + ${vNew * cloud2SpeedRate}px)`
|
|
|
this.cloud1PositionLeft = `calc(${initialCloud1PositionLeft} + ${vNew * cloud1SpeedRate}px)`
|
|
|
this.cloud3PositionLeft = `calc(${initialCloud3PositionLeft} + ${vNew * cloud3SpeedRate}px)`
|
|
|
- this.peopleFarPositionRight = `calc(${initPeopleFarPositionRight} - ${vNew * peopleFarSpeedRate}px)`
|
|
|
+ this.peopleFarPositionRight = `calc(${initialPeopleFarPositionRight} - ${vNew * peopleFarSpeedRate}px)`
|
|
|
this.peopleNearPositionLeft = `calc(${initialPeopleNearPositionLeft} + ${vNew * peopleNearSpeedRate}px)`
|
|
|
this.introducePositionLeft = `calc(3.347% + ${vNew * introduceSpeedRate}px)`
|
|
|
}
|
|
|
},
|
|
|
},
|
|
|
mounted() {
|
|
|
- this.animationFrameId = requestAnimationFrame(this.inertanceEffect)
|
|
|
+ const that = this
|
|
|
+ this.animationFrameId = requestAnimationFrame(this.animationFrameTask)
|
|
|
+
|
|
|
+ this.treasureFadeInTween = new TWEEN.Tween(that.treasureFadeInProgress)
|
|
|
+ this.treasureFadeInTween.to({
|
|
|
+ value: 100,
|
|
|
+ }, treasureFadeInDuration)
|
|
|
+ this.treasureFadeInTween.easing(TWEEN.Easing.Linear.None)
|
|
|
+
|
|
|
+ this.treasureFadeOutTween = new TWEEN.Tween(that.treasureFadeOutProgress)
|
|
|
+ this.treasureFadeOutTween.to({
|
|
|
+ value: 100,
|
|
|
+ }, treasureFadeOutDuration)
|
|
|
+ this.treasureFadeOutTween.easing(TWEEN.Easing.Linear.None)
|
|
|
+
|
|
|
},
|
|
|
unmounted() {
|
|
|
cancelAnimationFrame(this.animationFrameId)
|
|
@@ -405,7 +389,7 @@ export default {
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
- inertanceEffect() {
|
|
|
+ animationFrameTask() {
|
|
|
const timeStamp = Date.now()
|
|
|
const timeElapsed = timeStamp - this.lastAnimationTimeStamp
|
|
|
|
|
@@ -433,8 +417,10 @@ export default {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ TWEEN.update()
|
|
|
+
|
|
|
this.lastAnimationTimeStamp = timeStamp
|
|
|
- this.animationFrameId = requestAnimationFrame(this.inertanceEffect)
|
|
|
+ this.animationFrameId = requestAnimationFrame(this.animationFrameTask)
|
|
|
},
|
|
|
onClickPeopleFarHotSpot() {
|
|
|
if (this.isPeopleFarColorChanging) {
|
|
@@ -452,10 +438,18 @@ export default {
|
|
|
}
|
|
|
},
|
|
|
onClickPeopleNearHotSpot() {
|
|
|
+ if (this.tourState !== 3) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算淡入过渡的起始终止位置
|
|
|
this.treasureFadeInInitialLeft = this.$refs.treasure.offsetLeft
|
|
|
this.treasureFadeInInitialTop = this.$refs.treasure.offsetTop
|
|
|
- this.treasureFadeInFinalLeft = window.innerWidth / 2 - this.$refs.treasure.offsetParent.offsetLeft
|
|
|
- this.treasureFadeInFinalTop = window.innerHeight / 2 - this.$refs.treasure.offsetParent.offsetTop
|
|
|
+ this.treasureFadeInFinalLeft = window.innerWidth / 2 - this.$refs['people-near-wrap'].offsetLeft
|
|
|
+ this.treasureFadeInFinalTop = window.innerHeight / 2 - this.$refs['people-near-wrap'].offsetTop
|
|
|
+ this.tourState = 0
|
|
|
+
|
|
|
+ this.treasureFadeInTween.start()
|
|
|
},
|
|
|
onTreasureFrameLoad(idx) {
|
|
|
this.treasureFrameStateList[idx] = true
|
|
@@ -583,31 +577,6 @@ export default {
|
|
|
height: 100%;
|
|
|
object-fit: cover;
|
|
|
}
|
|
|
- > .text1 {
|
|
|
- color: #fff;
|
|
|
- position: absolute;
|
|
|
- top: 5%;
|
|
|
- left: 3%;
|
|
|
- .title {
|
|
|
- font-size: 24px;
|
|
|
- font-weight: bold;
|
|
|
- line-height: 2;
|
|
|
-
|
|
|
- }
|
|
|
- span {
|
|
|
- font-size: 18px;
|
|
|
- line-height: 1.5;
|
|
|
- }
|
|
|
- }
|
|
|
- > .text2 {
|
|
|
- color: #fff;
|
|
|
- position: absolute;
|
|
|
- bottom: 5%;
|
|
|
- right: 3%;
|
|
|
- width: 30%;
|
|
|
- font-size: 18px;
|
|
|
- line-height: 1.5;
|
|
|
- }
|
|
|
}
|
|
|
@media screen and (max-height: 810px) {
|
|
|
.people-far-wrap {
|