mirror of
https://github.com/hi2shark/nazhua.git
synced 2026-01-11 22:50:42 +08:00
✨ 让AI写了一个烟花和新年快乐的灯笼
This commit is contained in:
parent
d3e549cad0
commit
3ede341f3d
@ -66,6 +66,7 @@ module.exports = {
|
|||||||
'no-param-reassign': 'off',
|
'no-param-reassign': 'off',
|
||||||
'no-underscore-dangle': 'off',
|
'no-underscore-dangle': 'off',
|
||||||
'no-unsafe-optional-chaining': 'off',
|
'no-unsafe-optional-chaining': 'off',
|
||||||
|
'max-classes-per-file': 'off',
|
||||||
'max-len': ['warn', 120],
|
'max-len': ['warn', 120],
|
||||||
'vue/max-len': ['warn', 120],
|
'vue/max-len': ['warn', 120],
|
||||||
'object-property-newline': ['error', {
|
'object-property-newline': ['error', {
|
||||||
|
|||||||
@ -5,6 +5,8 @@ window.$$nazhuaConfig = {
|
|||||||
// buyBtnText: '购买', // 购买按钮文案
|
// buyBtnText: '购买', // 购买按钮文案
|
||||||
// customBackgroundImage: '', // 自定义的背景图片地址
|
// customBackgroundImage: '', // 自定义的背景图片地址
|
||||||
// lightBackground: true, // 启用了浅色系背景图,会强制关闭点点背景
|
// lightBackground: true, // 启用了浅色系背景图,会强制关闭点点背景
|
||||||
|
// showFireworks: true, // 是否显示烟花,建议开启浅色系背景
|
||||||
|
// showLantern: true, // 是否显示灯笼
|
||||||
// listServerItemTypeToggle: true, // 服务器列表项类型切换
|
// listServerItemTypeToggle: true, // 服务器列表项类型切换
|
||||||
// listServerItemType: 'row', // 服务器列表项类型 card/row row列表模式移动端自动切换至card
|
// listServerItemType: 'row', // 服务器列表项类型 card/row row列表模式移动端自动切换至card
|
||||||
// listServerStatusType: 'progress', // 服务器状态类型--列表
|
// listServerStatusType: 'progress', // 服务器状态类型--列表
|
||||||
|
|||||||
158
src/components/fireworks.vue
Normal file
158
src/components/fireworks.vue
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
<template>
|
||||||
|
<canvas
|
||||||
|
ref="canvas"
|
||||||
|
class="fireworks-canvas"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {
|
||||||
|
ref,
|
||||||
|
onMounted,
|
||||||
|
onUnmounted,
|
||||||
|
} from 'vue';
|
||||||
|
|
||||||
|
const canvas = ref(null);
|
||||||
|
let ctx = null;
|
||||||
|
let particles = [];
|
||||||
|
let rockets = [];
|
||||||
|
let animationFrameId = null;
|
||||||
|
|
||||||
|
class Particle {
|
||||||
|
constructor(x, y, color) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.color = color;
|
||||||
|
this.velocity = {
|
||||||
|
x: (Math.random() - 0.5) * 8,
|
||||||
|
y: (Math.random() - 0.5) * 12 - 8,
|
||||||
|
};
|
||||||
|
this.alpha = 1;
|
||||||
|
this.decay = 0.02;
|
||||||
|
}
|
||||||
|
|
||||||
|
draw() {
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(this.x, this.y, 2, 0, Math.PI * 2);
|
||||||
|
ctx.fillStyle = `rgba(${this.color}, ${this.alpha})`;
|
||||||
|
ctx.fill();
|
||||||
|
}
|
||||||
|
|
||||||
|
update() {
|
||||||
|
this.velocity.y += 0.1;
|
||||||
|
this.x += this.velocity.x;
|
||||||
|
this.y += this.velocity.y;
|
||||||
|
this.alpha -= this.decay;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function createFirework(x, y) {
|
||||||
|
const colors = [
|
||||||
|
'255, 0, 0',
|
||||||
|
'0, 255, 0',
|
||||||
|
'0, 0, 255',
|
||||||
|
'255, 255, 0',
|
||||||
|
'255, 0, 255',
|
||||||
|
'0, 255, 255',
|
||||||
|
];
|
||||||
|
const color = colors[Math.floor(Math.random() * colors.length)];
|
||||||
|
for (let i = 0; i < 80; i += 1) {
|
||||||
|
particles.push(new Particle(x, y, color));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Rocket {
|
||||||
|
constructor() {
|
||||||
|
this.x = Math.random() * canvas.value.width;
|
||||||
|
this.y = canvas.value.height;
|
||||||
|
this.targetY = canvas.value.height * 0.5;
|
||||||
|
this.speed = 15;
|
||||||
|
this.trail = [];
|
||||||
|
this.maxTrailLength = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
draw() {
|
||||||
|
// 绘制火箭尾迹
|
||||||
|
ctx.beginPath();
|
||||||
|
this.trail.forEach((pos, index) => {
|
||||||
|
ctx.fillStyle = `rgba(255, 200, 0, ${index / this.trail.length})`;
|
||||||
|
ctx.fillRect(pos.x, pos.y, 2, 2);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 绘制火箭本体
|
||||||
|
ctx.fillStyle = 'rgba(255, 220, 0, 1)';
|
||||||
|
ctx.fillRect(this.x, this.y, 3, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
update() {
|
||||||
|
this.trail.push({
|
||||||
|
x: this.x,
|
||||||
|
y: this.y,
|
||||||
|
});
|
||||||
|
if (this.trail.length > this.maxTrailLength) {
|
||||||
|
this.trail.shift();
|
||||||
|
}
|
||||||
|
this.y -= this.speed;
|
||||||
|
if (this.y <= this.targetY) {
|
||||||
|
createFirework(this.x, this.y);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function animate() {
|
||||||
|
ctx.clearRect(0, 0, canvas.value.width, canvas.value.height);
|
||||||
|
|
||||||
|
// 更新和绘制火箭
|
||||||
|
rockets = rockets.filter((rocket) => {
|
||||||
|
rocket.draw();
|
||||||
|
return rocket.update();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 更新和绘制粒子
|
||||||
|
particles = particles.filter((particle) => particle.alpha > 0);
|
||||||
|
particles.forEach((particle) => {
|
||||||
|
particle.draw();
|
||||||
|
particle.update();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 发射新的火箭
|
||||||
|
if (Math.random() < 0.03 && rockets.length < 3) {
|
||||||
|
rockets.push(new Rocket());
|
||||||
|
}
|
||||||
|
|
||||||
|
animationFrameId = requestAnimationFrame(animate);
|
||||||
|
}
|
||||||
|
|
||||||
|
function resizeCanvas() {
|
||||||
|
if (canvas.value) {
|
||||||
|
canvas.value.width = window.innerWidth;
|
||||||
|
canvas.value.height = window.innerHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
ctx = canvas.value.getContext('2d');
|
||||||
|
resizeCanvas();
|
||||||
|
window.addEventListener('resize', resizeCanvas);
|
||||||
|
animate();
|
||||||
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
window.removeEventListener('resize', resizeCanvas);
|
||||||
|
if (animationFrameId) {
|
||||||
|
cancelAnimationFrame(animationFrameId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.fireworks-canvas {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 8;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
257
src/components/lantern.vue
Normal file
257
src/components/lantern.vue
Normal file
@ -0,0 +1,257 @@
|
|||||||
|
<template>
|
||||||
|
<div class="lantern-container">
|
||||||
|
<div class="lantern-group right-group">
|
||||||
|
<div class="deng-box">
|
||||||
|
<div class="deng">
|
||||||
|
<div class="xian" />
|
||||||
|
<div class="deng-a">
|
||||||
|
<div class="deng-b">
|
||||||
|
<div class="deng-t">快</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="shui shui-a">
|
||||||
|
<div class="shui-c" />
|
||||||
|
<div class="shui-b" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="deng-box deng-box--2">
|
||||||
|
<div class="deng">
|
||||||
|
<div class="xian" />
|
||||||
|
<div class="deng-a">
|
||||||
|
<div class="deng-b">
|
||||||
|
<div class="deng-t">乐</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="shui shui-a">
|
||||||
|
<div class="shui-c" />
|
||||||
|
<div class="shui-b" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="lantern-group left-group">
|
||||||
|
<div class="deng-box">
|
||||||
|
<div class="deng">
|
||||||
|
<div class="xian" />
|
||||||
|
<div class="deng-a">
|
||||||
|
<div class="deng-b">
|
||||||
|
<div class="deng-t">新</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="shui shui-a">
|
||||||
|
<div class="shui-c" />
|
||||||
|
<div class="shui-b" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="deng-box deng-box--2">
|
||||||
|
<div class="deng">
|
||||||
|
<div class="xian" />
|
||||||
|
<div class="deng-a">
|
||||||
|
<div class="deng-b">
|
||||||
|
<div class="deng-t">年</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="shui shui-a">
|
||||||
|
<div class="shui-c" />
|
||||||
|
<div class="shui-b" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
// 灯笼组件
|
||||||
|
// 由AI生成
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.lantern-container {
|
||||||
|
position: fixed;
|
||||||
|
top: calc(var(--layout-header-height) + 5px);
|
||||||
|
width: 100%;
|
||||||
|
z-index: 50;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lantern-group {
|
||||||
|
position: fixed;
|
||||||
|
top: 70px;
|
||||||
|
animation: swing 3s infinite ease-in-out;
|
||||||
|
transform-origin: 50% -10px;
|
||||||
|
|
||||||
|
&.left-group {
|
||||||
|
left: 40px;
|
||||||
|
animation-delay: -1.5s;
|
||||||
|
|
||||||
|
.deng-box:nth-child(2) {
|
||||||
|
margin-top: -12px;
|
||||||
|
|
||||||
|
.deng {
|
||||||
|
animation: swing-extra 2s infinite ease-in-out;
|
||||||
|
animation-delay: -0.5s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.right-group {
|
||||||
|
right: 30px;
|
||||||
|
animation-delay: -0.5s;
|
||||||
|
|
||||||
|
.deng-box:nth-child(2) {
|
||||||
|
|
||||||
|
.deng {
|
||||||
|
animation: swing-extra 2s infinite ease-in-out;
|
||||||
|
animation-delay: -1s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.deng {
|
||||||
|
animation: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.deng-box {
|
||||||
|
position: relative;
|
||||||
|
top: -40px;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
z-index: 2;
|
||||||
|
.deng {
|
||||||
|
margin-bottom: 23px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(2) {
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.deng {
|
||||||
|
position: relative;
|
||||||
|
width: 120px;
|
||||||
|
height: 90px;
|
||||||
|
margin: 50px;
|
||||||
|
background: rgba(216, 0, 15, 0.8);
|
||||||
|
border-radius: 50% 50%;
|
||||||
|
transform-origin: 50% -100px;
|
||||||
|
animation: swing 3s infinite ease-in-out;
|
||||||
|
box-shadow: -5px 5px 50px 4px rgba(250, 108, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.deng-a {
|
||||||
|
width: 100px;
|
||||||
|
height: 90px;
|
||||||
|
background: rgba(216, 0, 15, 0.1);
|
||||||
|
margin: 12px 8px 8px 10px;
|
||||||
|
border-radius: 50% 50%;
|
||||||
|
border: 2px solid #dc8f03;
|
||||||
|
}
|
||||||
|
|
||||||
|
.deng-b {
|
||||||
|
width: 45px;
|
||||||
|
height: 90px;
|
||||||
|
background: rgba(216, 0, 15, 0.1);
|
||||||
|
margin: -4px 8px 8px 26px;
|
||||||
|
border-radius: 50% 50%;
|
||||||
|
border: 2px solid #dc8f03;
|
||||||
|
}
|
||||||
|
|
||||||
|
.xian {
|
||||||
|
position: absolute;
|
||||||
|
top: -20px;
|
||||||
|
left: 60px;
|
||||||
|
width: 2px;
|
||||||
|
height: 20px;
|
||||||
|
background: #dc8f03;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shui-a {
|
||||||
|
position: relative;
|
||||||
|
width: 5px;
|
||||||
|
height: 20px;
|
||||||
|
margin: -5px 0 0 59px;
|
||||||
|
transform-origin: 50% -45px;
|
||||||
|
background: #ffa500;
|
||||||
|
border-radius: 0 0 5px 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shui-b {
|
||||||
|
position: absolute;
|
||||||
|
top: 14px;
|
||||||
|
left: -2px;
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
background: #dc8f03;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shui-c {
|
||||||
|
position: absolute;
|
||||||
|
top: 18px;
|
||||||
|
left: -2px;
|
||||||
|
width: 10px;
|
||||||
|
height: 35px;
|
||||||
|
background: #ffa500;
|
||||||
|
border-radius: 0 0 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.deng:before {
|
||||||
|
position: absolute;
|
||||||
|
top: -7px;
|
||||||
|
left: 29px;
|
||||||
|
height: 12px;
|
||||||
|
width: 60px;
|
||||||
|
content: " ";
|
||||||
|
display: block;
|
||||||
|
z-index: 999;
|
||||||
|
border-radius: 5px 5px 0 0;
|
||||||
|
border: solid 1px #dc8f03;
|
||||||
|
background: linear-gradient(to right, #dc8f03, #ffa500, #dc8f03, #ffa500, #dc8f03);
|
||||||
|
}
|
||||||
|
|
||||||
|
.deng:after {
|
||||||
|
position: absolute;
|
||||||
|
bottom: -7px;
|
||||||
|
left: 10px;
|
||||||
|
height: 12px;
|
||||||
|
width: 60px;
|
||||||
|
content: " ";
|
||||||
|
display: block;
|
||||||
|
margin-left: 20px;
|
||||||
|
border-radius: 0 0 5px 5px;
|
||||||
|
border: solid 1px #dc8f03;
|
||||||
|
background: linear-gradient(to right, #dc8f03, #ffa500, #dc8f03, #ffa500, #dc8f03);
|
||||||
|
}
|
||||||
|
|
||||||
|
.deng-t {
|
||||||
|
font-family: 华文行楷, Arial, Lucida Grande, Tahoma, sans-serif;
|
||||||
|
font-size: 3.2rem;
|
||||||
|
color: #ffd000;
|
||||||
|
line-height: 85px;
|
||||||
|
text-align: center;
|
||||||
|
margin-left: -5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes swing {
|
||||||
|
0% { transform: rotate(-6deg) }
|
||||||
|
50% { transform: rotate(6deg) }
|
||||||
|
100% { transform: rotate(-6deg) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes swing-extra {
|
||||||
|
0% { transform: rotate(-3deg) }
|
||||||
|
50% { transform: rotate(3deg) }
|
||||||
|
100% { transform: rotate(-3deg) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 1024px) {
|
||||||
|
.lantern-container {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -12,6 +12,12 @@
|
|||||||
<slot />
|
<slot />
|
||||||
<layout-footer />
|
<layout-footer />
|
||||||
</div>
|
</div>
|
||||||
|
<template v-if="config.nazhua.showFireworks">
|
||||||
|
<fireworks />
|
||||||
|
</template>
|
||||||
|
<template v-if="config.nazhua.showLantern">
|
||||||
|
<lantern />
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -21,6 +27,8 @@
|
|||||||
*/
|
*/
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
import config from '@/config';
|
import config from '@/config';
|
||||||
|
import Fireworks from '@/components/fireworks.vue';
|
||||||
|
import Lantern from '@/components/lantern.vue';
|
||||||
import LayoutHeader from './components/header.vue';
|
import LayoutHeader from './components/header.vue';
|
||||||
import LayoutFooter from './components/footer.vue';
|
import LayoutFooter from './components/footer.vue';
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user