feat(map): 优化地图组件并添加新功能

- 注释掉部分地图图片以简化界面
- 为每个地图光标添加 data-title 属性
- 实现地图光标点击时显示详细信息的功能
- 添加新的 CSS 样式以美化光标描述
-优化 tabs 样式,添加渐变背景和圆角
This commit is contained in:
陈昱达
2025-07-04 18:29:11 +08:00
parent c07572b96b
commit 205ecd5c93
6 changed files with 233 additions and 19 deletions

View File

@@ -45,12 +45,13 @@
"babel-eslint": "^10.0.1", "babel-eslint": "^10.0.1",
"babel-jest": "^23.6.0", "babel-jest": "^23.6.0",
"babel-plugin-import": "^1.12.0", "babel-plugin-import": "^1.12.0",
"compression-webpack-plugin": "^6.1.2",
"eslint": "^5.16.0", "eslint": "^5.16.0",
"eslint-plugin-prettier": "^3.1.0", "eslint-plugin-prettier": "^3.1.0",
"eslint-plugin-vue": "^5.0.0", "eslint-plugin-vue": "^5.0.0",
"postcss-px-to-viewport": "^1.1.1", "postcss-px-to-viewport": "^1.1.1",
"sass-loader": "^7.1.0", "sass-loader": "^7.1.0",
"vue-template-compiler": "^2.6.10", "vee-validate": "^2.0.0-rc.25",
"vee-validate": "^2.0.0-rc.25" "vue-template-compiler": "^2.6.10"
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 606 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 600 B

View File

