67 lines
1.5 KiB
Vue
67 lines
1.5 KiB
Vue
<template>
|
|
<view class="wave-container" :style="{ background }">
|
|
<view v-for="(bar, index) in bars" :key="index" class="bar" :style="getBarStyle(index)" />
|
|
</view>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { computed } from 'vue';
|
|
|
|
const props = defineProps({
|
|
background: {
|
|
type: String,
|
|
default: 'linear-gradient(to right, #377dff, #9a60ff)',
|
|
},
|
|
});
|
|
|
|
// 默认参数(不暴露)
|
|
const barCount = 20;
|
|
const barWidth = 4;
|
|
const barHeight = 40;
|
|
const barRadius = 2;
|
|
const duration = 1200;
|
|
const gap = 4;
|
|
|
|
const bars = computed(() => new Array(barCount).fill(0));
|
|
|
|
const getBarStyle = (index) => {
|
|
const delay = (index * (duration / barCount)) % duration;
|
|
return {
|
|
width: `${barWidth}rpx`,
|
|
height: `${barHeight}rpx`,
|
|
background: '#fff',
|
|
borderRadius: `${barRadius}rpx`,
|
|
animation: `waveAnim ${duration}ms ease-in-out ${delay}ms infinite`,
|
|
transformOrigin: 'bottom center',
|
|
};
|
|
};
|
|
</script>
|
|
|
|
<style scoped>
|
|
.wave-container {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
padding: 16rpx;
|
|
border-radius: 36rpx;
|
|
height: calc(102rpx - 40rpx);
|
|
gap: 4rpx;
|
|
/* background: linear-gradient(90deg, #9e74fd 0%, #256bfa 100%); */
|
|
box-shadow: 0rpx 8rpx 40rpx 0rpx rgba(0, 54, 170, 0.15);
|
|
}
|
|
|
|
@keyframes waveAnim {
|
|
0%,
|
|
100% {
|
|
transform: scaleY(0.4);
|
|
}
|
|
50% {
|
|
transform: scaleY(1);
|
|
}
|
|
}
|
|
|
|
.bar {
|
|
transform-origin: bottom center;
|
|
}
|
|
</style>
|