700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > canvas--初识canvs 绘制:线型 简单图形 渐变背景颜色 绘制动画 canvs形变 事件绑定

canvas--初识canvs 绘制:线型 简单图形 渐变背景颜色 绘制动画 canvs形变 事件绑定

时间:2022-07-24 21:56:07

相关推荐

canvas--初识canvs 绘制:线型 简单图形 渐变背景颜色 绘制动画 canvs形变 事件绑定

目录

一、初识canvas

1.1 基本使用

1.2 示例

1.1 注意点

二、canvas线条相关属性

2.1 常用属性

2.2 示例

2.3 绘制多根线条

c.示例:

三、canvas绘制简单图形

3.1 绘制三角形

3.2 路径绘制

3.3 矩形绘制

3.4 绘制虚线

3.5 绘制表格

3.6 绘制坐标系

3.7 绘制数据点

3.8 绘制折线图

3.9 绘制柱状图

四、渐变背景颜色

4.1 设置图形渐变背景颜色步骤

4.2 绘制圆弧

4.3 绘制饼状图

4.4 绘制文字

4.5 图片绘制

五、绘制动画

六、canvs形变

七、事件绑定

一、初识canvas

Canvas是H5新增的一个标签, 我们可以通过JS在这个标签上绘制各种图案

Canvas 拥有多种绘制路径、矩形、圆形、字符以及图片的方法

Canvas可以替换像flash等其他做动画或游戏的插件的一个标签,能够大大减小页面的结构大小。让页面加载速度变快。

1.1 基本使用

canvas标签可以理解为一个‘div’

只不过div是存放元素的,而canvas则是提供了一个区域用来绘制图形。

canvas标签习惯上在标签内部对其大小进行设置,例如:

<canvas width=’300’ height=’300’>您的浏览器不支持canvas标签,请变更支持cnavas标签的浏览器</canvas>

canvas标签本身就是一个普通的画板,除此之外没有任何多余的功能

内部的所有内容或图形都需要通过js脚本来完成。

首先,创建canvas画布,在body标签中创建一个canvas标签

其次,进行相关样式设置

最后,如果想要在画布上进行操作,则需要通过脚本来创建一个‘画家’,来帮助我们进行内容绘制。

1.2 示例

*{margin: 0;padding: 0;}canvas{background: red;}

<canvas>您的浏览器不支持canvas标签,请更换支持canvas标签的浏览器</canvas>

// 2.通过js代码拿到canvas标签let oCanvas = document.querySelector("canvas");// 3.从canvas标签中获取到绘图工具let oCtx = oCanvas.getContext("2d");// 4.通过绘图工具在canvas标签上绘制图形// 4.1设置路径的起点oCtx.moveTo(50, 50);// 4.2设置路径的终点oCtx.lineTo(200, 50);// 4.3告诉canvas将这些点连接起来oCtx.stroke();

1.1 注意点

canvas标签有默认的宽度和高度:默认的宽度是300px;默认的高度是150px

不能通过CSS设置画布的宽高:通过CSS设置画布宽高会在默认宽高的基础上拉伸,如果需要设置canvas宽高请通过元素行内属性width和height设置

<canvas width="500" height="500"></canvas>

线条默认宽度和颜色:通过canvas绘制的线条默认宽度是1px, 颜色是纯黑色;但是由于默认情况下canvas会将线条的中心点和像素的底部对齐,所以会导致显示效果是2px和非纯黑色问题

二、canvas线条相关属性

2.1 常用属性

线型宽度:ctx.lineWith=数值;设置端点:ctx.lineCap='端点类型';

butt无端点round圆角端点square方块端点

设置连接:ctx.lineJoin='连接类型';

round圆弧连接bevel截面连接miter直角连接

设置虚线:ctx.setLineDash([第一段长度,第二段长度...]);

*{margin: 0;padding: 0;}canvas{background: red;}

<canvas width="300" height="200">您的浏览器不支持canvas标签,请更换支持canvas标签的浏览器</canvas>

2.2 示例

示例1:

//拿到画布let oCanvas = document.querySelector("canvas");//拿到绘制工具let ctx = oCanvas.getContext("2d");//修改线条高度ctx.lineWidth = 10;//修改线条颜色ctx.strokeStyle = "#fff";//修改线条两端样式// ctx.lineCap="";// ctx.lineCap="square";ctx.lineCap="round";//设置虚线ctx.setLineDash([10,5,20]);//利用后置工具绘制直线// 设置起始位置ctx.moveTo(50,50.5);// 设置路径上的点ctx.lineTo(200,50.5);ctx.lineTo(200,150.5);ctx.lineTo(50,150.5);ctx.lineTo(50,50.5);// 绘制已定义的路径ctx.stroke();

示例2:

var huaban = document.querySelector('canvas');var ctx = huaban.getContext('2d');ctx.beginPath(); //开始ctx.moveTo(40, 80); //起始位置ctx.lineTo(230, 80);ctx.lineTo(230, 180);ctx.lineWidth = 5; //线型宽度ctx.lineCap = 'butt'; //端点类型 无端点ctx.lineJoin = 'miter'; //设置连接 直角连接ctx.setLineDash([10, 5, 20]); //设置虚线 第一段长度,第二段长度,第三段长度...ctx.stroke();ctx.closePath(); //结束

