javascript|canvas核心内容


文章目录

  • canvas核心内容
    • 1、概念
            • 提示:
    • 2、绘制直线
        • 案例:
    • 3、绘制矩形
        • 案例:绘制柱状图
    • 4、绘制曲线
        • 案例一:时钟
        • 案例二:饼状图
    • 5、绘制文本信息
        • 案例:
    • 6、绘制图片
        • 案例:
    • 7、清除画布指定元素
        • 案例:橡皮擦
【javascript|canvas核心内容】
canvas核心内容 1、概念 canvas是画布,其实就是h5的一个新标签,他自己有一套画图的语法标准。
canvas本身没有任何的绘图能力,所有的绘图工作都是通过js来实现的。通常我们在js通过getElementById来获取要操作的canvas(这意味着咱得给canvas设个id):
> var c = document.getElementById("myCanvas"); //获取要操作的canvas //操作canvas的代码...

注意最好在一开始的时候就给canvas设置好其宽高(若不设定宽高,浏览器会默认设置canvas大小为宽300、高100像素),而且不能使用css来设置(会被拉伸,有失真的风险),建议直接写于canvas标签内部:

当然,也可以在脚本中设置:
> var c = document.getElementById("myCanvas"); c.width=200; c.height=200;

要知道的是; 超出此大小范围的部分是不可见的。顾名思义,可以把canvas看成一块画布,其大小是咱设定好的宽高,那么无论你怎么画,画布外的地方自然是画不到的。
.getContext() 是canvas的绘图对象/方法,要让canvas执行绘图工作必须先获取canvas的.getContext()对象来执行。
.getContext()只接受一个参数,该参数用于获取canvas的绘图环境,例如.getContext(“2d”)表示该canvas的绘图环境为2D平面(可以绘制文本、直线、弧线、矩形、圆形等)。还有3D环境,自行研究。
提示: vscode中获取提示内容,在script脚本中加入:
/** @type {HTMLCanvasElement} */

上面这一行代码,表示引入canvas,就会出现提示内容。
2、绘制直线
您的浏览器不支持canvas,建议使用最新版的Chrome > var c = document.getElementById("myCanvas"); var ctx = c.getContext("2d"); //获取该canvas的2D绘图环境对象 ctx.moveTo(10,10); //定义绘画开始的位置 ctx.lineTo(150,50); //画一条直线,结束点坐标是x=150,y=50 ctx.stroke(); //描边

效果如下:
javascript|canvas核心内容
文章图片

  • .moveTo(x坐标 , y坐标) 可以理解为定位画笔在画布上的位置(注意所有绘图方法所定义的坐标是相对canvas而言的而不是浏览器窗口,对canvas来说,最左上角的点的坐标是(0,0))
  • .lineTo(x坐标 , y坐标) 顾名思义,就是画一条直线到某个点,很好理解。需要知道的是此方法仅仅做路径运动,而不存在任何视觉上的绘图效果(上色、描边)。如果不另外设置moveTo则自动把上一条边的终点作为下一条边的起点。
  • .stroke() 描边方法,canvas想要运动路径轨迹能有视觉效果,需要使用相应的上色/描边方法。
  • .strokeStyle = “red”; 设定描边颜色为红色,只要写在.stroke()方法前面即可。
  • ctx.strokeStyle可获值的形式有三种:用的时候查一查
    ctx.strokeStyle=color|gradient|pattern; //即支持 “颜色/渐变/图案笔刷” 的赋值

如果要绘制两条不一样颜色的直线,就需要给第二条边绘制时,开启另外一条轨道,不然就算设置了两个颜色也不会显示出两条不同颜色的线。
案例:
> var c = document.getElementById("myCanvas"); var ctx = c.getContext("2d"); ctx.moveTo(0,0); ctx.lineTo(150,50); ctx.lineTo(20,100); ctx.strokeStyle = "blue"; //设定描边颜色为蓝色 ctx.stroke(); ctx.beginPath(); //告诉canvas咱们要重新绘制一条全新的路径了,之前画的东西从此再无关系 ctx.moveTo(90,90); ctx.lineTo(80,150); ctx.strokeStyle = "red"; //设定描边颜色为红色 ctx.stroke();

