Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | 25x 25x 25x 25x 25x 25x 24x 72x 73x | <script setup lang="ts">
import { computed } from 'vue'
import { scaleSize, toCssSize } from '../../../utils/size'
interface Props {
size?: number | string
color?: string
speed?: number
}
const props = withDefaults(defineProps<Props>(), {
size: 40,
color: 'currentColor',
speed: 1,
})
const boxSize = computed(() => toCssSize(props.size))
const dotSize = computed(() => scaleSize(props.size, '/', 5))
const duration = computed(() => {
const speed = props.speed > 0 ? props.speed : 1
return 1 / speed
})
</script>
<template>
<div
class="vslk-pulse-orbit"
:style="{
width: boxSize,
height: boxSize,
color: props.color,
}"
>
<span
v-for="i in 3"
:key="i"
class="dot"
:style="{
width: dotSize,
height: dotSize,
backgroundColor: props.color,
animationDuration: duration + 's',
animationDelay: ((i - 1) * duration / 3) + 's'
}"
/>
</div>
</template>
<style scoped>
.vslk-pulse-orbit {
position: relative;
display: flex;
align-items: center;
justify-content: center;
gap: 16%;
}
/* سه نقطه روی یک خط افقی، با فاصله نسبی */
.dot {
flex: 0 0 auto;
aspect-ratio: 1 / 1;
border-radius: 50%;
transform-origin: center;
animation-name: vslk-pulse-orbit-pulse;
animation-timing-function: ease-in-out;
animation-iteration-count: infinite;
will-change: transform;
}
@keyframes vslk-pulse-orbit-pulse {
0% {
transform: translateY(-25%) scale(0.7);
opacity: 0.5;
}
35% {
transform: translateY(10%) scale(1.35);
opacity: 1;
}
60% {
transform: translateY(10%) scale(1.35);
opacity: 1;
}
100% {
transform: translateY(-25%) scale(0.7);
opacity: 0.5;
}
}
</style> |