2.3 绘制多根线条

a.多根线条注意点:

如果是同一个路径, 那么路径样式会被重用(第二次绘制会复用第一次的样式)如果是同一个路径, 那么后设置的路径样式会覆盖先设置的路径样式

b.如何给每根线条单独设置路径样式?

每根线条都开启一个新的路径即可

c.示例:

//拿到画布let oCanvas = document.querySelector("canvas");//拿到绘制工具let ctx = oCanvas.getContext("2d");// //修改线条两端样式// // ctx.lineCap="";// // ctx.lineCap="square";// ctx.lineCap="round";//设置虚线// ctx.setLineDash([10,5,20]);//利用后置工具绘制直线// 设置起始位置ctx.moveTo(50, 50);// 设置路径上的点ctx.lineTo(200, 50);// 修改线条高度ctx.lineWidth = 20;//修改线条颜色ctx.strokeStyle = "blue";// 绘制已定义的路径ctx.stroke();ctx.beginPath(); // 重新开启一个路径ctx.moveTo(50, 100);ctx.lineTo(200, 100);ctx.lineWidth = 10; // 重新设置当前路径样式ctx.strokeStyle = "white";ctx.stroke();ctx.beginPath(); // 重新开启一个路径ctx.moveTo(50, 150);ctx.lineTo(200, 150);ctx.lineWidth = 15; // 重新设置当前路径样式ctx.strokeStyle = "green";ctx.stroke();

三、canvas绘制简单图形

3.1 绘制三角形

closePath():自动创建从当前点回到起始点的路径

lineJoin():设置相交线的拐点样式 miter(默认)、round、bevel

如果通过lineTo()来闭合图形, 那么是不能很好的闭合

默认情况下不会自动从最后一个点连接到起点

* {margin: 0;padding: 0;}canvas {background: red;display: block;margin: 0 auto;}

<canvas width="300" height="240">您的浏览器不支持canvas标签,请更换支持canvas标签的浏览器</canvas>

//拿到画布let oCanvas = document.querySelector("canvas");//拿到绘制工具let ctx = oCanvas.getContext("2d");ctx.moveTo(50,50);ctx.lineTo(200,50);ctx.lineTo(200,200);// ctx.lineTo(50,50);ctx.closePath(); // 自动创建从当前点回到起始点的路径ctx.lineWidth = 10;// 设置相交线的拐点样式 miter(默认)、round、bevelctx.lineJoin = "round"; ctx.stroke();

3.2 路径绘制

设置笔触(落笔)点坐标:ctx.moveTo(横,纵);设置笔触路径:ctx.lineTo(横,纵);设置笔触颜色:ctx.strokeStyle='颜色';笔触的绘制:ctx.stroke();设置填充颜色:ctx.fillStyle='颜色';设置封闭图形填充:ctx.fill();开启路径绘制:ctx.beignPath()结束路径绘制:ctx.closePath()

<canvas width="300" height="300">您的浏览器不支持canvas标签,请更换支持canvas标签的浏览器</canvas>

canvas {border: 1px solid;}

<script>var huaban = document.querySelector('canvas');var ctx = huaban.getContext('2d');//保证有效的图形能够独立ctx.beginPath(); //开启路径绘制ctx.moveTo(50, 50); //设置笔触(落笔)点坐标ctx.lineTo(100, 50); //设置笔触路径ctx.lineTo(75, 100); //设置笔触路径ctx.lineTo(50, 50); //设置笔触路径ctx.fillStyle = 'orange';ctx.fill(); //设置封闭图形填充ctx.closePath(); //结束路径绘制ctx.beginPath(); //开启路径绘制ctx.moveTo(60, 120); //设置笔触(落笔)点坐标ctx.lineTo(150, 190); //设置笔触路径ctx.lineTo(230, 190); //设置笔触路径ctx.lineTo(60, 120); //设置笔触路径ctx.fillStyle = 'blue';ctx.fill(); //设置封闭图形填充ctx.closePath(); //结束路径绘制</script>

3.3 矩形绘制

* {margin: 0;padding: 0;}canvas {background: red;display: block;margin: 0 auto;}

<canvas width="500" height="500"></canvas>

let oCanvas = document.querySelector("canvas");let oCtx = oCanvas.getContext("2d");oCtx.moveTo(100, 100);oCtx.lineTo(300, 100);oCtx.lineTo(300, 300);oCtx.lineTo(100, 300);oCtx.closePath();oCtx.moveTo(250, 150);oCtx.lineTo(150, 150);oCtx.lineTo(150, 250);oCtx.lineTo(250, 250);oCtx.closePath();/*注意点: 只要没有手动开启新的路径, 那么使用的都是默认路径如果都是默认路径, 那么设置的样式在同一个路径中都是有效的* */oCtx.fill();/*对于同一路径,在填充的时候会遵循非零环绕规则从当前的区域拉出一条直线, 遇到顺时针相交的线就+1, 遇到逆时针相交的线就-1最终计算的结果如果是0就不填充, 如果不是0就填充* */

