From 6b668ce3133090b98da8ffa7140ae6d2f9d7a68e Mon Sep 17 00:00:00 2001 From: limuxi <1251316345@qq.com> Date: Tue, 10 Mar 2026 14:01:29 +0800 Subject: [PATCH] mobile app register themes --- app.py | 3 +- templates/register.html | 165 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 161 insertions(+), 7 deletions(-) diff --git a/app.py b/app.py index ffc487a..fa22768 100644 --- a/app.py +++ b/app.py @@ -4835,8 +4835,9 @@ def admin_delete_contest(contest_id): return jsonify({'success': False, 'message': '请先废止杯赛再删除'}), 400 # 清理关联数据(无 cascade 的需手动处理) ContestRegistration.query.filter_by(contest_id=contest_id).delete() - ContestApplication.query.filter_by(contest_id=contest_id).delete() QuestionBankItem.query.filter_by(contest_id=contest_id).delete() + # 删除该杯赛的帖子 + Post.query.filter_by(contest_id=contest_id).delete() # 删除该杯赛教师申请的邀请码 ta_ids = [ta.id for ta in TeacherApplication.query.filter_by(contest_id=contest_id).all()] if ta_ids: diff --git a/templates/register.html b/templates/register.html index 9f1298e..4cd38a9 100644 --- a/templates/register.html +++ b/templates/register.html @@ -2,15 +2,20 @@ {% block title %}注册 - 智联青云{% endblock %} {% block navbar %}{% endblock %} {% block content %} -
+ +
+ + + +
-

注册新账户

-

- 已有账户? 立即登录 +

注册新账户

+

+ 已有账户? 立即登录

-
-
+
+
@@ -259,5 +264,153 @@ async function handleEmailRegister(e) { // 初始化图形验证码(默认手机选项卡) fetchCaptcha('phone'); + +// ========== 云团动态背景动画 ========== +const canvas = document.getElementById('cloudCanvas'); +const ctx = canvas.getContext('2d'); +let width, height; +let clouds = []; +let mouse = { x: -1000, y: -1000 }; + +function resize() { + width = canvas.width = window.innerWidth; + height = canvas.height = window.innerHeight; +} +window.addEventListener('resize', resize); +resize(); + +window.addEventListener('mousemove', (e) => { + mouse.x = e.clientX; + mouse.y = e.clientY; +}); +window.addEventListener('mouseleave', () => { + mouse.x = -1000; + mouse.y = -1000; +}); + +// 预渲染柔和的云朵粒子,提升性能和真实感 +const puffCanvas = document.createElement('canvas'); +puffCanvas.width = 200; +puffCanvas.height = 200; +const pctx = puffCanvas.getContext('2d'); +const grad = pctx.createRadialGradient(100, 100, 0, 100, 100, 100); +grad.addColorStop(0, 'rgba(255, 255, 255, 1)'); +grad.addColorStop(0.2, 'rgba(255, 255, 255, 0.8)'); +grad.addColorStop(0.5, 'rgba(255, 255, 255, 0.3)'); +grad.addColorStop(1, 'rgba(255, 255, 255, 0)'); +pctx.fillStyle = grad; +pctx.beginPath(); +pctx.arc(100, 100, 100, 0, Math.PI * 2); +pctx.fill(); + +class Cloud { + constructor() { + this.reset(true); + } + + reset(initial = false) { + this.size = Math.random() * 150 + 100; // 更大的云团 + this.x = initial ? Math.random() * width : -this.size * 2; + this.y = Math.random() * height * 0.8; // 主要分布在上方 + this.speedX = Math.random() * 0.5 + 0.2; + this.speedY = (Math.random() - 0.5) * 0.1; + this.baseOpacity = Math.random() * 0.5 + 0.3; + this.opacity = this.baseOpacity; + this.scattered = false; + + // 生成云朵形状(由多个柔和粒子组成) + this.parts = []; + const numParts = Math.floor(Math.random() * 6) + 6; + for (let i = 0; i < numParts; i++) { + // 云朵底部较平,顶部不规则 + const nx = (Math.random() - 0.5) * this.size * 1.5; + const ny = (Math.random() * 0.5 - 0.8) * this.size * 0.5; + this.parts.push({ + offsetX: nx, + offsetY: ny, + radius: Math.random() * this.size * 0.5 + this.size * 0.4, + vx: 0, + vy: 0 + }); + } + } + + update() { + if (!this.scattered) { + this.x += this.speedX; + this.y += this.speedY; + + // 鼠标交互(散开效果) + const dx = this.x - mouse.x; + const dy = this.y - mouse.y; + const dist = Math.sqrt(dx * dx + dy * dy); + + // 鼠标靠近时触发散开 + if (dist < 250) { + this.scattered = true; + // 给每个粒子一个远离鼠标的速度 + for (let part of this.parts) { + const pdx = (this.x + part.offsetX) - mouse.x; + const pdy = (this.y + part.offsetY) - mouse.y; + const pdist = Math.sqrt(pdx * pdx + pdy * pdy) || 1; + const force = Math.max(0, 300 - pdist) / 300; + part.vx = (pdx / pdist) * force * (Math.random() * 6 + 2); + part.vy = (pdy / pdist) * force * (Math.random() * 6 + 2); + } + } + } else { + // 散开状态:粒子移动并淡出 + this.opacity -= 0.015; + for (let part of this.parts) { + part.offsetX += part.vx; + part.offsetY += part.vy; + part.radius += 0.5; // 散开时稍微膨胀 + // 增加空气阻力 + part.vx *= 0.95; + part.vy *= 0.95; + } + } + + // 边界检测或完全淡出后重置 + if (this.x > width + this.size * 2 || this.opacity <= 0 || this.y < -this.size * 2 || this.y > height + this.size * 2) { + this.reset(); + } + } + + draw() { + if (this.opacity <= 0) return; + ctx.save(); + ctx.globalAlpha = Math.max(0, this.opacity); + + for (let part of this.parts) { + const cx = this.x + part.offsetX; + const cy = this.y + part.offsetY; + const r = part.radius; + + // 视野外不绘制 + if (cx + r < 0 || cx - r > width || cy + r < 0 || cy - r > height) continue; + + // 使用预渲染的柔和云朵粒子 + ctx.drawImage(puffCanvas, cx - r, cy - r, r * 2, r * 2); + } + + ctx.restore(); + } +} + +// 初始化云朵 +for (let i = 0; i < 12; i++) { + clouds.push(new Cloud()); +} + +function animate() { + ctx.clearRect(0, 0, width, height); + for (let cloud of clouds) { + cloud.update(); + cloud.draw(); + } + requestAnimationFrame(animate); +} +animate(); {% endblock %} \ No newline at end of file