前言:
此时朋友们对“html5canvas设置背景”大概比较关切,我们都想要分析一些“html5canvas设置背景”的相关资讯。那么小编也在网摘上收集了一些有关“html5canvas设置背景””的相关资讯,希望看官们能喜欢,各位老铁们一起来了解一下吧!前言
有没有很好奇,类似 processOn 这类作图网站中,网格背景 是怎么做的呢?
如果你 F12 看过它的代码,你将发现原来不是通过 background-image 之类 css 属性做的,而是通过 canvas 实现的。
这篇主要讲如何通过 canvas 来绘制出这样的 网格背景,以及中间碰到的一个 线条模糊的问题。
手把手写代码
1. 创建 ctx 对象
这边将新建一个和屏幕尺寸相同的 canvas 画布:
const canvasEl = document.createElement("canvas");const sh = screen.height;const sw = screen.width;canvasEl.width = sw;canvasEl.height = sh;const ctx = canvasEl.getContext("2d");
2. 绘制网格
先简单说下思路:
根据 canvas 画布尺寸,以 10px 为间距,分别绘制横纵坐标的线条。
比如绘制横向线条,先将“画笔”移至起点坐标 (0, y),然后通过线条方法 lineTo 绘制屏幕宽度的线条,即绘制 (0, y) 至 (screen.width, y) 的直线。
然后 y 会按照间距 10px 逐渐递增,直至绘制完整个屏幕。
下面根据横纵两个方向,封装了 draw 方法:
const draw = function (isColumn) { const gutter = 10; const limit = isColumn ? sh : sw; let i = 0; while (i * gutter + gutter <= limit) { i++; const point = i * gutter; // 清空子路径列表开始一个新路径 ctx.beginPath(); // 分割线 ctx.strokeStyle = point % 100 !== 0 ? "#f0f0f0" : "#d6e4ff"; // 将一个新的子路径的起始点移动到(x,y)坐标 if (isColumn) { ctx.moveTo(0, point); } else { ctx.moveTo(point, 0); } // 使用直线连接子路径的终点到x,y坐标 if (isColumn) { ctx.lineTo(sw, point); } else { ctx.lineTo(point, sh); } // 根据当前的画线样式,绘制当前或已经存在的路径的方法 ctx.stroke(); }};
然后分别绘制横纵坐标,并把 canvas 挂载到 body 上:
draw(true);draw(false);document.body.append(canvasEl);
很顺利你将得到 canvas 绘制的网格图形:
线条模糊
如果你观察比较细腻,能发现上面的网格图形并不是很清晰,可以仔细观察下面的图:
为什么会有这样的情况出现呢?
因为调用 lineTo 是从 A 点到 B 点,轨迹是点到点的连线。当绘制 1px 线条时,是以这个轨迹连线为中间线左右各渲染 0.5px 的线条。这会使得一个像素点只渲染了一半,而另一半会用一个比较弱的颜色填充,导致绘制出模糊的线条。
怎么改?
只要在 moveTo 时,将坐标偏移 0.5px(即将线条轨迹偏移 0.5 位置),然后调用 lineTo 时,也将坐标偏移 0.5px。
这样,最终绘制线条的时候,将在一个完整的像素区域进行渲染了。
有没有便捷的方法?
使用 translate 偏移 x 和 y 坐标值,然后绘制好后再调用 setTransform 重置回来:
ctx.translate(0.5, 0.5);//...ctx.setTransform(1, 0, 0, 1, 0, 0);参考canvas 画布解决 1px 线条模糊问题Drawing a 1px thick line in canvas creates a 2px thick lineCanvasRenderingContext2D.setTransform()
#前端开发##CSS##canvas#
标签: #html5canvas设置背景