release: v1
This commit is contained in:
parent
2598cdc3a9
commit
b010d69b99
2
.gitignore
vendored
2
.gitignore
vendored
@ -2,4 +2,6 @@ node_modules
|
||||
target
|
||||
dist
|
||||
.env
|
||||
.env*
|
||||
!.env.example
|
||||
.vite-ssg-temp
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.9 KiB |
1
src/components.d.ts
vendored
1
src/components.d.ts
vendored
@ -56,6 +56,7 @@ declare module 'vue' {
|
||||
SelectSeparator: typeof import('./components/ui/select/SelectSeparator.vue')['default']
|
||||
SelectTrigger: typeof import('./components/ui/select/SelectTrigger.vue')['default']
|
||||
SelectValue: typeof import('./components/ui/select/SelectValue.vue')['default']
|
||||
Switch: typeof import('./components/ui/switch/Switch.vue')['default']
|
||||
Table: typeof import('./components/ui/table/Table.vue')['default']
|
||||
TableBody: typeof import('./components/ui/table/TableBody.vue')['default']
|
||||
TableCaption: typeof import('./components/ui/table/TableCaption.vue')['default']
|
||||
|
||||
@ -7,11 +7,11 @@
|
||||
import { useOptions } from '@/composables/dateOpt'
|
||||
import '@amap/amap-jsapi-types'
|
||||
|
||||
const amapInstance = ref<null | typeof AMap>(null)
|
||||
const map = ref<null | AMap.Map>(null)
|
||||
const previousLayer = ref<null | AMap.ImageLayer>(null)
|
||||
let amapInstance: null | typeof AMap = null
|
||||
let map: null | AMap.Map = null
|
||||
let previousLayer: null | AMap.ImageLayer = null
|
||||
|
||||
const FORCE_MODE_OVERRIDE = 'image' as 'image' | 'heatmap' | null
|
||||
const FORCE_MODE_OVERRIDE = null as 'image' | 'heatmap' | null
|
||||
|
||||
function getPostionText(position: [number, number]) {
|
||||
const [x, y] = position
|
||||
@ -33,7 +33,7 @@ const apiKey = import.meta.env.VITE_AMAP_API_KEY
|
||||
const { options, currentFocus, getImageUrl, getHeatPoints } = useOptions()
|
||||
|
||||
watch(options, async () => {
|
||||
if (!map.value || !amapInstance.value) {
|
||||
if (!map || !amapInstance) {
|
||||
return
|
||||
}
|
||||
if (options.castBeginDate === '' || options.castDayNo === -1) {
|
||||
@ -56,24 +56,26 @@ watch(currentFocus, (newFocus) => {
|
||||
}
|
||||
const [lat, lon] = newFocus()
|
||||
// debugger
|
||||
map.value?.setCenter([lat, lon])
|
||||
map.value?.setZoom(4)
|
||||
if (map) {
|
||||
map.setCenter([lat, lon])
|
||||
map.setZoom(4)
|
||||
}
|
||||
})
|
||||
|
||||
const isDark = useDark()
|
||||
|
||||
watch(isDark, (newValue) => {
|
||||
map.value?.setMapStyle(newValue ? 'amap://styles/darkblue' : 'amap://styles/whitesmoke')
|
||||
map?.setMapStyle(newValue ? 'amap://styles/darkblue' : 'amap://styles/whitesmoke')
|
||||
})
|
||||
|
||||
async function updateMapImage() {
|
||||
if (!map.value || !amapInstance.value) {
|
||||
if (!map || !amapInstance) {
|
||||
return
|
||||
}
|
||||
|
||||
const url = await getImageUrl()
|
||||
|
||||
const image = new amapInstance.value.ImageLayer({
|
||||
const image = new amapInstance.ImageLayer({
|
||||
url,
|
||||
// @ts-expect-error AMap messed up their definition
|
||||
bounds: new AMap.Bounds([-180, -35], [180, 35]),
|
||||
@ -82,36 +84,38 @@ async function updateMapImage() {
|
||||
opacity: 1,
|
||||
// zooms: [15, 20],
|
||||
})
|
||||
map.value.add(image)
|
||||
map.add(image)
|
||||
image.on('complete', () => {
|
||||
previousLayer.value?.hide()
|
||||
previousLayer.value = image
|
||||
previousLayer?.hide()
|
||||
previousLayer = image
|
||||
})
|
||||
}
|
||||
|
||||
async function updateMapHeatpoints() {
|
||||
if (!map.value || !amapInstance.value) {
|
||||
if (!map || !amapInstance) {
|
||||
return
|
||||
}
|
||||
|
||||
previousLayer?.hide()
|
||||
const data = await getHeatPoints()
|
||||
|
||||
let heatMap: any
|
||||
const _map = map.value
|
||||
// @ts-expect-error Amap not providing heatmap types
|
||||
_map.plugin(['AMap.Heatmap'], () => {
|
||||
map.plugin(['AMap.HeatMap'], () => {
|
||||
// @ts-expect-error Amap not providing heatmap types
|
||||
heatMap = new amapInstance.value.HeatMap(_map, {
|
||||
heatMap = new amapInstance.HeatMap(map, {
|
||||
|
||||
radius: 100, // 给定半径
|
||||
radius: 25, // 给定半径
|
||||
opacity: [0, 0.8],
|
||||
|
||||
gradient: {
|
||||
0.0: 'red',
|
||||
1.0: 'red',
|
||||
},
|
||||
})
|
||||
heatMap.setDataSet({
|
||||
data,
|
||||
max: 1000,
|
||||
})
|
||||
heatMap.show()
|
||||
previousLayer = heatMap
|
||||
})
|
||||
}
|
||||
|
||||
@ -123,9 +127,9 @@ onMounted(async () => {
|
||||
version: '2.0',
|
||||
plugins: [],
|
||||
})
|
||||
amapInstance.value = _AMap
|
||||
amapInstance = _AMap
|
||||
|
||||
map.value = new _AMap.Map('amap-container', {
|
||||
map = new _AMap.Map('amap-container', {
|
||||
zoom: 5,
|
||||
center: [130, 17],
|
||||
zooms: [4, 20],
|
||||
@ -136,13 +140,13 @@ onMounted(async () => {
|
||||
// ],
|
||||
})
|
||||
|
||||
map.value.setBounds(new AMap.Bounds([-180, -35], [180, 35]))
|
||||
map.value.setLimitBounds(new AMap.Bounds([-180, -35], [180, 35]))
|
||||
map.value.setZoom(5)
|
||||
map.setBounds(new AMap.Bounds([-180, -35], [180, 35]))
|
||||
map.setLimitBounds(new AMap.Bounds([-180, -35], [180, 35]))
|
||||
map.setZoom(5)
|
||||
|
||||
map.value.on('click', (e) => {
|
||||
map.on('click', (e) => {
|
||||
const position = [e.lnglat.lng, e.lnglat.lat] as [number, number]
|
||||
const infoWindow = new amapInstance.value!.InfoWindow({
|
||||
const infoWindow = new amapInstance!.InfoWindow({
|
||||
content: `
|
||||
<div class="p-2 text-black">
|
||||
${getPostionText(position).getX()}
|
||||
@ -151,7 +155,7 @@ onMounted(async () => {
|
||||
</div>
|
||||
`,
|
||||
})
|
||||
infoWindow.open(map.value!, e.lnglat)
|
||||
infoWindow.open(map!, e.lnglat)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
@ -42,8 +42,8 @@ function getPostionText(position: [number, number]) {
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
<TableRow v-for="postion in currentTcLoc" :key="postion[0]">
|
||||
<TableCell>{{ getPostionText(postion).getX() }}</TableCell>
|
||||
<TableCell>{{ getPostionText(postion).getY() }}</TableCell>
|
||||
<TableCell>{{ getPostionText(postion).getX() }}</TableCell>
|
||||
<TableCell class="text-right">
|
||||
<Button
|
||||
class="h-6 text-[13.2px]" variant="outline"
|
||||
|
||||
39
src/components/ui/switch/Switch.vue
Normal file
39
src/components/ui/switch/Switch.vue
Normal file
@ -0,0 +1,39 @@
|
||||
<script setup lang="ts">
|
||||
import { cn } from '@/lib/utils'
|
||||
import {
|
||||
SwitchRoot,
|
||||
type SwitchRootEmits,
|
||||
type SwitchRootProps,
|
||||
SwitchThumb,
|
||||
useForwardPropsEmits,
|
||||
} from 'radix-vue'
|
||||
import { computed, type HTMLAttributes } from 'vue'
|
||||
|
||||
const props = defineProps<SwitchRootProps & { class?: HTMLAttributes['class'] }>()
|
||||
|
||||
const emits = defineEmits<SwitchRootEmits>()
|
||||
|
||||
const delegatedProps = computed(() => {
|
||||
const { class: _, ...delegated } = props
|
||||
|
||||
return delegated
|
||||
})
|
||||
|
||||
const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<SwitchRoot
|
||||
v-bind="forwarded"
|
||||
:class="cn(
|
||||
'peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input',
|
||||
props.class,
|
||||
)"
|
||||
>
|
||||
<SwitchThumb
|
||||
:class="cn('pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5')"
|
||||
>
|
||||
<slot name="thumb" />
|
||||
</SwitchThumb>
|
||||
</SwitchRoot>
|
||||
</template>
|
||||
1
src/components/ui/switch/index.ts
Normal file
1
src/components/ui/switch/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export { default as Switch } from './Switch.vue'
|
||||
@ -1,4 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
// import Switch from '@/components/ui/switch/Switch.vue'
|
||||
import { DrawerClose, DrawerTrigger } from 'vaul-vue'
|
||||
import Colorbar from '../assets/colorbar.png'
|
||||
|
||||
@ -24,7 +25,14 @@ function flipDark() {
|
||||
季节内台风预报系统
|
||||
</h1>
|
||||
<div class="size-5">
|
||||
<span class="i-tabler-sun size-5" @click="flipDark" />
|
||||
<!-- <Switch :checked="isDark" @update:checked="flipDark">
|
||||
<template #thumb>
|
||||
<div class="h-5 w-5 flex items-center justify-center">
|
||||
<div v-if="isDark" class="i-lucide-moon size-3" />
|
||||
<div v-else class="i-lucide-sun size-3" />
|
||||
</div>
|
||||
</template>
|
||||
</Switch> -->
|
||||
</div>
|
||||
</header>
|
||||
<main
|
||||
@ -41,8 +49,8 @@ function flipDark() {
|
||||
地图
|
||||
</Badge>
|
||||
<Card v-if="options.castDayNo !== -1" class="absolute right-3 top-3 z-400 p-3">
|
||||
当前发布日期是: <br>{{ castBeginDate }}<br>
|
||||
当前目标预报日期是:<br> {{ castTargetDate }}
|
||||
发布日期: <br>{{ castBeginDate }}<br>
|
||||
预报日期:<br> {{ castTargetDate }}
|
||||
</Card>
|
||||
<div class="flex-1" />
|
||||
<RouterView />
|
||||
@ -65,7 +73,7 @@ function flipDark() {
|
||||
{{ currentTcLoc.length }} 个区域预报出台风
|
||||
</div>
|
||||
</div> -->
|
||||
<div>
|
||||
<div v-if="options.renderMode === 'image'">
|
||||
<img :src="Colorbar" mx-auto max-h="60px">
|
||||
</div>
|
||||
<div grid="~ cols-2 gap-4">
|
||||
@ -104,7 +112,7 @@ function flipDark() {
|
||||
<DrawerHeader>
|
||||
<DrawerTitle>地图设置</DrawerTitle>
|
||||
<DrawerDescription>
|
||||
选择日期和渲染方式
|
||||
选择日期和展示方式
|
||||
</DrawerDescription>
|
||||
</DrawerHeader>
|
||||
<OptForm />
|
||||
@ -129,7 +137,7 @@ function flipDark() {
|
||||
<span i-mdi-play />
|
||||
{{
|
||||
options.castDayNo === -1 ? "选择一个日期后可以自动播放"
|
||||
: "开始自动播放"
|
||||
: "自动播放"
|
||||
}}
|
||||
</Button>
|
||||
<Button
|
||||
@ -139,7 +147,7 @@ function flipDark() {
|
||||
}"
|
||||
>
|
||||
<span i-material-symbols-pause />
|
||||
暂停自动播放
|
||||
暂停播放
|
||||
</Button>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user