zoukankan      html  css  js  c++  java
  • 如何使用irealtime.js实现一个基于websocket的同步画板

    同步画板演示

    同时打开2个tab,分别在画布上写下任意内容,观察演示结果,同时可设置画笔颜色及线条宽度。演示地址

    初始化画布

     <canvas id="drawBoard" width="700" height="400"></canvas>
    
       this.canvas = document.getElementById("drawBoard");
       this.ctx = this.canvas.getContext("2d");
       this.stage_info = this.canvas.getBoundingClientRect(); //初始化舞台信息
       this.path = { //初始化路径
          beginX: 0,
          beginY: 0,
          endX: 0,
          endY: 0,
        };
       this.ctx.lineWidth = this.size;//初始化线条宽度
    

    加载irealtime.js

    irealtime.js 是一个第三方websocket实时消息推送服务jssdk,可用于快速搭建安全可靠高并发的web实时通讯体系,同时支持多语言开发且兼容绝大多数主流浏览器, 了解更多

    1. 引入irealtime.js
    npm i irealtime --save
    
    1. 初始化irealtime
    import IRealTime from "irealtime";
    
    this.irealtime = new IRealTime({
      host: "hk.irealtime.cn",
      appkey: "your appkey", //如何获取appkey: https://irealtime.cn/docs/get_account_and_appkey.html
      onConnected: function () {
        console.log("连接成功...");
      },
      onDisconnected: function () {
        console.log("连接断开...");
      },
      onConnectFailed: function (error) {
        console.log("连接失败...", error);
      },
    });
    
    
    1. 订阅消息
      this.irealtime.subscribe({
          channels: ["mychannel"],
          onMessage: (data) => {
            this.syncPath(data.message); //通过irealtime将绘画内容同步到其他客户端
          },
          onSuccess: function () {},
          onFailed: function () {},
        });
    
    
    1. 发布消息
        publish(msg) {
          this.irealtime.publish({
            channel: "mychannel",
            message: msg,
            onSuccess: function (data) {
              console.log("success:", data);
            },
            onFailed: function (error) {
              console.log("failed:", error);
            },
          });
        },
    
    

    开始绘画

    1. 绑定鼠标事件
      draw() {
          let that = this;
          this.canvas.onmousedown = (e) => {
            that.ctx.beginPath();
            that.path.beginX = e.pageX - that.stage_info.left;
            that.path.beginY = e.pageY - that.stage_info.top;
            that.ctx.moveTo(that.path.beginX, that.path.beginY);
            that.isDraw = true;//isDraw 是否开始绘画
            this.publish(  //发送mousedown消息给其他客户端
              JSON.stringify({
                type: "mousedown",
                path: this.path,
              })
            );
          };
          this.canvas.onmousemove = (e) => {
            if (that.isDraw) {
              that.drawing(e); //按下并移动鼠标开始绘画
            }
          };
          this.canvas.onmouseup = () => {
            that.isDraw = false;
            this.publish(   //发送stop消息给其他客户端
              JSON.stringify({
                type: "stop",
                path: this.path,
              })
            );
          };
        },
    
    
    1. 绘画动作
        drawing(e) {
          this.path.endX = e.pageX - this.stage_info.left;
          this.path.endY = e.pageY - this.stage_info.top;
          this.ctx.lineTo(this.path.endX, this.path.endY);
          this.ctx.stroke();
          let data = {
            type: "draw",
            size: this.size,
            current: this.current,
            path: this.path,
          };
          this.publish(JSON.stringify(data));//将当前绘画路径、线条宽度、当前颜色等信息发送给其他客户端
        },
    
    
    1. 同步绘画信息

    通过不同类型的消息,判断客户端需要做的操作

      syncPath(data) {
          const { type, size, current, path } = JSON.parse(data);
          if (type === "changeColor") { //改变颜色
            this.current = current;
            this.ctx.strokeStyle = this.palette[this.current];
            return;
          }
          if (type === "changeSize") { //改变线条宽度
            this.size = size;
            this.ctx.lineWidth = this.size;
            return;
          }
    
          if (type == "clear") {  //清空画布
            this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
            return;
          }
          if (this.path.beginX != path.beginX) { //防止重复
            if (type === "mousedown") {
              this.ctx.beginPath();
    
              this.ctx.moveTo(path.beginX, path.beginY);
              this.isDraw = 1;
            } else if (type === "draw" && this.isDraw === 1) {
              this.ctx.lineTo(path.endX, path.endY);
              this.ctx.stroke();
            }
          }
          if (type === "stop") {//停止绘画
            this.isDraw = 0;
          }
        },
    
    

    查看源码

    总结

    本文通过使用irealtime.js的两个简单api(subscribe|publish)便实现了基于websocket的消息发布及订阅,开发者无需过多关注websocket服务端操作,可直接使用irealtime api开发基于websocket的应用,如需了解更多内容,请直接访问https://irealtime.cn/

    make a difference
  • 相关阅读:
    FJUT3260
    Codeforces Round #387 (Div. 2)
    poj 1375
    试题 历届试题 蚂蚁感冒(模拟)
    丢手绢(尺取)
    「金」点石成金(dfs)
    小A买彩票(dp)
    不平行的直线
    最少交换次数
    第k小数(桶排序)
  • 原文地址:https://www.cnblogs.com/paul-xiao/p/14436376.html
Copyright © 2011-2022 走看看