效果如下:
javascript|canvas核心内容
文章图片

3、绘制矩形 canvas本身就自带绘制矩形的方法;ctx.rect(x,y,w,h);
参数说明:
  • x,y:表示起点坐标,以画布左上角为坐标中心,x向右增大,y向下增大。
  • w,h:分别代表矩形的宽高。
> var canvas = document.getElementById("box"); var ctx = canvas.getContext("2d"); ctx.strokeStyle = "red"; ctx.fillStyle = "blue"; ctx.lineWidth = 5; ctx.beginPath(); ctx.rect(100, 100, 200, 200); ctx.closePath(); //闭合通道ctx.fill(); //填充ctx.stroke(); //描边

效果如下:
javascript|canvas核心内容
文章图片

如果我们想给一个图像不仅要填充,还要绘制边框,那我们要先填充,后绘制边框,这样我们的边框才会正常显示。
所以还有另外的方法:fillRect(x,y,w,h)和strokeRect(x,y,w,h);
> var canvas = document.getElementById("box"); var ctx = canvas.getContext("2d"); ctx.strokeStyle = "red"; ctx.fillStyle = "blue"; ctx.lineWidth = 5; ctx.strokeStyle = 'red'; ctx.fillRect(100, 100, 200, 200); ctx.strokeRect(100, 100, 200, 200);

效果如上一样。
案例:绘制柱状图
> #box { border: 2px solid pink; } > /** @type {HTMLCanvasElement} */ var canvas = document.querySelector('#box'); var ctx = canvas.getContext('2d'); var arr = [234, 535, 2343, 4266, 2345, 7895]; var arr1 = ['红烧肉', '鸡腿', '肘子', '火锅', '串串', '冒菜'] ctx.lineTo(50, 500); ctx.lineTo(580, 500); ctx.stroke(); var h = 450 / Math.max(...arr); for (let i = 0; i < arr.length; i++) { ctx.fillStyle = 'blue'; ctx.strokeText(arr1[i], 100 + i * 73, 520); ctx.fillRect(100 + i * 70, 500 - h * arr[i], 50, h * arr[i]); }

效果如下:
javascript|canvas核心内容
文章图片

4、绘制曲线 方法:ctx.arc():在当前子路经添加一条弧线;
语法:context.arc(x,y,r,sAngle,eAngle,counterclockwise);
参数 描述
x 圆的中心的 x 坐标。
y 圆的中心的 y 坐标。
r 圆的半径。
sAngle 起始角,以弧度计。(弧的圆形的三点钟位置是 0 度)。
eAngle 结束角,以弧度计。
counterclockwise 可选。规定应该逆时针还是顺时针绘图。False = 顺时针,true = 逆时针。
案例一:时钟
> #box { border: 2px solid black; } > /** @type {HTMLCanvasElement} */ var canvas = document.querySelector('#box'); var ctx = canvas.getContext('2d'); //角度转换单位度 let deg = Math.PI / 180; //表盘的绘制 function biaopan() { //圆心(300,300) 半径:200,从0度-360度画圆 ctx.arc(300, 300, 200, 0, 360 * deg) //刻度 //设置开始角度6度 刻盘上每两个刻度之间的角度是6度 var startAnge = 6, r = 200, y1 = 300, x1 = 300; var kedu = 10; //刻度的长度 for (let i = 0; i < 60; i++) { var kedu = 10; //刻度的长度,i%5为真时刻度不变,为假时长度变为二倍 let a; if (i % 5) { a = kedu; } else { a = kedu * 2; }//计算每个刻度所在的坐标 var y2 = y1 + r * Math.sin(i * startAnge * deg); var x2 = x1 + r * Math.cos(i * startAnge * deg); var y3 = y1 + (r - a) * Math.sin(i * startAnge * deg); var x3 = x1 + (r - a) * Math.cos(i * startAnge * deg); //刻度连线 ctx.moveTo(x2, y2); ctx.lineTo(x3, y3); ctx.stroke(); }}//绘制表针 function biaozhen() { //三根针的长度 var sh = 160, mh = 130, hh = 100; var s = new Date().getSeconds(); ctx.moveTo(300, 300); //秒针 var x4 = 300 + sh * Math.cos(s * 6 * deg); var y4 = 300 + sh * Math.sin(s * 6 * deg); //分针,一秒钟分针转动1/10度 var x5 = 300 + mh * Math.cos(s * 1 / 10 * deg); var y5 = 300 + mh * Math.sin(s * 1 / 10 * deg); //时针,一秒钟分针转动1/120度 var x6 = 300 + hh * Math.cos(s * 1 / 120 * deg); var y6 = 300 + hh * Math.sin(s * 1 / 120 * deg); ctx.lineTo(x4, y4); ctx.moveTo(300, 300); ctx.lineTo(x5, y5); ctx.moveTo(300, 300); ctx.lineWidth = 2; ctx.lineTo(x6, y6); ctx.stroke(); } setInterval(() => { canvas.width = canvas.width; //清除上一次的直线 biaopan() biaozhen() }, 1000)

