vue纯前端结合css动画实现模拟导航效果
vue纯前端结合css动画实现模拟导航效果
- 实现效果
- 实现逻辑
实现效果
顶部为红绿灯数据,可根据实际情况接入
道路两侧为告警提醒,可根据实际情况接入
道路中间为车辆行驶图标样例,底部为车辆行驶速度
最右侧为导航全程概览进度缩略
实现逻辑
页面布局
<template>
<div class="all-container">
<div class="hud-container">
<div class="light light-left light-red"
><div>{{ light.left }}</div></div
>
<div class="light light-middle light-red"
><div>{{ light.middle }}</div></div
>
<div class="light light-right light-green"
><div>{{ light.right }}</div></div
>
<div class="road left-road">
<div class="road-shadow">
<template v-for="item in speed * 2" :key="item">
<div
class="shadow-container"
:style="{ 'margin-top': ((186 - 8 * speed) * 2) / (speed + 2) + 'px' }"
></div>
</template>
</div>
</div>
<div class="road-middle">
<div class="road-car road-car-animation"></div>
</div>
<div class="hud-speed">{{ vehicleSpeed }}</div>
<div class="road right-road">
<div class="road-shadow">
<template v-for="item in speed * 2" :key="item">
<div
class="shadow-container"
:style="{ 'margin-top': ((186 - 8 * speed) * 2) / (speed + 2) + 'px' }"
></div>
</template>
</div>
</div>
<div class="road-progress">
<div>南</div>
<img :src="require('@/assets/images/vehicle/right/north.png')" />
<div class="road-progress-grey">
<div class="road-progress-green" :style="{ height: progress + '%' }">
<img :src="require('@/assets/images/vehicle/right/line-car.png')" />
</div>
</div>
</div>
<div class="left-top warning">
<img :src="require('@/assets/images/vehicle/right/icon/crossroad.png')" />
</div>
<div class="left-bottom warning">
<img :src="require('@/assets/images/vehicle/right/icon/crossroad.png')" />
</div>
<div class="right-top warning">
<img :src="require('@/assets/images/vehicle/right/icon/light-red.png')" />
</div>
<div class="right-bottom warning">
<img :src="require('@/assets/images/vehicle/right/icon/light-red.png')" />
</div>
</div>
</div>
</template>
数据绑定
speed:道路两侧阴影的移动速度,分为了3至6四个等级;可以根据车辆的实际速度来选择对应的挡位,这里就写死了3级;
progress:右侧全场进度缩略图的进度条百分比,从0-100可以进行修改;
vehicleSpeed:为车辆速度;
light:红绿灯倒计时
<script lang="ts">
import { defineComponent, ref } from 'vue';
export default defineComponent({
name: 'HudPicture',
setup() {
const speed = ref<number>(3); //3-6
document.documentElement.style.setProperty('--roadSpeed', 5 / speed.value + 's');
return {
speed,
progress: 50,
vehicleSpeed: 56,
light: {
left: 12,
middle: 10,
right: 14,
},
};
},
});
</script>
用到的css样式
<style scoped lang="less">
:root {
--roadSpeed: 5s;
}
.all-container {
width: 666px;
height: 340px;
background: rgba(0, 43, 78, 0.47);
box-shadow: 0 1px 15px 0 rgba(0, 161, 255, 0.7) inset;
padding: 14px;
margin: 14px 0 0 19px;
.hud-container {
width: 638px;
height: 310px;
background: #000000;
border-radius: 12px;
position: relative;
.light {
position: absolute;
top: 12px;
width: 50px;
height: 50px;
background: rgba(0, 2, 20, 0.8);
border-radius: 50%;
&.light-green {
border: 2px solid #6af125;
box-shadow: 0 0 14px 3px rgba(6, 249, 0, 0.64) inset,
0 0 16px 1px rgba(0, 255, 0, 0.59) inset;
}
&.light-red {
box-shadow: 0 0 14px 3px rgba(249, 0, 30, 0.64) inset,
0 0 16px 1px rgba(255, 0, 0, 0.59) inset;
border: 2px solid #eb1d15;
}
&.light-left {
left: 227px;
background: url('../../../assets/images/vehicle/right/left.png') center no-repeat;
background-size: 60% 50%;
}
&.light-middle {
left: 292px;
background: url('../../../assets/images/vehicle/right/middle.png') center no-repeat;
background-size: 50% 60%;
}
&.light-right {
left: 357px;
background: url('../../../assets/images/vehicle/right/right.png') center no-repeat;
background-size: 60% 50%;
}
div {
text-align: center;
font-size: 36px;
font-weight: 500;
color: white;
line-height: 130px;
}
}
.road {
position: absolute;
top: 85px;
width: 3px;
height: 210px;
background-image: linear-gradient(
180deg,
rgba(28, 212, 234, 0) 0%,
#1cd4ea 43%,
#1cd4ea 94%
);
overflow: hidden;
&.left-road {
left: 230px;
transform: rotateZ(27deg);
}
&.right-road {
right: 230px;
transform: rotateZ(-27deg);
}
.road-shadow {
animation: movePercent var(--roadSpeed) linear infinite;
.shadow-container {
width: 4px;
height: 8px;
background-color: #03272a;
border-radius: 2px;
box-shadow: 0 1px 5px 2px rgba(52, 52, 52, 0.5);
}
}
@keyframes movePercent {
0% {
transform: translateY(-55.5%);
}
100% {
transform: translateY(0);
}
}
}
.road-middle {
position: absolute;
width: 35px;
height: 120px;
top: 120px;
left: 300px;
background: url('../../../assets/images/vehicle/right/road.png') center no-repeat;
background-size: 100% 100%;
.road-car {
width: 45px;
height: 60px;
background: url('../../../assets/images/vehicle/right/road-car.png') center no-repeat;
background-size: 100% 100%;
margin: 78px 0 0 -5px;
&.road-car-animation {
animation: rollPercent 2s linear infinite;
}
}
@keyframes rollPercent {
0% {
transform: translateY(0) scale(1);
}
50% {
transform: translateY(-4px) scale(1.1);
}
100% {
transform: translateY(0) scale(1);
}
}
}
.hud-speed {
position: absolute;
left: 0;
top: 230px;
text-align: center;
width: 100%;
font-size: 50px;
font-weight: 700;
background-image: -webkit-linear-gradient(top, #ffffff, #aaaaaa 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.road-progress {
position: absolute;
right: 22px;
top: 15px;
color: white;
font-size: 26px;
line-height: 26px;
text-align: center;
img {
width: 25px;
height: 25px;
}
.road-progress-grey {
width: 8px;
height: 187px;
background-color: #7d7d7d;
border-radius: 5px;
margin: 12px auto;
.road-progress-green {
width: 100%;
height: 100%;
background-color: #00b537;
border-radius: 5px;
position: relative;
img {
position: absolute;
left: -8px;
bottom: -8px;
}
}
}
}
.warning {
position: absolute;
img {
width: 80px;
height: 80px;
}
&.left-top {
left: 125px;
top: 80px;
img {
width: 90px;
height: 80px;
}
}
&.left-bottom {
left: 70px;
top: 170px;
img {
width: 90px;
height: 80px;
}
}
&.right-top {
right: 130px;
top: 80px;
}
&.right-bottom {
right: 75px;
top: 170px;
}
}
}
}
</style>
相关图标样例,其余通过css实现
left.png
middle.png
right.png
road.png
road-car.png
line-car.png
north.png
crossroad.png
light-red.png