前言
最近也是在学习 canvas,跟着绘制了一个最基本柱状图,canvas 是一个基于 HTML5 的绘图标准,提供了一系列的 API 可以用来绘制图形,包括直线、矩形、圆形、文本等等。我介绍如何使用 canvas 绘制简单的柱状图,并优化技巧,使得代码更加高效
绘制柱状图
在上图的柱状图里有什么?
绘制坐标轴
首先来对画布进行一个初始化,获取 canvas 元素并获取其 2D 上下文对象的,对 canvas 元素的尺寸进行缩放,将 canvas 元素的 CSS 宽高设置为它在 HTML 中设置的宽度和高度,确保 canvas 在页面中显示的大小不会改变,然后根据设备像素比扩大画布的像素,提高图像的清晰度,防止模糊发虚
 <canvas id="canvas" width="600" height="500"></canvas><script>  const canvas = document.getElementById("canvas");  const ctx = canvas.getContext("2d");  canvas.style.width = canvas.width + "px";  canvas.style.height = canvas.height + "px";  canvas.width = canvas.width * 1.5;  canvas.height = canvas.height * 1.5;</script>
       复制代码
 
然后定义一些相关的属性,在绘制的过程中以备使用
 const ht = canvas.clientHeight; //画布高度const wd = canvas.clientWidth; //画布宽度const pad = 20; //边距const bottomPad = 20; //底部边距const step = 100; //坐标轴刻度间距
       复制代码
 
首先要把坐标轴的那条直角画出来,设置 lineWidth 线宽为 2,strokeStyle 笔画颜色为'lightblue',绘制的起点为定义好的常量 pad 为 20,一直绘制到最底部然后再往右边绘制
 // 绘制坐标轴ctx.beginPath();ctx.lineWidth = 2;ctx.strokeStyle = "lightblue";ctx.moveTo(pad, pad);ctx.lineTo(pad, ht * 1.5 - bottomPad);ctx.lineTo(wd * 1.5 - pad, ht * 1.5 - bottomPad);ctx.stroke();ctx.closePath();
       复制代码
 
然后循环绘制 x 轴方向刻度,起点 x 轴固定不变为 pad,y 轴坐标为画布高度 * 1.5 - bottomPad - i * 坐标轴刻度间距,终点 x 轴为 pad + 10,y 轴和起点 y 轴一致
循环 y 轴方向刻度也是同理,只不过是反过来了
 // 绘制x轴方向刻度ctx.beginPath();ctx.lineWidth = 1;ctx.strokeStyle = "#666";for (let i = 1; i < Math.floor((ht * 1.5) / step); i++) {ctx.moveTo(pad, ht * 1.5 - bottomPad - i * step);ctx.lineTo(pad + 10, ht * 1.5 - bottomPad - i * step);}ctx.stroke();ctx.closePath();
// 绘制y轴方向刻度ctx.beginPath();ctx.lineWidth = 1;ctx.strokeStyle = "#666";for (let i = 1; i < Math.floor((wd * 1.5) / step); i++) {ctx.moveTo(pad + i * step, ht * 1.5 - bottomPad);ctx.lineTo(pad + i * step, ht * 1.5 - bottomPad + 10);}ctx.stroke();ctx.closePath();
       复制代码
 
绘制柱子
柱子实际上就是一个矩形,绘制矩形分三种,有描边有填充,无描边有填充,有描边无填充
有描边有填充通过rect方法绘制出一个矩形的路径,但不会实际绘制矩形,还需要通过stroke方法和fill方法来绘制描边和填充
无描边有填充通过fillRect方法绘制一个填充的矩形,有描边无填充通过strokeRect方法绘制一个边框矩形
无论是rect方法,fillRect方法还是strokeRect方法都要传入四个参数:x 轴坐标,y 轴坐标,宽度,高度
 // 绘制矩形填充ctx.beginPath();ctx.lineWidth = 5; //线条宽度ctx.strokeStyle = "orange"; //笔画颜色ctx.fillStyle = "hotpink"; //填充颜色ctx.rect(100, 100, 300, 200); //绘制矩形路径ctx.stroke(); //绘制描边ctx.fill(); //填充ctx.closePath();
ctx.beginPath();ctx.lineWidth = 4;ctx.strokeStyle = "blue";ctx.strokeRect(100, 310, 300, 200); //绘制矩形(无填充)ctx.closePath();
ctx.beginPath();ctx.fillStyle = "skyblue";ctx.fillRect(410, 310, 300, 200); //绘制矩形(填充)ctx.closePath();
       复制代码
 
知道如何绘制矩形然后就可以绘制出柱子了,只需要绘制有填充五描边的矩形就行了,于是循环调用fillRect方法绘制
 ctx.beginPath();for (let i = 1; i < Math.floor((wd * 1.5) / step); i++) {    const height = Math.random() * 500 + 50;    ctx.fillStyle = "#5470C6";    ctx.fillRect(i * step, ht * 1.5 - bottomPad, 40, -height);}ctx.closePath();
       复制代码
 
评论