1.54ReflectiveLCDTest/手绘记录小工具.html
2026-02-05 01:57:28 +08:00

328 lines
9.8 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>像素风画布 - 一键生成C语言数组版</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: "Microsoft YaHei", sans-serif;
}
body {
background: #f5f7fa;
padding: 15px;
}
/* 主卡片容器 */
.main-card {
max-width: 680px;
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;
}
/* 像素画布核心 */
#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;
}
/* 控制组:新增生成按钮,自动换行不挤压 */
.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;
}
/* 按钮统一样式:清除红+生成蓝,最小宽度一致 */
.func-btn {
min-width: 140px;
white-space: nowrap;
padding: 6px 16px;
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: 180px;
border: 1px solid #eee;
border-radius: 4px;
padding: 12px;
overflow-y: auto;
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) | 一键生成C语言坐标数组</h3>
<p class="canvas-tip">按住左键绘制 → 自动记录坐标 → 点击生成C数组 → 直接复制使用</p>
<!-- 200x200像素画布 -->
<div class="canvas-box">
<canvas id="drawCanvas" width="200" height="200"></canvas>
</div>
<!-- 控制区:滑块 + 清除按钮 + 生成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" class="func-btn">清除图像&记录</button>
<button id="genCArrBtn" class="func-btn">生成C语言坐标数组</button>
</div>
<!-- 坐标记录区 -->
<h4 class="record-title">绘制坐标记录20ms/次)</h4>
<div id="recordArea">
<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元素 ==========
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');
// ========== 全局状态新增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;
}
// ========== 开始绘制 ==========
function startDraw(e) {
isDrawing = true;
[lastX, lastY] = getCanvasXY(e);
// 绘制起点也记录坐标
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);
ctx.fillStyle = '#2c3e50';
ctx.fill();
}
// ========== 停止绘制 ==========
function stopDraw() {
if (!isDrawing) return;
isDrawing = false;
clearInterval(recordTimer);
recordTimer = null;
}
// ========== 工具方法:获取画布相对坐标 ==========
function getCanvasXY(e) {
const rect = canvas.getBoundingClientRect();
return [
Math.round(e.clientX - rect.left),
Math.round(e.clientY - rect.top)
];
}
// ========== 坐标记录同步更新coordsArr和页面展示 ==========
function recordCoord(x, y) {
// 1. 存储原始坐标到数组核心用于生成C数组
coordsArr.push([x, y]);
// 2. 页面展示坐标(带序号)
if (recordArea.querySelector('.empty-tip')) {
recordArea.innerHTML = '';
}
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. 清空画布
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 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;
if (recordTimer) {
clearInterval(recordTimer);
recordTimer = null;
}
alert('清除成功!画布、记录和坐标数组已全部重置~');
}
// ========== 页面初始化 ==========
window.onload = function() {
initCanvas();
bindEvents();
};
</script>
</body>
</html>