当前位置: 首页 > news >正文

50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | ButtonRippleEffect(按钮涟漪效果)

📅 我们继续 50 个小项目挑战!—— ButtonRippleEffect组件

仓库地址:https://github.com/SunACong/50-vue-projects

项目预览地址:https://50-vue-projects.vercel.app/
在这里插入图片描述


使用 Vue 3 的 Composition API 和 <script setup> 语法结合 TailwindCSS 构建一个带有点击波纹动画效果的按钮组件。这个按钮在点击时会从点击位置生成一个扩散的“涟漪”动画,增强用户交互体验。

🎯 组件目标

  • 创建一个具有点击波纹动画的按钮
  • 波纹动画从点击位置开始扩散
  • 支持多个连续点击的波纹动画
  • 使用 TailwindCSS 快速构建现代 UI 界面
  • 使用 Vue 3 Composition API 管理状态和事件

⚙️ 技术实现点

技术点描述
Vue 3 Composition API (<script setup>)使用响应式变量管理组件状态
ref 响应式变量存储波纹的位置与尺寸
@click 事件绑定触发波纹动画生成
getBoundingClientRect()获取按钮在页面中的位置
TailwindCSS 动画类构建美观的波纹扩散动画
setTimeout 定时清理控制波纹动画结束后的清除逻辑

🧱 组件实现

模板结构 <template>

<template><div class="flex h-screen items-center justify-center bg-gray-900"><buttonclass="relative h-20 w-48 overflow-hidden rounded-lg bg-blue-500 font-bold text-white transition-colors hover:bg-blue-600 active:bg-blue-700"@click="addRipple">Click Me<spanv-for="(ripple, index) in ripples":key="index":style="{left: ripple.x + 'px',top: ripple.y + 'px',width: ripple.size + 'px',height: ripple.size + 'px',}"class="animate-ripple pointer-events-none absolute rounded-full bg-white/50 opacity-0"></span></button></div>
</template>

脚本逻辑 <script setup>

<script setup>
import { ref } from 'vue'const ripples = ref([])const addRipple = (event) => {const button = event.currentTargetconst rect = button.getBoundingClientRect()const x = event.clientX - rect.leftconst y = event.clientY - rect.topconst size = Math.max(button.offsetWidth, button.offsetHeight)ripples.value.push({ x, y, size })// 300ms 后移除最早添加的波纹,与动画持续时间匹配setTimeout(() => {ripples.value.shift()}, 300)
}
</script>

自定义样式 <style scoped>

<style scoped>
@keyframes ripple {0% {transform: translate(-50%, -50%) scale(0);opacity: 1;}100% {transform: translate(-50%, -50%) scale(4);opacity: 0;}
}.animate-ripple {animation: ripple 0.3s ease-out;
}
</style>

🔍 重点效果实现

✅ 波纹动画触发逻辑

通过 @click 事件获取点击坐标,并计算相对于按钮左上角的位置:

const x = event.clientX - rect.left
const y = event.clientY - rect.top

再根据按钮宽高确定波纹的最大扩散范围:

const size = Math.max(button.offsetWidth, button.offsetHeight)

然后将该波纹对象加入数组中,由模板循环渲染出对应的 <span> 元素。

💡 波纹动画样式

我们使用 CSS 自定义了一个名为 ripple 的动画,从中心缩放并逐渐消失:

@keyframes ripple {0% {transform: translate(-50%, -50%) scale(0);opacity: 1;}100% {transform: translate(-50%, -50%) scale(4);opacity: 0;}
}

并通过 .animate-ripple 类应用到每个波纹元素上。

🗑️ 波纹清理机制

每次添加新波纹后,设置一个定时器(0.3 秒)来移除最早的那个波纹,避免内存堆积:

setTimeout(() => {ripples.value.shift()
}, 300)

🎨 TailwindCSS 样式重点讲解

类名作用
h-screen, items-center, justify-center设置全屏高度并垂直居中布局
bg-gray-900设置深色背景
relative为按钮设置相对定位,方便内部绝对定位的波纹元素
h-20, w-48设置按钮高度和宽度
rounded-lg圆角按钮
bg-blue-500, hover:bg-blue-600, active:bg-blue-700按钮颜色及悬停、激活状态下的变色效果
font-bold, text-white文字加粗和白色字体
transition-colors添加颜色变化的过渡动画
absolute, rounded-full, bg-white/50波纹元素的基本样式
pointer-events-none避免波纹干扰按钮点击事件
opacity-0初始隐藏波纹,由动画控制显示

这些 Tailwind 工具类帮助我们快速构建了一个视觉丰富、交互性强的按钮组件。


📁 常量定义 + 组件路由

constants/index.js 添加组件预览常量:

{id: 20,title: 'Button Ripple Effect',image: 'https://50projects50days.com/img/projects-img/20-button-ripple-effect.png',link: 'ButtonRippleEffect',},

router/index.js 中添加路由选项:

{path: '/ButtonRippleEffect',name: 'ButtonRippleEffect',component: () => import('@/projects/ButtonRippleEffect.vue'),},

🏁 总结

扩展的功能推荐:

  • 支持不同颜色主题的波纹按钮
  • 支持禁用状态下的点击无反应
  • 支持自定义波纹颜色或透明度
  • 多个按钮共享波纹动画逻辑(封装为可复用组件)

感谢阅读,欢迎点赞、收藏和分享 😊


👉 下一篇,我们将完成DragNDrop组件,一个非常有意思的拖拽组件,可以对元素进行重新排列。🚀

http://www.lryc.cn/news/579287.html

相关文章:

  • springboot切面编程
  • Softhub软件下载站实战开发(十):实现图片视频上传下载接口
  • 全角半角空格在网页中占位符和编码emsp;ensp;
  • CentOS 6操作系统安装
  • 毫米波雷达 – 深度学习
  • ubuntu 22.04 LTS 安装preempt-rt
  • C++2d我的世界V1.4
  • 模型预测专题:强鲁棒性DPCC
  • YOLOv11剪枝与量化(二)通道剪枝技术原理
  • Dify 工作流全栈解析:从零构建你的 AI 应用流程引擎
  • 【Java面试】Redis的poll函数epoll函数区别?
  • springboot 显示打印加载bean耗时工具类
  • 【大模型学习 | MINIGPT-4原理】
  • MYSQL基础内容
  • dial tcp 10.1.68.88:3306: connect: cannot assign requested address
  • Python 数据分析:numpy,说人话,说说数组维度。听故事学知识点怎么这么容易?
  • 深度剖析NumPy核心函数reshape()
  • 使用Scapy构造OSPF交互报文欺骗网络设备与主机建立Full关系
  • Python 高光谱分析工具(PyHAT)
  • 【Linux】不小心又创建了一个root权限账户,怎么将它删除?!
  • 数据结构与算法:贪心(二)
  • Docker Compose 基础——AI教你学Docker
  • 鸿蒙UI框架深度解析:对比Android/iOS的布局适配与组件设计
  • 优雅草蜻蜓T语音会议系统私有化部署方案与RTC技术深度解析-优雅草卓伊凡|clam
  • 【字节跳动】数据挖掘面试题0002:从转发数据中求原视频用户以及转发的最长深度和二叉排序树指定值
  • gin框架 中间件 是在判断路由存在前执行还是存在后执行的研究
  • 人工智能-基础篇-14-知识库和知识图谱介绍(知识库是基石、知识图谱是增强语义理解的知识库、结构化数据和非结构化数据区分)
  • ubentu服务器版本安装Dify
  • docker拉取redis并使用
  • 代码训练LeetCode(44)螺旋矩阵