绘制填充矩形:ctx.fillRect(横,纵,宽,高);

绘制描边矩形:ctx.strokeRect(横,纵,宽,高);

擦除矩形区域:ctx.clearRect(横,纵,宽,高);

ctx.fillStyle='blue';ctx.fillRect(50,70,50,50);ctx.strokeRect(150,70,50,50);ctx.clearRect(75,70,100,50);

3.4 绘制虚线

setLineDash():设置

lineDashOffset():设置偏移位

//拿到画布let oCanvas = document.querySelector("canvas");//拿到绘制工具let ctx = oCanvas.getContext("2d");ctx.moveTo(20,120);ctx.lineTo(280,120);ctx.lineWidth = 2;ctx.strokeStyle = "white";// ctx.setLineDash([2,8]);ctx.setLineDash([2,8,10]);// console.log(ctx.getLineDash());//设置虚线的偏移位 ctx.lineDashOffset = -200;ctx.stroke();

3.5 绘制表格

* {margin: 0;padding: 0;}canvas {/* background: red; */display: block;margin: 0 auto;margin: 50px auto;}

<canvas width="500" height="400">您的浏览器不支持canvas标签,请更换支持canvas标签的浏览器</canvas>

//拿到画布let oCanvas = document.querySelector("canvas");//拿到绘制工具let ctx = oCanvas.getContext("2d");//定义变量,保存小方格的尺寸let gridSize = 10;//拿到 canvas 的宽高let canvasWidth = ctx.canvas.width;let canvasHeight = ctx.canvas.height;// 计算在垂直和水平方向可以画多少条横线let row = Math.floor(canvasHeight / gridSize);let col = Math.floor(canvasWidth / gridSize);//绘制垂直方向的横线for (let i = 0; i < row; i++) {ctx.beginPath();ctx.moveTo(0, i * gridSize - 0.5); //设置路径的起点ctx.lineTo(canvasWidth, i * gridSize - 0.5); //设置路径的终点ctx.stroke();}//绘制水平方向的横线for (let i = 0; i < col; i++) {ctx.beginPath();ctx.moveTo(i * gridSize - 0.5, 0); //设置路径的起点ctx.lineTo(i * gridSize - 0.5, canvasHeight); //设置路径的终点ctx.stroke();}

3.6 绘制坐标系

* {margin: 0;padding: 0;}canvas {/* background: red; */display: block;margin: 0 auto;margin: 50px auto;}

<canvas width="500" height="400">您的浏览器不支持canvas标签,请更换支持canvas标签的浏览器</canvas>

//拿到画布let oCanvas = document.querySelector("canvas");//拿到绘制工具let ctx = oCanvas.getContext("2d");//定义变量,保存小方格的尺寸let gridSize = 50;//拿到 canvas 的宽高let canvasWidth = ctx.canvas.width;let canvasHeight = ctx.canvas.height;// 计算在垂直和水平方向可以画多少条横线let row = Math.floor(canvasHeight / gridSize);let col = Math.floor(canvasWidth / gridSize);//绘制垂直方向的横线for (let i = 0; i < row; i++) {ctx.beginPath();ctx.moveTo(0, i * gridSize - 0.5); //设置路径的起点ctx.lineTo(canvasWidth, i * gridSize - 0.5); //设置路径的终点ctx.strokeStyle = "#ccc";ctx.stroke();}//绘制水平方向的横线for (let i = 0; i < col; i++) {ctx.beginPath();ctx.moveTo(i * gridSize - 0.5, 0); //设置路径的起点ctx.lineTo(i * gridSize - 0.5, canvasHeight); //设置路径的终点ctx.strokeStyle = "#ccc";ctx.stroke();}//计算坐标系原点的位置let originX = gridSize;let originY = canvasHeight - gridSize;//计算X轴终点位置let endX = canvasWidth - gridSize;//绘制X轴ctx.beginPath();ctx.moveTo(originX,originY);ctx.lineTo(endX,originY);ctx.strokeStyle = "#f40";ctx.stroke();//绘制X轴的箭头ctx.lineTo(endX -10,originY + 5);ctx.lineTo(endX -10,originY - 5);ctx.lineTo(endX,originY);ctx.fill();//计算Y轴终点位置let endY = gridSize;//绘制Y轴ctx.beginPath();ctx.moveTo(originX,originY);ctx.lineTo(originX,endY);ctx.strokeStyle = "#f40";ctx.stroke();//绘制Y轴的箭头ctx.lineTo(originX -5,endY + 10);ctx.lineTo(originX +5,endY + 10);ctx.lineTo(originX,endY);ctx.fill();

3.7 绘制数据点

* {margin: 0;padding: 0;}canvas {/* background: red; */display: block;margin: 0 auto;margin: 50px auto;}

<canvas width="500" height="400">您的浏览器不支持canvas标签,请更换支持canvas标签的浏览器</canvas>

