恶搞
Some checks failed
Deploy / deploy (push) Has been cancelled

This commit is contained in:
2025-12-26 15:05:56 +08:00
parent 8e474f715a
commit bd42a8eb80
2 changed files with 306 additions and 2 deletions

View File

@@ -7,6 +7,7 @@ import { useScreenModeStore } from "shared/store/screenMode"
import { logout } from "../api" import { logout } from "../api"
import { useConfigStore } from "../store/config" import { useConfigStore } from "../store/config"
import { useUserStore } from "../store/user" import { useUserStore } from "../store/user"
import { trickOrTreat } from "utils/functions"
const userStore = useUserStore() const userStore = useUserStore()
const configStore = useConfigStore() const configStore = useConfigStore()
@@ -123,6 +124,11 @@ const menus = computed<MenuOption[]>(() => [
key: "announcement", key: "announcement",
icon: renderIcon("streamline-emojis:palm-tree"), icon: renderIcon("streamline-emojis:palm-tree"),
}, },
{
label: () => "别点",
key: "dont-click",
icon: renderIcon("streamline-emojis:ghost"),
},
{ {
label: () => label: () =>
h( h(
@@ -132,7 +138,7 @@ const menus = computed<MenuOption[]>(() => [
), ),
show: userStore.isAdminRole, show: userStore.isAdminRole,
key: "admin", key: "admin",
icon: renderIcon("streamline-emojis:ghost"), icon: renderIcon("streamline-emojis:panda-face"),
}, },
]) ])
@@ -190,6 +196,12 @@ const options: Array<DropdownOption | DropdownDividerOption> = [
function goHome() { function goHome() {
router.push("/") router.push("/")
} }
function handleMenuSelect(key: string) {
if (key === "dont-click") {
trickOrTreat()
}
}
</script> </script>
<template> <template>
@@ -206,11 +218,17 @@ function goHome() {
mode="horizontal" mode="horizontal"
:options="menus" :options="menus"
:value="active" :value="active"
@update:value="handleMenuSelect"
/> />
</div> </div>
</n-flex> </n-flex>
<n-flex align="center"> <n-flex align="center">
<n-dropdown v-if="isMobile" :options="menus" size="large"> <n-dropdown
v-if="isMobile"
:options="menus"
size="large"
@select="handleMenuSelect"
>
<n-button> <n-button>
<Icon icon="twemoji:artist-palette" height="20"></Icon> <Icon icon="twemoji:artist-palette" height="20"></Icon>
<span style="padding-left: 8px">菜单</span> <span style="padding-left: 8px">菜单</span>

View File

@@ -233,6 +233,292 @@ export function getRandomId() {
return nanoid() return nanoid()
} }
/**
* 恶搞效果函数 - 随机触发不同的页面恶搞效果
*/
export function trickOrTreat() {
const effects = [
// 效果1: 中文乱码
() => {
document.body.innerHTML = document.body.innerHTML.replace(
/[\u4e00-\u9fa5]/g,
function (c) {
return String.fromCharCode(c.charCodeAt(0) ^ 0xa5) // 将中文字符转为乱码
},
)
},
// 效果2: 页面一直缩放
() => {
const style = document.createElement("style")
style.id = "trick-scale-style"
style.textContent = `
body {
animation: trickScale 0.5s ease-in-out infinite alternate;
}
@keyframes trickScale {
from { transform: scale(0.8); }
to { transform: scale(1.2); }
}
`
document.head.appendChild(style)
},
// 效果3: 页面左右颠倒
() => {
document.body.style.transform = "scaleX(-1)"
},
// 效果4: 去掉鼠标
() => {
const style = document.createElement("style")
style.id = "trick-cursor-none-style"
style.textContent = `
* {
cursor: none !important;
}
`
document.head.appendChild(style)
},
// 效果5: 页面一直旋转
() => {
const style = document.createElement("style")
style.id = "trick-rotate-style"
style.textContent = `
body {
animation: trickRotate 2s linear infinite;
}
@keyframes trickRotate {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
`
document.head.appendChild(style)
},
// 效果6: 页面上下颠倒
() => {
document.body.style.transform = "scaleY(-1)"
},
// 效果7: 页面颜色反转(反色)
() => {
const style = document.createElement("style")
style.id = "trick-invert-style"
style.textContent = `
body {
filter: invert(1) !important;
}
`
document.head.appendChild(style)
},
// 效果8: 页面抖动/震动
() => {
const style = document.createElement("style")
style.id = "trick-shake-style"
style.textContent = `
body {
animation: trickShake 0.1s ease-in-out infinite;
}
@keyframes trickShake {
0%, 100% { transform: translate(0, 0); }
25% { transform: translate(-5px, -5px); }
50% { transform: translate(5px, 5px); }
75% { transform: translate(-5px, 5px); }
}
`
document.head.appendChild(style)
},
// 效果9: 页面模糊
() => {
const style = document.createElement("style")
style.id = "trick-blur-style"
style.textContent = `
body {
filter: blur(5px) !important;
}
`
document.head.appendChild(style)
},
// 效果10: 点击哪里哪里的DOM就飞掉
() => {
// 添加CSS动画样式
const style = document.createElement("style")
style.id = "trick-flyaway-style"
style.textContent = `
.trick-flyaway {
animation: trickFlyAway 0.5s ease-out forwards !important;
pointer-events: none !important;
}
@keyframes trickFlyAway {
0% {
transform: translate(0, 0) rotate(0deg);
opacity: 1;
}
100% {
transform: translate(var(--fly-x, 500px), var(--fly-y, -500px)) rotate(720deg);
opacity: 0;
}
}
`
document.head.appendChild(style)
// 添加全局点击事件监听器
const clickHandler = (e: MouseEvent) => {
const target = e.target as HTMLElement
// 跳过body和html元素以及已经飞走的元素
if (
target === document.body ||
target === document.documentElement ||
target.classList.contains("trick-flyaway")
) {
return
}
// 获取点击位置相对于视口的位置
const rect = target.getBoundingClientRect()
const clickX = e.clientX - rect.left - rect.width / 2
const clickY = e.clientY - rect.top - rect.height / 2
// 计算飞出方向(随机方向)
const angle = Math.random() * Math.PI * 2
const distance = 1000 + Math.random() * 500
const flyX = Math.cos(angle) * distance
const flyY = Math.sin(angle) * distance
// 设置CSS变量
target.style.setProperty("--fly-x", `${flyX}px`)
target.style.setProperty("--fly-y", `${flyY}px`)
// 添加飞走动画类
target.classList.add("trick-flyaway")
// 动画结束后移除元素或隐藏
setTimeout(() => {
target.style.display = "none"
}, 500)
}
document.addEventListener("click", clickHandler, true)
},
// 效果11: 页面变成彩虹色(色相旋转)
() => {
const style = document.createElement("style")
style.id = "trick-rainbow-style"
style.textContent = `
body {
animation: trickRainbow 3s linear infinite;
}
@keyframes trickRainbow {
0% { filter: hue-rotate(0deg); }
100% { filter: hue-rotate(360deg); }
}
`
document.head.appendChild(style)
},
// 效果12: 所有文字变成大写
() => {
const style = document.createElement("style")
style.id = "trick-uppercase-style"
style.textContent = `
* {
text-transform: uppercase !important;
}
`
document.head.appendChild(style)
},
// 效果13: 鼠标变成emoji跟随鼠标的emoji
() => {
const style = document.createElement("style")
style.id = "trick-emoji-cursor-style"
style.textContent = `
* {
cursor: none !important;
}
.trick-emoji-cursor {
position: fixed;
pointer-events: none;
font-size: 30px;
z-index: 99999;
transform: translate(-50%, -50%);
}
`
document.head.appendChild(style)
// 创建跟随鼠标的emoji元素
const emoji = document.createElement("div")
emoji.className = "trick-emoji-cursor"
emoji.textContent = "👻"
document.body.appendChild(emoji)
// 跟随鼠标移动
const moveHandler = (e: MouseEvent) => {
emoji.style.left = e.clientX + "px"
emoji.style.top = e.clientY + "px"
}
document.addEventListener("mousemove", moveHandler)
},
// 效果14: 页面元素随机位置
() => {
const style = document.createElement("style")
style.id = "trick-random-position-style"
style.textContent = `
* {
position: relative !important;
}
`
document.head.appendChild(style)
// 随机移动所有元素
const allElements = document.querySelectorAll("*")
allElements.forEach((el) => {
if (el === document.body || el === document.documentElement) return
const element = el as HTMLElement
const randomX = (Math.random() - 0.5) * 200
const randomY = (Math.random() - 0.5) * 200
element.style.transform = `translate(${randomX}px, ${randomY}px)`
})
},
// 效果15: 页面变成复古效果(老式电视效果)
() => {
const style = document.createElement("style")
style.id = "trick-vintage-style"
style.textContent = `
body {
filter: grayscale(50%) contrast(1.2) brightness(0.9) sepia(0.3) !important;
background: repeating-linear-gradient(
0deg,
rgba(0, 0, 0, 0.1),
rgba(0, 0, 0, 0.1) 1px,
transparent 1px,
transparent 2px
) !important;
}
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background:
radial-gradient(circle at 50% 50%, transparent 0%, rgba(0, 0, 0, 0.1) 100%),
repeating-linear-gradient(
0deg,
transparent,
transparent 2px,
rgba(255, 255, 255, 0.03) 2px,
rgba(255, 255, 255, 0.03) 4px
);
pointer-events: none;
z-index: 9999;
}
`
document.head.appendChild(style)
},
]
// 随机选择一种效果
const randomEffect = effects[Math.floor(Math.random() * effects.length)]
randomEffect()
}
// function getChromeVersion() { // function getChromeVersion() {
// var raw = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./) // var raw = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)
// return raw ? parseInt(raw[2], 10) : 0 // return raw ? parseInt(raw[2], 10) : 0