小工具新增自动生成C数组功能

This commit is contained in:
kirltrz 2026-02-05 01:57:28 +08:00
parent ee20d6c4bd
commit 1d31d2b244

View File

@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>像素风画布 - 纯原生秒开</title>
<title>像素风画布 - 一键生成C语言数组</title>
<style>
* {
margin: 0;
@ -15,9 +15,9 @@
background: #f5f7fa;
padding: 15px;
}
/* 主卡片容器模拟Element样式层级清晰 */
/* 主卡片容器 */
.main-card {
max-width: 600px;
max-width: 680px;
margin: 0 auto;
padding: 20px;
background: #fff;
@ -25,33 +25,30 @@
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
border: 1px solid #ebeef5;
}
/* 像素画布核心:无抗锯齿+像素化严格200x200 */
/* 像素画布核心 */
#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;
}
/* 控制组:自动换行,绝不挤压,滑块+按钮100%显示 */
/* 控制组:新增生成按钮,自动换行不挤压 */
.control-group {
display: flex;
align-items: center;
@ -60,52 +57,60 @@
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;
}
/* 清除按钮:红色显眼,固定最小宽度,文字不折行 */
#clearBtn {
/* 按钮统一样式:清除红+生成蓝,最小宽度一致 */
.func-btn {
min-width: 140px;
white-space: nowrap;
padding: 6px 16px;
background: #f56c6c;
color: #fff;
border: 1px solid #f56c6c;
border: 1px solid;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
transition: all 0.2s;
}
#clearBtn {
background: #f56c6c;
color: #fff;
border-color: #f56c6c;
}
#clearBtn:hover {
background: #f78989;
border-color: #f78989;
}
/* 分割线 */
#genCArrBtn {
background: #409eff;
color: #fff;
border-color: #409eff;
}
#genCArrBtn:hover {
background: #66b1ff;
border-color: #66b1ff;
}
.divider {
height: 1px;
background: #ebeef5;
margin: 0 0 10px 0;
}
/* 坐标记录区标题 */
.record-title {
font-size: 16px;
color: #333;
margin: 0 0 10px 0;
}
/* 坐标记录容器:固定高度,滚动显示 */
/* 坐标记录 */
#recordArea {
height: 220px;
height: 180px;
border: 1px solid #eee;
border-radius: 4px;
padding: 12px;
@ -113,113 +118,137 @@
font-size: 14px;
line-height: 2;
color: #333;
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;
}
/* 空记录提示 */
.empty-tip {
font-size: 13px;
color: #999;
}
/* 坐标记录项 */
.record-item {
display: block;
}
/* 代码区空提示 */
.c-empty-tip {
font-size: 13px;
color: #999;
font-family: "Microsoft YaHei", sans-serif;
}
</style>
</head>
<body>
<div class="main-card">
<h3 class="canvas-title">像素风画布 (200×200px)</h3>
<p class="canvas-tip">按住左键绘制 | 圆形像素笔刷 | 20ms自动记录坐标</p>
<h3 class="canvas-title">像素风画布 (200×200px) | 一键生成C语言坐标数组</h3>
<p class="canvas-tip">按住左键绘制 → 自动记录坐标 → 点击生成C数组 → 直接复制使用</p>
<!-- 200x200像素画布 -->
<div class="canvas-box">
<canvas id="drawCanvas" width="200" height="200"></canvas>
</div>
<!-- 控制区:笔刷滑块+数值+清除按钮100%显示 -->
<!-- 控制区:滑块 + 清除按钮 + 生成C数组按钮自动换行 -->
<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
<button id="clearBtn">清除图像&记录</button>
<button id="clearBtn" class="func-btn">清除图像&记录</button>
<button id="genCArrBtn" class="func-btn">生成C语言坐标数组</button>
</div>
<!-- 坐标记录区 -->
<div class="divider"></div>
<h4 class="record-title">坐标记录(画布相对坐标)</h4>
<h4 class="record-title">绘制坐标记录20ms/次)</h4>
<div id="recordArea">
<span class="empty-tip">按住鼠标在画布绘制,自动记录笔刷中心坐标~</span>
<span class="empty-tip">按住鼠标绘制,自动记录笔刷中心坐标~</span>
</div>
<!-- C语言数组生成区 -->
<h4 class="record-title">C语言坐标数组可直接复制</h4>
<div id="cArrayArea">
<span class="c-empty-tip">绘制后点击「生成C语言坐标数组」自动生成规范代码~</span>
</div>
</div>
<script>
// ========== 获取DOM元素原生直接获取无依赖 ==========
// ========== 获取DOM元素 ==========
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');
const genCArrBtn = document.getElementById('genCArrBtn');
const recordArea = document.getElementById('recordArea');
const cArrayArea = document.getElementById('cArrayArea');
// ========== 全局状态(核心功能变量 ==========
let brushRadius = 5; // 笔刷半径
let isDrawing = false; // 是否正在绘制
let lastX = 0; // 笔刷中心最后X坐标
let lastY = 0; // 笔刷中心最后Y坐标
let recordTimer = null; // 20ms坐标记录定时器
let recordCount = 0; // 坐标记录序号
// ========== 全局状态(新增coordsArr存储原始坐标用于生成C数组 ==========
let brushRadius = 5;
let isDrawing = false;
let lastX = 0;
let lastY = 0;
let recordTimer = null;
let coordsArr = []; // 核心存储所有绘制的X/Y坐标用于生成C数组
// ========== 初始化画布(关闭抗锯齿,保证圆形像素风) ==========
// ========== 初始化画布 ==========
function initCanvas() {
// 全浏览器关闭抗锯齿,圆形笔刷无模糊,纯像素质感
ctx.imageSmoothingEnabled = false;
ctx.msImageSmoothingEnabled = false;
ctx.webkitImageSmoothingEnabled = false;
ctx.mozImageSmoothingEnabled = false;
}
// ========== 绑定所有事件(原生事件,无兼容问题 ==========
// ========== 绑定所有事件(新增生成C数组按钮点击事件 ==========
function bindEvents() {
// 画布鼠标事件:绘制核心
// 画布绘制事件
canvas.onmousedown = startDraw;
canvas.onmousemove = draw;
canvas.onmouseup = stopDraw;
canvas.onmouseout = stopDraw;
// 滑块事件:实时调节笔刷半径
// 滑块事件
radiusSlider.oninput = updateRadius;
// 按钮事件:一键清除
// 功能按钮事件
clearBtn.onclick = clearAll;
genCArrBtn.onclick = generateCArray; // 绑定生成C数组方法
}
// ========== 笔刷半径实时更新(滑块拖动/输入同步) ==========
// ========== 笔刷半径更新 ==========
function updateRadius() {
brushRadius = parseInt(this.value);
radiusValue.textContent = brushRadius;
}
// ========== 开始绘制启动20ms坐标记录 ==========
// ========== 开始绘制 ==========
function startDraw(e) {
isDrawing = true;
// 获取画布内精准相对坐标(取整,贴合像素)
[lastX, lastY] = getCanvasXY(e);
// 启动定时器每20ms记录一次笔刷中心坐标
// 绘制起点也记录坐标
recordCoord(lastX, lastY);
recordTimer = setInterval(() => {
recordCoord(lastX, lastY);
}, 20);
}
// ========== 核心绘制:圆形像素笔刷(无抗锯齿) ==========
// ========== 核心绘制:圆形像素笔刷 ==========
function draw(e) {
if (!isDrawing) return;
// 更新当前笔刷中心坐标
[lastX, lastY] = getCanvasXY(e);
// 绘制圆形笔刷
ctx.beginPath();
ctx.arc(lastX, lastY, brushRadius, 0, Math.PI * 2); // 0-360度完整圆形
ctx.fillStyle = '#2c3e50'; // 笔刷颜色(深灰,可自定义)
ctx.arc(lastX, lastY, brushRadius, 0, Math.PI * 2);
ctx.fillStyle = '#2c3e50';
ctx.fill();
}
// ========== 停止绘制:清除定时器,结束记录 ==========
// ========== 停止绘制 ==========
function stopDraw() {
if (!isDrawing) return;
isDrawing = false;
@ -227,53 +256,73 @@
recordTimer = null;
}
// ========== 工具方法:获取画布内精准相对坐标 ==========
// ========== 工具方法:获取画布相对坐标 ==========
function getCanvasXY(e) {
const rect = canvas.getBoundingClientRect();
// 减去画布偏移,取整得到像素级精准坐标
return [
Math.round(e.clientX - rect.left),
Math.round(e.clientY - rect.top)
];
}
// ========== 坐标记录:20ms一次追加到记录区 ==========
// ========== 坐标记录:同步更新coordsArr和页面展示 ==========
function recordCoord(x, y) {
recordCount++;
// 移除空提示
// 1. 存储原始坐标到数组核心用于生成C数组
coordsArr.push([x, y]);
// 2. 页面展示坐标(带序号)
if (recordArea.querySelector('.empty-tip')) {
recordArea.innerHTML = '';
}
// 新记录放顶部,方便查看最新坐标
const recordItem = `<span class="record-item">【${recordCount}】X: ${x}, Y: ${y}</span>`;
const recordItem = `<span class="record-item">【${coordsArr.length}】X: ${x}, Y: ${y}</span>`;
recordArea.innerHTML = recordItem + recordArea.innerHTML;
}
// ========== 一键清除:画布+记录+所有状态全重置 ==========
// ========== 核心新增一键生成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代码区 ==========
function clearAll() {
// 1. 清空整个画布
// 1. 清空画布
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 2. 清空坐标记录,恢复空提示
recordArea.innerHTML = '<span class="empty-tip">按住鼠标在画布绘制,自动记录笔刷中心坐标~</span>';
// 3. 重置所有状态
// 2. 重置坐标数组(核心,避免生成旧数据)
coordsArr = [];
// 3. 清空坐标记录区,恢复空提示
recordArea.innerHTML = '<span class="empty-tip">按住鼠标绘制,自动记录笔刷中心坐标~</span>';
// 4. 清空C代码区恢复空提示
cArrayArea.innerHTML = '<span class="c-empty-tip">绘制后点击「生成C语言坐标数组」自动生成规范代码~</span>';
// 5. 重置绘制状态
isDrawing = false;
lastX = 0;
lastY = 0;
recordCount = 0;
// 4. 清除定时器(防止绘制中清除仍在记录)
if (recordTimer) {
clearInterval(recordTimer);
recordTimer = null;
}
// 可选清除成功提示原生alert无依赖
alert('清除成功!画布和记录已重置');
alert('清除成功!画布、记录和坐标数组已全部重置~');
}
// ========== 页面初始化:执行核心方法 ==========
// ========== 页面初始化 ==========
window.onload = function() {
initCanvas(); // 初始化像素画布
bindEvents(); // 绑定所有事件
initCanvas();
bindEvents();
};
</script>
</body>
</html>
</html>