//拿到画布let oCanvas = document.querySelector("canvas");//拿到绘制工具let ctx = oCanvas.getContext("2d");//定义变量,保存小方格的尺寸let gridSize = 50;//拿到 canvas 的宽高let canvasWidth = ctx.canvas.width;let canvasHeight = ctx.canvas.height;// 计算在垂直和水平方向可以画多少条横线let row = Math.floor(canvasHeight / gridSize);let col = Math.floor(canvasWidth / gridSize);//绘制垂直方向的横线for (let i = 0; i < row; i++) {ctx.beginPath();ctx.moveTo(0, i * gridSize - 0.5); //设置路径的起点ctx.lineTo(canvasWidth, i * gridSize - 0.5); //设置路径的终点ctx.strokeStyle = "#ccc";ctx.stroke();}//绘制水平方向的横线for (let i = 0; i < col; i++) {ctx.beginPath();ctx.moveTo(i * gridSize - 0.5, 0); //设置路径的起点ctx.lineTo(i * gridSize - 0.5, canvasHeight); //设置路径的终点ctx.strokeStyle = "#ccc";ctx.stroke();}//计算坐标系原点的位置let originX = gridSize;let originY = canvasHeight - gridSize;//计算X轴终点位置let endX = canvasWidth - gridSize;//绘制X轴ctx.beginPath();ctx.moveTo(originX, originY);ctx.lineTo(endX, originY);ctx.strokeStyle = "#f40";ctx.stroke();//绘制X轴的箭头ctx.lineTo(endX - 10, originY + 5);ctx.lineTo(endX - 10, originY - 5);ctx.lineTo(endX, originY);ctx.fill();//计算Y轴终点位置let endY = gridSize;//绘制Y轴ctx.beginPath();ctx.moveTo(originX, originY);ctx.lineTo(originX, endY);ctx.strokeStyle = "#f40";ctx.stroke();//绘制Y轴的箭头ctx.lineTo(originX - 5, endY + 10);ctx.lineTo(originX + 5, endY + 10);ctx.lineTo(originX, endY);ctx.fill();// 拿到服务器返回数据let list = [{x: 100,y: 300,},{x: 200,y: 200,},{x: 300,y: 250,},{x: 400,y: 100,},];let dotLocation = {x: 100,y: 300,};let dotSize = 20;for (let i = 0; i < list.length; i++) {ctx.beginPath();ctx.moveTo(list[i].x - dotSize / 2, list[i].y - dotSize / 2);ctx.lineTo(list[i].x + dotSize - dotSize / 2, list[i].y - dotSize / 2);ctx.lineTo(list[i].x + dotSize - dotSize / 2,list[i].y + dotSize - dotSize / 2);ctx.lineTo(list[i].x - dotSize / 2, list[i].y + dotSize - dotSize / 2);ctx.closePath();ctx.fill();}

3.8 绘制折线图

* {margin: 0;padding: 0;}canvas {/* background: red; */display: block;margin: 0 auto;margin: 50px auto;}

