Javascript提高:canvas画布的网格背景-由Deepseek产生

以下是简化后的版本,保留了正方形画布和科技感网络线,代码结构清晰,视觉风格干净利落。

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <title>简洁网格画布 | Canvas 网络线</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            min-height: 100vh;
            background: linear-gradient(145deg, #1a2a3a 0%, #0a1118 100%);
            display: flex;
            justify-content: center;
            align-items: center;
            font-family: system-ui, 'Segoe UI', monospace;
        }

        /* 画布容器微光边框,简单提升质感 */
        .canvas-wrapper {
            border-radius: 24px;
            background: #0a1018;
            box-shadow: 0 20px 35px -12px rgba(0,0,0,0.5), 0 0 0 1px rgba(0, 255, 255, 0.2) inset;
            padding: 6px;
        }

        canvas {
            display: block;
            width: 480px;
            height: 480px;
            border-radius: 20px;
            cursor: crosshair;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
        }

        /* 简单文字标注,可选,不影响核心网格视觉 */
        .caption {
            text-align: center;
            margin-top: 18px;
            font-size: 13px;
            letter-spacing: 1px;
            color: #9bbcdb;
            background: rgba(10, 20, 30, 0.6);
            backdrop-filter: blur(4px);
            padding: 6px 16px;
            border-radius: 40px;
            display: inline-block;
            width: auto;
            font-family: monospace;
        }

        @media (max-width: 560px) {
            canvas {
                width: 320px;
                height: 320px;
            }
            .canvas-wrapper {
                padding: 4px;
            }
            .caption {
                font-size: 10px;
            }
        }
    </style>
</head>
<body>
<div style="display: flex; flex-direction: column; align-items: center;">
    <div class="canvas-wrapper">
        <canvas id="gridCanvas" width="480" height="480"></canvas>
    </div>
    <div class="caption">
        ✦ 网格线 | 步长 40px ✦
    </div>
</div>