效果图:
javascript|canvas核心内容
文章图片

案例二:饼状图
> /** @type {HTMLCanvasElement} */ var canvas = document.querySelector('#box'); var ctx = canvas.getContext('2d'); //模拟数据,一个月的消费统计 var arr = [{ name: '食物', money: 1870 }, { name: '出行', money: 2470 }, { name: '衣服', money: 3470 }, { name: '药物', money: 470 }, { name: '其他', money: 1470 }, ] //添加元素记录总金额 arr.total = 0; for (let j = 0; j < arr.length; j++) { //计算总金额 arr.total += arr[j].money; }//开始绘制的角度位置 var start = 0; for (let i = 0; i < arr.length; i++) { //每一次绘制扇形呈现不一样的颜色,所以要开启新的轨道 ctx.beginPath() //每一个扇形的比例 var bili = arr[i].money / arr.total * 360; //换算一度的单位deg保存 var deg = Math.PI / 180; //绘制扇形 ctx.arc(300, 300, 200, start * deg, (start + bili) * deg); //每次扇形绘制的终点,为下一个扇形绘制的起点//添加文字到每个角度的中心线 var x = 300 + 230 * Math.cos(((start + bili) - bili / 2) * deg); var y = 300 + 230 * Math.sin(((start + bili) - bili / 2) * deg); //设置文字大小,字体样式 ctx.font = " 14px sans-serif" //设置文字颜色 ctx.fillStyle = 'black'; //设置文字水平方向居中 ctx.textAlign = "center"; //设置垂直方向居中 ctx.textBaseline = "middle" ctx.fillText(`${arr[i].name}`, x, y) start = start + bili; //每次扇形绘制的终点与圆心连接起来 ctx.lineTo(300, 300); //生成随机色 let r = parseInt(Math.random() * (255)); let g = parseInt(Math.random() * (255)); let b = parseInt(Math.random() * (255)); ctx.fillStyle = `rgb(${r},${g},${b})`; //填充颜色 ctx.fill() //绘制图形 ctx.stroke() }

效果图:
javascript|canvas核心内容
文章图片

5、绘制文本信息 1、font属性:可以设置字体的大小和字体名称。
fillText方法的作用:填充文字。
ctx.fillText("我是微软雅黑",100,100);

第一个参数:填充的文字内容。
第二、三个参数: 绘制的内容; 起点x坐标; 起点y坐标。
2、textAlign属性的作用:文字水平的对齐方式。
ctx.textAlign = "left";

