vue3 随机生产音符扩散效果

news/2025/11/22 10:37:22/文章来源:https://www.cnblogs.com/wq2333/p/19255697
  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>

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/972856.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ASM1042A3S车规级CANFD芯片在两轮车和平衡车控制器优秀的方案中的技术应用

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

2025抚州一对一辅导测评排行榜:高性价比平台推荐,提分效果实测

在临川、东乡、南城、南丰、崇仁、乐安、金溪、黎川、宜黄、资溪、广昌11县(区)及高新区、东临新区2个功能区,家长们正被相似的教育焦虑困扰:孩子数学压轴题卡壳、英语听力频繁丢分,语文阅读理解抓不住得分点,理…

Linux中: 一个服务器上运行多个Redis服务,应该保证哪些配置不一致

Linux中: "一个服务器上运行多个Redis服务,应该保证哪些配置不一致"在同一台服务器上运行多个 Redis 实例时,需要确保每个实例具有独立且不冲突的配置。重点需要保证以下四个配置不冲突:监听的端口指定的…

青岛市一对一教育机构推荐,2026课外家教补习机构权威排行榜

"老师教学质量参差不齐怎么办?""课程费用到底值不值?""万一效果不好能退费吗?"这三个核心问题,正困扰着市南、市北、李沧、崂山、城阳、西海岸新区、即墨、胶州、平度、莱西等地的众…

AI元人文:首论客观值的表征

AI元人文:首论客观值的表征 —— 构建人机价值对齐的工程基石 摘要: 本文立足于“AI元人文”理论框架,首次系统性地论述其核心工程要素——“客观值”的表征问题。文章首先阐释了为何该问题在理论雏形阶段后才成为焦…

2025吉安市一对一辅导测评排行榜:高性价比平台权威推荐

一、开篇:吉安家长的辅导困境与测评背景 在吉安,无论是吉州区、青原区的城区家庭,还是吉安县、泰和县、永丰县、遂川县、万安县、安福县、永新县、峡江县、新干县的乡镇家庭,都绕不开孩子的学科辅导难题。数学函数…

2025年别墅供暖厂家权威推荐榜单:别墅锅炉/联排别墅供暖/小别墅供暖源头厂家精选

在高端分户采暖需求日益增长的今天,别墅供暖系统正朝着高效节能、智能控制与个性化定制的方向快速发展。 别墅供暖市场近年来呈现出年均12%以上的稳定增长,高端住宅对分户采暖系统的需求持续攀升。随着"双碳&qu…

面向对象第一次大作业 - nanqiu

一、前言 1. 核心知识点 三次pta大作业围绕电梯调度展开,核心知识点逐渐深入:基础语法:从简单的输入输出、条件判断、循环,到枚举(enum)、类与对象的使用。 数据结构:用到了链表(LinkedList)存储请求队列,哈…

2025年11月央国企求职机构选择指南:权威榜单与避坑要点

随着就业市场竞争日益激烈,越来越多的求职者将目光投向稳定性强、福利体系完善的央国企单位。2025年,央国企招聘规模持续扩大,但求职者面临信息不对称、招聘流程复杂、竞争激烈等现实挑战。根据教育部数据显示,202…

济南市一对一培训机构排行榜:权威榜单发布2026年综合评分前十强机构推荐

在济南,从历下区、市中区的教育高地,到槐荫区、天桥区的资源聚集地,再到历城区、长清区、章丘区、济阳区、莱芜区、钢城区、平阴县、商河县的广大家庭,每一位重视教育的家长,或许都曾在深夜自问:“投入了不菲的学…

2025年高浮雕优质厂家权威推荐榜单:石浮雕/大理石浮雕/中式石浮雕源头厂家精选

在公共艺术与建筑装饰需求持续增长的今天,高浮雕作品以其独特的立体感和艺术表现力,成为众多市政工程、商业空间与文旅项目的焦点。 高浮雕作为一种兼具艺术性与实用性的石材加工产品,近年来市场规模持续扩大。行业…

2025 年 11 月预制袋套袋机,袋中袋套袋机,食品套袋机,八边封套袋机最新推荐,产能、专利、环保三维数据透视!

引言 在全球包装行业自动化升级的趋势下,食品套袋机与八边封套袋机作为关键包装设备,其产能效率、专利技术应用与环保性能直接决定企业生产竞争力。据国际包装机械协会(IPMA)最新测评数据显示,全球优质套袋机品牌…

2025 年 11 月侧推式套袋机,卧式套袋机,M型袋套袋机最新推荐,产能、专利、环保三维数据透视!

引言 在全球包装设备智能化升级的浪潮中,卧式套袋机与 M 型袋套袋机作为后道包装的核心设备,其产能效率、专利技术应用与环保性能直接决定企业生产竞争力。据国际包装机械协会(IPMA)最新测评数据显示,全球该类设备…

AT AGC005 题解

AT AGC005 EditorialA 栈维护括号匹配,\(S \to (, T \to )\)。 #include <bits/stdc++.h>using i64 = long long;void solve() {std::string s;std::cin >> s;std::stack<char> stc;for (auto i : …

Spring Security-PasswordEncoder密码解析器详解和自定义登录逻辑

在Spring Security中,BCryptPasswordEncoder是一个非常强大的工具,用于对密码进行加密,以确保存储的密码的安全性。 BCrypt是一种基于Blowfish密码哈希函数的加密算法,专门设计为防止通过彩虹表攻击和暴力破解等常…

2025 胶管厂家最新推荐排行榜:耐高压 35MPa / 热熔 / 特种工况优质品牌精选矿用/大口径吸排泥/低压/耐高温/钢丝编制/输油胶管公司推荐

引言 在工业生产、石油钻探、工程机械等核心领域,胶管作为流体输送关键部件,其耐压性、耐腐蚀性与适配性直接决定生产安全与效率。据国际流体输送设备协会(IFTA)最新测评数据显示,全球胶管市场不合格产品发生率达…

2025 装盒机厂家最新推荐排行榜:全自动 / 食品 / 纸巾 / 卫生巾装盒机权威测评,技术创新与整线配套能力

引言 在全球包装工业智能化升级的浪潮中,装盒机作为后道包装核心设备,其性能稳定性、智能化水平与整线适配能力直接决定生产效率与产品品质。当前市场品牌繁杂,设备质量差异显著,诸多企业面临产能不足、人工成本高…

模板进阶:从非类型参数到分离编译,吃透 C++ 泛型编程的核心逻辑 - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

机械 / 汽车 / 电子设计师必看!Creo 11.0 下载安装,创成式设计 + 实时仿真

Creo 11.0 是 PTC 公司推出的一款高性能 3D CAD 设计软件,主打适配电气化、复合材料设计等多个前沿领域,在建模效率、跨领域协作、仿真与制造适配等方面都做了大幅增强,广泛适用于机械设计、汽车工程、电子产品研发…

Linux 中截取文本的最后几个字符

001、 awk 实现[root@PC1 test2]# ls a.txt [root@PC1 test2]# cat a.txt 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 [root@PC1 test2]# awk {print substr($0, length($0) - 2)} a.txt …