尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

vue3 随机生产音符扩散效果

vue3 随机生产音符扩散效果
📅 发布时间:2026/6/20 0:44:47
  1 <template>
  2   <div class="container">
  3     <div class="flower-center"></div>
  4     <div 
  5       class="note-petal"
  6       v-for="note in activeNotes"
  7       :key="note.id"
  8       :style="note.style"
  9     >
 10       {{ note.symbol }}
 11     </div>
 12     <div class="controls">
 13       <button @click="toggleAnimation">{{ isPlaying ? '暂停动画' : '播放动画' }}</button>
 14     </div>
 15   </div>
 16 </template>
 17 
 18 <script setup>
 19 import { ref, onMounted, onUnmounted } from 'vue'
 20 
 21 const activeNotes = ref([])
 22 const isPlaying = ref(true)
 23 let animationInterval = null
 24 let noteCounter = 0
 25 
 26 const noteSymbols = ['♪', '♫', '♩', '♬', '♭', '♮', '♯']
 27 const colors = [
 28   '#ff6b6b', '#4ecdc4', '#ffbe76', 
 29   '#a5d8ff', '#d8b4fe', '#ff9e9e', '#b5ead7'
 30 ]
 31 
 32 function createPetalGroup() {
 33   const newNotes = []
 34   // 随机生成5-12个音符
 35   const noteCount = Math.floor(Math.random() * 8) + 5
 36   
 37   for (let i = 0; i < noteCount; i++) {
 38     const angle = (i * (Math.PI * 2 / noteCount)) + (Math.random() * 0.5 - 0.25)
 39     const distance = 300 + Math.random() * 150
 40     const endX = Math.cos(angle) * distance
 41     const endY = Math.sin(angle) * distance
 42     const rotation = (Math.random() * 60 - 30)
 43     
 44     const noteId = `note-${Date.now()}-${noteCounter++}`
 45     
 46     newNotes.push({
 47       id: noteId,
 48       symbol: noteSymbols[Math.floor(Math.random() * noteSymbols.length)],
 49       style: {
 50         color: colors[Math.floor(Math.random() * colors.length)],
 51         '--end-x': `${endX}px`,
 52         '--end-y': `${endY}px`,
 53         '--rotation': `${rotation}deg`,
 54         'animation-duration': `${3 + Math.random() * 1.5}s`
 55       }
 56     })
 57   }
 58   
 59   activeNotes.value = [...activeNotes.value, ...newNotes]
 60   
 61   setTimeout(() => {
 62     activeNotes.value = activeNotes.value.filter(note => !newNotes.some(newNote => newNote.id === note.id))
 63   }, 4000)
 64 }
 65 
 66 function startAnimation() {
 67   if (animationInterval) clearInterval(animationInterval)
 68   createPetalGroup()
 69   animationInterval = setInterval(createPetalGroup, 1200)
 70   isPlaying.value = true
 71 }
 72 
 73 function stopAnimation() {
 74   clearInterval(animationInterval)
 75   isPlaying.value = false
 76 }
 77 
 78 function toggleAnimation() {
 79   if (isPlaying.value) {
 80     stopAnimation()
 81   } else {
 82     startAnimation()
 83   }
 84 }
 85 
 86 onMounted(() => {
 87   startAnimation()
 88 })
 89 
 90 onUnmounted(() => {
 91   stopAnimation()
 92 })
 93 </script>
 94 
 95 <style>
 96 .container {
 97   position: relative;
 98   width: 100vw;
 99   height: 100vh;
100   background: radial-gradient(circle at center, #1a2a6c, #2a5298);
101   overflow: hidden;
102 }
103 
104 .flower-center {
105   position: absolute;
106   width: 120px;
107   height: 120px;
108   top: 50%;
109   left: 50%;
110   transform: translate(-50%, -50%);
111   background: radial-gradient(circle, rgba(255,255,255,0.9) 0%, rgba(255,255,255,0) 80%);
112   border-radius: 50%;
113   z-index: 1;
114   animation: flowerPulse 3s ease-in-out infinite;
115 }
116 
117 @keyframes flowerPulse {
118   0%, 100% { transform: translate(-50%, -50%) scale(1); opacity: 0.8; }
119   50% { transform: translate(-50%, -50%) scale(1.4); opacity: 1; }
120 }
121 
122 .note-petal {
123   position: absolute;
124   font-size: 48px;
125   top: 50%;
126   left: 50%;
127   transform: translate(-50%, -50%);
128   animation: petalBloom 4s ease-out forwards;
129   opacity: 0;
130   text-shadow: 0 0 20px currentColor;
131   z-index: 10;
132   will-change: transform, opacity;
133 }
134 
135 @keyframes petalBloom {
136   0% {
137     transform: translate(-50%, -50%) scale(0.5) rotate(0deg);
138     opacity: 0;
139     filter: blur(3px);
140   }
141   20% {
142     opacity: 1;
143     transform: translate(-50%, -50%) scale(1) rotate(0deg);
144     filter: blur(0);
145   }
146   80% {
147     opacity: 0.7;
148   }
149   100% {
150     transform: translate(var(--end-x), var(--end-y)) scale(0.3) rotate(var(--rotation));
151     opacity: 0;
152     filter: blur(2px);
153   }
154 }
155 
156 .controls {
157   position: absolute;
158   bottom: 40px;
159   left: 50%;
160   transform: translateX(-50%);
161   z-index: 100;
162 }
163 
164 button {
165   padding: 12px 24px;
166   background: linear-gradient(45deg, #ff6b6b, #ff8e8e);
167   border: none;
168   border-radius: 30px;
169   color: white;
170   font-weight: bold;
171   cursor: pointer;
172   transition: all 0.3s;
173   box-shadow: 0 4px 15px rgba(255, 107, 107, 0.4);
174 }
175 
176 button:hover {
177   transform: translateY(-3px);
178   box-shadow: 0 6px 20px rgba(255, 107, 107, 0.6);
179 }
180 </style>

 

惟精惟一,允执厥中

相关新闻

  • ASM1042A3S车规级CANFD芯片在两轮车和平衡车控制器优秀的方案中的技术应用
  • 2025年别墅供暖厂家权威推荐榜单:别墅锅炉/联排别墅供暖/小别墅供暖源头厂家精选
  • 2025年11月央国企求职机构选择指南:权威榜单与避坑要点

最新新闻

  • Mac上的Windows启动盘制作革命:WinDiskWriter全方位指南
  • 2026行业内优秀非法吸收公众存款罪刑事律师口碑推荐 - 品牌排行榜
  • 实战测试10款降AI率软件:帮你锁定达标神器
  • 解析2026年武汉会展场地对接服务:如何甄选兼具资源与实力的靠谱合作伙伴 - 品牌鉴赏官2026
  • JavaScript DXF Writer终极指南:在浏览器中生成CAD图纸的完整教程
  • 北京大理石修补推荐良匠千艺2026口碑榜 - 我叫一

日新闻

  • 信任的进化:技术实现详解——如何用JavaScript构建博弈论模拟器
  • Terrakube自定义工作流:如何集成OPA、Infracost等工具扩展IaC能力
  • grunt-concurrent快速入门:5分钟学会并行运行Grunt任务

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号