css动画 | 实现一个星空动画

172 阅读2分钟

前言

单独的vue组件,拿走即用。 css动画往往需要调节,如何会表达以及调教AI,你会得到更棒的效果

效果图

image.png

运动轨迹

image.png

全代码组件,拿走即用

<template>
  <div class="warp-container">
    <!-- 通过 v-for 渲染多颗星星 -->
    <div
        v-for="i in starCount"
        :key="i"
        class="star"
        :class="`star-${i}`"
    />
  </div>
</template>

<script setup>
/**
 * 星星总数
 * 注意:需与 SCSS 中 $star-count 同步
 */
const starCount = 500
</script>

<style lang="scss" scoped>
/* ============================================
   1. 可调参数
   ============================================ */
$star-count: 500;              // 星星数量
$max-angle: 360;               // 随机角度范围 0° ~ 360°
$max-distance: 700;            // 星星离中心的最大半径
$animation-min-duration: 5;    // 最短动画时长(秒)
$animation-max-duration: 10;   // 最长动画时长(秒)
$animation-max-delay: 5;       // 最大延迟(秒)
/* 星星大小在 1~2 像素之间,更小更低调 */
$star-min-size: 1;
$star-max-size: 2;

/* ============================================
   2. 容器设置
   ============================================ */
.warp-container {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  /* 深邃星空背景 */
  background: radial-gradient(circle, rgba(0,10,20,1) 10%, rgba(0,0,0,1) 100%);
  /* 3D 透视:值越小透视越强 */
  perspective: 1500px;
}

/* ============================================
   3. 星星通用样式
   ============================================ */
.star {
  position: absolute;
  top: 50%;
  left: 50%;
  border-radius: 50%;
  background: white;
  transform-origin: center;
  animation-name: warp;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}

/* ============================================
   4. 为每颗星星生成随机自定义属性
   ============================================ */
@for $i from 1 through $star-count {
  .star-#{$i} {
    /* 随机角度(0° ~ 360°) */
    --star-rotate: #{random($max-angle)}deg;
    /* 随机半径(0 ~ $max-distance) */
    --star-distance: #{random($max-distance)}px;
    /* 随机动画时长(5~10秒) */
    --star-duration: #{random($animation-max-duration - $animation-min-duration) + $animation-min-duration}s;
    /* 随机延迟(0~5秒) */
    --star-delay: #{random($animation-max-delay)}s;
    /* 随机大小(1~2 像素) */
    --star-size: #{random($star-max-size - $star-min-size) + $star-min-size}px;

    width: var(--star-size);
    height: var(--star-size);

    animation-duration: var(--star-duration);
    animation-delay: var(--star-delay);
  }
}

/* ============================================
   5. 动画关键帧:warp
   ============================================ */
@keyframes warp {
  /*
    优化要点:
    - 延长整体动画时长,让星星慢慢飞过
    - 减少最终 scale,避免后期过度放大
    - 在 60% 左右加个中间帧,让前半段保持较佳观感
  */
  0% {
    /* 星星刚出现:位于随机角度/半径,z=0,体积很小,透明度0 */
    transform: rotate(var(--star-rotate))
    translateX(var(--star-distance))
    translateZ(0)
    scale(0.2);
    opacity: 0;
  }
  15% {
    /* 前 15% 渐入至不透明 */
    opacity: 1;
  }
  60% {
    /* 中间帧:星星已飞出一定距离,体积变大 */
    transform: rotate(var(--star-rotate))
    translateX(var(--star-distance))
    translateZ(600px)
    scale(1.1);
    opacity: 1;
  }
  100% {
    /* 最终:飞到更远距离,稍微再变大,逐渐消失 */
    transform: rotate(var(--star-rotate))
    translateX(var(--star-distance))
    translateZ(1200px)
    scale(1.2);
    opacity: 0;
  }
}
</style>