Vue 3动画角色登录页:从创意到优化

张开发
2026/4/16 14:11:42 15 分钟阅读

分享文章

Vue 3动画角色登录页:从创意到优化
Vue 3 动画角色登录页面从创意实现到性能优化本文基于 GitHub 开源项目进行学习和优化实践原项目地址https://github.com/marker964/animated-characters-login-page项目简介今天给大家分享一个有趣的 Vue 3 登录页面项目 ——CareerCompass。这个项目的亮点在于左侧有四个可爱的动画角色它们会根据用户的输入行为做出不同的反应眼睛跟随鼠标- 角色的眼睛会追踪鼠标移动输入邮箱时- 角色会变高仿佛在关注你的输入输入密码时- 角色会用手遮挡眼睛保护隐私显示密码时- 角色会偷偷偷看增添趣味性技术栈Vue 3- 使用 Composition APIVite- 极速开发构建工具Tailwind CSS- 现代化 CSS 框架tailwindcss-animate- 动画增强插件核心实现思路1. 眼睛追踪原理眼睛追踪的核心是计算鼠标相对于眼睛中心的位置然后根据角度和距离计算瞳孔的偏移constcalculatePupilPosition(eyeRef,mouseX,mouseY,maxDistance){constrecteyeRef.getBoundingClientRect()constcenterXrect.leftrect.width/2constcenterYrect.toprect.height/2constdeltaXmouseX-centerXconstdeltaYmouseY-centerY// 限制瞳孔移动距离防止超出眼球范围constdistanceMath.min(Math.sqrt(deltaX**2deltaY**2),maxDistance)constangleMath.atan2(deltaY,deltaX)return{x:Math.cos(angle)*distance,y:Math.sin(angle)*distance}}2. 角色状态响应通过 Vue 的响应式系统我们可以轻松实现角色对不同状态的响应script setup const props defineProps({ isTyping: { type: Boolean, default: false }, showPassword: { type: Boolean, default: false }, passwordLength: { type: Number, default: 0 } }) // 判断是否处于遮挡密码状态 const isHidingPassword computed(() props.passwordLength 0 !props.showPassword ) // 角色变高的条件 const shouldGrow computed(() props.isTyping || isHidingPassword.value ) /script3. 角色身体变形使用 CSStransform: skewX()实现角色身体的倾斜效果让角色看起来更生动template div classcharacter :style{ transform: shouldGrow ? skewX(${bodySkew - 12}deg) translateX(40px) : skewX(${bodySkew}deg), transformOrigin: bottom center } / /template性能优化历程在项目初版中我发现了几个性能问题经过优化后效果显著提升。问题一重复的鼠标事件监听初版代码中三个组件各自监听了mousemove事件// EyeBall.vueonMounted(()window.addEventListener(mousemove,onMouseMove))// Pupil.vueonMounted(()window.addEventListener(mousemove,onMouseMove))// AnimatedCharacters.vueonMounted(()window.addEventListener(mousemove,onMouseMove))这意味着每次鼠标移动会触发3 次事件处理优化方案Composable 单例模式创建useMousePositioncomposable使用单例模式共享鼠标位置// src/composables/useMousePosition.jsimport{ref}fromvue// 单例全局共享letmouseXref(0)letmouseYref(0)letisListeningfalseexportfunctionuseMousePosition(){if(!isListening){window.addEventListener(mousemove,onMouseMove,{passive:true})isListeningtrue}return{mouseX,mouseY}}问题二高频事件无节流mousemove是高频事件每秒可能触发数十次导致computed计算过于频繁。优化方案requestAnimationFrame 节流letrafIdnullletpendingX0letpendingY0constonMouseMove(e){pendingXe.clientX pendingYe.clientY// 使用 rAF 节流每帧最多更新一次if(!rafId){rafIdrequestAnimationFrame((){mouseX.valuependingX mouseY.valuependingY rafIdnull})}}问题三冗长的 inline CSS class初版 App.vue 中input 元素的 class 超过 200 字符!-- 优化前 -- input classlogin-input flex w-full rounded-full border px-4 py-2 text-base ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm h-12 bg-background border-border/60 focus:border-primary /优化方案提取 CSS 类/* src/style.css */.login-input{applyflex w-full rounded-full border px-4 py-2 text-base ring-offset-background;applyplaceholder:text-muted-foreground;applyfocus-visible:outline-nonefocus-visible:ring-2focus-visible:ring-ring;applyh-12 bg-background border-border/60;}.login-input:focus{applyborder-primary;}!-- 优化后 -- input classlogin-input /可访问性改进添加键盘支持密码显示切换按钮初版只支持鼠标点击优化后添加了键盘支持button clickshowPassword !showPassword keydown.entershowPassword !showPassword keydown.space.preventshowPassword !showPassword classfocus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring !-- 眼睛图标 -- /button本地化图片资源初版使用外部 URL 加载 Logo 图片存在加载失败风险!-- 优化前 -- img srchttps://i-postimg.cc/nLrDYrHW/icon.png /优化后将图片存入本地src/assets/!-- 优化后 -- img src./assets/logo.svg /项目结构src/ ├── assets/ │ └── logo.svg # 本地化 Logo ├── components/ │ ├── AnimatedCharacters.vue # 主角色组件 │ ├── EyeBall.vue # 眼球组件带眨眼 │ ├── Pupil.vue # 瞳孔组件 │ └── InteractiveHoverButton.vue # 悬浮按钮 ├── composables/ │ ├── useMousePosition.js # 鼠标位置追踪 │ └── useEyeTracking.js # 眼睛追踪计算 ├── App.vue # 主应用 ├── main.js # 入口文件 └── style.css # 全局样式运行项目# 安装依赖npminstall# 启动开发服务器npmrun dev# 构建生产版本npmrun build总结本文基于 GitHub 开源项目进行学习和二次优化展示了如何利用 Vue 3 Composition API构建响应式动画组件通过 Composables实现逻辑复用和性能优化使用 requestAnimationFrame节流高频事件提取 CSS 类提高代码可维护性注重可访问性添加键盘交互支持GitHub 原项目地址https://github.com/marker964/animated-characters-login-pageGitee 优化版地址https://gitee.com/gomes/animated-characters-login-page如果觉得有帮助欢迎点赞收藏有什么问题可以在评论区讨论。

更多文章