| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 |
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
- <meta name="renderer" content="webkit">
- <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
- <link rel="icon" href="/favicon.ico">
- <title>予书管理系统</title>
- <!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]-->
- <style>
- html,
- body,
- #app {
- height: 100%;
- margin: 0px;
- padding: 0px;
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
- }
- /* 内容页淡入动画 */
- #app {
- opacity: 0;
- transition: opacity 0.8s ease-in-out;
- }
-
- #app.app-loaded {
- opacity: 1;
- }
- /* 容器 - 自带背景色,不依赖body */
- .app-loading {
- position: fixed;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- background: #090a0f; /* 深空黑 */
- z-index: 99999;
- display: flex;
- justify-content: center;
- align-items: center;
- transition: opacity 1.2s ease-in-out, visibility 1.2s; /* 延长消失时间 */
- overflow: hidden; /* 仅在Loading时隐藏滚动条 */
- }
- /* Canvas 粒子背景 */
- #loading-canvas {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- z-index: 0;
- }
- /* 内容区域 */
- .loading-content {
- position: relative;
- z-index: 1;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- }
- /* 极简标题 */
- .app-loading-title {
- color: #fff;
- font-size: 24px;
- /* 强制指定字体,防止被 Element Plus / Normalize.css 覆盖导致跳变 */
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif !important;
- letter-spacing: 8px;
- font-weight: 200;
- line-height: 1.5; /* 锁定行高 */
- text-transform: uppercase;
- opacity: 0.9;
- animation: text-breathe 3s ease-in-out infinite;
- text-shadow: 0 0 20px rgba(59, 130, 246, 0.5); /* 蓝色微光 */
- }
- /* 进度条容器 */
- .loading-bar-container {
- margin-top: 20px;
- width: 200px;
- height: 2px;
- background: rgba(255, 255, 255, 0.1);
- border-radius: 2px;
- overflow: hidden;
- position: relative;
- }
- /* 进度条流光 */
- .loading-bar {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- background: linear-gradient(90deg, transparent, #3b82f6, transparent);
- transform: translateX(-100%);
- animation: loading-scan 2s cubic-bezier(0.4, 0, 0.2, 1) infinite;
- }
- @keyframes text-breathe {
- 0%, 100% { opacity: 0.8; text-shadow: 0 0 10px rgba(59, 130, 246, 0.3); }
- 50% { opacity: 1; text-shadow: 0 0 25px rgba(59, 130, 246, 0.8); }
- }
- @keyframes loading-scan {
- 0% { transform: translateX(-100%); }
- 50% { transform: translateX(0%); }
- 100% { transform: translateX(100%); }
- }
- </style>
- </head>
- <body>
- <div id="app"></div>
-
- <!-- Vue 挂载前显示的 Loading (移出 #app 以免被 Vue 覆盖) -->
- <div class="app-loading">
- <canvas id="loading-canvas"></canvas>
- <div class="loading-content">
- <div class="app-loading-title">YUSHU SYSTEM</div>
- <div class="loading-bar-container">
- <div class="loading-bar"></div>
- </div>
- </div>
- </div>
- <script>
- // 沉浸式星空背景
- (function() {
- const canvas = document.getElementById('loading-canvas');
- const ctx = canvas.getContext('2d');
- let width, height;
- let stars = [];
-
- const starCount = 120; // 减少粒子数量优化性能
- let speedMultiplier = 1; // 速度倍率
- class Star {
- constructor() {
- this.reset();
- // 初始化时随机进度
- this.opacity = Math.random();
- this.fadeDir = Math.random() > 0.5 ? 0.01 : -0.01;
- }
- reset() {
- this.x = Math.random() * width;
- this.y = Math.random() * height;
- this.size = Math.random() * 1.5;
- if (Math.random() > 0.95) this.size = Math.random() * 2 + 1; // 减少大星星概率
-
- this.speedY = Math.random() * 0.2 + 0.05;
- this.speedX = (Math.random() - 0.5) * 0.1;
- }
- update() {
- this.y -= this.speedY * speedMultiplier;
- this.x += this.speedX * speedMultiplier;
- this.opacity += this.fadeDir * (speedMultiplier > 1 ? speedMultiplier * 0.5 : 1);
- if (this.opacity > 1) {
- this.opacity = 1;
- this.fadeDir = -0.01 - Math.random() * 0.02;
- } else if (this.opacity < 0.2) {
- this.opacity = 0.2;
- this.fadeDir = 0.01 + Math.random() * 0.02;
- }
- if (this.y < 0) {
- this.y = height;
- this.x = Math.random() * width;
- }
- }
- draw() {
- ctx.fillStyle = `rgba(255, 255, 255, ${this.opacity})`;
- ctx.beginPath();
- ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
- ctx.fill();
-
- // 性能优化:移除 shadowBlur,改用绘制两层圆模拟光晕
- if (this.size > 1.5) {
- ctx.fillStyle = `rgba(255, 255, 255, ${this.opacity * 0.3})`;
- ctx.beginPath();
- ctx.arc(this.x, this.y, this.size * 2, 0, Math.PI * 2);
- ctx.fill();
- }
- }
- }
- function init() {
- resize();
- for (let i = 0; i < starCount; i++) {
- stars.push(new Star());
- }
- loop();
-
- // 模拟加速过程:1秒后开始加速,营造冲刺感
- setTimeout(() => {
- const accelerate = setInterval(() => {
- speedMultiplier += 0.5; // 加速更快
- if (speedMultiplier > 30) clearInterval(accelerate); // 最大加速到30倍,极速穿梭
- }, 50);
- }, 800);
- }
- function resize() {
- width = canvas.width = window.innerWidth;
- height = canvas.height = window.innerHeight;
- }
- function loop() {
- if (window.loadingAnimationStopped) return; // 停止动画循环
- // 创建拖尾效果 (background with opacity)
- ctx.fillStyle = 'rgba(9, 10, 15, 0.2)'; // 深色背景,0.2透明度产生拖尾
- ctx.fillRect(0, 0, width, height);
-
- // 偶尔绘制流星 (可选,暂不加,保持宁静)
- for (let star of stars) {
- star.update();
- star.draw();
- }
-
- requestAnimationFrame(loop);
- }
- window.addEventListener('resize', resize);
- init();
-
- // 暴露停止函数给外部调用
- window.stopLoadingAnimation = function() {
- window.loadingAnimationStopped = true;
- }
- })();
- </script>
- <script type="module" src="/src/main.js"></script>
- </body>
- </html>
|