style:首页
This commit is contained in:
212
src/components/InfiniteScroll/index.vue
Normal file
212
src/components/InfiniteScroll/index.vue
Normal file
@@ -0,0 +1,212 @@
|
||||
<template>
|
||||
<div
|
||||
ref="scrollBox"
|
||||
:class="`infinite-scroll-component-box-${direction}`"
|
||||
:style="{
|
||||
'--speed-': `${speed}s`,
|
||||
mask: `linear-gradient(${degList[direction]}, #000 70%, transparent)`
|
||||
}"
|
||||
>
|
||||
<div class="scroll-content" ref="scrollContent">
|
||||
<template v-if="Array.isArray(content)">
|
||||
<div v-for="(item, index) in content" :key="'arrayFirst' + index" class="loop-item">
|
||||
<slot :item="item" :index="index"></slot>
|
||||
</div>
|
||||
<template v-if="loop">
|
||||
<div v-for="(item, index) in content" class="loop-item" :key="'arrayCopy' + index">
|
||||
<slot :item="item" :index="index"></slot>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
<template v-else>
|
||||
<slot></slot>
|
||||
<slot v-if="loop"></slot>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
direction: {
|
||||
type: String,
|
||||
default: 'top',
|
||||
validate: (value) => ['left', 'top', 'right', 'bottom'].findIndex(value) !== -1
|
||||
},
|
||||
|
||||
content: {
|
||||
type: [String, Array],
|
||||
default: ''
|
||||
},
|
||||
|
||||
mask: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
|
||||
// 速率倍速,越大越快,默认值20
|
||||
speedRate: {
|
||||
type: Number,
|
||||
default: 20
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
|
||||
let degList = {
|
||||
left: '90deg',
|
||||
top: '180deg',
|
||||
right: '270deg',
|
||||
bottom: '0deg'
|
||||
}
|
||||
// 滚动速度
|
||||
let speed = ref(0)
|
||||
// 是否需要无限滚动
|
||||
let loop = ref(false)
|
||||
// 容器ref
|
||||
let scrollBox = ref()
|
||||
|
||||
watch(
|
||||
() => props.content,
|
||||
() => {
|
||||
loop.value = false
|
||||
init()
|
||||
},
|
||||
{ deep: true }
|
||||
)
|
||||
|
||||
// 初始化速度,以及是否需要无限滚动
|
||||
const init = async () => {
|
||||
await nextTick()
|
||||
if (props.direction === 'left' || props.direction === 'right') {
|
||||
// 可视区域的宽度
|
||||
const boxWidth = scrollBox.value.offsetWidth
|
||||
// 滚动内容的宽度
|
||||
const itemWidth = scrollBox.value.getElementsByClassName('scroll-content')[0].offsetWidth
|
||||
if (itemWidth >= boxWidth) {
|
||||
loop.value = true
|
||||
speed.value = itemWidth / props.speedRate
|
||||
} else {
|
||||
speed.value = 0
|
||||
scrollBox.value.getElementsByClassName('scroll-content')[0].style.transform =
|
||||
'translateX(0)'
|
||||
loop.value = false
|
||||
}
|
||||
} else {
|
||||
const boxHeight = scrollBox.value.offsetHeight
|
||||
const itemHeight = scrollBox.value.getElementsByClassName('scroll-content')[0].offsetHeight
|
||||
if (itemHeight >= boxHeight) {
|
||||
loop.value = true
|
||||
speed.value = itemHeight / props.speedRate
|
||||
} else {
|
||||
speed.value = 0
|
||||
scrollBox.value.getElementsByClassName('scroll-content')[0].style.transform =
|
||||
'translateY(0)'
|
||||
loop.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.infinite-scroll-component-box-left,
|
||||
.infinite-scroll-component-box-right {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
.scroll-content {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
&:hover {
|
||||
animation-play-state: paused;
|
||||
}
|
||||
}
|
||||
}
|
||||
.infinite-scroll-component-box-top,
|
||||
.infinite-scroll-component-box-bottom {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
.scroll-content {
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
&:hover {
|
||||
animation-play-state: paused;
|
||||
}
|
||||
|
||||
.loop-item {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.infinite-scroll-component-box-left .scroll-content {
|
||||
flex-direction: row;
|
||||
animation: var(--speed-) move-left linear infinite;
|
||||
|
||||
@keyframes move-left {
|
||||
0% {
|
||||
transform: translateX(0);
|
||||
}
|
||||
100% {
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.infinite-scroll-component-box-right .scroll-content {
|
||||
flex-direction: row-reverse;
|
||||
animation: var(--speed-) move-right linear infinite;
|
||||
|
||||
@keyframes move-right {
|
||||
0% {
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
100% {
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.infinite-scroll-component-box-top .scroll-content {
|
||||
flex-direction: column;
|
||||
animation: var(--speed-) move-top linear infinite;
|
||||
|
||||
@keyframes move-top {
|
||||
0% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
100% {
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.infinite-scroll-component-box-bottom .scroll-content {
|
||||
flex-direction: column-reverse;
|
||||
animation: var(--speed-) move-bottom linear infinite;
|
||||
|
||||
@keyframes move-bottom {
|
||||
0% {
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
100% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -11,7 +11,7 @@
|
||||
import * as echarts from 'echarts'
|
||||
import styleUtil from '@/utils/styleUtil'
|
||||
import { fitChartSize } from '@/utils/dataUtil'
|
||||
|
||||
import { guid } from '@/utils/util'
|
||||
const props = defineProps({
|
||||
width: {
|
||||
type: Number,
|
||||
@@ -20,19 +20,29 @@
|
||||
height: {
|
||||
type: Number,
|
||||
default: () => 0
|
||||
},
|
||||
id: {
|
||||
type: String,
|
||||
default: () => ''
|
||||
}
|
||||
})
|
||||
|
||||
let id = ref(guid())
|
||||
let lineChart = null
|
||||
let timer = null
|
||||
let currentIndex = -1
|
||||
let defaultCofig = {
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'cross'
|
||||
backgroundColor: 'transparent',
|
||||
borderWidth: 0,
|
||||
formatter: (params) => {
|
||||
let str = `<div style="
|
||||
background: #07356B;
|
||||
border: 1px solid #0096FF;
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
font-size: ${fitChartSize(16)}px;
|
||||
border-radius: ${fitChartSize(4)}px;
|
||||
padding: ${fitChartSize(4)}px ${fitChartSize(12)}px;">
|
||||
${params[0].value}</div>`
|
||||
return str
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
@@ -54,7 +64,7 @@
|
||||
},
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#0096FF'
|
||||
color: 'rgba(5, 72, 134, 1)'
|
||||
}
|
||||
},
|
||||
axisLabel: {
|
||||
@@ -101,11 +111,9 @@
|
||||
]
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
const init = () => {
|
||||
lineChart = echarts.init(document.getElementById(props.id))
|
||||
const dom = document.getElementById(id.value)
|
||||
lineChart = echarts.init(dom)
|
||||
defaultCofig.xAxis.data = [
|
||||
'10:00',
|
||||
'10:05',
|
||||
@@ -120,8 +128,25 @@
|
||||
lineChart.setOption({
|
||||
...defaultCofig
|
||||
})
|
||||
// // 开启轮播
|
||||
// startTooltipLoop()
|
||||
|
||||
// // 鼠标悬浮,停止轮播
|
||||
// dom.addEventListener('mousemove', () => {
|
||||
// console.log('mouse move')
|
||||
// closeSwitchTooltip()
|
||||
// })
|
||||
|
||||
// // 鼠标离开,继续轮播
|
||||
// dom.addEventListener('mousedown', () => {
|
||||
// console.log('mouse down')
|
||||
// startTooltipLoop()
|
||||
// })
|
||||
|
||||
// 监听窗口大小变化
|
||||
window.addEventListener('resize', resize)
|
||||
}
|
||||
|
||||
const resize = () => {
|
||||
if (lineChart) {
|
||||
lineChart.dispose()
|
||||
@@ -129,5 +154,39 @@
|
||||
init()
|
||||
}
|
||||
}
|
||||
|
||||
// 切换tooltip
|
||||
const switchTooltip = () => {
|
||||
// 取消之前高亮的图形
|
||||
lineChart.dispatchAction({
|
||||
type: 'downplay',
|
||||
seriesIndex: 0,
|
||||
dataIndex: currentIndex
|
||||
})
|
||||
currentIndex = (currentIndex + 1) % 8
|
||||
// 高亮当前图形
|
||||
lineChart.dispatchAction({
|
||||
type: 'highlight',
|
||||
seriesIndex: 0,
|
||||
dataIndex: currentIndex
|
||||
})
|
||||
// 显示tooltip
|
||||
lineChart.dispatchAction({
|
||||
type: 'showTip',
|
||||
seriesIndex: 0,
|
||||
dataIndex: currentIndex
|
||||
})
|
||||
}
|
||||
const startTooltipLoop = () => {
|
||||
timer = setInterval(() => switchTooltip(), 3000)
|
||||
}
|
||||
const closeSwitchTooltip = () => {
|
||||
clearInterval(timer)
|
||||
timer = undefined
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
</script>
|
||||
<style lang="scss"></style>
|
||||
|
||||
@@ -3,17 +3,65 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted } from 'vue'
|
||||
import axios from 'axios'
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
const res = await axios.get(
|
||||
'https://jiaotong.baidu.com/openapi/v2/event/alarmlist?nodeId=7162&roadType=1,2,3,4,5&eventSource=1,2,3&ak=hPEEq9eAtL3t1SXL8hqNYQkGmWT1oOWh&returnType=1'
|
||||
)
|
||||
console.log(res, '数据')
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
onMounted(() => {
|
||||
// fetchData()
|
||||
var map = new BMapGL.Map('container')
|
||||
map.centerAndZoom(new BMapGL.Point(106.506299, 29.613929), 18)
|
||||
map.centerAndZoom(new BMapGL.Point(109.643452, 31.028006), 15)
|
||||
map.enableScrollWheelZoom(true)
|
||||
map.setMapType(BMAP_SATELLITE_MAP)
|
||||
|
||||
// 绘制线
|
||||
var polyline = new BMapGL.Polyline(
|
||||
[
|
||||
new BMapGL.Point(109.65053, 31.034752),
|
||||
new BMapGL.Point(109.647332, 31.033104),
|
||||
new BMapGL.Point(109.646883, 31.031797),
|
||||
new BMapGL.Point(109.640254, 31.021136)
|
||||
],
|
||||
{
|
||||
strokeStyle: 'solid',
|
||||
strokeColor: 'red ',
|
||||
// strokeTexture: {
|
||||
// url: 'https://mapopen-pub-jsapigl.bj.bcebos.com/svgmodel/Icon_road_blue_arrow.png',
|
||||
// width: 16,
|
||||
// height: 64
|
||||
// },
|
||||
strokeWeight: 4,
|
||||
strokeOpacity: 0.8
|
||||
}
|
||||
)
|
||||
map.addOverlay(polyline)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
:deep(.BMap_cpyCtrl) {
|
||||
display: none;
|
||||
}
|
||||
:deep(.anchorBL) {
|
||||
display: none;
|
||||
}
|
||||
// ::v-deep {
|
||||
// .BMap_cpyCtrl {
|
||||
// display: none;
|
||||
// }
|
||||
// .anchorBL {
|
||||
// display: none;
|
||||
// }
|
||||
// }
|
||||
.map {
|
||||
width: vw(3040);
|
||||
height: vh(1080);
|
||||
width: 100%;
|
||||
height: vh(700);
|
||||
}
|
||||
</style>
|
||||
|
||||
42
src/components/Title1/index.vue
Normal file
42
src/components/Title1/index.vue
Normal file
@@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<div class="title-1">
|
||||
<div class="title">
|
||||
<span> {{ title }} </span>
|
||||
</div>
|
||||
<slot name="right" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
let props = defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.title-1 {
|
||||
position: relative;
|
||||
.title {
|
||||
margin: vh(10) auto;
|
||||
width: vw(468);
|
||||
height: vh(32);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-image: url('@/assets/images/title-4.png');
|
||||
background-size: 100% 100%;
|
||||
& > span {
|
||||
font-weight: 800;
|
||||
font-size: vw(16);
|
||||
background-image: linear-gradient(to bottom, #ffffff 0%, #75c1ff 100%);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent; /* 兼容WebKit内核浏览器 */
|
||||
color: transparent; /* 兼容其他浏览器 */
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
35
src/components/Title2/index.vue
Normal file
35
src/components/Title2/index.vue
Normal file
@@ -0,0 +1,35 @@
|
||||
<template>
|
||||
<div class="title-2">
|
||||
<span>{{ title }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
let props = defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.title-2 {
|
||||
width: vw(250);
|
||||
height: vh(28);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-image: url('@/assets/images/title-5.png');
|
||||
background-size: 100% 100%;
|
||||
& > span {
|
||||
padding-left: vw(22);
|
||||
font-weight: bold;
|
||||
font-size: vw(15);
|
||||
background-image: linear-gradient(to bottom, #ffffff 0%, #75c1ff 100%);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent; /* 兼容WebKit内核浏览器 */
|
||||
color: transparent; /* 兼容其他浏览器 */
|
||||
}
|
||||
}
|
||||
</style>
|
||||
38
src/components/Title3/index.vue
Normal file
38
src/components/Title3/index.vue
Normal file
@@ -0,0 +1,38 @@
|
||||
<template>
|
||||
<div class="title-3">
|
||||
<span>{{ title }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
let props = defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.title-3 {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: vh(12);
|
||||
margin-top: vh(20);
|
||||
background-image: url('@/assets/images/title-6.png');
|
||||
background-size: 100% 100%;
|
||||
|
||||
& > span {
|
||||
position: absolute;
|
||||
bottom: vh(4);
|
||||
left: vw(20);
|
||||
font-size: vw(15);
|
||||
font-weight: bold;
|
||||
background-image: linear-gradient(to bottom, #ffffff 0%, #0096ff 100%);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent; /* 兼容WebKit内核浏览器 */
|
||||
color: transparent; /* 兼容其他浏览器 */
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user