<script>
    (function() {
        const canvas = document.getElementById('gridCanvas');
        const ctx = canvas.getContext('2d');
        
        // 正方形边长 (像素)
        const SIZE = 480;
        // 网格步长 (40px 完全整除 480 → 12x12 网格线,整齐)
        const STEP = 40;
        
        // 1. 绘制深邃渐变背景 (简单但好看)
        function drawBackground() {
            const grad = ctx.createLinearGradient(0, 0, SIZE, SIZE);
            grad.addColorStop(0, '#0c1824');
            grad.addColorStop(0.6, '#07111c');
            grad.addColorStop(1, '#03070e');
            ctx.fillStyle = grad;
            ctx.fillRect(0, 0, SIZE, SIZE);
            
            // 可选:添加极简微光点 (几个静默星点提升质感,不复杂)
            ctx.fillStyle = 'rgba(180, 220, 255, 0.4)';
            for (let i = 0; i < 80; i++) {
                if (i % 2 === 0) continue; // 只画约40个点,保持简洁
                const x = (i * 131) % SIZE;
                const y = (i * 253) % SIZE;
                ctx.beginPath();
                ctx.arc(x, y, 1.2, 0, Math.PI * 2);
                ctx.fill();
            }
        }
        
        // 2. 绘制主要网格线 (锐利、科技感)
        function drawGrid() {
            ctx.save();
            // 线条光晕效果 (轻微发光)
            ctx.shadowBlur = 2.5;
            ctx.shadowColor = '#0af';
            ctx.lineWidth = 1.2;
            ctx.strokeStyle = '#3ccbff';
            ctx.globalAlpha = 0.85;
            
            // 绘制所有竖线
            for (let x = 0; x <= SIZE; x += STEP) {
                ctx.beginPath();
                // 偏移0.5让线条更锐利 (像素对齐)
                ctx.moveTo(x + 0.5, 0);
                ctx.lineTo(x + 0.5, SIZE);
                ctx.stroke();
            }
            
            // 绘制所有横线
            for (let y = 0; y <= SIZE; y += STEP) {
                ctx.beginPath();
                ctx.moveTo(0, y + 0.5);
                ctx.lineTo(SIZE, y + 0.5);
                ctx.stroke();
            }
            
            // 加强中心轴线 (让视觉更平衡)
            ctx.lineWidth = 2;
            ctx.strokeStyle = '#0ff';
            ctx.shadowBlur = 5;
            const center = SIZE / 2;
            ctx.beginPath();
            ctx.moveTo(center + 0.5, 0);
            ctx.lineTo(center + 0.5, SIZE);
            ctx.stroke();
            ctx.beginPath();
            ctx.moveTo(0, center + 0.5);
            ctx.lineTo(SIZE, center + 0.5);
            ctx.stroke();
            
            ctx.restore();
        }
        
        // 3. 绘制网格交叉点小圆球 (强化网络节点的感觉,简洁精致)
        function drawNodes() {
            ctx.save();
            ctx.shadowBlur = 3;
            ctx.shadowColor = '#0cf';
            for (let x = 0; x <= SIZE; x += STEP) {
                for (let y = 0; y <= SIZE; y += STEP) {
                    ctx.beginPath();
                    ctx.arc(x, y, 2.2, 0, Math.PI * 2);
                    ctx.fillStyle = '#40d0ff';
                    ctx.fill();
                    // 内层高光
                    ctx.beginPath();
                    ctx.arc(x - 0.8, y - 0.8, 0.8, 0, Math.PI * 2);
                    ctx.fillStyle = '#ffffff';
                    ctx.fill();
                }
            }
            // 中心节点加大一点强调
            ctx.beginPath();
            ctx.arc(center, center, 4, 0, Math.PI * 2);
            ctx.fillStyle = '#0cf';
            ctx.fill();
            ctx.beginPath();
            ctx.arc(center - 1, center - 1, 1.5, 0, Math.PI * 2);
            ctx.fillStyle = 'white';
            ctx.fill();
            ctx.restore();
        }
        
        // 4. 添加简单的内发光边框 (让画布边界更精致)
        function drawBorderGlow() {
            ctx.save();
            ctx.shadowBlur = 0;
            ctx.beginPath();
            ctx.strokeStyle = 'rgba(0, 200, 255, 0.5)';
            ctx.lineWidth = 1.5;
            ctx.strokeRect(2, 2, SIZE - 4, SIZE - 4);
            ctx.beginPath();
            ctx.strokeStyle = 'rgba(100, 180, 255, 0.25)';
            ctx.lineWidth = 0.8;
            ctx.strokeRect(4, 4, SIZE - 8, SIZE - 8);
            ctx.restore();
        }
        
        // 主渲染 (所有绘制步骤)
        function render() {
            drawBackground();
            drawGrid();
            drawNodes();
            drawBorderGlow();
        }
        
        // 确保canvas尺寸与CSS一致 (像素比完美)
        canvas.width = SIZE;
        canvas.height = SIZE;
        render();
        
        // 可选: 如果窗口大小改变导致显示问题, 但canvas固定尺寸无需重绘,但保留以防万一
        window.addEventListener('resize', () => render());
    })();
</script>
</body>
</html>

