【Excalidraw揭秘】canvas无限画布及矩形绘制

本文介绍了如何使用JavaScript实现Excalidraw的无限画布功能,详细阐述了从屏幕坐标系转换到canvas坐标系的过程,以及如何在无限画布上绘制和管理矩形。此外,还探讨了画布滚动、坐标轴更新以及图形导出为PNG图片的实现方法。
摘要由CSDN通过智能技术生成

前言

本节我们通过简单的矩形绘制学习如何实现无限画布

准备工作

在绘制前,我们需要矫正 canvas 的分辨率,使用 appState 保存 canvas 相关的信息。新建一个 index.jsx 文件,初始化代码如下:

const appState = {offsetLeft: 0,offsetTop: 0,
};
const Canvas = memo(() => {const canvasRef = useRef(null);const canvasContainer = useRef(null);useEffect(() => {const canvas = canvasRef.current;const context = canvas.getContext("2d");const { offsetWidth, offsetHeight, offsetLeft, offsetTop } = canvas;canvas.width = offsetWidth * window.devicePixelRatio;canvas.height = offsetHeight * window.devicePixelRatio;context.scale(window.devicePixelRatio, window.devicePixelRatio);appState.offsetLeft = offsetLeft;appState.offsetTop = offsetTop;}, []);return (<div ref={canvasContainer}><canvas ref={canvasRef} className="canvas">绘制canvas</canvas></div>);
}); 

绘制坐标轴

为方便观察,首先在 canvas 上绘制一个坐标轴。新建一个 renderScene.js 文件,实现 drawAxis 方法:

const drawAxis = (ctx) => {ctx.save();const rectH = 100; // 纵轴刻度间距const rectW = 100; // 横轴刻度间距const tickLength = 8; // 刻度线长度const canvas = ctx.canvas;ctx.translate(0, 0);ctx.strokeStyle = "red";ctx.fillStyle = "red";// 绘制横轴和纵轴ctx.save();ctx.beginPath();ctx.setLineDash([10, 10]);ctx.moveTo(0, 0);ctx.lineTo(0, canvas.height);ctx.moveTo(0, 0);ctx.lineTo(canvas.width, 0);ctx.stroke();ctx.restore();// 绘制横轴和纵轴刻度ctx.beginPath();ctx.lineWidth = 2;ctx.textBaseline = "middle";for (let i = 0; i < canvas.height / rectH; i++) {// 绘制纵轴刻度ctx.moveTo(0, i * rectH);ctx.lineTo(tickLength, i * rectH);ctx.font = "20px Arial";ctx.fillText(i, -25, i * rectH);}for (let i = 1; i < canvas.width / rectW; i++) {// 绘制横轴刻度ctx.moveTo(i * rectW, 0);ctx.lineTo(i * rectW, tickLength);ctx.font = "20px Arial";ctx.fillText(i, i * rectW - 5, -15);}ctx.stroke();ctx.restore();
};

const renderScene = (canvas) => {const context = canvas.getContext("2d");drawAxis(context);
};

export default renderScene; 

然后在 index.jsx 中引入 renderScene

useEffect(() => {//...renderScene(canvas);
}, []); 

效果如下:

infinite-01.jpg

绘制矩形

屏幕坐标系转 canvas 坐标系

在开始绘制矩形之前,我们先来看下屏幕坐标系如何转换成 canvas 坐

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值