@@ -4,9 +4,9 @@
<div class="map-1 map-comp"> <div class="map-1 map-comp">
<div class="relative"> <div class="relative">
<img src="../../../assets/images/home/map-1-t1.png" alt="" class="map-1-t1" /> <img src="../../../assets/images/home/map-1-t1.png" alt="" class="map-1-t1" />
<img src="../../../assets/images/home/map-1-t1-ban.png" alt="" class="map-1-t1-ban map-ban" :class="{ showOpacity: openFlag }" /> <!-- <img src="../../../assets/images/home/map-1-t1-ban.png" alt="" class="map-1-t1-ban map-ban" :class="{ showOpacity: openFlag }" />-->
<img src="../../../assets/images/home/map-1-t1-road.png" alt="" class="map-1-t1-road map-road" :class="{ showOpacity: openFlag }" /> <!-- <img src="../../../assets/images/home/map-1-t1-road.png" alt="" class="map-1-t1-road map-road" :class="{ showOpacity: openFlag }" />-->
<div class="cursor" :class="{ showOpacity: openFlag }"> <div class="cursor" :class="{ showOpacity: openFlag }" data-title="睿智财富">
<div class="cursor-title">睿智财富</div> <div class="cursor-title">睿智财富</div>
<div class="cursor-pointer"></div> <div class="cursor-pointer"></div>
</div> </div>
@@ -16,7 +16,7 @@
<div class="relative"> <div class="relative">
<img src="../../../assets/images/home/map-2-t1.png" alt="" class="map-2-t1" /> <img src="../../../assets/images/home/map-2-t1.png" alt="" class="map-2-t1" />
<img src="../../../assets/images/home/map-2-t1-ban.png" alt="" class="map-2-t1-ban" :class="{ showOpacity: openFlag }" /> <img src="../../../assets/images/home/map-2-t1-ban.png" alt="" class="map-2-t1-ban" :class="{ showOpacity: openFlag }" />
<div class="cursor" :class="{ showOpacity: openFlag }"> <div class="cursor" :class="{ showOpacity: openFlag }" data-title="乐活人生">
<div class="cursor-title">乐活人生</div> <div class="cursor-title">乐活人生</div>
<div class="cursor-pointer"></div> <div class="cursor-pointer"></div>
</div> </div>
@@ -27,7 +27,7 @@
<img src="../../../assets/images/home/map-3-t1.png" alt="" class="map-3-t1" /> <img src="../../../assets/images/home/map-3-t1.png" alt="" class="map-3-t1" />
<img src="../../../assets/images/home/map-3-t1-ban.png" alt="" class="map-3-t1-ban" :class="{ showOpacity: openFlag }" /> <img src="../../../assets/images/home/map-3-t1-ban.png" alt="" class="map-3-t1-ban" :class="{ showOpacity: openFlag }" />
<img src="../../../assets/images/home/map-3-t1-road.png" alt="" class="map-3-t1-road" :class="{ showOpacity: openFlag }" /> <img src="../../../assets/images/home/map-3-t1-road.png" alt="" class="map-3-t1-road" :class="{ showOpacity: openFlag }" />
<div class="cursor" :class="{ showOpacity: openFlag }"> <div class="cursor" :class="{ showOpacity: openFlag }" data-title="养老生活">
<div class="cursor-title">养老生活</div> <div class="cursor-title">养老生活</div>
<div class="cursor-pointer"></div> <div class="cursor-pointer"></div>
</div> </div>
@@ -38,7 +38,7 @@
<img src="../../../assets/images/home/map-4-t1.png" alt="" class="map-4-t1" /> <img src="../../../assets/images/home/map-4-t1.png" alt="" class="map-4-t1" />
<img src="../../../assets/images/home/map-4-t1-ban.png" alt="" class="map-4-t1-ban" :class="{ showOpacity: openFlag }" /> <img src="../../../assets/images/home/map-4-t1-ban.png" alt="" class="map-4-t1-ban" :class="{ showOpacity: openFlag }" />
<img src="../../../assets/images/home/map-4-t1-road.png" alt="" class="map-4-t1-road" :class="{ showOpacity: openFlag }" /> <img src="../../../assets/images/home/map-4-t1-road.png" alt="" class="map-4-t1-road" :class="{ showOpacity: openFlag }" />
<div class="cursor" :class="{ showOpacity: openFlag }"> <div class="cursor" :class="{ showOpacity: openFlag }" data-title="臻享健康">
<div class="cursor-title">臻享健康</div> <div class="cursor-title">臻享健康</div>
<div class="cursor-pointer"></div> <div class="cursor-pointer"></div>
</div> </div>
@@ -49,7 +49,7 @@
<img src="../../../assets/images/home/map-5-t1.png" alt="" class="map-5-t1" /> <img src="../../../assets/images/home/map-5-t1.png" alt="" class="map-5-t1" />
<!-- <img src="" alt="" class="map-5-t1-ban" />--> <!-- <img src="" alt="" class="map-5-t1-ban" />-->
<!-- <img src="" alt="" class="map-5-t1-road" />--> <!-- <img src="" alt="" class="map-5-t1-road" />-->
<div class="cursor" :class="{ showOpacity: openFlag }"> <div class="cursor" :class="{ showOpacity: openFlag }" data-title="成长护航">
<div class="cursor-title">成长护航</div> <div class="cursor-title">成长护航</div>
<div class="cursor-pointer"></div> <div class="cursor-pointer"></div>
</div> </div>
@@ -67,18 +67,33 @@
</div> </div>
</div> </div>
<div class="ma-tab flex justify-content-c" :class="{ hideOpacity: openFlag }"> <div class="ma-tab flex justify-content-c">
<div class="tab"> <div class="tab" :class="{ hideWidth: openFlag }">
<van-tabs v-model="active" :ellipsis="false"> <van-tabs v-model="active" :ellipsis="false">
<van-tab title="标签 1" v-for="item in list"> <van-tab title="标签 1" v-for="item in list">
<template #title> <template #title>
<div class="tab-title">{{ item.title }}</div> <div class="tab-title">{{ item.title }}</div>
</template> </template>
<div class="tab-content">{{ item.content }}</div> <div class="tab-content" :class="{ hideWidth: openFlag }">{{ item.content }}</div>
</van-tab> </van-tab>
</van-tabs> </van-tabs>
</div> </div>
</div> </div>
<div
class="cursor-desc"
:class="{
hideWidth: !cursorTitle,
}"
>
<div class="cursor-desc-title flex align-items-c justify-content-b" :class="{ showOpacity: cursorTitle }">
<div class="left-title-text">{{ cursorTitle }}</div>
<div class="right-title-icon"></div>
</div>
<div class="cursor-desc-content" :class="{ showOpacity: cursorContent }">{{ cursorContent }}</div>
<button class="pointer-button" :class="{ showOpacity: cursorContent }">查看详情</button>
</div>
</div> </div>
</template> </template>
<script> <script>
@@ -96,9 +111,49 @@ export default {
[Tab.name]: Tab, [Tab.name]: Tab,
[Tabs.name]: Tabs, [Tabs.name]: Tabs,
}, },
watch: {
openFlag(val) {
this.cursorContent = ''
setTimeout(() => {
this.cursorTitle = ''
}, 300)
// if (val) {
// }
},
},
data() { data() {
return { return {
active: 0, active: 0,
cursorTitle: '',
cursorContent: '',
cursorList: [
{
key: '睿智财富',
title: '世代财富传承',
content: '从教育储备到素质培养,为孩子的每个成长关键点铺设阶梯口覆盖教育金规划、国际学校择校、兴趣特长发展等全周期需求',
},
{
key: '乐活人生',
title: '乐活人生俱乐部',
content: '从教育储备到素质培养,为孩子的每个成长关键点铺设阶梯口覆盖教育金规划、国际学校择校、兴趣特长发展等全周期需求',
},
{
key: '养老生活',
title: '颐养天年无忧方案 ',
content: '从教育储备到素质培养,为孩子的每个成长关键点铺设阶梯口覆盖教育金规划、国际学校择校、兴趣特长发展等全周期需求',
},
{
key: '臻享健康',
title: '至臻健康守护圈',
content: '从教育储备到素质培养,为孩子的每个成长关键点铺设阶梯口覆盖教育金规划、国际学校择校、兴趣特长发展等全周期需求',
},
{
key: '成长护航',
title: '未来菁英成长计划',
content: '从教育储备到素质培养,为孩子的每个成长关键点铺设阶梯口覆盖教育金规划、国际学校择校、兴趣特长发展等全周期需求',
},
],
list: [ list: [
{ {
title: '生态服务', title: '生态服务',
@@ -124,22 +179,45 @@ export default {
], ],
} }
}, },
methods: {}, methods: {
findCursor(value) {
let item = this.cursorList.find((item) => item.key === value)
console.log(item)
return item
? item
: {
title: '',
content: '',
}
},
},
mounted() { mounted() {
const cursors = document.querySelectorAll('.cursor') const cursors = document.querySelectorAll('.cursor')
cursors.forEach((cursor) => { cursors.forEach((cursor) => {
cursor.addEventListener('click', () => { this.cursorTitle = ''
this.cursorContent = ''
cursor.addEventListener('click', (e) => {
// 移除所有 .map 的 active 类 // 移除所有 .map 的 active 类
document.querySelectorAll('.cursor').forEach((map) => { document.querySelectorAll('.cursor').forEach((map) => {
console.log(map)
map.classList.remove('active') map.classList.remove('active')
this.cursorTitle = ''
this.cursorContent = ''
}) })
// 给当前点击的 .cursor 所在的 .map 添加 active 类 // 给当前点击的 .cursor 所在的 .map 添加 active 类
const currentMap = cursor.closest('.cursor') const currentMap = cursor.closest('.cursor')
if (currentMap) { if (currentMap) {
currentMap.classList.add('active') currentMap.classList.add('active')
this.cursorTitle = ''
this.cursorContent = ''
setTimeout(() => {
let item = this.findCursor(cursor.getAttribute('data-title'))
this.cursorTitle = item.title
setTimeout(() => {
this.cursorContent = item.content
}, 500)
}, 500)
} }
}) })
}) })
@@ -148,15 +226,34 @@ export default {
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.pointer-button {
transition: all 0.3s ease-in-out;
outline: none;
padding: 5px 10px;
background: transparent;
border-radius: 5px;
border: 1px solid #000;
margin-top: 10px;
margin-left: 10px;
opacity: 0;
}
.relative { .relative {
position: relative; position: relative;
} }
.showOpacity { .showOpacity {
opacity: 1 !important; opacity: 1 !important;
//display: block;
} }
.hideOpacity { .hideOpacity {
opacity: 0 !important; opacity: 0 !important;
} }
.hideWidth {
opacity: 0 !important;
//display: none !important;
height: 0 !important;
width: 0 !important;
}
.cursor { .cursor {
opacity: 0; opacity: 0;
position: absolute; position: absolute;
@@ -429,32 +526,51 @@ export default {
& .ma-tab { & .ma-tab {
opacity: 1; opacity: 1;
display: block;
position: absolute; position: absolute;
top: 390px; top: 390px;
z-index: 5; z-index: 5;
width: 100%; width: 100%;
//height: 266px;
& .tab { & .tab {
width: 350px; width: 350px;
border-radius: 12px 12px 0 0; border-radius: 12px;
font-size: 10px; font-size: 10px;
background: #fff; box-shadow: 0 0 11px 0 #9fbfe0;
height: 265px;
//background: #fff;
//上下蓝白渐变
overflow: hidden; overflow: hidden;
//& . //& .
::v-deep .van-tabs--line { ::v-deep .van-tabs--line {
background: linear-gradient(to bottom, #e0eefd, #fff);
.van-tabs__wrap { .van-tabs__wrap {
overflow: unset; overflow: unset;
.van-tabs__nav {
background: transparent;
}
} }
.van-tabs__nav--complete { .van-tabs__nav--complete {
padding-left: 0; padding-left: 0;
padding-right: 0; padding-right: 0;
} }
} }
::v-deep .van-tabs { ::v-deep .van-tabs {
* { * {
transition: unset !important; transition: unset !important;
} }
.van-tabs__content { .van-tabs__content {
padding: 15px 10px; //padding: 15px 10px;
//color: red;
.tab-content {
font-size: 13px;
line-height: 16px;
height: 200px;
padding: 10px;
}
} }
.van-tabs__line { .van-tabs__line {
width: 0; width: 0;
@@ -496,6 +612,90 @@ export default {
} }
} }
& .cursor-desc {
background: linear-gradient(to bottom, #e0eefd, #f6f8fd);
width: 236px;
height: 166px;
position: absolute;
top: 485px;
left: 10px;
border-radius: 10px;
z-index: 12;
& .cursor-desc-title {
opacity: 0;
padding: 5px 10px;
&.showOpacity {
color: blue;
& .left-title-text {
&:after,
&:before {
opacity: 1;
}
}
}
& .left-title-text {
position: relative;
//背景色颜色 蓝白渐变 90% 到 100%
background: linear-gradient(to bottom, red 60%, #fff 100%);
font-size: 14px;
font-weight: 700;
letter-spacing: 2px; /* 每个字符之间增加 2px 的间距 */
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
padding: 5px 10px;
&:after {
opacity: 0;
content: '';
background: url('../../../assets/images/home/kl.png') no-repeat 100% 100%;
background-size: contain;
left: 0;
top: 0px;
z-index: 5;
position: absolute;
width: 10px;
height: 18px;
-webkit-text-fill-color: red;
}
&:before {
opacity: 0;
content: '';
background: url('../../../assets/images/home/kr.png') no-repeat 100% 100%;
background-size: contain;
right: 0;
bottom: 5px;
z-index: 5;
position: absolute;
width: 10px;
height: 18px;
-webkit-text-fill-color: red;
}
}
& .right-title-icon {
width: 16px;
height: 2px;
margin-right: 10px;
background: red;
}
}
& .cursor-desc-content {
opacity: 0;
padding: 0 10px;
line-height: 20px;
// 文本超过四行胜率号
display: -webkit-box; /* 旧版弹性盒子模型 */
-webkit-box-orient: vertical; /* 内容垂直排列 */
-webkit-line-clamp: 4; /* 限制显示的行数 */
overflow: hidden; /* 隐藏溢出内容 */
text-overflow: ellipsis; /* 超出部分显示省略号 */
line-clamp: 4; /* 标准属性(部分浏览器支持) */
}
}
&.moveMap { &.moveMap {
& .map-comp { & .map-comp {
&.map-1 { &.map-1 {
@@ -519,6 +719,7 @@ export default {
} }
&.map-7 { &.map-7 {
top: 304px; top: 304px;
right: -10px;
& .map-7-t1-ban { & .map-7-t1-ban {
width: 135px; width: 135px;
height: 104px; height: 104px;

View File

@@ -1,6 +1,8 @@
const autoprefixer = require('autoprefixer') const autoprefixer = require('autoprefixer')
const pxtoviewport = require('postcss-px-to-viewport') const pxtoviewport = require('postcss-px-to-viewport')
const path = require('path') const path = require('path')
const CompressionPlugin = require('compression-webpack-plugin')
function resolve(dir) { function resolve(dir) {
return path.join(__dirname, dir) return path.join(__dirname, dir)
} }
@@ -65,5 +67,15 @@ module.exports = {
return assetFilename.endsWith('.js') return assetFilename.endsWith('.js')
}, },
}) })
// config.plugins.push(
// new CompressionPlugin({
// filename: '[path][base].gz',
// algorithm: 'gzip',
// test: /\.(js|css|html|svg)$/,
// threshold: 10240,
// minRatio: 0.8,
// deleteOriginalAssets: false,
// })
// )
}, },
} }