class LineChart {constructor(width = 300, height = 150) {// 1.创建canvasthis.canvas = document.createElement("canvas");this.canvas.width = width;this.canvas.height = height;document.body.appendChild(this.canvas);// 2.拿到绘图工具this.ctx = this.canvas.getContext("2d");}//画小格子drawGrid(gridSize = 20) {let ctx = this.ctx;//拿到 canvas 的宽高let canvasWidth = ctx.canvas.width;let canvasHeight = ctx.canvas.height;// 计算在垂直和水平方向可以画多少条横线let row = Math.floor(canvasHeight / gridSize);let col = Math.floor(canvasWidth / gridSize);//绘制垂直方向的横线for (let i = 0; i < row; i++) {ctx.beginPath();ctx.moveTo(0, i * gridSize - 0.5); //设置路径的起点ctx.lineTo(canvasWidth, i * gridSize - 0.5); //设置路径的终点ctx.strokeStyle = "#ccc";ctx.stroke();}//绘制水平方向的横线for (let i = 0; i < col; i++) {ctx.beginPath();ctx.moveTo(i * gridSize - 0.5, 0); //设置路径的起点ctx.lineTo(i * gridSize - 0.5, canvasHeight); //设置路径的终点ctx.strokeStyle = "#ccc";ctx.stroke();}}//画坐标系drawCoor(gridSize = 20) {let ctx = this.ctx;let canvasWidth = this.ctx.canvas.width;let canvasHeight = this.ctx.canvas.height;//计算坐标系原点的位置let originX = gridSize;let originY = canvasHeight - gridSize;//计算X轴终点位置let endX = canvasWidth - gridSize;//绘制X轴ctx.beginPath();ctx.moveTo(originX, originY);ctx.lineTo(endX, originY);ctx.strokeStyle = "#f40";ctx.stroke();//绘制X轴的箭头ctx.lineTo(endX - 10, originY + 5);ctx.lineTo(endX - 10, originY - 5);ctx.lineTo(endX, originY);ctx.fill();//计算Y轴终点位置let endY = gridSize;//绘制Y轴ctx.beginPath();ctx.moveTo(originX, originY);ctx.lineTo(originX, endY);ctx.strokeStyle = "#f40";ctx.stroke();//绘制Y轴的箭头ctx.lineTo(originX - 5, endY + 10);ctx.lineTo(originX + 5, endY + 10);ctx.lineTo(originX, endY);ctx.fill();}//绘制数据点drawDot(list, dotSize = 10) {let ctx = this.ctx;for (let i = 0; i < list.length; i++) {ctx.beginPath();ctx.moveTo(list[i].x - dotSize / 2, list[i].y - dotSize / 2);ctx.lineTo(list[i].x + dotSize - dotSize / 2,list[i].y - dotSize / 2);ctx.lineTo(list[i].x + dotSize - dotSize / 2,list[i].y + dotSize - dotSize / 2);ctx.lineTo(list[i].x - dotSize / 2,list[i].y + dotSize - dotSize / 2);ctx.closePath();ctx.fill();}}//绘制折线drawLine(list) {let ctx = this.ctx;ctx.beginPath();for (let i = 0; i < list.length; i++) {if (i === 0) {ctx.moveTo(list[i].x, list[i].y);} else {ctx.lineTo(list[i].x, list[i].y);}}ctx.stroke();}}// 拿到服务器返回数据let list = [{x: 100,y: 300,},{x: 200,y: 200,},{x: 300,y: 250,},{x: 400,y: 100,},];let dotLocation = {x: 100,y: 300,};let lineChart = new LineChart(500, 400);lineChart.drawGrid(50);lineChart.drawCoor(50);lineChart.drawDot(list, 20);lineChart.drawLine(list);

3.9 绘制柱状图

* {margin: 0;padding: 0;}canvas {/* background: red; */display: block;margin: 0 auto;margin: 50px auto;}

class LineChart {constructor(width = 300, height = 150) {// 1.创建canvasthis.canvas = document.createElement("canvas");this.canvas.width = width;this.canvas.height = height;document.body.appendChild(this.canvas);// 2.拿到绘图工具this.ctx = this.canvas.getContext("2d");}//画小格子drawGrid(gridSize = 20) {let ctx = this.ctx;//拿到 canvas 的宽高let canvasWidth = ctx.canvas.width;let canvasHeight = ctx.canvas.height;// 计算在垂直和水平方向可以画多少条横线let row = Math.floor(canvasHeight / gridSize);let col = Math.floor(canvasWidth / gridSize);//绘制垂直方向的横线for (let i = 0; i < row; i++) {ctx.beginPath();ctx.moveTo(0, i * gridSize - 0.5); //设置路径的起点ctx.lineTo(canvasWidth, i * gridSize - 0.5); //设置路径的终点ctx.strokeStyle = "#ccc";ctx.stroke();}//绘制水平方向的横线for (let i = 0; i < col; i++) {ctx.beginPath();ctx.moveTo(i * gridSize - 0.5, 0); //设置路径的起点ctx.lineTo(i * gridSize - 0.5, canvasHeight); //设置路径的终点ctx.strokeStyle = "#ccc";ctx.stroke();}}//画坐标系drawCoor(gridSize = 20) {let ctx = this.ctx;let canvasWidth = this.ctx.canvas.width;let canvasHeight = this.ctx.canvas.height;//计算坐标系原点的位置let originX = gridSize;let originY = canvasHeight - gridSize;//计算X轴终点位置let endX = canvasWidth - gridSize;//绘制X轴ctx.beginPath();ctx.moveTo(originX, originY);ctx.lineTo(endX, originY);ctx.strokeStyle = "#f40";ctx.stroke();//绘制X轴的箭头ctx.lineTo(endX - 10, originY + 5);ctx.lineTo(endX - 10, originY - 5);ctx.lineTo(endX, originY);ctx.fill();//计算Y轴终点位置let endY = gridSize;//绘制Y轴ctx.beginPath();ctx.moveTo(originX, originY);ctx.lineTo(originX, endY);ctx.strokeStyle = "#f40";ctx.stroke();//绘制Y轴的箭头ctx.lineTo(originX - 5, endY + 10);ctx.lineTo(originX + 5, endY + 10);ctx.lineTo(originX, endY);ctx.fill();}//绘制矩形drawRectangle(list,gridSize=20) {let ctx = this.ctx;let canvasHeight = this.ctx.canvas.height;let originY = canvasHeight - gridSize;//绘制矩形for (let i = 0; i < list.length; i++) {let barHeight = originY - list[i].y;ctx.fillRect(list[i].x, list[i].y, gridSize, barHeight);}}}// 拿到服务器返回数据let list = [{x: 100,y: 300,},{x: 200,y: 200,},{x: 300,y: 250,},];let dotLocation = {x: 100,y: 300,};let lineChart = new LineChart(500, 400);lineChart.drawGrid(50);lineChart.drawCoor(50);lineChart.drawRectangle(list,50);

四、渐变背景颜色

和普通标签一样我们也可以给填充的图形设置线性渐变和径向渐变的背景颜色

4.1 设置图形渐变背景颜色步骤

通过绘图工具创建渐变背景颜色指定渐变的范围将渐变背景颜色设置给对应的图形

* {margin: 0;padding: 0;}canvas {/* background: red; */display: block;margin: 0 auto;margin: 50px auto;}

<canvas width="500" height="400">您的浏览器不支持canvas标签,请更换支持canvas标签的浏览器</canvas>

let canvas = document.querySelector("canvas");let ctx = canvas.getContext("2d");/* 1.创建渐变方案可以通过x0,y0 / x1,y1确定渐变的方向和渐变的范围* */let linearGradient = ctx.createLinearGradient(100, 100, 300, 300);// ctx.createRadialGradient();//径向渐变/*2.指定渐变的范围第一个参数是一个百分比 0~1第二个参数是一个颜色* */linearGradient.addColorStop(0, "green");linearGradient.addColorStop(0.5, "yellow");linearGradient.addColorStop(1, "blue");/*3.将渐变背景颜色设置给对应的图形**/ctx.fillStyle = linearGradient;ctx.fillRect(100, 100, 200, 200);

4.2 绘制圆弧

a.基本概念(请翻开初中数学课本) 哈哈~

角度: 一个圆360度, 一个半圆是180度

弧度: 一个圆2π, 一个半圆π

b.角度转换弧度公式:

∵ 180角度 = π弧度

∴ 1角度 = π/180;

∴ 弧度 = 角度 * π/180;

90角度 * π/180 = π/2

c.弧度转换角度公式:

∵ π弧度 = 180角度

∴ 1弧度 = 180/π

∴ 角度 = 弧度 * 180/π

π/2 * 180/π = 180/2 = 90度

ctx.arc(圆心x,圆心y,半径r,开始弧度,结束弧度,false);

ctx.arc(圆心x,圆心y,半径r,开始弧度,结束弧度,true);

false就是顺时针绘制, true就是逆时针绘制

false先开始后结束, true是先结束后开始,都是顺时针方向画弧

示例1:画圆和半圆

canvas {border: 1px solid;}

<canvas width="300" height="300">您的浏览器不支持canvas标签,请更换支持canvas标签的浏览器</canvas>

var huaban = document.querySelector('canvas');var ctx = huaban.getContext('2d'); ctx.beginPath(); //开始落脚//ctx.arc(150, 150, 50, 0 * Math.PI, 1 * Math.PI, false);//半圆ctx.arc(150, 150, 50, 0 * Math.PI, 2 * Math.PI, false);//圆// ctx.stroke();ctx.fillStyle = 'skyblue'; //填充ctx.fill();ctx.closePath(); //结束

示例1:绘制扇形

* {margin: 0;padding: 0;}canvas {/* background: red; */display: block;margin: 0 auto;margin: 50px auto;}

<canvas width="500" height="400"></canvas>

// 1.拿到canvaslet canvas = document.querySelector("canvas");// 2.从canvas中拿到绘图工具let ctx = canvas.getContext("2d");//设置起点ctx.moveTo(100,100);//ctx.arc(圆心x,圆心y,半径r,开始弧度,结束弧度,false);ctx.arc(100,100,100,0,Math.PI/2);ctx.closePath();// ctx.stroke();ctx.fill();

4.3 绘制饼状图

* {margin: 0;padding: 0;}canvas {/* background: red; */display: block;margin: 0 auto;margin: 50px auto;}

<canvas width="500" height="400"></canvas>

// 1.拿到canvaslet canvas = document.querySelector("canvas");// 2.从canvas中拿到绘图工具let ctx = canvas.getContext("2d");//计算圆心的位置let rx = ctx.canvas.width / 2;let ry = ctx.canvas.height / 2;/*//绘制第一个扇形//ctx.arc(圆心x,圆心y,半径r,开始弧度,结束弧度,false);ctx.moveTo(rx, ry);ctx.arc(rx, ry, 100, 0, Math.PI / 2);ctx.fillStyle = randomColor();ctx.fill();//绘制第二个扇形//ctx.arc(圆心x,圆心y,半径r,开始弧度,结束弧度,false);ctx.beginPath(); // 开启新路径ctx.moveTo(rx, ry);ctx.arc(rx, ry, 100, Math.PI / 2, Math.PI);ctx.fillStyle = randomColor();ctx.fill();//绘制第三个扇形//ctx.arc(圆心x,圆心y,半径r,开始弧度,结束弧度,false);ctx.beginPath(); // 开启新路径ctx.moveTo(rx, ry);ctx.arc(rx, ry, 100, Math.PI, Math.PI + Math.PI / 2);ctx.fillStyle = randomColor();ctx.fill();//绘制第四个扇形//ctx.arc(圆心x,圆心y,半径r,开始弧度,结束弧度,false);ctx.beginPath(); // 开启新路径ctx.moveTo(rx, ry);ctx.arc(rx, ry, 100, Math.PI + Math.PI / 2, Math.PI * 2);ctx.fillStyle = randomColor();ctx.fill();*/let startAngle = 0;//开始的弧度for (let i = 1; i <= 4; i++) {// 结束的弧度let endAngle = i * Math.PI / 2;//ctx.arc(圆心x,圆心y,半径r,开始弧度,结束弧度,false);ctx.beginPath(); // 开启新路径ctx.moveTo(rx, ry);ctx.arc(rx, ry, 100, startAngle, endAngle);ctx.fillStyle = randomColor();ctx.fill();// 上一次结束的角度是下一次的起始角度startAngle = endAngle; }//随机生成圆弧填充颜色function randomColor() {let r = Math.floor(Math.random() * 256);let g = Math.floor(Math.random() * 256);let b = Math.floor(Math.random() * 256);return `rgb(${r},${g},${b})`;}

4.4 绘制文字

* {margin: 0;padding: 0;}canvas {/* background: red; */display: block;margin: 0 auto;margin: 50px auto;}

<canvas width="500" height="400"></canvas>

// 1.拿到canvaslet canvas = document.querySelector("canvas");// 2.从canvas中拿到绘图工具let ctx = canvas.getContext("2d");//3.绘制参考线let canvasWidth = ctx.canvas.width;let canvasHeight = ctx.canvas.height;ctx.moveTo(0,canvasHeight / 2);ctx.lineTo(canvasWidth,canvasHeight / 2);ctx.stroke();ctx.moveTo(canvasWidth / 2,0);ctx.lineTo(canvasWidth / 2,canvasHeight);ctx.stroke();//4.绘制文字let str = '世界很大';//通过 font 属性可以设置文字的大小和样式ctx.font = "50px 微软雅黑";//textBaseline:修改文字垂直方向的对齐方式// 在对齐的时候是以绘制文字的y作为参考点进行对齐的//textBaseline = top/middle/bottomctx.textBaseline = "middle";//textAlign:修改文字水平方向对齐方式// 在对齐的时候是以文字的x作为参考点进行的//textAlign = star/end/centerctx.textAlign = "end";/*** ctx.strokeText(需要绘制的文字,绘制的位置);* 在绘制文字的时候是以文字的左下角作为参考点进行绘制*/// ctx.strokeText(str,canvasWidth / 2,canvasHeight / 2); 或// fillText()绘制的文字是实心;strokeText()绘制的文字是空心ctx.fillText(str,canvasWidth / 2,canvasHeight / 2);

4.5 图片绘制

描述:canvas中绘制图片必须等到图片完全加载成功之后再上屏,否则就会绘制失败。

方法:

ctx.drawImage();

语法:

ctx.drawImage(img对象,x,y)

如果只有三个参数, 那么第一个参数就是需要绘制的图片,后面的两个参数是指定图片从什么位置开始绘制

oCtx.drawImage(oImg, 100, 100);

ctx.drawImage(img对象,x,y,w,h)

如果只有五个参数, 那么第一个参数就是需要绘制的图片,第二和第三个参数是指定图片从什么位置开始绘制,第四、第五两个参数是指定图片需要拉伸到多大

oCtx.drawImage(oImg, 100, 100, 100, 100);

ctx.drawImage(img对象,裁切x,裁切y,裁切w,裁切h,绘制x,绘制y,绘制w,绘制h)

如果有九个参数, 那么第一个参数就是需要绘制的图片,第2~3个参数指定图片上定位的位置,第4~5个参数指定从定位的位置开始截取多大的图片,第6~7个参数指定图片从什么位置开始绘制,最后的两个参数是指定图片需要拉伸到多大

示例:

canvas {border: 1px solid;}

<canvas width="1300" height="600">您的浏览器不支持canvas标签,请更换支持canvas标签的浏览器</canvas>

var huaban = document.querySelector('canvas');var ctx = huaban.getContext('2d');ctx.beginPath(); //开始//创建图片var tempImage = new Image();//加载图片tempImage.src = 'img/timg.jpg';//图片完全加载后再绘制tempImage.onload = function() {//将加载的图片绘制到canvas上ctx.drawImage(tempImage, 190, 65, 210, 80, 50, 50, 80, 100);};ctx.closePath(); //结束

五、绘制动画

* {margin: 0;padding: 0;}canvas {/* background: red; */display: block;margin: 0 auto;margin: 50px auto;}

<canvas width="500" height="400"></canvas>

// 1.拿到canvaslet canvas = document.querySelector("canvas");// 2.从canvas中拿到绘图工具let ctx = canvas.getContext("2d");//3.加载图片let oImg = new Image();oImg.onload = function (){//3.1计算每一张图片的宽高let imageWidth = oImg.width;let imageHeight = oImg.height;let personWidth = imageWidth / 4;let personHeight = imageHeight / 4;//3.2计算绘制的位置let canvasWidth = ctx.canvas.width;let canvasHeight = ctx.canvas.height;let originX = canvasWidth / 2 - personWidth / 2;let originY = canvasHeight / 2 - personHeight / 2;//3.3绘制图片ctx.drawImage(oImg,0,personHeight *2,personWidth,personHeight,originX,originY,personWidth,personHeight);//3.4实现逐帧动画let index = 1;setInterval(function(){// 清除以前绘制的图片ctx.clearRect(0,0,canvasWidth,canvasHeight);//重新绘制ctx.drawImage(oImg,index * personWidth,personHeight *2,personWidth,personHeight,originX,originY,personWidth,personHeight);index++;if(index > 3){index = 0;}},50);};oImg.src = "images/person.png";

对上面的代码进行封装:

// 1.拿到canvaslet canvas = document.querySelector("canvas");// 2.从canvas中拿到绘图工具let ctx = canvas.getContext("2d");/*面向对象思想:找到小人对象, 你给我画到指定的位置, 你给我走起来, 你给我停下来* */class Person {constructor(canvas, x, y) {this.canvas = canvas;this.x = x;this.y = y;this.ctx = this.canvas.getContext("2d");this.index = 1;this.timeId = null;// 0正面/1左面/2右面/3后面this.direction = 0;}//绘制render() {//1.加载图片let oImg = new Image();oImg.onload = () => {//1.1计算每一张图片的宽高let imageWidth = oImg.width;let imageHeight = oImg.height;let personWidth = imageWidth / 4;let personHeight = imageHeight / 4;//1.2绘制图片this.ctx.drawImage(oImg, // 需要绘制的图片0, //图片定位的位置this.direction * personHeight, //图片定位的位置personWidth, // 图片裁剪的大小personHeight, // 图片裁剪的大小this.x, // 图片绘制的位置this.y, // 图片绘制的位置personWidth, // 指定图片绘制大小personHeight // 指定图片绘制大小);this.oImg = oImg;this.personWidth = personWidth;this.personHeight = personHeight;};oImg.src = "images/person.png";}//运动方法run(stepX, stepY) {let canvasWidth = this.ctx.canvas.width;let canvasHeight = this.ctx.canvas.height;clearInterval(this.timeId);this.timeId = setInterval(() => {if (stepX !== 0) {this.x += stepX;}if (stepY !== 0) {this.y += stepY;}// 清除以前绘制的图片this.ctx.clearRect(0, 0, canvasWidth, canvasHeight);//重新绘制this.ctx.drawImage(this.oImg, // 需要绘制的图片this.index * this.personWidth, //图片定位的位置this.direction * this.personHeight, //图片定位的位置this.personWidth, // 图片裁剪的大小this.personHeight, // 图片裁剪的大小this.x, // 图片绘制的位置this.y, // 图片绘制的位置this.personWidth, // 指定图片绘制大小this.personHeight // 指定图片绘制大小);this.index++;if (this.index > 3) {this.index = 0;}}, 200);}moveDown() {this.direction = 0;this.run(0, 5);}moveUp() {this.direction = 3;this.run(0, -5);}moveLeft() {this.direction = 1;this.run(-5, 0);}moveRight() {this.direction = 2;this.run(5, 0);}//停止运动方法stop() {clearInterval(this.timeId);}}let person = new Person(canvas, 100, 100);person.render();// person.moveDown();// person.stop();window.onkeydown = function (e) {let key = e.key;// console.log(key);switch (key.toLowerCase()) {case "w":person.moveUp();break;case "s":person.moveDown();break;case "a":person.moveLeft();break;case "d":person.moveRight();break;}};

六、canvs形变

在canvas中所有的形变属性操作的都是坐标系, 而不是图形!!!

* {margin: 0;padding: 0;}canvas {/* background: red; */display: block;margin: 0 auto;margin: 50px auto;}

<canvas width="500" height="400"></canvas>

// 1.拿到canvaslet canvas = document.querySelector("canvas");// 2.从canvas中拿到绘图工具let ctx = canvas.getContext("2d");ctx.translate(100,0);//位移ctx.scale(.8,.6);//缩放ctx.rotate(Math.PI/6);//旋转// 3.绘制一个矩形ctx.strokeRect(100, 100, 200, 100);

七、事件绑定

因为整个canvas是一个标签, 所以只能通过监听鼠标在canvas上(事件只能绑定到canvas标签上)的位置来判断是否需要处理对应的图形,当然也可以通过第三方框架来解决交互问题,诸如: zrender.js / Knova.js /three.js / egret.js / pixi.js等等

isPointInPath方法如果开启了一个新的路径, 那么判断的就是该点是否在新的路径的图形中

示例:

*{margin: 0;padding: 0;}canvas{display: block;margin: 0 auto;/* background: red; */margin: 50px auto;}

<canvas width="500" height="400">您的浏览器不支持canvas标签,请更换支持canvas标签的浏览器</canvas>

let oCanvas = document.querySelector("canvas");// 2.从canvas中拿到绘图工具let oCtx = oCanvas.getContext("2d");// 3.绘制矩形let rectX = 100;let rectY = 100;let rectWidth = 100;let rectHeight = 100;oCtx.rect(rectX, rectY, rectWidth, rectHeight);oCtx.fill();oCtx.beginPath();oCtx.rect(200, 200, 100, 100);oCtx.fill();// 4.添加点击事件oCanvas.onclick = function (event) {let x = event.offsetX;let y = event.offsetY;if(x >= rectX && x <= rectX + rectWidth &&y >= rectY && y <= rectY + rectHeight){console.log("矩形被点击了");}else{console.log("矩形没有被点击");}console.log(oCtx.isPointInPath(x, y));}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。