3、textBaseline则指定垂直方向,可选值:top、hanging,middle,等
ctx.textBaseline='middle';

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PRTI5J4b-1658633907279)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20220724111833533.png)]
案例:
> canvas{ border: 1px solid black; } > var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); //写文字 ctx.font = "30px 微软雅黑"; ctx.textAlign = "left"; ctx.fillText("我是微软雅黑",100,100); // (100,100)是绘制文字的位置

效果如下:
javascript|canvas核心内容
文章图片

6、绘制图片 drawImage():将原图片像素的内容复制到画布上;
? 第一个参数是源图片,可以是img元素或Image构造函数创建的屏幕外图片对象;
? 三个参数时: 指定图片绘制的x、y坐标;
? 五个参数时: 指定图片绘制的x、y坐标,以及图片的宽度、高度;
? 九个参数时: 裁剪的对象 裁剪的位置(x,y); 裁剪的宽度和高度(w,h); 裁剪后图片绘制的位置(x,y); 图片显示出来的宽度和高度(w,h);
参数 描述
img 规定要使用的图像、画布或视频。
sx 可选。开始剪切的 x 坐标位置。
sy 可选。开始剪切的 y 坐标位置。
swidth 可选。被剪切图像的宽度。
sheight 可选。被剪切图像的高度。
x 在画布上放置图像的 x 坐标位置。
y 在画布上放置图像的 y 坐标位置。
width 可选。要使用的图像的宽度。(伸展或缩小图像)
height 可选。要使用的图像的高度。(伸展或缩小图像)
绘制的两种方法:
案例:
  1. 获取页面已经存在的图片节点,绘制到画布上。
    > #box { border: 2px solid black; } javascript|canvas核心内容
    文章图片
    > /** @type {HTMLCanvasElement} */ var canvas = document.querySelector('#box'); var img1 = document.querySelector('img') var ctx = canvas.getContext('2d'); img1.onload = function () { ctx.drawImage(img1, 20, 20, 100, 100); }

  2. 创建构造函数加载图片
    > #box { border: 2px solid black; } > /** @type {HTMLCanvasElement} */ var canvas = document.querySelector('#box'); var ctx = canvas.getContext('2d'); var imgobj = new Image(); imgobj.src = 'https://www.it610.com/dom/image/flower1.png' imgobj.onload = function () { ctx.drawImage(imgobj, 20, 20, 100, 100); }

    效果如下:
    javascript|canvas核心内容
    文章图片

7、清除画布指定元素 clearRect() 方法清空给定矩形内的指定像素 ;
JavaScript 语法:
context.clearRect(x,y,width,height);

参数 描述
x 要清除的矩形左上角的 x 坐标
y 要清除的矩形左上角的 y 坐标
width 要清除的矩形的宽度,以像素计
height 要清除的矩形的高度,以像素计
案例:橡皮擦
Document - 锐客网 > #box { border: 2px solid black; }.cut { width: 60px; height: 60px; background: url(./image/橡皮擦.png); background-size: cover; /* background-color: green; */ position: absolute; display: inline-block; }
画布内点击生花,拖动右方橡皮擦擦除画布> /** @type {HTMLCanvasElement} */var canvas = document.querySelector('#box'); var ctx = canvas.getContext("2d"); var cut = document.querySelector('.cut'); cut.addEventListener('mousedown', function (e) { // console.log(1111); var x = e.pageX - cut.offsetLeft; var y = e.pageY - cut.offsetTop; document.addEventListener('mousemove', move); function move(e) { cut.style.left = (e.pageX - x) + 'px'; cut.style.top = (e.pageY - y) + 'px'; ctx.clearRect(e.pageX - x, e.pageY - y, 40, 40); }document.addEventListener('mouseup', function () { document.removeEventListener('mousemove', move); }) })var imgobj = new Image(); imgobj.src = 'https://www.it610.com/dom/image/flower1.png'; //点击生花 imgobj.onload = function () { canvas.addEventListener('click', function (e) { var x = e.pageX - 30, y = e.pageY - 30; ctx.drawImage(imgobj, x, y, 60, 60); }) }

效果如下:
javascript|canvas核心内容
文章图片

    推荐阅读