2023-12-08 日积月累(3)

一、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()
      }
    }
  }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容

  • 本文简介 点赞 + 关注 + 收藏 = 学会了 接着 《Canvas 从入门到劝朋友放弃(图解版)》[https:...
    德育处主任阅读 330评论 0 5
  • 本文简介 p5.js 作为一款艺术类的 canvas 库,对颜色方面的支持是挺下功夫的,比如本文要介绍的渐变方法。...
    德育处主任阅读 263评论 0 1
  • 设计模式:https://www.jianshu.com/p/35f76e87ac45[https://www.j...
    luckyShan_95阅读 438评论 0 0
  • 1. HTML、XML、XHTML 的区别 HTML:超文本标记语言,是语法较为松散的、不严格的Web语言;XML...
    嗳湫阅读 338评论 0 2
  • 2019 9月 [工具] TreeJS 在线编辑器: https://threejs.org/editor/[ht...
    halber阅读 1,988评论 0 2