cyber/src/pages/accountPages/Account_userInfo.vue
Guarp 2c367ad0ba 修复了在屏幕边缘不能滚动的bug
添加双端逻辑
将导航栏标签居中
修改页面选择栏
新增编辑器表格样式
新增用户管理
更换新logo
2025-02-26 18:27:47 +08:00

150 lines
3.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup>
import {ref, onMounted, onBeforeUnmount} from 'vue'
import store from "../../store/index.js";
const avatarRef = ref(null)
const redCoverRef = ref(null);
let animationFrame = null
let rotateSpeed = 0
let rotateValue = 0
let redValue = 0;
let maxSpeed = 16 // 最大旋转速度(度/帧)
let shakeIntensity = 0 // 抖动强度
let isHovering = false
const animate = () => {
if (!isHovering || !avatarRef.value || !redCoverRef.value) return
// 加速逻辑
rotateSpeed += 0.01;
rotateValue += rotateSpeed;
if (rotateSpeed > maxSpeed) {
// 达到最大速度后开始增加抖动强度
shakeIntensity = Math.min(shakeIntensity + 0.2, 500)
}
redValue = Math.min(redValue + 0.0001, 0.8);
// 生成抖动偏移
const shakeX = (Math.random() - 0.5) * shakeIntensity
const shakeY = (Math.random() - 0.5) * shakeIntensity
// 应用变换
avatarRef.value.style.transform = `
translate(${shakeX}px, ${shakeY}px)
rotate(${rotateValue}deg)
`
redCoverRef.value.style.opacity = redValue;
animationFrame = requestAnimationFrame(animate)
}
const resetState = () => {
rotateSpeed = 0
redValue = 0;
shakeIntensity = 0
if (avatarRef.value) {
avatarRef.value.style.transform = 'none'
redCoverRef.value.style.opacity = '0'
}
}
const handleMouseEnter = () => {
isHovering = true
animationFrame = requestAnimationFrame(animate)
}
const handleMouseLeave = () => {
isHovering = false;
rotateSpeed = 0
rotateValue = 0
cancelAnimationFrame(animationFrame)
resetState()
}
</script>
<template>
<div class="user-info-card">
<div class="avatar" ref="avatarRef"
@mouseenter="handleMouseEnter"
@mouseleave="handleMouseLeave">
<div class="red-overlay" ref="redCoverRef"/>
<img
:src="store.getters.profileImage"
alt="User Avatar"
/>
</div>
<div class="user-info">
<h3>{{ store.state.userInfo.username }}</h3>
<p>注册日期{{ store.state.userInfo.birth?.split(' ')[0] || '未知' }}</p>
</div>
</div>
</template>
<style scoped>
.user-info-card {
width: 100%;
height: 100%;
overflow-y: auto;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
border-radius: 20px;
padding: 30px 0;
}
.user-info-card h3 button {
color: #fff;
font-size: 24px;
margin-top: 10px;
}
.theme-light .user-info-card h3 {
color: #252525;
}
.user-info-card p {
font-size: 16px;
}
.red-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(255, 0, 0, 0);
mix-blend-mode: multiply;
transition: background 0.25s ease-in-out;
}
.avatar {
position: relative;
width: 120px;
height: 120px;
object-fit: cover;
border-radius: 50%;
margin-bottom: 20px;
overflow: hidden;
transition: all 0.5s ease;
}
.red-overlay {
z-index: 10;
width: 100%;
height: 100%;
background: rgb(255, 0, 0);
opacity: 0;
mix-blend-mode: darken;
}
.avatar img {
width: 100%;
height: 100%;
transition: transform 0.1s linear;
will-change: transform; /* 优化动画性能 */
}
</style>