文章目录
一、前言
在线画板是许多应用(如白板协作工具、手写笔记、绘图软件)中的重要组件。我们可以使用 React
+ Konva.js
结合 react-konva
来实现一个功能丰富的画板。
本教程将带你实现一个支持 自由绘制、清空画布、撤销/重做 的 React 画板组件。
二、Konva.js 介绍
Konva.js 是一个基于 Canvas API 的 2D 图形库,支持高性能的绘图操作,如路径、形状、文本、图片等。它具有以下优点:
- 更高性能:相比 DOM 操作,Canvas 渲染更加流畅;
- 提供丰富的图形 API(直线、多边形、贝塞尔曲线等);
- 支持事件监听,如
click
、drag
、touch
等。
react-konva
是 Konva.js 的 React 封装库,使其可以在 React 中更方便地使用。
三、创建 React 画板项目
3.1 安装依赖
在 React 项目中,安装 react-konva
和 konva
:
{bash}
npm install react-konva konva
{bash}
3.2 创建 CanvasBoard
组件
新建 CanvasBoard.js
,并使用 react-konva
组件创建一个可绘制的 Canvas。
// CanvasBoard.js
import React, { useRef, useState } from "react";
import { Stage, Layer, Line } from "react-konva";
const CanvasBoard = () => {
const [lines, setLines] = useState([]);
const [isDrawing, setIsDrawing] = useState(false);
const stageRef = useRef(null);
// 开始绘制
const handleMouseDown = (event) => {
setIsDrawing(true);
const { x, y } = event.target.getStage().getPointerPosition();
setLines([...lines, { points: [x, y] }]);
};
// 画线
const handleMouseMove = (event) => {
if (!isDrawing) return;
const { x, y } = event.target.getStage().getPointerPosition();
const newLines = [...lines];
newLines[newLines.length - 1].points.push(x, y);
setLines(newLines);
};
// 结束绘制
const handleMouseUp = () => {
setIsDrawing(false);
};
return (
<div>
<Stage
width={800}
height={500}
ref={stageRef}
onMouseDown={handleMouseDown}
onMousemove={handleMouseMove}
onMouseup={handleMouseUp}
style={{ border: "1px solid #ccc", background: "#fff" }}
>
<Layer>
{lines.map((line, index) => (
<Line key={index} points={line.points} stroke="black" strokeWidth={3} tension={0.5} lineCap="round" />
))}
</Layer>
</Stage>
</div>
);
};
export default CanvasBoard;
四、增加画布控制功能
4.1 清空画布
我们可以添加一个“清空”按钮,点击后清除所有线条。
const handleClearCanvas = () => {
setLines([]);
};
{javascript}
并在 `CanvasBoard` 组件中添加按钮:
{javascript}
<button onClick={handleClearCanvas}>清空画布</button>
4.2 撤销 & 重做功能
为了实现 撤销/重做,我们需要一个状态栈来存储历史操作。
修改 CanvasBoard.js
:
const [history, setHistory] = useState([]);
const [redoStack, setRedoStack] = useState([]);
const handleUndo = () => {
if (lines.length > 0) {
setRedoStack([...redoStack, lines[lines.length - 1]]);
setLines(lines.slice(0, -1));
}
};
const handleRedo = () => {
if (redoStack.length > 0) {
setLines([...lines, redoStack[redoStack.length - 1]]);
setRedoStack(redoStack.slice(0, -1));
}
};
并在 CanvasBoard
组件中添加按钮:
<button onClick={handleUndo}>撤销</button>
<button onClick={handleRedo}>重做</button>
五、增加颜色和画笔大小选择
我们可以添加选择颜色和画笔大小的功能,使画板更丰富。
5.1 选择颜色
在 CanvasBoard.js
中添加颜色选择器:
const [color, setColor] = useState("black");
<input type="color" value={color} onChange={(e) => setColor(e.target.value)} />
并修改 Line
组件,让它支持动态颜色:
<Line key={index} points={line.points} stroke={line.color || "black"} strokeWidth={3} />
{javascript}
当鼠标按下时,将颜色存入 `lines`:
{javascript}
setLines([...lines, { points: [x, y], color }]);
5.2 选择画笔大小
在 CanvasBoard.js
添加画笔大小选择器:
const [strokeWidth, setStrokeWidth] = useState(3);
<input type="range" min="1" max="10" value={strokeWidth} onChange={(e) => setStrokeWidth(e.target.value)} />
{javascript}
修改 `Line` 组件,让它支持动态画笔大小:
{javascript}
<Line key={index} points={line.points} stroke={line.color || "black"} strokeWidth={line.strokeWidth || 3} />
当鼠标按下时,将 strokeWidth
存入 lines
:
setLines([...lines, { points: [x, y], color, strokeWidth }]);
六、最终效果
最终,我们的在线画板具备以下功能:
✅ 支持自由绘制
✅ 支持清空画布
✅ 支持撤销/重做
✅ 支持颜色选择
✅ 支持画笔大小调整
你可以将 CanvasBoard
组件导入 App.js
进行测试:
// App.js
import React from "react";
import CanvasBoard from "./CanvasBoard";
function App() {
return (
<div className="App">
<h1>React 画板</h1>
<CanvasBoard />
</div>
);
}
export default App;
七、总结
本篇文章介绍了如何使用 React
+ Konva
实现一个 在线画板组件,并添加了 撤销/重做、颜色选择、画笔大小调整 等功能。Konva
提供了高效的 Canvas API,使得 React 处理复杂的绘图操作变得更加轻松。
你可以在此基础上继续扩展,比如:
- 添加橡皮擦功能
- 支持图像导入与导出
- 多人协作(结合 WebSocket)
到这里,这篇文章就和大家说再见啦!我的主页里还藏着很多 篇 前端 实战干货,感兴趣的话可以点击头像看看,说不定能找到你需要的解决方案~
创作这篇内容花了很多的功夫。如果它帮你解决了问题,或者带来了启发,欢迎:
点个赞❤️ 让更多人看到优质内容
关注「前端极客探险家」🚀 每周解锁新技巧
收藏文章⭐️ 方便随时查阅
📢 特别提醒:
转载请注明原文链接,商业合作请私信联系
感谢你的阅读!我们下篇文章再见~ 💕