|
@@ -1,63 +1,103 @@
|
|
|
<template>
|
|
|
- <div class="home" @mousedown="onMouseDown" @mousemove="onMouseMove" @mouseup="onMouseUp" @mouseleave="onMouseLeave"
|
|
|
- @touchstart.passive="onTouchStart" @touchmove.prevent="onTouchMove" @touchend="onTouchEnd"
|
|
|
- @touchcancel="onTouchCancel" @wheel.passive="onWheel">
|
|
|
-
|
|
|
- <div ref="hcon$" class="h-con" :style="{
|
|
|
- left: `-${translateLength}px`,
|
|
|
- }">
|
|
|
+ <div
|
|
|
+ class="home"
|
|
|
+ @mousedown="onMouseDown"
|
|
|
+ @mousemove="onMouseMove"
|
|
|
+ @mouseup="onMouseUp"
|
|
|
+ @mouseleave="onMouseLeave"
|
|
|
+ @touchstart.passive="onTouchStart"
|
|
|
+ @touchmove.prevent="onTouchMove"
|
|
|
+ @touchend="onTouchEnd"
|
|
|
+ @touchcancel="onTouchCancel"
|
|
|
+ @wheel.passive="onWheel"
|
|
|
+ >
|
|
|
+ <div
|
|
|
+ ref="hcon$"
|
|
|
+ class="h-con"
|
|
|
+ :style="{
|
|
|
+ left: `-${translateLength}px`,
|
|
|
+ }"
|
|
|
+ >
|
|
|
<div class="h-left">
|
|
|
- <img draggable="false" :src="$getImageUrl('h-left.jpg')" alt="">
|
|
|
+ <img draggable="false" :src="$getImageUrl('h-left.jpg')" alt="" />
|
|
|
<div class="l-con">
|
|
|
- <img draggable="false" class="title" :src="$getImageUrl('title.png')" alt="">
|
|
|
+ <img class="logo" :src="$getImageUrl('logo.png')" alt="" />
|
|
|
+ <img
|
|
|
+ draggable="false"
|
|
|
+ class="title"
|
|
|
+ :src="$getImageUrl('title.png')"
|
|
|
+ alt=""
|
|
|
+ />
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<div class="h-right">
|
|
|
<ul>
|
|
|
<li v-for="(item, idx) in list" :key="item.id">
|
|
|
- <img @click="onClickItem(item)" draggable="false" class="title" :src="$getImageUrl(`home-img/${idx + 1}.png`)"
|
|
|
- alt="">
|
|
|
+ <img
|
|
|
+ @click="onClickItem(item)"
|
|
|
+ draggable="false"
|
|
|
+ class="title"
|
|
|
+ :src="$getImageUrl(`home-img/${idx + 1}.png`)"
|
|
|
+ alt=""
|
|
|
+ />
|
|
|
</li>
|
|
|
</ul>
|
|
|
</div>
|
|
|
- <img @click="isShowCR = true" draggable="false" class="menu" :src="$getImageUrl('menu.png')" alt="">
|
|
|
-
|
|
|
+ <img
|
|
|
+ @click="isShowCR = true"
|
|
|
+ draggable="false"
|
|
|
+ class="menu"
|
|
|
+ :src="$getImageUrl('menu.png')"
|
|
|
+ alt=""
|
|
|
+ />
|
|
|
</div>
|
|
|
|
|
|
- <teleport to='body'>
|
|
|
+ <teleport to="body">
|
|
|
<Transition>
|
|
|
<CulturalRelic @close="isShowCR = ''" v-if="isShowCR" />
|
|
|
</Transition>
|
|
|
|
|
|
<Transition>
|
|
|
- <TwoDetail :data="current" @close="current = ''" v-if="current && current.isTwo" />
|
|
|
+ <TwoDetail
|
|
|
+ :data="current"
|
|
|
+ @close="current = ''"
|
|
|
+ v-if="current && current.isTwo"
|
|
|
+ />
|
|
|
</Transition>
|
|
|
-
|
|
|
+
|
|
|
<Transition>
|
|
|
- <ThreeDetail :data="current" @close="current = ''" v-if="current && !current.isTwo" />
|
|
|
+ <ThreeDetail
|
|
|
+ :data="current"
|
|
|
+ @close="current = ''"
|
|
|
+ v-if="current && !current.isTwo"
|
|
|
+ />
|
|
|
</Transition>
|
|
|
-
|
|
|
-
|
|
|
</teleport>
|
|
|
</div>
|
|
|
+ <!-- 请横屏浏览 -->
|
|
|
+ <div class="toHengBox">
|
|
|
+ <img src="../assets/images/toHeng.png" alt="" />
|
|
|
+ <p>请横屏浏览</p>
|
|
|
+ </div>
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
-import { onBeforeUnmount, onMounted, ref } from "vue"
|
|
|
+import { onBeforeUnmount, onMounted, ref } from "vue";
|
|
|
|
|
|
import TwoDetail from "@/components/detail/TwoDetail.vue";
|
|
|
import ThreeDetail from "@/components/detail/ThreeDetail.vue";
|
|
|
|
|
|
-import CulturalRelic from "@/views/cultural-relic.vue"
|
|
|
+import CulturalRelic from "@/views/cultural-relic.vue";
|
|
|
import { two, three } from "@/data/category";
|
|
|
|
|
|
+let list = three.data.concat(
|
|
|
+ two.data.map((item) => {
|
|
|
+ return { ...item, isTwo: true };
|
|
|
+ })
|
|
|
+);
|
|
|
|
|
|
-let list = three.data.concat(two.data.map(item => {
|
|
|
- return { ...item, isTwo: true }
|
|
|
-}))
|
|
|
-
|
|
|
-console.log('result:', list);
|
|
|
+console.log("result:", list);
|
|
|
|
|
|
const isMouseDown = ref(false);
|
|
|
const lastMoveEventTimeStamp = ref(0);
|
|
@@ -69,167 +109,163 @@ const maxTranslateLength = ref(0);
|
|
|
const lastAnimationTimeStamp = ref(0);
|
|
|
const animationFrameId = ref(0);
|
|
|
|
|
|
-const isShowCR = ref('');
|
|
|
-const current = ref('')
|
|
|
-
|
|
|
-const isMove = ref(false)
|
|
|
-
|
|
|
+const isShowCR = ref("");
|
|
|
+const current = ref("");
|
|
|
|
|
|
+const isMove = ref(false);
|
|
|
|
|
|
// 镜头平移相关
|
|
|
const translateLength = ref(0);
|
|
|
|
|
|
-
|
|
|
-const hcon$ = ref(null)
|
|
|
+const hcon$ = ref(null);
|
|
|
|
|
|
const onClickItem = (item) => {
|
|
|
if (!isMove.value) {
|
|
|
- current.value = item
|
|
|
+ current.value = item;
|
|
|
}
|
|
|
-}
|
|
|
+};
|
|
|
|
|
|
const animationFrameTask = () => {
|
|
|
- const timeStamp = Date.now()
|
|
|
- const timeElapsed = timeStamp - lastAnimationTimeStamp.value
|
|
|
+ const timeStamp = Date.now();
|
|
|
+ const timeElapsed = timeStamp - lastAnimationTimeStamp.value;
|
|
|
|
|
|
// 速度减慢
|
|
|
if (moveSpeed.value > 0) {
|
|
|
- moveSpeed.value -= 0.003 * timeElapsed
|
|
|
+ moveSpeed.value -= 0.003 * timeElapsed;
|
|
|
if (moveSpeed.value < 0) {
|
|
|
- moveSpeed.value = 0
|
|
|
+ moveSpeed.value = 0;
|
|
|
}
|
|
|
} else if (moveSpeed.value < 0) {
|
|
|
- moveSpeed.value += 0.003 * timeElapsed
|
|
|
+ moveSpeed.value += 0.003 * timeElapsed;
|
|
|
if (moveSpeed.value > 0) {
|
|
|
- moveSpeed.value = 0
|
|
|
+ moveSpeed.value = 0;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 根据速度更新距离
|
|
|
- translateLength.value += moveSpeed.value * timeElapsed
|
|
|
+ translateLength.value += moveSpeed.value * timeElapsed;
|
|
|
if (translateLength.value < 0) {
|
|
|
- translateLength.value = 0
|
|
|
+ translateLength.value = 0;
|
|
|
} else if (translateLength.value > maxTranslateLength.value) {
|
|
|
- translateLength.value = maxTranslateLength.value
|
|
|
- moveSpeed.value = 0
|
|
|
+ translateLength.value = maxTranslateLength.value;
|
|
|
+ moveSpeed.value = 0;
|
|
|
}
|
|
|
|
|
|
- lastAnimationTimeStamp.value = timeStamp
|
|
|
- animationFrameId.value = requestAnimationFrame(animationFrameTask)
|
|
|
-}
|
|
|
+ lastAnimationTimeStamp.value = timeStamp;
|
|
|
+ animationFrameId.value = requestAnimationFrame(animationFrameTask);
|
|
|
+};
|
|
|
|
|
|
const calcTranslateLimit = () => {
|
|
|
- maxTranslateLength.value = hcon$.value.clientWidth - window.innerWidth
|
|
|
-}
|
|
|
+ maxTranslateLength.value = hcon$.value.clientWidth - window.innerWidth;
|
|
|
+};
|
|
|
|
|
|
const onMouseDown = () => {
|
|
|
- isMouseDown.value = true
|
|
|
- moveSpeed.value = 0
|
|
|
- lastMoveEventTimeStamp.value = 0
|
|
|
- lastAnimationTimeStamp.value = Date.now()
|
|
|
-}
|
|
|
-
|
|
|
+ isMouseDown.value = true;
|
|
|
+ moveSpeed.value = 0;
|
|
|
+ lastMoveEventTimeStamp.value = 0;
|
|
|
+ lastAnimationTimeStamp.value = Date.now();
|
|
|
+};
|
|
|
|
|
|
const onMouseMove = (e) => {
|
|
|
if (isMouseDown.value) {
|
|
|
// 有些pc端浏览器比如firefox会有两次事件时间戳相同的情况发生。
|
|
|
- if (lastMoveEventTimeStamp.value && (e.timeStamp - lastMoveEventTimeStamp.value > 1)) {
|
|
|
- isMove.value = true
|
|
|
+ if (
|
|
|
+ lastMoveEventTimeStamp.value &&
|
|
|
+ e.timeStamp - lastMoveEventTimeStamp.value > 1
|
|
|
+ ) {
|
|
|
+ isMove.value = true;
|
|
|
// 更新speed
|
|
|
- const currentMoveSpeed = - e.movementX / (e.timeStamp - lastMoveEventTimeStamp.value)
|
|
|
- moveSpeed.value = moveSpeed.value * 0.9 + currentMoveSpeed * 0.1
|
|
|
+ const currentMoveSpeed =
|
|
|
+ -e.movementX / (e.timeStamp - lastMoveEventTimeStamp.value);
|
|
|
+ moveSpeed.value = moveSpeed.value * 0.9 + currentMoveSpeed * 0.1;
|
|
|
}
|
|
|
- lastMoveEventTimeStamp.value = e.timeStamp
|
|
|
+ lastMoveEventTimeStamp.value = e.timeStamp;
|
|
|
}
|
|
|
-}
|
|
|
+};
|
|
|
|
|
|
const onMouseUp = () => {
|
|
|
- isMouseDown.value = false
|
|
|
+ isMouseDown.value = false;
|
|
|
setTimeout(() => {
|
|
|
- isMove.value = false
|
|
|
+ isMove.value = false;
|
|
|
});
|
|
|
-}
|
|
|
+};
|
|
|
|
|
|
const onMouseLeave = () => {
|
|
|
- isMouseDown.value = false
|
|
|
+ isMouseDown.value = false;
|
|
|
setTimeout(() => {
|
|
|
- isMove.value = false
|
|
|
+ isMove.value = false;
|
|
|
});
|
|
|
-}
|
|
|
+};
|
|
|
|
|
|
const onTouchStart = (e) => {
|
|
|
- isMouseDown.value = true
|
|
|
- moveSpeed.value = 0
|
|
|
- lastMoveEventTimeStamp.value = 0
|
|
|
- lastAnimationTimeStamp.value = Date.now()
|
|
|
- lastTouchPos.value = e.changedTouches[0].clientX
|
|
|
-}
|
|
|
-
|
|
|
+ isMouseDown.value = true;
|
|
|
+ moveSpeed.value = 0;
|
|
|
+ lastMoveEventTimeStamp.value = 0;
|
|
|
+ lastAnimationTimeStamp.value = Date.now();
|
|
|
+ lastTouchPos.value = e.changedTouches[0].clientX;
|
|
|
+};
|
|
|
|
|
|
const onTouchMove = (e) => {
|
|
|
if (isMouseDown.value && e.changedTouches.length === 1) {
|
|
|
// 疯狂操作的极端情况下两个时间戳之间的时差会不合理,甚至为0
|
|
|
- if (lastMoveEventTimeStamp.value && (e.timeStamp - lastMoveEventTimeStamp.value > 1)) {
|
|
|
+ if (
|
|
|
+ lastMoveEventTimeStamp.value &&
|
|
|
+ e.timeStamp - lastMoveEventTimeStamp.value > 1
|
|
|
+ ) {
|
|
|
// 更新speed
|
|
|
- isMove.value = true
|
|
|
- const currentMoveSpeed = - (e.changedTouches[0].clientX - lastTouchPos.value) / (e.timeStamp - lastMoveEventTimeStamp.value) * 1.5
|
|
|
- moveSpeed.value = moveSpeed.value * 0.9 + currentMoveSpeed * 0.1
|
|
|
- lastTouchPos.value = e.changedTouches[0].clientX
|
|
|
+ isMove.value = true;
|
|
|
+ const currentMoveSpeed =
|
|
|
+ (-(e.changedTouches[0].clientX - lastTouchPos.value) /
|
|
|
+ (e.timeStamp - lastMoveEventTimeStamp.value)) *
|
|
|
+ 1.5;
|
|
|
+ moveSpeed.value = moveSpeed.value * 0.9 + currentMoveSpeed * 0.1;
|
|
|
+ lastTouchPos.value = e.changedTouches[0].clientX;
|
|
|
}
|
|
|
- lastMoveEventTimeStamp.value = e.timeStamp
|
|
|
+ lastMoveEventTimeStamp.value = e.timeStamp;
|
|
|
}
|
|
|
-}
|
|
|
-
|
|
|
+};
|
|
|
|
|
|
const onTouchEnd = () => {
|
|
|
- isMouseDown.value = false
|
|
|
+ isMouseDown.value = false;
|
|
|
setTimeout(() => {
|
|
|
- isMove.value = false
|
|
|
+ isMove.value = false;
|
|
|
});
|
|
|
-}
|
|
|
-
|
|
|
+};
|
|
|
|
|
|
const onTouchCancel = () => {
|
|
|
- isMouseDown.value = false
|
|
|
+ isMouseDown.value = false;
|
|
|
setTimeout(() => {
|
|
|
- isMove.value = false
|
|
|
+ isMove.value = false;
|
|
|
});
|
|
|
-}
|
|
|
-
|
|
|
+};
|
|
|
|
|
|
const onWheel = (e) => {
|
|
|
- translateLength.value += e.deltaY
|
|
|
+ translateLength.value += e.deltaY;
|
|
|
if (translateLength.value < 0) {
|
|
|
- translateLength.value = 0
|
|
|
+ translateLength.value = 0;
|
|
|
} else if (translateLength.value > maxTranslateLength.value) {
|
|
|
- translateLength.value = maxTranslateLength.value
|
|
|
- moveSpeed.value = 0
|
|
|
+ translateLength.value = maxTranslateLength.value;
|
|
|
+ moveSpeed.value = 0;
|
|
|
}
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
+};
|
|
|
|
|
|
onMounted(() => {
|
|
|
- animationFrameId.value = requestAnimationFrame(animationFrameTask)
|
|
|
- window.addEventListener('resize', calcTranslateLimit)
|
|
|
- calcTranslateLimit()
|
|
|
+ animationFrameId.value = requestAnimationFrame(animationFrameTask);
|
|
|
+ window.addEventListener("resize", calcTranslateLimit);
|
|
|
+ calcTranslateLimit();
|
|
|
document.onreadystatechange = () => {
|
|
|
- if (document.readyState === 'complete') {
|
|
|
+ if (document.readyState === "complete") {
|
|
|
// 页面上所有资源加载完成后执行的逻辑
|
|
|
- console.log('所有资源加载完成');
|
|
|
- calcTranslateLimit()
|
|
|
+ console.log("所有资源加载完成");
|
|
|
+ calcTranslateLimit();
|
|
|
}
|
|
|
};
|
|
|
-})
|
|
|
+});
|
|
|
|
|
|
onBeforeUnmount(() => {
|
|
|
- document.onreadystatechange = null
|
|
|
- window.removeEventListener('resize', calcTranslateLimit)
|
|
|
-})
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
+ document.onreadystatechange = null;
|
|
|
+ window.removeEventListener("resize", calcTranslateLimit);
|
|
|
+});
|
|
|
</script>
|
|
|
|
|
|
<style lang="less" scoped>
|
|
@@ -249,17 +285,17 @@ onBeforeUnmount(() => {
|
|
|
position: relative;
|
|
|
width: max-content;
|
|
|
|
|
|
- >img {
|
|
|
+ > img {
|
|
|
height: 100%;
|
|
|
}
|
|
|
|
|
|
.l-con {
|
|
|
-
|
|
|
.logo {
|
|
|
position: absolute;
|
|
|
- left: 1rem;
|
|
|
- top: 1rem;
|
|
|
- width: 16%;
|
|
|
+ width: 160px;
|
|
|
+ top: 26%;
|
|
|
+ left: 50%;
|
|
|
+ transform: translateX(-50%);
|
|
|
}
|
|
|
|
|
|
.title {
|
|
@@ -267,13 +303,13 @@ onBeforeUnmount(() => {
|
|
|
left: 50%;
|
|
|
top: 50%;
|
|
|
width: 70%;
|
|
|
- transform: translate(-50%, -50%);
|
|
|
+ transform: translateX(-50%);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.h-right {
|
|
|
- background-image: url('@/assets/images/bg-top.jpg');
|
|
|
+ background-image: url("@/assets/images/bg-top.jpg");
|
|
|
background-repeat: no-repeat;
|
|
|
background-size: auto 80%;
|
|
|
background-color: #dddad1;
|
|
@@ -287,15 +323,15 @@ onBeforeUnmount(() => {
|
|
|
width: 100%;
|
|
|
position: absolute;
|
|
|
bottom: 0;
|
|
|
- content: '';
|
|
|
+ content: "";
|
|
|
display: inline-block;
|
|
|
height: 20%;
|
|
|
box-sizing: border-box;
|
|
|
- border-top: 2rem solid #8B8980;
|
|
|
- background-image: linear-gradient(180deg, #93918A 0%, #AAA89F 63%);
|
|
|
+ border-top: 2rem solid #8b8980;
|
|
|
+ background-image: linear-gradient(180deg, #93918a 0%, #aaa89f 63%);
|
|
|
}
|
|
|
|
|
|
- >ul {
|
|
|
+ > ul {
|
|
|
height: 100%;
|
|
|
position: relative;
|
|
|
z-index: 999;
|
|
@@ -304,11 +340,11 @@ onBeforeUnmount(() => {
|
|
|
padding-left: 10rem;
|
|
|
margin-bottom: 10rem;
|
|
|
|
|
|
- >li {
|
|
|
+ > li {
|
|
|
list-style: none;
|
|
|
margin: 0 6rem;
|
|
|
|
|
|
- >img {
|
|
|
+ > img {
|
|
|
max-width: 80%;
|
|
|
cursor: pointer;
|
|
|
}
|
|
@@ -318,12 +354,61 @@ onBeforeUnmount(() => {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-.menu{
|
|
|
+.menu {
|
|
|
position: fixed;
|
|
|
right: 2rem;
|
|
|
top: 2rem;
|
|
|
width: 3%;
|
|
|
+ min-width: 40px;
|
|
|
cursor: pointer;
|
|
|
z-index: 999;
|
|
|
}
|
|
|
+.toHengBox {
|
|
|
+ display: none;
|
|
|
+}
|
|
|
+
|
|
|
+@media screen and (max-width: 1000px) {
|
|
|
+ .l-con {
|
|
|
+ .logo {
|
|
|
+ width: 100px !important;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .home .h-con .h-right > ul > li {
|
|
|
+ margin: 0 20px;
|
|
|
+ & > img {
|
|
|
+ max-height: 90vh;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .toHengBox {
|
|
|
+ opacity: 0;
|
|
|
+ pointer-events: none;
|
|
|
+ transition: all 0.2s;
|
|
|
+ position: fixed;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ z-index: 9999;
|
|
|
+ background-color: rgba(0, 0, 0, 0.8);
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ flex-direction: column;
|
|
|
+ & > img {
|
|
|
+ width: 80%;
|
|
|
+ }
|
|
|
+ & > p {
|
|
|
+ margin-top: 10px;
|
|
|
+ color: #fff;
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+/*竖屏*/
|
|
|
+@media screen and (orientation: portrait) {
|
|
|
+ .toHengBox {
|
|
|
+ opacity: 1;
|
|
|
+ pointer-events: auto;
|
|
|
+ }
|
|
|
+}
|
|
|
</style>
|