2026-02-05 01:45:35 +08:00
|
|
|
|
<!DOCTYPE html>
|
|
|
|
|
|
<html lang="zh-CN">
|
|
|
|
|
|
<head>
|
|
|
|
|
|
<meta charset="UTF-8">
|
|
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
2026-02-05 01:57:28 +08:00
|
|
|
|
<title>像素风画布 - 一键生成C语言数组版</title>
|
2026-02-05 01:45:35 +08:00
|
|
|
|
<style>
|
|
|
|
|
|
* {
|
|
|
|
|
|
margin: 0;
|
|
|
|
|
|
padding: 0;
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
font-family: "Microsoft YaHei", sans-serif;
|
|
|
|
|
|
}
|
|
|
|
|
|
body {
|
|
|
|
|
|
background: #f5f7fa;
|
|
|
|
|
|
padding: 15px;
|
|
|
|
|
|
}
|
2026-02-05 01:57:28 +08:00
|
|
|
|
/* 主卡片容器 */
|
2026-02-05 01:45:35 +08:00
|
|
|
|
.main-card {
|
2026-02-05 01:57:28 +08:00
|
|
|
|
max-width: 680px;
|
2026-02-05 01:45:35 +08:00
|
|
|
|
margin: 0 auto;
|
|
|
|
|
|
padding: 20px;
|
|
|
|
|
|
background: #fff;
|
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
|
|
|
|
|
|
border: 1px solid #ebeef5;
|
|
|
|
|
|
}
|
2026-02-05 01:57:28 +08:00
|
|
|
|
/* 像素画布核心 */
|
2026-02-05 01:45:35 +08:00
|
|
|
|
#drawCanvas {
|
|
|
|
|
|
border: 1px solid #2c3e50;
|
|
|
|
|
|
background: #f8f8f8;
|
|
|
|
|
|
cursor: crosshair;
|
|
|
|
|
|
image-rendering: pixelated;
|
|
|
|
|
|
}
|
|
|
|
|
|
.canvas-title {
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
font-size: 18px;
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
margin: 0 0 8px 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
.canvas-tip {
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
|
color: #67c23a;
|
|
|
|
|
|
margin: 0 0 18px 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
.canvas-box {
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
margin: 0 0 20px 0;
|
|
|
|
|
|
}
|
2026-02-05 01:57:28 +08:00
|
|
|
|
/* 控制组:新增生成按钮,自动换行不挤压 */
|
2026-02-05 01:45:35 +08:00
|
|
|
|
.control-group {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
gap: 12px 15px;
|
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
margin: 0 0 20px 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
#radiusSlider {
|
|
|
|
|
|
min-width: 180px;
|
|
|
|
|
|
max-width: 250px;
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
height: 6px;
|
|
|
|
|
|
}
|
|
|
|
|
|
#radiusValue {
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
width: 45px;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
}
|
2026-02-05 01:57:28 +08:00
|
|
|
|
/* 按钮统一样式:清除红+生成蓝,最小宽度一致 */
|
|
|
|
|
|
.func-btn {
|
2026-02-05 01:45:35 +08:00
|
|
|
|
min-width: 140px;
|
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
|
padding: 6px 16px;
|
2026-02-05 01:57:28 +08:00
|
|
|
|
border: 1px solid;
|
2026-02-05 01:45:35 +08:00
|
|
|
|
border-radius: 4px;
|
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
transition: all 0.2s;
|
|
|
|
|
|
}
|
2026-02-05 01:57:28 +08:00
|
|
|
|
#clearBtn {
|
|
|
|
|
|
background: #f56c6c;
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
border-color: #f56c6c;
|
|
|
|
|
|
}
|
2026-02-05 01:45:35 +08:00
|
|
|
|
#clearBtn:hover {
|
|
|
|
|
|
background: #f78989;
|
|
|
|
|
|
border-color: #f78989;
|
|
|
|
|
|
}
|
2026-02-05 01:57:28 +08:00
|
|
|
|
#genCArrBtn {
|
|
|
|
|
|
background: #409eff;
|
|
|
|
|
|
color: #fff;
|
|
|
|
|
|
border-color: #409eff;
|
|
|
|
|
|
}
|
|
|
|
|
|
#genCArrBtn:hover {
|
|
|
|
|
|
background: #66b1ff;
|
|
|
|
|
|
border-color: #66b1ff;
|
|
|
|
|
|
}
|
2026-02-05 01:45:35 +08:00
|
|
|
|
.divider {
|
|
|
|
|
|
height: 1px;
|
|
|
|
|
|
background: #ebeef5;
|
|
|
|
|
|
margin: 0 0 10px 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
.record-title {
|
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
|
color: #333;
|
|
|
|
|
|
margin: 0 0 10px 0;
|
|
|
|
|
|
}
|
2026-02-05 01:57:28 +08:00
|
|
|
|
/* 坐标记录区 */
|
2026-02-05 01:45:35 +08:00
|
|
|
|
#recordArea {
|
2026-02-05 01:57:28 +08:00
|
|
|
|
height: 180px;
|
2026-02-05 01:45:35 +08:00
|
|
|
|
border: 1px solid #eee;
|
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
|
padding: 12px;
|
|
|
|
|
|
overflow-y: auto;
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
line-height: 2;
|
|
|
|
|
|
color: #333;
|
2026-02-05 01:57:28 +08:00
|
|
|
|
margin: 0 0 20px 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
/* C语言数组展示区:等宽字体,适配代码展示 */
|
|
|
|
|
|
#cArrayArea {
|
|
|
|
|
|
height: 180px;
|
|
|
|
|
|
border: 1px solid #eee;
|
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
|
padding: 12px;
|
|
|
|
|
|
overflow-y: auto;
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
line-height: 1.8;
|
|
|
|
|
|
font-family: Consolas, "Courier New", monospace; /* 编程等宽字体 */
|
|
|
|
|
|
background: #fafafa;
|
|
|
|
|
|
color: #333;
|
2026-02-05 01:45:35 +08:00
|
|
|
|
}
|
|
|
|
|
|
.empty-tip {
|
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
|
color: #999;
|
|
|
|
|
|
}
|
|
|
|
|
|
.record-item {
|
|
|
|
|
|
display: block;
|
|
|
|
|
|
}
|
2026-02-05 01:57:28 +08:00
|
|
|
|
/* 代码区空提示 */
|
|
|
|
|
|
.c-empty-tip {
|
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
|
color: #999;
|
|
|
|
|
|
font-family: "Microsoft YaHei", sans-serif;
|
|
|
|
|
|
}
|
2026-02-05 01:45:35 +08:00
|
|
|
|
</style>
|
|
|
|
|
|
</head>
|
|
|
|
|
|
<body>
|
|
|
|
|
|
<div class="main-card">
|
2026-02-05 01:57:28 +08:00
|
|
|
|
<h3 class="canvas-title">像素风画布 (200×200px) | 一键生成C语言坐标数组</h3>
|
|
|
|
|
|
<p class="canvas-tip">按住左键绘制 → 自动记录坐标 → 点击生成C数组 → 直接复制使用</p>
|
2026-02-05 01:45:35 +08:00
|
|
|
|
|
|
|
|
|
|
<!-- 200x200像素画布 -->
|
|
|
|
|
|
<div class="canvas-box">
|
|
|
|
|
|
<canvas id="drawCanvas" width="200" height="200"></canvas>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-02-05 01:57:28 +08:00
|
|
|
|
<!-- 控制区:滑块 + 清除按钮 + 生成C数组按钮(自动换行) -->
|
2026-02-05 01:45:35 +08:00
|
|
|
|
<div class="control-group">
|
|
|
|
|
|
<span style="font-size: 14px;">笔刷半径:</span>
|
|
|
|
|
|
<input type="range" id="radiusSlider" min="1" max="20" step="1" value="5">
|
|
|
|
|
|
<span id="radiusValue">5</span>px
|
2026-02-05 01:57:28 +08:00
|
|
|
|
<button id="clearBtn" class="func-btn">清除图像&记录</button>
|
|
|
|
|
|
<button id="genCArrBtn" class="func-btn">生成C语言坐标数组</button>
|
2026-02-05 01:45:35 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 坐标记录区 -->
|
2026-02-05 01:57:28 +08:00
|
|
|
|
<h4 class="record-title">绘制坐标记录(20ms/次)</h4>
|
2026-02-05 01:45:35 +08:00
|
|
|
|
<div id="recordArea">
|
2026-02-05 01:57:28 +08:00
|
|
|
|
<span class="empty-tip">按住鼠标绘制,自动记录笔刷中心坐标~</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- C语言数组生成区 -->
|
|
|
|
|
|
<h4 class="record-title">C语言坐标数组(可直接复制)</h4>
|
|
|
|
|
|
<div id="cArrayArea">
|
|
|
|
|
|
<span class="c-empty-tip">绘制后点击「生成C语言坐标数组」,自动生成规范代码~</span>
|
2026-02-05 01:45:35 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<script>
|
2026-02-05 01:57:28 +08:00
|
|
|
|
// ========== 获取DOM元素 ==========
|
2026-02-05 01:45:35 +08:00
|
|
|
|
const canvas = document.getElementById('drawCanvas');
|
|
|
|
|
|
const ctx = canvas.getContext('2d');
|
|
|
|
|
|
const radiusSlider = document.getElementById('radiusSlider');
|
|
|
|
|
|
const radiusValue = document.getElementById('radiusValue');
|
|
|
|
|
|
const clearBtn = document.getElementById('clearBtn');
|
2026-02-05 01:57:28 +08:00
|
|
|
|
const genCArrBtn = document.getElementById('genCArrBtn');
|
2026-02-05 01:45:35 +08:00
|
|
|
|
const recordArea = document.getElementById('recordArea');
|
2026-02-05 01:57:28 +08:00
|
|
|
|
const cArrayArea = document.getElementById('cArrayArea');
|
2026-02-05 01:45:35 +08:00
|
|
|
|
|
2026-02-05 01:57:28 +08:00
|
|
|
|
// ========== 全局状态(新增coordsArr存储原始坐标,用于生成C数组) ==========
|
|
|
|
|
|
let brushRadius = 5;
|
|
|
|
|
|
let isDrawing = false;
|
|
|
|
|
|
let lastX = 0;
|
|
|
|
|
|
let lastY = 0;
|
|
|
|
|
|
let recordTimer = null;
|
|
|
|
|
|
let coordsArr = []; // 核心:存储所有绘制的X/Y坐标,用于生成C数组
|
2026-02-05 01:45:35 +08:00
|
|
|
|
|
2026-02-05 01:57:28 +08:00
|
|
|
|
// ========== 初始化画布 ==========
|
2026-02-05 01:45:35 +08:00
|
|
|
|
function initCanvas() {
|
|
|
|
|
|
ctx.imageSmoothingEnabled = false;
|
|
|
|
|
|
ctx.msImageSmoothingEnabled = false;
|
|
|
|
|
|
ctx.webkitImageSmoothingEnabled = false;
|
|
|
|
|
|
ctx.mozImageSmoothingEnabled = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-05 01:57:28 +08:00
|
|
|
|
// ========== 绑定所有事件(新增生成C数组按钮点击事件) ==========
|
2026-02-05 01:45:35 +08:00
|
|
|
|
function bindEvents() {
|
2026-02-05 01:57:28 +08:00
|
|
|
|
// 画布绘制事件
|
2026-02-05 01:45:35 +08:00
|
|
|
|
canvas.onmousedown = startDraw;
|
|
|
|
|
|
canvas.onmousemove = draw;
|
|
|
|
|
|
canvas.onmouseup = stopDraw;
|
|
|
|
|
|
canvas.onmouseout = stopDraw;
|
2026-02-05 01:57:28 +08:00
|
|
|
|
// 滑块事件
|
2026-02-05 01:45:35 +08:00
|
|
|
|
radiusSlider.oninput = updateRadius;
|
2026-02-05 01:57:28 +08:00
|
|
|
|
// 功能按钮事件
|
2026-02-05 01:45:35 +08:00
|
|
|
|
clearBtn.onclick = clearAll;
|
2026-02-05 01:57:28 +08:00
|
|
|
|
genCArrBtn.onclick = generateCArray; // 绑定生成C数组方法
|
2026-02-05 01:45:35 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-05 01:57:28 +08:00
|
|
|
|
// ========== 笔刷半径更新 ==========
|
2026-02-05 01:45:35 +08:00
|
|
|
|
function updateRadius() {
|
|
|
|
|
|
brushRadius = parseInt(this.value);
|
|
|
|
|
|
radiusValue.textContent = brushRadius;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-05 01:57:28 +08:00
|
|
|
|
// ========== 开始绘制 ==========
|
2026-02-05 01:45:35 +08:00
|
|
|
|
function startDraw(e) {
|
|
|
|
|
|
isDrawing = true;
|
|
|
|
|
|
[lastX, lastY] = getCanvasXY(e);
|
2026-02-05 01:57:28 +08:00
|
|
|
|
// 绘制起点也记录坐标
|
|
|
|
|
|
recordCoord(lastX, lastY);
|
2026-02-05 01:45:35 +08:00
|
|
|
|
recordTimer = setInterval(() => {
|
|
|
|
|
|
recordCoord(lastX, lastY);
|
|
|
|
|
|
}, 20);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-05 01:57:28 +08:00
|
|
|
|
// ========== 核心绘制:圆形像素笔刷 ==========
|
2026-02-05 01:45:35 +08:00
|
|
|
|
function draw(e) {
|
|
|
|
|
|
if (!isDrawing) return;
|
|
|
|
|
|
[lastX, lastY] = getCanvasXY(e);
|
|
|
|
|
|
ctx.beginPath();
|
2026-02-05 01:57:28 +08:00
|
|
|
|
ctx.arc(lastX, lastY, brushRadius, 0, Math.PI * 2);
|
|
|
|
|
|
ctx.fillStyle = '#2c3e50';
|
2026-02-05 01:45:35 +08:00
|
|
|
|
ctx.fill();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-05 01:57:28 +08:00
|
|
|
|
// ========== 停止绘制 ==========
|
2026-02-05 01:45:35 +08:00
|
|
|
|
function stopDraw() {
|
|
|
|
|
|
if (!isDrawing) return;
|
|
|
|
|
|
isDrawing = false;
|
|
|
|
|
|
clearInterval(recordTimer);
|
|
|
|
|
|
recordTimer = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-05 01:57:28 +08:00
|
|
|
|
// ========== 工具方法:获取画布相对坐标 ==========
|
2026-02-05 01:45:35 +08:00
|
|
|
|
function getCanvasXY(e) {
|
|
|
|
|
|
const rect = canvas.getBoundingClientRect();
|
|
|
|
|
|
return [
|
|
|
|
|
|
Math.round(e.clientX - rect.left),
|
|
|
|
|
|
Math.round(e.clientY - rect.top)
|
|
|
|
|
|
];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-05 01:57:28 +08:00
|
|
|
|
// ========== 坐标记录:同步更新coordsArr和页面展示 ==========
|
2026-02-05 01:45:35 +08:00
|
|
|
|
function recordCoord(x, y) {
|
2026-02-05 01:57:28 +08:00
|
|
|
|
// 1. 存储原始坐标到数组(核心,用于生成C数组)
|
|
|
|
|
|
coordsArr.push([x, y]);
|
|
|
|
|
|
// 2. 页面展示坐标(带序号)
|
2026-02-05 01:45:35 +08:00
|
|
|
|
if (recordArea.querySelector('.empty-tip')) {
|
|
|
|
|
|
recordArea.innerHTML = '';
|
|
|
|
|
|
}
|
2026-02-05 01:57:28 +08:00
|
|
|
|
const recordItem = `<span class="record-item">【${coordsArr.length}】X: ${x}, Y: ${y}</span>`;
|
2026-02-05 01:45:35 +08:00
|
|
|
|
recordArea.innerHTML = recordItem + recordArea.innerHTML;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-05 01:57:28 +08:00
|
|
|
|
// ========== 核心新增:一键生成C语言坐标数组 ==========
|
|
|
|
|
|
function generateCArray() {
|
|
|
|
|
|
// 无坐标时提示
|
|
|
|
|
|
if (coordsArr.length === 0) {
|
|
|
|
|
|
alert('暂无绘制坐标,请先在画布上绘制后再生成!');
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 1. 生成const int 记录坐标长度(变量名:drawPointNum,可自定义)
|
|
|
|
|
|
const lenCode = `const int drawPointNum = ${coordsArr.length};`;
|
|
|
|
|
|
// 2. 生成二维int坐标数组(变量名:drawPoints[drawPointNum][2],按绘制顺序存储)
|
|
|
|
|
|
const arrItems = coordsArr.map(coord => `{${coord[0]}, ${coord[1]}}`).join(',\n');
|
|
|
|
|
|
const arrCode = `int drawPoints[drawPointNum][2] = {\n${arrItems}\n};`;
|
|
|
|
|
|
// 3. 拼接完整C代码(换行+缩进,规范易读)
|
|
|
|
|
|
const cFullCode = `${lenCode}\n\n${arrCode}`;
|
|
|
|
|
|
|
|
|
|
|
|
// 4. 渲染到C代码区,清空空提示
|
|
|
|
|
|
cArrayArea.innerHTML = cFullCode;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ========== 一键清除:同步清空坐标数组和C代码区 ==========
|
2026-02-05 01:45:35 +08:00
|
|
|
|
function clearAll() {
|
2026-02-05 01:57:28 +08:00
|
|
|
|
// 1. 清空画布
|
2026-02-05 01:45:35 +08:00
|
|
|
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
2026-02-05 01:57:28 +08:00
|
|
|
|
// 2. 重置坐标数组(核心,避免生成旧数据)
|
|
|
|
|
|
coordsArr = [];
|
|
|
|
|
|
// 3. 清空坐标记录区,恢复空提示
|
|
|
|
|
|
recordArea.innerHTML = '<span class="empty-tip">按住鼠标绘制,自动记录笔刷中心坐标~</span>';
|
|
|
|
|
|
// 4. 清空C代码区,恢复空提示
|
|
|
|
|
|
cArrayArea.innerHTML = '<span class="c-empty-tip">绘制后点击「生成C语言坐标数组」,自动生成规范代码~</span>';
|
|
|
|
|
|
// 5. 重置绘制状态
|
2026-02-05 01:45:35 +08:00
|
|
|
|
isDrawing = false;
|
|
|
|
|
|
lastX = 0;
|
|
|
|
|
|
lastY = 0;
|
|
|
|
|
|
if (recordTimer) {
|
|
|
|
|
|
clearInterval(recordTimer);
|
|
|
|
|
|
recordTimer = null;
|
|
|
|
|
|
}
|
2026-02-05 01:57:28 +08:00
|
|
|
|
alert('清除成功!画布、记录和坐标数组已全部重置~');
|
2026-02-05 01:45:35 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-02-05 01:57:28 +08:00
|
|
|
|
// ========== 页面初始化 ==========
|
2026-02-05 01:45:35 +08:00
|
|
|
|
window.onload = function() {
|
2026-02-05 01:57:28 +08:00
|
|
|
|
initCanvas();
|
|
|
|
|
|
bindEvents();
|
2026-02-05 01:45:35 +08:00
|
|
|
|
};
|
|
|
|
|
|
</script>
|
|
|
|
|
|
</body>
|
2026-02-05 01:57:28 +08:00
|
|
|
|
</html>
|