mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-24 17:00:36 +01:00
docs(app): improve stars lazy loading
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { kebabCase } from 'scule'
|
||||
|
||||
interface Star {
|
||||
x: number
|
||||
y: number
|
||||
@@ -22,6 +24,8 @@ const props = withDefaults(defineProps<{
|
||||
speed: 'normal'
|
||||
})
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
// Generate random stars
|
||||
const generateStars = (count: number): Star[] => {
|
||||
return Array.from({ length: count }, () => {
|
||||
@@ -35,7 +39,7 @@ const generateStars = (count: number): Star[] => {
|
||||
}
|
||||
|
||||
// Generate all stars
|
||||
const stars = ref<Star[]>(generateStars(props.starCount))
|
||||
const stars = useState<Star[]>(`${kebabCase(route.path)}-sky`, () => generateStars(props.starCount))
|
||||
|
||||
// Compute twinkle animation duration based on speed
|
||||
const twinkleDuration = computed(() => {
|
||||
@@ -50,22 +54,20 @@ const twinkleDuration = computed(() => {
|
||||
|
||||
<template>
|
||||
<div class="absolute pointer-events-none z-[-1] inset-y-0 left-4 right-4 lg:right-[50%] overflow-hidden">
|
||||
<ClientOnly>
|
||||
<div
|
||||
v-for="star in stars"
|
||||
:key="star.id"
|
||||
class="star absolute"
|
||||
:style="{
|
||||
'left': `${star.x}%`,
|
||||
'top': `${star.y}%`,
|
||||
'transform': 'translate(-50%, -50%)',
|
||||
'--star-size': `${star.size}px`,
|
||||
'--star-color': color,
|
||||
'--twinkle-delay': `${star.twinkleDelay}s`,
|
||||
'--twinkle-duration': twinkleDuration
|
||||
}"
|
||||
/>
|
||||
</ClientOnly>
|
||||
<div
|
||||
v-for="star in stars"
|
||||
:key="star.id"
|
||||
class="star absolute"
|
||||
:style="{
|
||||
'left': `${star.x}%`,
|
||||
'top': `${star.y}%`,
|
||||
'transform': 'translate(-50%, -50%)',
|
||||
'--star-size': `${star.size}px`,
|
||||
'--star-color': color,
|
||||
'--twinkle-delay': `${star.twinkleDelay}s`,
|
||||
'--twinkle-duration': twinkleDuration
|
||||
}"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import { kebabCase } from 'scule'
|
||||
|
||||
interface Star {
|
||||
x: number
|
||||
y: number
|
||||
size: number
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
starCount?: number
|
||||
color?: string
|
||||
@@ -14,8 +22,10 @@ const props = withDefaults(defineProps<{
|
||||
})
|
||||
})
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
// Generate random star positions and sizes
|
||||
const generateStars = (count: number) => {
|
||||
const generateStars = (count: number): Star[] => {
|
||||
return Array.from({ length: count }, () => ({
|
||||
x: Math.floor(Math.random() * 2000),
|
||||
y: Math.floor(Math.random() * 2000),
|
||||
@@ -25,52 +35,58 @@ const generateStars = (count: number) => {
|
||||
}))
|
||||
}
|
||||
|
||||
// Compute star layers with different speeds and opacities
|
||||
const starLayers = computed(() => {
|
||||
const speedMap = {
|
||||
slow: { duration: 200, opacity: 0.5 },
|
||||
normal: { duration: 150, opacity: 0.75 },
|
||||
fast: { duration: 100, opacity: 1 }
|
||||
}
|
||||
// Define speed configurations once
|
||||
const speedMap = {
|
||||
slow: { duration: 200, opacity: 0.5, ratio: 0.3 },
|
||||
normal: { duration: 150, opacity: 0.75, ratio: 0.3 },
|
||||
fast: { duration: 100, opacity: 1, ratio: 0.4 }
|
||||
}
|
||||
|
||||
return [
|
||||
{ stars: generateStars(props.starCount), ...speedMap.fast },
|
||||
{ stars: generateStars(Math.floor(props.starCount * 0.6)), ...speedMap.normal },
|
||||
{ stars: generateStars(Math.floor(props.starCount * 0.3)), ...speedMap.slow }
|
||||
]
|
||||
// Use a more efficient approach to generate and store stars
|
||||
const stars = useState<{ slow: Star[], normal: Star[], fast: Star[] }>(`${kebabCase(route.path)}-stars`, () => {
|
||||
return {
|
||||
slow: generateStars(Math.floor(props.starCount * speedMap.slow.ratio)),
|
||||
normal: generateStars(Math.floor(props.starCount * speedMap.normal.ratio)),
|
||||
fast: generateStars(Math.floor(props.starCount * speedMap.fast.ratio))
|
||||
}
|
||||
})
|
||||
|
||||
// Compute star layers with different speeds and opacities
|
||||
const starLayers = computed(() => [
|
||||
{ stars: stars.value.fast, ...speedMap.fast },
|
||||
{ stars: stars.value.normal, ...speedMap.normal },
|
||||
{ stars: stars.value.slow, ...speedMap.slow }
|
||||
])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="absolute pointer-events-none z-[-1] inset-y-0 inset-x-5 sm:inset-x-7 lg:inset-x-9 overflow-hidden">
|
||||
<ClientOnly>
|
||||
<div class="stars size-full absolute inset-x-0 top-0">
|
||||
<div class="stars size-full absolute inset-x-0 top-0">
|
||||
<div
|
||||
v-for="(layer, index) in starLayers"
|
||||
:key="index"
|
||||
class="star-layer"
|
||||
:style="{
|
||||
'--star-duration': `${layer.duration}s`,
|
||||
'--star-opacity': layer.opacity,
|
||||
'--star-color': color
|
||||
}"
|
||||
>
|
||||
<div
|
||||
v-for="(layer, index) in starLayers"
|
||||
:key="index"
|
||||
class="star-layer"
|
||||
v-for="(star, starIndex) in layer.stars"
|
||||
:key="starIndex"
|
||||
class="star absolute rounded-full"
|
||||
:style="{
|
||||
'--star-duration': `${layer.duration}s`,
|
||||
'--star-opacity': layer.opacity,
|
||||
'--star-color': color
|
||||
left: `${star.x}px`,
|
||||
top: `${star.y}px`,
|
||||
width: `${star.size}px`,
|
||||
height: `${star.size}px`,
|
||||
backgroundColor: 'var(--star-color)',
|
||||
opacity: 'var(--star-opacity)'
|
||||
}"
|
||||
>
|
||||
<div
|
||||
v-for="(star, starIndex) in layer.stars"
|
||||
:key="starIndex"
|
||||
class="star absolute rounded-full"
|
||||
:style="{
|
||||
left: `${star.x}px`,
|
||||
top: `${star.y}px`,
|
||||
width: `${star.size}px`,
|
||||
height: `${star.size}px`,
|
||||
backgroundColor: 'var(--star-color)',
|
||||
opacity: 'var(--star-opacity)'
|
||||
}"
|
||||
/>
|
||||
</div>
|
||||
/>
|
||||
</div>
|
||||
</ClientOnly>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user