有勇气的牛排博客

如何使用Contenteditable实现简单画布功能:详解教程

有勇气的牛排 374 前端 2024-11-25 22:08:30

1 前言

contenteditable可以使html元素实现可编辑功能,基于此属性,以及上一篇文章的基础,我们可以实现一个简单的画布功能呢。

有了画布自然可以做很多事情,比如绘画、做一些基础的图片都是非常不错的功能。

对比一些现有的第三方库来说,给有优缺点,因此通过contenteditable自定义适合自己的画布是很有必要的。

2 样式设计

样式定义基础画布大小、颜色等工能。

<style> /* 画布样式 */ #canvas { width: 500px; height: 500px; border: 1px solid #000; background-color: #f0f0f0; user-select: none; /* 禁止选择文本 */ position: relative; /* 画布的定位方式,用于定位画笔 */ } /* 使contenteditable元素在点击时没有默认的轮廓样式,并设置光标为十字形 */ #canvas[contenteditable="true"] { outline: none; /*去除点击时的默认轮廓*/ cursor: crosshair; /*设置光标为十字形*/ } /* 画笔样式 */ .brush { position: absolute; /* 使用绝对定位, 使得画笔可以随鼠标移动 */ width: 5px; height: 5px; background-color: black; pointer-events: none; /*不响应鼠标事件,让鼠标事件只作用于画布*/ border-radius: 50%; } </style>

html

<div style="display: flex;justify-content: center;align-items: center;flex-direction: column"> <div id="canvas" contenteditable="true"></div> <ul id="log"></ul> </div>

3 功能设计

<script> const canvas = document.getElementById("canvas"); // 初始化会话状态,默认未绘画 let isDrawing = false; // 鼠标按下事件:开始绘画 canvas.addEventListener("mousedown", (e) => { isDrawing = true; draw(e); }) // 鼠标松开事件:停止绘画 canvas.addEventListener('mouseup', () => { isDrawing = false; // 设置绘画状态为false,表示停止绘画 }); // 鼠标移动事件:如果正在绘画,则继续绘制 canvas.addEventListener('mousemove', (e) => { if (isDrawing) { // 如果处于绘画状态,则调用绘制函数 draw(e); } }); /** * 绘制函数:用于在画布上创建一个小圆点作为画笔 * */ function draw(e) { console.log(e) logEvent('Keydown 事件', `${e}`); // 创建一个新的div元素,用于表示画笔 const brush = document.createElement('div'); brush.classList.add('brush'); // 设置画笔的位置,基于鼠标的当前位置,并且让画笔的中心与鼠标位置对齐 brush.style.left = `${e.offsetX - 2}px`; // 横坐标位置,减去2px使画笔居中 brush.style.top = `${e.offsetY - 2}px`; // 纵坐标位置,减去2px使画笔居中 // 将创建的画笔元素添加到画布中 canvas.appendChild(brush) } </script>

4 日志功能

用于实时输出当前正在调试的时间,便于查看,就不用F12了。

<script> const logList = document.getElementById('log'); // 工具函数:记录事件日志 function logEvent(eventType, additionalInfo = '') { const listItem = document.createElement('li'); const currentTime = new Date().toLocaleTimeString(); // 获取当前时间 listItem.textContent = `[${currentTime}] ${eventType} ${additionalInfo}`.trim(); // listItem.textContent = `${eventType} ${additionalInfo}`.trim(); logList.appendChild(listItem); trimLog(); } // 限制日志长度,防止过多 function trimLog() { if (logList.children.length > 5) { logList.removeChild(logList.firstChild); } } setInterval(trimLog, 500); </script>

5 最终效果

image.png


留言

专栏
文章
加入群聊