完成第一屏幕页面基本布局以及TheHeader和DigitalFlop的UI界面
This commit is contained in:
14
src/render/components/DigitalFlop.vue
Normal file
14
src/render/components/DigitalFlop.vue
Normal file
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<div class="digital-flop text-3xl font-bold" :style="style">
|
||||
{{ value }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import Vue from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
value: Number,
|
||||
style: String
|
||||
})
|
||||
</script>
|
||||
71
src/render/components/DigitalFlopContainer.vue
Normal file
71
src/render/components/DigitalFlopContainer.vue
Normal file
@@ -0,0 +1,71 @@
|
||||
<template>
|
||||
<div class="digital-flop-container h-1/6 relative flex flex-shrink-0 justify-between items-center">
|
||||
<div class="digital-flop-item w-1/6 h-4/5 flex flex-col justify-center items-center"
|
||||
v-for="item in digitalFlopData"
|
||||
:key="item.title"
|
||||
>
|
||||
<div class="digital-flop-title text-2xl mb-5">{{ item.title }}</div>
|
||||
<div class="digital-flop flex">
|
||||
<DigitalFlop
|
||||
:value="item.value"
|
||||
:style="item.style"
|
||||
/>
|
||||
<div class="unit ml-2.5 leading-10">{{ item.unit }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive } from 'vue'
|
||||
import DigitalFlop from './DigitalFlop.vue'
|
||||
|
||||
const digitalFlopData = reactive([
|
||||
{
|
||||
title: '日 期',
|
||||
value: 28,
|
||||
style: 'color: #4d99fc',
|
||||
unit : '座'
|
||||
}, {
|
||||
title: '时 间',
|
||||
value: 28,
|
||||
style: 'color: #f46827',
|
||||
unit : '座'
|
||||
}, {
|
||||
title: '经 度',
|
||||
value: 28,
|
||||
style: 'color: #40faee',
|
||||
unit : '座'
|
||||
}, {
|
||||
title: '纬 度',
|
||||
value: 28,
|
||||
style: 'color: #4d99fc',
|
||||
unit : '座'
|
||||
}, {
|
||||
title: '海 拔',
|
||||
value: 28,
|
||||
style: 'color: #f46827',
|
||||
unit : '座'
|
||||
}, {
|
||||
title: '定位卫星数目',
|
||||
value: 28,
|
||||
style: 'color: #40faee',
|
||||
unit : '座'
|
||||
}
|
||||
])
|
||||
|
||||
const update = console.log
|
||||
|
||||
defineExpose({ update })
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.digital-flop-container {
|
||||
background-color: rgba(6,30,93,.5);
|
||||
}
|
||||
|
||||
.digital-flop-item {
|
||||
border-left: 3px solid #061e5d;
|
||||
border-right: 3px solid #061e5d;
|
||||
}
|
||||
</style>
|
||||
@@ -1,65 +0,0 @@
|
||||
<template>
|
||||
<h1>{{ msg }}</h1>
|
||||
|
||||
<p>
|
||||
Recommended IDE setup:
|
||||
<a href="https://code.visualstudio.com/" target="_blank">VSCode</a>
|
||||
+
|
||||
<a
|
||||
href="https://marketplace.visualstudio.com/items?itemName=octref.vetur"
|
||||
target="_blank"
|
||||
>Vetur</a>
|
||||
or
|
||||
<a href="https://github.com/johnsoncodehk/volar" target="_blank">Volar</a>
|
||||
(if using
|
||||
<code><script setup></code>)
|
||||
</p>
|
||||
|
||||
<p>See <code>README.md</code> for more information.</p>
|
||||
|
||||
<p>
|
||||
<a href="https://vitejs.dev/guide/features.html" target="_blank">Vite Docs</a> |
|
||||
<a href="https://v3.vuejs.org/" target="_blank">Vue 3 Docs</a>
|
||||
</p>
|
||||
|
||||
<button @click="count++">count is: {{ count }}</button>
|
||||
<p>
|
||||
Edit
|
||||
<code>components/HelloWorld.vue</code> to test hot module replacement.
|
||||
</p>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { ref, defineComponent } from 'vue'
|
||||
export default defineComponent({
|
||||
name: 'HelloWorld',
|
||||
props: {
|
||||
msg: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
setup: () => {
|
||||
const count = ref(0)
|
||||
return { count }
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
a {
|
||||
color: #42b983;
|
||||
}
|
||||
|
||||
label {
|
||||
margin: 0 0.5em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
code {
|
||||
background-color: #eee;
|
||||
padding: 2px 4px;
|
||||
border-radius: 4px;
|
||||
color: #304455;
|
||||
}
|
||||
</style>
|
||||
81
src/render/components/Layout/Decoration5.vue
Normal file
81
src/render/components/Layout/Decoration5.vue
Normal file
@@ -0,0 +1,81 @@
|
||||
<template>
|
||||
<div class="decoration-5" ref="dom">
|
||||
<svg :width="width" :height="height">
|
||||
<polyline
|
||||
fill="transparent"
|
||||
:stroke="stroke"
|
||||
stroke-width="3"
|
||||
:points="line1.points"
|
||||
>
|
||||
<animate
|
||||
attributeName="stroke-dasharray"
|
||||
attributeType="XML"
|
||||
:from="`0, ${line1.length / 2}, 0, ${line1.length / 2}`"
|
||||
:to="`0, 0, ${line1.length}, 0`"
|
||||
:dur="`${dur}s`"
|
||||
begin="0s"
|
||||
calcMode="spline"
|
||||
keyTimes="0;1"
|
||||
keySplines="0.4,1,0.49,0.98"
|
||||
repeatCount="indefinite"
|
||||
/>
|
||||
</polyline>
|
||||
<polyline
|
||||
fill="transparent"
|
||||
:stroke="stroke"
|
||||
stroke-width="2"
|
||||
:points="line2.points"
|
||||
>
|
||||
<animate
|
||||
attributeName="stroke-dasharray"
|
||||
attributeType="XML"
|
||||
:from="`0, ${line2.length / 2}, 0, ${line2.length / 2}`"
|
||||
:to="`0, 0, ${line2.length}, 0`"
|
||||
:dur="`${dur}s`"
|
||||
begin="0s"
|
||||
calcMode="spline"
|
||||
keyTimes="0;1"
|
||||
keySplines=".4,1,.49,.98"
|
||||
repeatCount="indefinite"
|
||||
/>
|
||||
</polyline>
|
||||
</svg>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import { getPolylineLength } from '../../api/util'
|
||||
|
||||
const stroke = '#3f96a5'
|
||||
const dur = 1.2
|
||||
|
||||
const dom = ref(null)
|
||||
const width = ref(0)
|
||||
const height = ref(0)
|
||||
onMounted(() => {
|
||||
width.value = dom.value.clientWidth
|
||||
height.value = dom.value.clientHeight
|
||||
|
||||
calcSVGData()
|
||||
})
|
||||
|
||||
const line1 = reactive({ points: [], length: 0})
|
||||
const line2 = reactive({ points: [], length: 0})
|
||||
const calcSVGData = () => {
|
||||
line1.points = [
|
||||
[0, height.value * 0.2], [width.value * 0.18, height.value * 0.2], [width.value * 0.2, height.value * 0.4], [width.value * 0.25, height.value * 0.4],
|
||||
[width.value * 0.27, height.value * 0.6], [width.value * 0.72, height.value * 0.6], [width.value * 0.75, height.value * 0.4],
|
||||
[width.value * 0.8, height.value * 0.4], [width.value * 0.82, height.value * 0.2], [width.value, height.value * 0.2]
|
||||
]
|
||||
line2.points = [
|
||||
[width.value * 0.3, height.value * 0.8], [width.value * 0.7, height.value * 0.8]
|
||||
]
|
||||
|
||||
line1.length = getPolylineLength(line1.points)
|
||||
line2.length = getPolylineLength(line2.points)
|
||||
|
||||
line1.points = line1.points.map(point => point.join(',')).join(' ')
|
||||
line2.points = line2.points.map(point => point.join(',')).join(' ')
|
||||
}
|
||||
</script>
|
||||
45
src/render/components/Layout/Decoration8.vue
Normal file
45
src/render/components/Layout/Decoration8.vue
Normal file
@@ -0,0 +1,45 @@
|
||||
<template>
|
||||
<div class="decoration-8" ref="dom">
|
||||
<svg :width="width" :height="height">
|
||||
<polyline
|
||||
:stroke="stroke"
|
||||
stroke-width="2"
|
||||
fill="transparent"
|
||||
:points="`${xPos(0)}, 0 ${xPos(30)}, ${height / 2}`"
|
||||
/>
|
||||
|
||||
<polyline
|
||||
:stroke="stroke"
|
||||
stroke-width="2"
|
||||
fill="transparent"
|
||||
:points="`${xPos(20)}, 0 ${xPos(50)}, ${height / 2} ${xPos(width)}, ${height / 2}`"
|
||||
/>
|
||||
|
||||
<polyline
|
||||
:stroke="stroke"
|
||||
fill="transparent"
|
||||
stroke-width="3"
|
||||
:points="`${xPos(0)}, ${height - 3}, ${xPos(200)}, ${height - 3}`"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
|
||||
const stroke = '#3f96a5'
|
||||
|
||||
const dom = ref(null)
|
||||
const width = ref(0)
|
||||
const height = ref(0)
|
||||
onMounted(() => {
|
||||
width.value = dom.value.clientWidth
|
||||
height.value = dom.value.clientHeight
|
||||
})
|
||||
|
||||
const props = defineProps({
|
||||
reverse: Boolean
|
||||
})
|
||||
const xPos = (val: number) => props.reverse ? width.value - val : val
|
||||
</script>
|
||||
33
src/render/components/Layout/FullScreenContainer.vue
Normal file
33
src/render/components/Layout/FullScreenContainer.vue
Normal file
@@ -0,0 +1,33 @@
|
||||
<template>
|
||||
<div class="full-screen-container w-h-full fixed flex flex-col top-0 left-0 origin-top-left" ref="container">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, onBeforeUnmount } from 'vue'
|
||||
|
||||
const { width, height } = screen
|
||||
|
||||
const container = ref(null)
|
||||
|
||||
const onResize = () => {
|
||||
const currentWidth = document.body.clientWidth
|
||||
container.value.style.transform = `scale(${currentWidth / width})`
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
container.value.style.width = `${width}px`
|
||||
container.value.style.height = `${height}px`
|
||||
window.addEventListener('resize', onResize)
|
||||
})
|
||||
onBeforeUnmount(() => {
|
||||
window.removeEventListener('resize', onResize)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.full-screen-container {
|
||||
background-image: url('../../assets/img/bg-full.png');
|
||||
}
|
||||
</style>
|
||||
13
src/render/components/Layout/TheHeader.vue
Normal file
13
src/render/components/Layout/TheHeader.vue
Normal file
@@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<div class="the-header h-28 flex justify-between flex-shrink-0">
|
||||
<Decoration8 class="w-1/4 h-16" />
|
||||
<Decoration5 class="w-2/5 h-16 m-12" />
|
||||
<Decoration8 class="w-1/4 h-16" :reverse="true" />
|
||||
<div class="absolute left-1/2 transform -translate-x-2/4 text-3xl font-bold top-8 text-white">卫星数据监控平台</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import Decoration5 from './Decoration5.vue'
|
||||
import Decoration8 from './Decoration8.vue'
|
||||
</script>
|
||||
Reference in New Issue
Block a user