一、canvas画布基础
1.canvas标签
(1)在HTML结构中写一个canvas 双闭合标签,双标签内的子元素会在 浏览器无法渲染canvas时替换显示。
(2)获取canvas的DOM对象。
(3)使用getContext()获取cavans上下文对象,参数写 2d 即可。
(4)一切内容的绘制都要基于 cavans上下文对象 进行,这里将名称定为 cxt。
<body>
<canvas
id="myCanvas"
width="1800"
height="800"
style="border: 1px solid #ccc"
>
这里是不兼容浏览器会显示的内容。
</canvas>
<script>
const cnv = document.querySelector("#myCanvas"); // 获取canvas对象
const cxt = cnv.getContext("2d"); // 获取canvas上下文环境对象
</script>
</body>
2.画一条线段
(1)cxt.moveTo(x,y) 绘制 起点。参数代表 x轴和y轴坐标。
(2)cxt.lineTo(x,y) 绘制 终点。参数代表 x轴和y轴坐标。
(3)cxt.stroke() 将起点和终点 连接。 cxt.stroke()总是写到最后!!!
// 画条线段
cxt.moveTo(300,100); // 起点坐标(x,y)
cxt.lineTo(200,100); // 终点坐标(x,y)
cxt.lineWidth = 20; // 修改直线的宽度
cxt.strokeStyle = "pink"; // 修改直线的颜色
cxt.lineCap = "square"; // 修改直线两端样式。默认:butt; 圆形:round;方形:square
cxt.stroke() // 将终点和起点连接起来
3.样式与隔离
(1)每个图形绘制之前,使用 cxt.beginPath() 开辟一条新的路径,否则前面的样式会影响后面的图形。
(2)每个图形要 单独设置样式,否则会受到后面样式的影响。
// 样式隔离
cxt.beginPath(); // 1.从第二个图形开始,每个图形要重新开辟一条路径,否则前面的线段样式会覆盖后面的。
cxt.moveTo(100,400);
cxt.lineTo(100,600);
cxt.lineTo(400,600);
cxt.closePath();
// 2.每个图形需要单独设置自己的样式,否则没有单独样式的线段会使用后面的样式。
cxt.lineWidth = 5; // 线段宽度,默认为1
cxt.strokeStyle="aqua"; // 线段颜色,默认黑色
cxt.lineCap = "square"; // 线段两端样式,默认butt,square:方形,round:圆形
cxt.lineJoin = "bevel"; // 拐角样式,默认尖角miter,round:圆角,bevel:斜角
cxt.setLineDash([5,10]); // 设置虚线。数组元素是数值类型,可以是一个值、两个值、三个值。
cxt.fillStyle="springgreen"; // 填充的颜色
cxt.fillRect(120,500,10,10); // 填充图形的大小(填充区域左上角x,填充区域左上角y,填充区域的宽,填充区域的高)
// cxt.fill(); // 自定义图形可以使用fillRect()进行局部填充,也可以使用fill()全部填充。
cxt.stroke();
4.绘制三角形,使用closePath()
(1)确认三个顶点坐标。
(2)cxt.stroke() 只能将顶点1与顶点2连接,再将顶点2与顶点3连接。
(3)cxt.closePath() 负责将图形闭合,将顶点3再和顶点1连接。
// 手动绘制三角形,使用closePath()。
cxt.beginPath();
cxt.moveTo(400,400);
cxt.lineTo(400,500);
cxt.lineTo(500,400);
cxt.closePath(); // 手动闭合
cxt.lineJoin = "miter"; // 连接处的样式。默认:miter; bevel:斜面;round:圆角
cxt.lineWidth = 20;
cxt.stroke();
5.绘制矩形,不用closePath()
(1)不使用closePath()来绘制矩形或其他多边形时,起点坐标和终点坐标要保持一致。
(2)如果线段lineWidth值比较大时,顶点连接处显示怪异。
// 手动绘制矩形,不用closesPath()。缺点:终点要和起点保持一致;如果线段lineWidth值比较大时,顶点连接处显示怪异。
cxt.beginPath();
cxt.moveTo(50,50);
cxt.lineTo(50,100);
cxt.lineTo(100,100);
cxt.lineTo(100,50);
cxt.lineTo(50,50);
cxt.lineWidth = 20;
cxt.stroke();
6.使用strokeRect()绘制矩形与颜色填充
- 绘制矩形可以确认四个顶点坐标后连接,也有方法快速绘制;绘制其他多边形则必须确定好所有顶点坐标。
- 绘制矩形:
(1)使用 strokeRect() 绘制矩形时 无需调用stroke()方法。
(2)strokeRect(x,y,width,height),x和y代表 矩形 左上点的坐标,width和height是矩形的宽高。 - 矩形的颜色填充:
(1)修改cxt的 fillStyle 属性值。
(2)调用 cxt.fillRect(x,y,width,height) 方法。x和y代表 填充区域 左上点的坐标,width和height是填充区域的宽高。
(3)自定义图形 可以使用 fill()全部填充 或者 fillRect()局部填充;使用strokeRect()绘制的矩形,只能用fillRect()填充。
// 使用strokeRect()绘制矩形。无需调用stroke()方法
cxt.beginPath();
cxt.lineWidth = 1;
cxt.strokeStyle = "green"; // 线条颜色
// 描边矩形,此属性应在strokeStyle后面。(x,y,width,height) x和y代表矩形左上点的坐标,width和height是矩形的宽高。
cxt.strokeRect(150, 150, 100, 100);
// (1) 图形的填充色
cxt.fillStyle = "orange";
// (2) 图形的填充范围。(x,y,width,height) x和y代表填充区域左上点的坐标,width和height是填充范围的宽高。
// (3) 自定义图形可以使用fill()全部填充或者fillRect()局部填充;使用strokeRect()绘制的矩形,只能用fillRect()填充。
cxt.fillRect(160, 160, 80, 80)
7.使用rect()绘制矩形与颜色填充
(1)使用rect()绘制矩时,必须要调用 stroke() 方法辅助绘制和 fill() 方法辅助颜色填充。
(2)rect(x,y,width,height)。x和y代表 矩形 左上点的坐标,width和height是矩形的宽高。
// 使用rect()绘制矩形。需要调用stroke()方法和fill()方法
cxt.beginPath();
cxt.strokeStyle="brown";
cxt.fillStyle="yellow";
cxt.rect(300,300,60,80); // (x,y,width,height) x和y代表矩形左上点的坐标,width和height是矩形的宽高。
cxt.stroke();
cxt.fill();
8.在图形中清空出一个矩形空白区域
cxt.clearRect(x,y,width,height),x和y代表 矩形 左上点的坐标,width和height是 空白区域 的宽高。
// 在矩形中清空出一个矩形的空白区域
cxt.clearRect(310,310,30,20); // (x,y,width,height) x和y代表矩形左上点的坐标,width和height是空白区域的宽高。
9.清空画布中的所有内容
cxt.clearRect(x,y,width,height),x和y代表 矩形 左上点的坐标,width和height是整个canvas的宽高。
cxt.clearRect(0,0,800,500); // (x,y,width,height) x和y代表矩形左上点的坐标,width和height是整个canvas的宽高。
10.绘制圆形
(1)必须要以beginPath()开始,以closePath()结束。
(2)cxt.arc(圆心x,圆心y,半径r,开始角度,结束角度,绘制方向默认顺时针false)。
// 绘制圆形,必须要以beginPath()开始,以closePath()结束
cxt.beginPath();
cxt.arc(420, 220, 60, 0, 360*Math.PI/180, true); // (圆心x,圆心y,半径r,开始角度,结束角度,绘制方向默认顺时针false)
cxt.strokeStyle = "red";
cxt.closePath();
cxt.stroke();
11.绘制半圆
(1)用arc()方法画圆时只画180度。
// 绘制半圆。用arc()方法画圆时只画180度
cxt.beginPath();
cxt.arc(600, 200, 70, 0, 180*Math.PI/180, true);
cxt.strokeStyle="pink";
cxt.closePath();
cxt.stroke();
12.用arc()画弧线
(1)画圆时不调用closePath()方法即可。
// 用arc()画弧线:画圆时不调用closePath()方法即可
cxt.beginPath();
cxt.arc(700,250,30,0,180*Math.PI/180,false);
cxt.strokeStyle="purple";
cxt.stroke();
13.用arcTo()画弧线
14.文本和文本样式
// 文本和样式
cxt.beginPath();
cxt.font = "50px 微软雅黑";
cxt.strokeStyle="gold";
cxt.setLineDash([]);
cxt.textAlign = "left"; // 水平对齐方式。默认start:在指定位置的横坐标开始;end:在指定位置的横坐标结束;left:左对齐;right:右对齐;center:居中对齐
cxt.textBaseline = "top"; // 垂直对齐方式。默认alphabetic:文本基线是字母基线;top:文本基线是em框顶端;bottom:文本基线是em框底端;middle:文本基线是em框正中;hanging:文本基线是悬挂基线
cxt.strokeText("敢想敢干", 550, 400, 150); // 描边文案。样式要写到这之前 (文案,文本左边要对齐的x,文本下边要对齐的y,[文本渲染的最大宽度])
cxt.fillStyle="yellowgreen";
cxt.fillText("女娃陛下请酸丝", 550,500) // 填充文案。样式要写到这之前 (文案,文本左边要对齐的x,文本下边要对齐的y)
let text = "计算文案长度"
cxt.fillText(text, 550, 600);
console.log(cxt.measureText(text).width); // 获取文案长度
15.渲染图片和截取图片
(1)渲染:cxt.drawImage(图片对象,图片左上角的x,图片左上角的y,图片的宽,图片的高)。
(2)截取:cxt.drawImage(图片对象,开始截取的x,开始截取的y, 截取的宽,截取的高,图片左上角的x,图片左上角的y,图片的宽,图片的高)。
<img src="https://www.3-v.net/UploadFiles/201905/2019052135568585.jpg" alt="" id="image2" style="display:none">
<script>
// JS方式渲染图片
const image1 = new Image();
image1.src = "https://www.3-v.net/UploadFiles/201905/2019052135568585.jpg";
image1.onload = ()=> {
cxt.drawImage(image1, 200, 500, 50, 30); // (图片对象,图片左上角的x,图片左上角的y,图片的宽,图片的高)
}
// DOM方式渲染图片
const image2 = document.querySelector("#image2");
cxt.drawImage(image2, 100, 300, 100, 60)
// 截取图片 (图片对象,开始截取的x,开始截取的y, 截取的宽,截取的高,图片左上角的x,图片左上角的y,图片的宽,图片的高)
const image3 = document.querySelector("#image2");
cxt.drawImage(image3, 420, 520, 600, 300, 400, 500, 80, 60);
</script>
入门:https://juejin.cn/post/7116784455561248775?searchId=202312211031587C6AA397873EFAC34961#heading-0
进阶:https://juejin.cn/post/7176055713733541943
官方文档:https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial
二、百度地图
三、WebSocket
前端使用websocket可以与服务器建立长连接;它是基于HTML5的一种协议;和HTTP协议一样都是通过TCP来传输数据的。
1.实例化对象。
用new关键字调用WebSocket()构造函数,创建一个实例对象ws。
const ws = new WebSocket(url地址)
2.WebSocket事件
(1)open事件:连接建立时会触发。可在此向服务器发送一些信息。
ws.onopen = function() {
ws.send("你好!")
}
(2)message事件:客户端接收到服务端的数据时会触发。可在此处理数据。
ws.onmessage = function(e) {
console.log("接收到的数据:", e)
}
(3)error事件:通信发生错误时会触发。发生错误后可以进行重连。
ws.onerror = function(e) {
console.log("错误信息:", e) // 在此重新建立连接或其他处理
}
(4)close事件:连接关闭时会触发。可以判断是否为手动关闭,是否需要重连。
ws.onclose = function() {
// 客户手动断开连接一般无需处理,否则可能需要进行一些处理。
}
3.WebSocket方法
(1)send方法:成功建立连接后,可以用send()方法向服务器发送数据。
ws.send("客户端信息")
(2)close方法:手动断开连接。
ws.close()
4.WebSocket属性
(1)readyState:只读属性,表示连接状态。0表示连接尚未建立;1表示连接已建立,可以进行通信。2表示连接正在进行关闭;3表示连接已经关闭或者连接不能打开。
(2)bufferedAmount:只读属性。已被 send() 放入正在队列中等待传输,但是还没有发出的 UTF-8 文本字节数。
5.类的封装
// websocket类封装
class SocketPlugin {
constructor (param) {
this.websocket = null // WebSocket实例对象,默认为null
this.isConnect = false // 当前的连接状态,默认为未连接
this.timeoutNum = null // 一个定时器
this.isActivelyClose = false // 连接是否是客户端手动关闭的,默认不是
this.param = param // 传入的配置信息
}
// 1.实例化WebSocket对象
connect () {
this.websocket = new WebSocket(this.param.url)
this.initSocket(this.param)
}
// 2.监听WebSocket事件
initSocket (param) {
this.isActivelyClose = false // 将当前状态设置为非手动关闭连接的状态
// (1)监听连接事件
this.websocket.onopen = () => {
this.isConnect = true // 连接状态设置为已连接
if (param.hasOwnProperty('msg')) {
this.send(param.msg || '') // 如果我们有什么信息需要发送给服务器,在此进行发送
}
}
// (2)监听消息获取成功的事件
this.websocket.onmessage = e => {
param.callback(e) // 调用我们外部定义的回调函数
}
// (3)监听关闭事件
this.websocket.onclose = e => {
this.isConnect = false // 连接状态设置为已关闭
if (!this.isActivelyClose) {
this.reconnectSocket(param) // 如果不是手动关闭的,则需要重新连接
}
}
// (4)监听错误发生的事件
this.websocket.onerror = e => {
this.reconnectSocket(param) // 重新连接
}
}
// 3.重新连接
reconnectSocket (param) {
if (this.isConnect === true) {
return false // 如果当前已经是连接状态了,则不进行重新连接
}
this.isConnect = true // 连接状态设置为已连接
this.timeoutNum && clearTimeout(this.timeoutNum) // 清空上一次的定时器
this.timeoutNum = setTimeout(() => {
this.connect(param)
this.isConnect = false
}, 3000)
}
// 向服务器发送消息的方法。websocket连接状态下才能进行send()。
send (msg) {
this.websocket.send(JSON.stringify(msg))
}
// 手动关闭的方法
close () {
this.isActivelyClose = true
if (this.websocket) {
this.websocket.close()
}
}
}