ggfwjsc/src/view/guide.vue

575 lines
12 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<!-- mousedown事件放在页面最外层确保鼠标在页面任意点按下都会旋转照片墙 -->
<div id="m" class="page" ref="draggable" @mousedown="startDrag">
<div id="container">
<div class="header">
<div class="rightLineClass"></div>
<div class="leftLineClass"></div>
</div>
<div class="main">
<div class="leftPage"></div>
<div class="rightPage"></div>
<div class="btnPage"></div>
<div class="btnPp"></div>
<div class="wall">
<!-- 旋转ring的dom元素实现整个照片墙的偏转 -->
<div
class="ring"
:style="{
transform: `rotateX(${rotateX}deg) rotateY(${rotateY}deg)`,
transition: `transform ${transTime}s ease 0s`,
}"
>
<!-- 照片墙的图片使用transform实现立体的环形照片墙 -->
<!-- translateZ属性控制每一面的距离也会把image-wall等比例放大 -->
<div
v-for="(itemP, indexP) in tabData.scenList"
class="image-wall"
style="transition: transform 1s ease 0.5s"
:style="{
transform: `rotateY(${45 * indexP}deg) translateZ(450px)`,
}"
@click="toPage(itemP.url)"
>
<div class="animate-border">
<i></i>
<i></i>
</div>
<img :src="itemP.img" alt="" />
</div>
</div>
</div>
</div>
<div class="foot">
<div
class="fItems"
v-for="(item, index) in tabData.tabList"
@click="changeTab(index)"
>
<div :class="tabData.tabNum == index ? 'fiTopC' : 'fiTop'">
<img :src="item.img" alt="" />
</div>
<div class="tabGif" v-if="tabData.tabNum == index"></div>
<div :class="tabData.tabNum == index ? 'fiCenC' : 'fiCen'"></div>
<div class="fiText">{{ item.name }}</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted, reactive } from "vue";
import { useRouter, useRoute } from "vue-router";
import tab1 from "@/assets/guide/tab1.png";
import tab2 from "@/assets/guide/tab2.png";
import tab3 from "@/assets/guide/tab3.png";
import tab4 from "@/assets/guide/tab4.png";
import tab5 from "@/assets/guide/tab5.png";
import tab6 from "@/assets/guide/tab6.png";
import tab7 from "@/assets/guide/tab7.png";
import tab8 from "@/assets/guide/tab8.png";
import png1 from "@/assets/guide/Dp/1.png";
import png2 from "@/assets/guide/Dp/2.png";
import png3 from "@/assets/guide/Dp/3.png";
import png4 from "@/assets/guide/Dp/4.png";
import png5 from "@/assets/guide/Dp/5.png";
import png6 from "@/assets/guide/Dp/6.png";
const router = useRouter();
const routers = useRoute();
const draggable = ref(null);
const transTime = ref(0); // 参考系动画时长
const rotateY = ref(0); // 参考系偏转角度,动态赋值
const rotateX = ref(0);
const startX = ref(0); // 鼠标按下时开始的坐标
const startY = ref(0);
let dragging = false; // 是否监听鼠标移动
// 鼠标按下时触发
const startDrag = (event) => {
dragging = true; // 开始偏转
startX.value = event.clientX; //记录按下时的坐标
startY.value = event.clientY;
document.addEventListener("mousemove", doDrag); // 开始监听鼠标移动和鼠标放开事件
document.addEventListener("mouseup", stopDrag);
};
// 鼠标移动事件
const doDrag = (event) => {
// 如果不加dragging判断放开鼠标一样会改变坐标
if (dragging) {
// 计算移动偏转的角度
let dy = ((event.clientX - startX.value) / 1080) * 90;
let dx = ((event.clientY - startY.value) / 1920) * 160 * -1;
// 鼠标移动后,现在鼠标的位置变成下一次鼠标移动事件的初始位置
startX.value = event.clientX;
startY.value = event.clientY;
// 偏转角度赋值
rotateX.value += dx;
rotateY.value += dy;
}
};
// 鼠标放开事件
const stopDrag = () => {
dragging = false; // 不可改变偏转角度
document.removeEventListener("mousemove", doDrag); // 销毁监听器
document.removeEventListener("mouseup", stopDrag);
};
onUnmounted(() => {
// 清理事件监听器
stopDrag();
});
const reset_font = () => {
let width = document.documentElement.clientWidth || document.body.clientWidth;
let height =
document.documentElement.clientHeight || document.body.clientHeight;
document.querySelector("#m").style.transformOrigin = "top left";
document.querySelector("#m").style.transform =
"scale(" + width / 1920 + "," + height / 1080 + ")";
};
onMounted(() => {
reset_font();
reset_font();
});
window.addEventListener("resize", function () {
reset_font();
reset_font();
});
// 底部数据
const tabData = reactive({
tabNum: 0,
tabList: [
{
name: "要素一张图",
img: tab7,
},
{
name: "指标模型模块",
img: tab8,
},
{
name: "总体概况",
img: tab1,
},
{
name: "养老体系",
img: tab2,
},
{
name: "卫生体系",
img: tab3,
},
{
name: "教育体系",
img: tab4,
},
{
name: "救助体系",
img: tab5,
},
{
name: "智能分析",
img: tab6,
},
],
scenList: [
{
img: png1,
url: "/home/index/map",
},
{
img: png1,
url: "/home/index/table",
},
{
img: png1,
url: "/home/index",
},
{
img: png2,
url: "/home/yl",
},
{
img: png3,
url: "/home/hygiene",
},
{
img: png4,
url: "/home/education",
},
{
img: png5,
url: "/home/work",
},
{
img: png6,
url: "/home/analyze",
},
],
});
const changeTab = (val) => {
transTime.value = 0.8;
tabData.tabNum = val;
rotateY.value = 360 - 45 * val;
rotateX.value = 0;
setTimeout(() => {
transTime.value = 0;
}, 800);
};
const toPage = (val) => {
// console.log(val);
router.push({
path: `${val}`,
});
};
</script>
<style lang="scss" scoped>
.page {
/* 所有元素不可选中避免影响mousemove的监听 */
user-select: none;
background: url("../assets/guide/bg.png") no-repeat 0/100% 100%;
}
* {
padding: 0;
margin: 0;
box-sizing: border-box;
// color: #ccffff;
}
html {
width: 100%;
height: 100%;
}
body {
width: 100%;
height: 100%;
}
#m {
width: 100%;
height: 100%;
overflow: hidden;
// position: absolute;
z-index: 101;
}
#container {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
position: relative;
overflow: hidden;
}
.header {
background-image: url(../assets/guide/header.png);
background-size: 100% 100%;
display: flex;
height: 125px;
width: 100%;
// background-color: beige;
position: relative;
.rightLineClass {
position: absolute;
width: 760px;
height: 260px;
right: -45px;
bottom: -70px;
background-image: url(../assets/guide/RightLine.gif);
background-size: 100% 100%;
}
.leftLineClass {
position: absolute;
width: 760px;
height: 260px;
transform: scaleX(-1);
left: -45px;
bottom: -70px;
background-image: url(../assets/guide/RightLine.gif);
background-size: 100% 100%;
}
}
.main {
pointer-events: none;
padding-top: 60px;
height: 550px;
position: relative;
.leftPage {
position: absolute;
width: 220px;
height: 540px;
left: 145px;
background-image: url(../assets/guide/leftImg.png);
background-size: 100% 100%;
}
.rightPage {
position: absolute;
width: 220px;
height: 540px;
right: 145px;
background-image: url(../assets/guide/leftImg.png);
background-size: 100% 100%;
transform: scaleX(-1);
}
.btnPage {
position: absolute;
width: 1366px;
height: 347px;
bottom: -200px;
left: 270px;
background-image: url(../assets/guide/btnImg.png);
background-size: 100% 100%;
}
.btnPp {
position: absolute;
width: 500px;
height: 320px;
bottom: -115px;
left: 694px;
background-image: url(../assets/guide/min-pp.gif);
background-size: 100% 100%;
}
}
.wall {
perspective: 1000px;
width: 400px;
height: 237px;
margin: auto;
margin-top: 190px;
pointer-events: all;
}
.ring {
position: relative;
width: 100%;
height: 100%;
transform-style: preserve-3d;
transition: transform 0.1s ease-in-out;
}
.image-wall {
width: 80%;
height: 80%;
position: absolute;
top: 0;
left: 40px;
cursor: pointer;
background-image: url(../assets/guide/itemBg.png);
background-size: 100% 100%;
// 添加倒影
-webkit-box-reflect: below 10px -webkit-linear-gradient(top, rgba(0, 0, 0, 0)
60%, rgba(0, 0, 0, 0.2) 100%);
overflow: hidden;
/* 利用伪元素和两个i元素产生4条线 */
.animate-border {
position: absolute;
top: 0px;
width: 100%;
height: 100%;
&::before,
&::after {
content: "";
position: absolute;
width: 100%;
height: 2px;
}
i {
position: absolute;
display: inline-block;
height: 100%;
width: 2px;
}
&::before {
top: 0;
left: -100%;
background-image: linear-gradient(90deg, transparent, #fff, transparent);
animation: one 4s linear infinite;
}
i:nth-child(1) {
top: -100%;
right: 0;
background-image: linear-gradient(180deg, transparent, #fff, transparent);
/* 动画名称 动画持续时间 动画渲染函数 动画延迟时间 动画执行次数 */
animation: two 4s linear 3s infinite;
}
&::after {
bottom: 0;
right: -100%;
background-image: linear-gradient(
-90deg,
transparent,
#ffffff,
transparent
);
animation: three 4s linear 2s infinite;
}
i:nth-child(2) {
bottom: -100%;
left: 0;
background-image: linear-gradient(360deg, transparent, #fff, transparent);
animation: four 4s linear 1s infinite;
}
}
}
@keyframes one {
0% {
left: 100%;
}
50%,
100% {
left: -100%;
}
}
@keyframes two {
0% {
top: 100%;
}
50%,
100% {
top: -100%;
}
}
@keyframes three {
0% {
right: 100%;
}
50%,
100% {
right: -100%;
}
}
@keyframes four {
0% {
bottom: 100%;
}
50%,
100% {
bottom: -100%;
}
}
.image-wall img {
width: calc(100% - 20px);
height: calc(100% - 20px);
margin: 10px;
}
.foot {
display: flex;
justify-content: space-around;
width: 100%;
padding: 0 80px;
height: 200px;
margin-top: 150px;
border-bottom: 1px solid #71ddff;
position: relative;
font-family: titleNore;
&::after {
content: "";
position: absolute;
width: 200px;
height: 2px;
}
&::after {
top: 200px;
left: -200px;
background-image: linear-gradient(90deg, transparent, #fff, transparent);
animation: footAni 4s linear infinite;
}
@keyframes footAni {
0% {
left: -200px;
}
100% {
left: 100%;
}
}
.fItems {
width: 180px;
height: 180px;
position: relative;
.fiTop {
width: 100%;
img {
width: 86px;
height: 100px;
margin: 0 47px;
}
}
.fiTopC {
width: 100%;
animation: example 1.82s infinite linear;
img {
width: 86px;
height: 100px;
margin: 0 47px;
}
}
@keyframes example {
0% {
transform: translateY(0);
}
25% {
transform: translateY(-3px);
}
50% {
transform: translateY(0);
}
75% {
transform: translateY(3px);
}
100% {
transform: translateY(0);
}
}
.fiCen {
width: 180px;
height: 126px;
background-image: url(../assets/guide/tabBtn.png);
background-size: 100% 100%;
position: absolute;
top: 40px;
}
.fiCenC {
width: 180px;
height: 126px;
background-image: url(../assets/guide/tabBtnC.png);
background-size: 100% 100%;
position: absolute;
top: 40px;
}
.tabGif {
width: 100%;
height: 140px;
position: absolute;
top: -20px;
left: 10px;
background-image: url(../assets/guide/bt-pp.gif);
background-size: 100% 100%;
}
.fiText {
position: absolute;
bottom: -10px;
width: 100%;
height: 31px;
line-height: 31px;
text-align: center;
color: #fff;
font-size: 24px;
letter-spacing: 2px;
text-shadow: 0px 0px 4px #58b9ff;
}
}
}
</style>