以下是您所需的一个使用Canvas技术绘制的、带有科技感网格线的正方形画布的HTML代码。它创建了一个带有渐变背景、发光网格线和交互提示的视觉元素。

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <title>科技网格画布 | Canvas 正方形视觉艺术</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            min-height: 100vh;
            background: radial-gradient(circle at 20% 30%, #0a0f1e, #03060c);
            display: flex;
            justify-content: center;
            align-items: center;
            font-family: 'Segoe UI', 'Poppins', 'Orbitron', monospace;
            padding: 20px;
        }

        /* 画布容器,美化外框效果 */
        .canvas-container {
            position: relative;
            border-radius: 32px;
            background: rgba(0, 10, 20, 0.4);
            backdrop-filter: blur(2px);
            box-shadow: 0 20px 35px -15px rgba(0, 0, 0, 0.6), 
                        0 0 0 1px rgba(0, 255, 255, 0.15) inset,
                        0 0 20px rgba(0, 255, 255, 0.2);
            transition: all 0.3s ease;
        }

        .canvas-container:hover {
            box-shadow: 0 25px 40px -12px rgba(0, 0, 0, 0.8), 
                        0 0 0 1.5px rgba(0, 255, 255, 0.4) inset,
                        0 0 28px rgba(0, 210, 255, 0.4);
        }

        canvas {
            display: block;
            width: 500px;
            height: 500px;
            border-radius: 28px;
            cursor: crosshair;
            transition: filter 0.2s;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
        }

        /* 信息面板 - 显示鼠标坐标网格信息,提升科技感 */
        .info-panel {
            margin-top: 24px;
            text-align: center;
            background: rgba(12, 20, 28, 0.75);
            backdrop-filter: blur(8px);
            border-radius: 60px;
            padding: 10px 24px;
            border: 1px solid rgba(0, 255, 255, 0.3);
            box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3);
            font-size: 14px;
            font-weight: 500;
            letter-spacing: 1px;
            color: #bbf0ff;
            transition: all 0.2s;
        }

        .info-panel span {
            color: #0ff;
            font-weight: bold;
            text-shadow: 0 0 4px #0ff;
            font-family: monospace;
            font-size: 16px;
        }

        .info-title {
            display: inline-block;
            margin-right: 16px;
            border-right: 1px solid rgba(0, 255, 255, 0.5);
            padding-right: 16px;
            font-family: 'Orbitron', monospace;
            font-size: 13px;
            letter-spacing: 1.5px;
        }

        .coordinates {
            font-family: 'Fira Code', monospace;
            background: #05161f;
            padding: 4px 12px;
            border-radius: 32px;
            display: inline-block;
            box-shadow: inset 0 0 4px rgba(0,0,0,0.5), 0 0 6px rgba(0,255,255,0.2);
        }

        /* 底部装饰网格标识 */
        .badge {
            position: absolute;
            bottom: -30px;
            right: 12px;
            font-size: 11px;
            opacity: 0.5;
            color: #6cf;
            font-family: monospace;
            pointer-events: none;
        }

        @media (max-width: 600px) {
            canvas {
                width: 320px;
                height: 320px;
            }
            .info-panel {
                font-size: 11px;
                padding: 6px 16px;
            }
            .info-title {
                font-size: 10px;
            }
            .canvas-container {
                border-radius: 24px;
            }
            canvas {
                border-radius: 22px;
            }
        }

        /* 简单动画提示光晕 */
        @keyframes softPulse {
            0% { text-shadow: 0 0 2px #0ff; }
            100% { text-shadow: 0 0 6px #0ff; }
        }
        .info-panel span {
            animation: softPulse 1.2s infinite alternate;
        }
    </style>
</head>
<body>
<div style="display: flex; flex-direction: column; align-items: center;">
    <div class="canvas-container">
        <canvas id="techCanvas" width="500" height="500" style="width:500px; height:500px;"></canvas>
        <div class="badge">✧ GRID NETWORK v1.0 ✧</div>
    </div>
    <div class="info-panel">
        <span class="info-title">◈ 网格定位 ◈</span>
        <span>鼠标位置 → 网格单元: </span>
        <span id="gridCoordDisplay">(--- , ---)</span>
        <span style="margin-left:10px;">| 步长 50px | 11 x 11 节点</span>
    </div>
</div>

<script>
    (function() {
        // 获取canvas元素
        const canvas = document.getElementById('techCanvas');
        const ctx = canvas.getContext('2d');

        // 定义画布尺寸 (正方形)
        const SIZE = 500;
        // 网格步长 (50px 完美整除,边界完整)
        const STEP = 50;
        // 网格线数量: 边界0到500, 线条数 = (SIZE / STEP) + 1 = 11
        const GRID_LINES = SIZE / STEP;   // 10个间隔, 11条线
        
        // 让画布实际像素与CSS匹配 (已经设置width/height=500),无需额外处理,但确保持清晰
        // 抗锯齿优化对于线条偏移0.5即可
        
        // ---------- 绚丽背景绘制: 径向渐变 + 星空微粒 ----------
        function drawBackground() {
            // 深空科技感径向渐变 (中心亮蓝紫渐变到深邃黑蓝)
            const grad = ctx.createRadialGradient(SIZE*0.4, SIZE*0.3, 30, SIZE*0.5, SIZE*0.5, SIZE*0.8);
            grad.addColorStop(0, '#0a1a2f');
            grad.addColorStop(0.4, '#07121f');
            grad.addColorStop(0.7, '#030b14');
            grad.addColorStop(1, '#010408');
            ctx.fillStyle = grad;
            ctx.fillRect(0, 0, SIZE, SIZE);
            
            // 添加动态星尘效果 (随机亮点,增加视觉深度)
            // 为了丰富星空,生成固定随机点 (但是为了美感,不同刷新位置略有差异但每次都不同也无伤大雅,不过我们做稳定的伪随机)
            // 使用确定性的随机种子保证每次刷新效果一致,但为了自然感可不追求严格一致性,但都仅在初始化执行一次完美。
            const starCount = 360;
            for (let i = 0; i < starCount; i++) {
                // 避免过多重叠在中心过度区域,采用随机分布
                const x = Math.random() * SIZE;
                const y = Math.random() * SIZE;
                const radius = Math.random() * 1.8 + 0.5;
                // 星星透明度随机的亮白/淡蓝
                const alpha = Math.random() * 0.5 + 0.2;
                const colorChoice = Math.random() > 0.7 ? 'rgba(120, 200, 255, ' + alpha + ')' : 'rgba(255, 240, 200, ' + alpha + ')';
                ctx.beginPath();
                ctx.arc(x, y, radius, 0, Math.PI * 2);
                ctx.fillStyle = colorChoice;
                ctx.fill();
                // 偶尔添加微光晕
                if (radius > 1.2 && Math.random() > 0.85) {
                    ctx.shadowBlur = 2;
                    ctx.shadowColor = '#7df9ff';
                    ctx.fill();
                    ctx.shadowBlur = 0; // 重置避免影响过多
                }
            }
            
            // 额外增加淡淡星云旋臂效果: 极淡的椭圆光晕 (科技氛围)
            ctx.save();
            ctx.globalCompositeOperation = 'lighter';
            ctx.beginPath();
            ctx.ellipse(SIZE*0.7, SIZE*0.2, 100, 60, -0.5, 0, Math.PI*2);
            ctx.fillStyle = 'rgba(20, 80, 130, 0.08)';
            ctx.fill();
            ctx.beginPath();
            ctx.ellipse(SIZE*0.2, SIZE*0.8, 130, 90, 0.8, 0, Math.PI*2);
            ctx.fillStyle = 'rgba(30, 100, 150, 0.07)';
            ctx.fill();
            ctx.restore();
        }
        
        // ---------- 绘制科技感网格线 (发光效果 + 精确偏移0.5确保清晰) ----------
        function drawGridLines() {
            ctx.save();
            // 开启阴影光晕特效 (让网格线科技感十足)
            ctx.shadowBlur = 3.5;
            ctx.shadowColor = '#0af';
            ctx.lineWidth = 1.2;
            ctx.strokeStyle = 'rgba(0, 210, 255, 0.75)';
            
            // 绘制竖线 (x = i) , i 从 0 到 SIZE 步长 STEP
            for (let x = 0; x <= SIZE; x += STEP) {
                ctx.beginPath();
                // 偏移0.5使线条在像素边界清晰锐利
                const xPos = x + 0.5;
                ctx.moveTo(xPos, 0);
                ctx.lineTo(xPos, SIZE);
                ctx.stroke();
            }
            
            // 绘制横线 (y = i)
            for (let y = 0; y <= SIZE; y += STEP) {
                ctx.beginPath();
                const yPos = y + 0.5;
                ctx.moveTo(0, yPos);
                ctx.lineTo(SIZE, yPos);
                ctx.stroke();
            }
            
            // 额外绘制更亮的主轴线 (中轴线交叉高亮) 提升美学: 绘制 x = 250, y = 250 的中心线加粗增亮效果
            ctx.lineWidth = 2;
            ctx.strokeStyle = 'rgba(80, 240, 255, 0.9)';
            ctx.shadowBlur = 6;
            ctx.shadowColor = '#0cf';
            // 中间竖线 (250)
            ctx.beginPath();
            const center = SIZE / 2;
            ctx.moveTo(center + 0.5, 0);
            ctx.lineTo(center + 0.5, SIZE);
            ctx.stroke();
            // 中间横线
            ctx.beginPath();
            ctx.moveTo(0, center + 0.5);
            ctx.lineTo(SIZE, center + 0.5);
            ctx.stroke();
            
            // 边界额外微光轮廓 (可选)
            ctx.lineWidth = 1.2;
            ctx.strokeStyle = 'rgba(0, 200, 230, 0.5)';
            ctx.shadowBlur = 2;
            ctx.strokeRect(0.5, 0.5, SIZE-1, SIZE-1);
            
            ctx.restore();
        }
        
        // ---------- 绘制网格交点光点 (科技感节点) 让连接更生动 ----------
        function drawIntersectionPoints() {
            ctx.save();
            ctx.shadowBlur = 4;
            ctx.shadowColor = '#0cf';
            // 遍历所有交点 (0,0) 到 (500,500) 步长 STEP
            for (let x = 0; x <= SIZE; x += STEP) {
                for (let y = 0; y <= SIZE; y += STEP) {
                    // 根据位置不同略微改变色调: 边缘冷色,中心暖一点
                    let pointColor;
                    const distToCenter = Math.hypot(x - SIZE/2, y - SIZE/2);
                    const ratio = distToCenter / (SIZE/2);
                    if (ratio < 0.6) {
                        pointColor = `rgba(0, 220, 255, ${0.85 - ratio*0.2})`;
                    } else {
                        pointColor = `rgba(100, 180, 255, 0.65)`;
                    }
                    ctx.beginPath();
                    ctx.arc(x, y, 2.2, 0, Math.PI * 2);
                    ctx.fillStyle = pointColor;
                    ctx.fill();
                    // 内层小高光
                    ctx.beginPath();
                    ctx.arc(x, y, 1.0, 0, Math.PI * 2);
                    ctx.fillStyle = `rgba(255, 255, 255, 0.9)`;
                    ctx.fill();
                }
            }
            
            // 强化中心交叉点:  增加特殊光晕效果
            const cx = SIZE/2;
            const cy = SIZE/2;
            ctx.beginPath();
            ctx.arc(cx, cy, 4.5, 0, Math.PI*2);
            ctx.fillStyle = 'rgba(0, 230, 255, 0.7)';
            ctx.shadowBlur = 8;
            ctx.fill();
            ctx.beginPath();
            ctx.arc(cx, cy, 2.2, 0, Math.PI*2);
            ctx.fillStyle = '#ffffff';
            ctx.fill();
            // 四个辅助方向小光晕
            for (let i = -1; i <= 1; i++) {
                for (let j = -1; j <= 1; j++) {
                    if (i === 0 && j === 0) continue;
                    const xOff = i * STEP;
                    const yOff = j * STEP;
                    if (Math.abs(xOff) <= SIZE && Math.abs(yOff) <= SIZE) {
                        ctx.beginPath();
                        ctx.arc(cx + xOff, cy + yOff, 2.8, 0, Math.PI*2);
                        ctx.fillStyle = 'rgba(0, 200, 240, 0.65)';
                        ctx.fill();
                    }
                }
            }
            ctx.restore();
        }
        
        // 可选添加微妙的动态流光粒子 (进阶美化: 简单的漂浮粒子, 增强"网络线"的感觉)
        // 但为了避免性能消耗,在静态画布中添加一组"数据流"装饰点 --- 只绘制静态光粒,不做动画 (保持简洁但充满细节)
        function drawDataParticles() {
            ctx.save();
            ctx.shadowBlur = 2;
            ctx.shadowColor = '#6cf';
            // 增加一些随机微粒漂浮感,在网格之间游弋 (固定位置,但散布在空隙)
            const particles = [
                [75, 125], [180, 340], [420, 80], [360, 450], [110, 390], [290, 190], 
                [460, 270], [40, 430], [32, 88], [480, 475], [230, 470], [310, 30], 
                [150, 270], [410, 330], [55, 210], [499, 310], [280, 410], [390, 160]
            ];
            for (let p of particles) {
                ctx.beginPath();
                ctx.arc(p[0], p[1], 1.8, 0, Math.PI * 2);
                ctx.fillStyle = 'rgba(0, 210, 255, 0.6)';
                ctx.fill();
                ctx.beginPath();
                ctx.arc(p[0]-0.7, p[1]-0.5, 0.6, 0, Math.PI * 2);
                ctx.fillStyle = 'rgba(255, 255, 255, 0.8)';
                ctx.fill();
            }
            // 随机再增加一些光晕线段? 为了更符合网络线科技感, 增加短线连接相邻节点的光晕 (可选)
            ctx.restore();
        }
        
        // 绘制精致的边框修饰 + 角落科技图案 (提升正方形整体美感)
        function drawCornerTech() {
            ctx.save();
            ctx.shadowBlur = 0;
            ctx.lineWidth = 1.5;
            ctx.strokeStyle = 'rgba(0, 210, 230, 0.7)';
            // 绘制四个角落点缀 (小L形和点阵)
            const cornerSize = 18;
            const offset = 8;
            // 左上角
            ctx.beginPath();
            ctx.moveTo(offset, cornerSize);
            ctx.lineTo(offset, offset);
            ctx.lineTo(cornerSize, offset);
            ctx.stroke();
            ctx.beginPath();
            ctx.arc(offset + 3, offset + 3, 1.2, 0, Math.PI*2);
            ctx.fillStyle = '#0ff';
            ctx.fill();
            
            // 右上角
            ctx.beginPath();
            ctx.moveTo(SIZE - offset, cornerSize);
            ctx.lineTo(SIZE - offset, offset);
            ctx.lineTo(SIZE - cornerSize, offset);
            ctx.stroke();
            ctx.beginPath();
            ctx.arc(SIZE - offset - 3, offset + 3, 1.2, 0, Math.PI*2);
            ctx.fill();
            
            // 左下角
            ctx.beginPath();
            ctx.moveTo(offset, SIZE - cornerSize);
            ctx.lineTo(offset, SIZE - offset);
            ctx.lineTo(cornerSize, SIZE - offset);
            ctx.stroke();
            ctx.beginPath();
            ctx.arc(offset + 3, SIZE - offset - 3, 1.2, 0, Math.PI*2);
            ctx.fill();
            
            // 右下角
            ctx.beginPath();
            ctx.moveTo(SIZE - offset, SIZE - cornerSize);
            ctx.lineTo(SIZE - offset, SIZE - offset);
            ctx.lineTo(SIZE - cornerSize, SIZE - offset);
            ctx.stroke();
            ctx.beginPath();
            ctx.arc(SIZE - offset - 3, SIZE - offset - 3, 1.2, 0, Math.PI*2);
            ctx.fill();
            
            // 额外装饰:顶部和底部的微细光带
            ctx.beginPath();
            ctx.lineWidth = 1;
            ctx.strokeStyle = 'rgba(0, 210, 230, 0.4)';
            for (let i = 0; i < 4; i++) {
                const yOff = 12 + i * 8;
                ctx.beginPath();
                ctx.moveTo(20, yOff);
                ctx.lineTo(50, yOff);
                ctx.stroke();
                ctx.beginPath();
                ctx.moveTo(SIZE - 20, yOff);
                ctx.lineTo(SIZE - 50, yOff);
                ctx.stroke();
                // 底部
                ctx.beginPath();
                ctx.moveTo(20, SIZE - yOff);
                ctx.lineTo(50, SIZE - yOff);
                ctx.stroke();
                ctx.beginPath();
                ctx.moveTo(SIZE - 20, SIZE - yOff);
                ctx.lineTo(SIZE - 50, SIZE - yOff);
                ctx.stroke();
            }
            ctx.restore();
        }
        
        // 主渲染函数: 合并所有图层 (背景、星尘、网格线、交点和装饰)
        function renderCanvas() {
            if (!ctx) return;
            
            // 1.深邃背景及星尘
            drawBackground();
            
            // 2. 网格线 (含科技光晕效果)
            drawGridLines();
            
            // 3. 网格交点光点 (增强网络视觉)
            drawIntersectionPoints();
            
            // 4. 数据微粒点缀 (分布网格空隙之间增加科技数据感)
            drawDataParticles();
            
            // 5. 四角机械风格装饰边框细节
            drawCornerTech();
            
            // 额外增加淡淡的内发光边框,让正方形画布更精致
            ctx.save();
            ctx.shadowBlur = 0;
            ctx.beginPath();
            ctx.strokeStyle = 'rgba(100, 210, 255, 0.5)';
            ctx.lineWidth = 1.2;
            ctx.strokeRect(2, 2, SIZE - 4, SIZE - 4);
            ctx.beginPath();
            ctx.strokeStyle = 'rgba(0, 150, 200, 0.3)';
            ctx.lineWidth = 0.8;
            ctx.strokeRect(4, 4, SIZE - 8, SIZE - 8);
            ctx.restore();
        }
        
        // 鼠标交互:显示鼠标所在网格信息 (提升体验, 展示网络线定位)
        function setupCoordinateTracker() {
            const coordSpan = document.getElementById('gridCoordDisplay');
            if (!coordSpan) return;
            
            function updateMousePosition(e) {
                const rect = canvas.getBoundingClientRect();
                const scaleX = canvas.width / rect.width;   // 因为canvas实际像素500,rect宽高可能因css变化但宽高500px严格相等,scale恒为1
                const scaleY = canvas.height / rect.height;
                // 确保相对canvas坐标 (px)
                let mouseX = (e.clientX - rect.left) * scaleX;
                let mouseY = (e.clientY - rect.top) * scaleY;
                // 边界裁剪
                mouseX = Math.min(Math.max(0, mouseX), SIZE);
                mouseY = Math.min(Math.max(0, mouseY), SIZE);
                
                // 计算当前所在网格行列 (步长 STEP = 50)
                const col = Math.floor(mouseX / STEP);
                const row = Math.floor(mouseY / STEP);
                // 边界修正: 如果恰好落在网格线上且为边界最后一个,最大行列是10(因为0~10共11条线,单元格索引0~9)
                let gridCol = col;
                let gridRow = row;
                if (gridCol >= GRID_LINES) gridCol = GRID_LINES - 1;
                if (gridRow >= GRID_LINES) gridRow = GRID_LINES - 1;
                if (gridCol < 0) gridCol = 0;
                if (gridRow < 0) gridRow = 0;
                
                const cellX = gridCol;
                const cellY = gridRow;
                // 显示 "行,列" 和 单元格范围信息
                coordSpan.innerHTML = `(${cellX}, ${cellY})  |  [${cellX*STEP}~${(cellX+1)*STEP}, ${cellY*STEP}~${(cellY+1)*STEP}]`;
                // 额外视觉反馈: 改变鼠标样式已在CSS中体现(crosshair),可以不给canvas加额外重绘性能开销
            }
            
            canvas.addEventListener('mousemove', updateMousePosition);
            canvas.addEventListener('mouseleave', () => {
                coordSpan.innerHTML = '(--- , ---)';
            });
        }
        
        // 初始化渲染, 并处理设备像素比(无需额外, 因为固定尺寸)
        function init() {
            renderCanvas();
            setupCoordinateTracker();
        }
        
        // 可选:让窗口尺寸改变时保持质量 (由于canvas固定尺寸,无需重新渲染,但若用户缩放页面无影响)
        // 为了完美主义,若用户调整字体缩放可能导致canvas变形?不会,canvas像素固定,重新渲染一次也没损失。
        window.addEventListener('resize', () => {
            // 重绘确保质量 (因canvas内容不变, resize不会清空, 但某些极端情况设备旋转? 无需额外, 但重绘也无妨)
            // 但是为了稳妥, 监听resize重新渲染, 可能用户旋转手机屏幕虽然canvas宽高固定不变, 但父容器不影响canvas绘图.
            // 重绘保证无闪烁
            renderCanvas();
        });
        
        // 启动所有效果
        init();
    })();
</script>
</body>
</html>
相关推荐
清灵xmf1 小时前
JS 原生深拷贝的终极方案——structuredClone
前端·javascript·vue.js·json.stringify·structuredclone
前端 贾公子1 小时前
响应式系统基础:依赖追踪的基础 —— 发布订阅模式(前端应用最广的设计模式)上
javascript·vue.js
gCode Teacher 格码致知2 小时前
Javascript提高:使用canvas绘制一个绚丽的按钮-由Deepseek产生
javascript·css·css3
小四的小六2 小时前
WebView安全防护实战:从XSS到中间人攻击,我的踩坑与防御总结
javascript·webview
ZC跨境爬虫2 小时前
跟着 MDN 学 HTML day_41:(DOMParser 接口详解)
前端·javascript·ui·html·音视频
threelab2 小时前
Three.js 概率统计可视化 | 三维可视化 / AI 提示词
开发语言·javascript·人工智能
光影少年3 小时前
useLayoutEffect 和 useEffect 区别、使用场景
开发语言·前端·javascript
下雨打伞干嘛3 小时前
redux的使用
开发语言·javascript·ecmascript
small_white_robot3 小时前
idek-2022 web 全wp——持续更新
开发语言·前端·javascript·网络·安全·web安全·网络安全