css vue vite实现闪烁的呼吸效果

效果如上所示:

代码如下所示

js 复制代码
<template>
  <div class="pulse-container">
    <!-- 核心小圆点 -->
    <div class="pulse-core"></div>

    <!-- 多重光环:3 层 -->
    <div
        v-for="(ring, index) in rings"
        :key="index"
        class="pulse-ring"
        :style="{
        width: ring.size + 'px',
        height: ring.size + 'px',
        backgroundColor: ring.color,
        boxShadow: `0 0 ${ring.blur}px ${ring.color}`,
        animationDelay: index * 0.06 + 's' /* 50px下,延迟极短,避免挤在一起 */
      }"
    ></div>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const rings = ref([
  { size: 20, color: 'rgba(168, 71, 47, 0.85)', blur: 6 },
  { size: 35, color: 'rgba(210, 135, 115, 0.6)', blur: 12 },
  { size: 50, color: 'rgba(235, 190, 175, 0.3)', blur: 20 }
])
</script>

<style scoped>
.pulse-container {
  position: relative;
  width: 50px;
  height: 50px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.pulse-ring {
  position: absolute;
  border-radius: 50%;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) scale(0);
  opacity: 0;
  /*
    总时长 1 秒
    使用 cubic-bezier(0.5, 0, 0.5, 1) 实现匀加速-匀减速对称
    让变大和变小看起来用时完全相等,节奏一致
  */
  animation: pulse-wave-symmetry 1s cubic-bezier(0.5, 0, 0.5, 1) infinite;
}

.pulse-core {
  position: absolute;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: #4a1a10;
  z-index: 10;
  box-shadow: 0 0 4px rgba(74, 26, 16, 0.8);
  animation: core-pulse-symmetry 1s cubic-bezier(0.5, 0, 0.5, 1) infinite;
}

/* --- 完美对称的动画关键帧 --- */
/* 0% -> 50% 变大 (耗时 0.5s) */
/* 50% -> 100% 变小 (耗时 0.5s) */

@keyframes pulse-wave-symmetry {
  0% {
    transform: translate(-50%, -50%) scale(0);
    opacity: 1;
  }
  50% {
    /* 在此处达到最大,正好过去 0.5 秒 */
    transform: translate(-50%, -50%) scale(1.2);
    opacity: 0.5;
  }
  100% {
    /* 再过去 0.5 秒,回到起点 */
    transform: translate(-50%, -50%) scale(0);
    opacity: 0;
  }
}

/* 核心点的呼吸也完美对称 */
@keyframes core-pulse-symmetry {
  0% {
    transform: scale(0.8);
    opacity: 0.8;
  }
  50% {
    /* 在 0.5 秒时变大到最大 */
    transform: scale(1.1);
    opacity: 1;
  }
  100% {
    /* 1 秒时缩回最小 */
    transform: scale(0.8);
    opacity: 0.8;
  }
}
</style>
相关推荐
默_笙2 小时前
🎃 前端学了 Next.js,后端该学啥?NestJS 就是 Node 版的蜜雪冰城
前端·javascript
এ慕ོ冬℘゜3 小时前
navigator 导航对象 BOM制作方法
javascript
慧一居士5 小时前
Vite项目中使用Less步骤,详细使用示例
前端·css
kyriewen5 小时前
面试官让我用 AI 重构一个 8 年陈的 React 组件——他说他不看代码,只看我会不会拆
前端·javascript·面试
Jacky19996 小时前
Electron + Vue 3 桌面打字游戏实战:从 VSCode 扩展到独立应用的架构改造
javascript
用户50093768390397 小时前
热敏小票 Web 打印:我在 58/80mm 上折腾的两周
前端·vue.js
柚yuzumi8 小时前
别再猜 this:先看它属于谁,再看它指向谁
前端·javascript
汉堡大王95278 小时前
面试必考:手写代码 new 做了什么?从原理到实现全解析
前端·javascript·面试
BillKu8 小时前
TypeScript中,字符串字面量联合类型(Union Type)、enum的用法说明
前端·javascript·typescript
慧一居士9 小时前
Sass和Less功能、使用场景、用法对比
前端·css·less·sass