首页 > 其他分享 >vue canvas绘制信令图,动态显示标题、宽度、高度

vue canvas绘制信令图,动态显示标题、宽度、高度

时间:2024-04-09 17:04:17浏览次数:18  
标签:动态显示 canvas 信令 ctx height length context document words

需求:

1、 根据后端返回的数据,动态绘制出信令图
2、根据 dataStatus 返回值: 0 和 1, 判断 文字内容的颜色,0:#000,1:red
3.、根据 lineType 返回值: 0 和 1,  判断 箭头线的显示 是实线、虚线
4、根据返回的文字内容的换行符:“\r\n” 自动换行 (这步比较难,得计算高度)
最后的效果图大概是这样的:

 一、标题的动态获取


1-1、如果后端给你返回的标题是随机顺序的,这里需要根据全部标题数组做一下排序。
// 全部标题数组:
titletypeArr: ['ATP', 'MT', 'BTS', 'BSC', 'MSC', 'RBC'],


// 后端返回的随机标题数组: 
resultTitle: ['MT', 'ATP' ]


// 处理方法
this.typeArr = this.titletypeArr.filter(item => this.resultTitle.indexOf(item) !== -1)

 二、canvas绘制初始化

    // 初始化加载
    initData() {
      var mycanvas = document.getElementById("myCanvas");
      this.canvas = mycanvas;
      var context = mycanvas.getContext("2d");
      // 动态设置宽高一定要在 myCanvas 节点添加之后
      document.getElementById("myCanvas").width = this.typeArr.length * 320 - 120;
      document.getElementById("myCanvas").style.background = "#fff";
      const minHeight = window.innerHeight - 180;
      if (this.xlArr.length > 0) {
        document.getElementById("myCanvas").height =
          30 * this.xlArr.length + 80 < minHeight
            ? minHeight
            : 30 * this.xlArr.length + 80;
      } else {
        document.getElementById("myCanvas").height = minHeight;
      }
      var height = this.paddingTop + 62; // 初始值
      this.xlArr.map((v, i) => {
        const k = this.typeArr.indexOf(v.startDataDir);
        const j = this.typeArr.indexOf(v.endDataDir);
        context.font = '13px "微软雅黑"'; // 设置字体
        // 时间文字
        context.fillStyle = '#000' // 时间颜色
        context.fillText(v.recTime.split(' ')[1], 40, height);

        // 箭头
        this.paintArr(
          v,
          [this.gapX * k + this.paddingLeft, height],
          [this.gapX * j + this.paddingLeft, height],
          k < j ? "right" : "left",
          context
        );

        var maxWidth = 260; // 最大宽度,超过这个宽度会自动换行
        var words = v.showInfo.split("\r\n");

        // 文字自动换行
        this.wrapText(
          v,
          context,
          words,
          this.gapX * (k < j ? k : j) + this.paddingLeft,
          height - 10,
          maxWidth,
          this.lineHeight
        );

        if (i < this.xlArr.length - 1) {
          let nextWords = this.xlArr[i + 1].showInfo.split("\r\n");
          height += (this.lineHeight * (words.length + nextWords.length)) / 2 + 30;
        } else {
          height += this.lineHeight * words.length + 30;
        }
        // console.log(height, "height")
      })
      // 画虚线以及标题
      this.typeArr.map((v, i) => {
        this.paintText(context, v, i);
        setTimeout(() => {
          this.drawDashed(context, i);
        }, 300)
      })

      // document.getElementById('container').onscroll = (e) => {
      //   // console.log('e:', e.target)
      //   this.left = e.target.scrollLeft
      // }
      // 屏蔽所有页面 右键菜单
      // document.oncontextmenu = (event) => {
      //   event.returnValue = false
      // }
      // 屏蔽当前页面 右键菜单
      // document.getElementById('container').oncontextmenu = (event) => {
      //   event.returnValue = false
      // }
    }

三、绘制箭头

    // 箭头
    paintArr(item, s, t, direction, ctx) {
      ctx.beginPath()
      ctx.lineWidth = 1
      if (item.dataStatus == 1) {
        ctx.strokeStyle = 'red'
      } else {
        ctx.strokeStyle = '#000' // 箭头线的颜色
      }

      if (item.lineType === 1) {
        ctx.setLineDash([5, 2]); // 虚线
      }
      ctx.moveTo(s[0], s[1])
      ctx.lineTo(t[0], t[1])
      ctx.stroke()
      ctx.closePath()

      ctx.beginPath()
      if (direction === 'right') {
        ctx.moveTo(t[0] - 10, t[1] + 3)
        ctx.lineTo(t[0], t[1])
        ctx.lineTo(t[0] - 10, t[1] - 3)
      } else {
        ctx.moveTo(t[0] + 10, t[1] - 3)
        ctx.lineTo(t[0], t[1])
        ctx.lineTo(t[0] + 10, t[1] + 3)
      }
      // ctx.closePath()
      ctx.stroke()
      // ctx.fill()
    },

四、绘制 标题列的虚线

    // 标题列的虚线
    drawDashed(ctx, i) {
      ctx.beginPath()
      ctx.lineWidth = 1
      ctx.strokeStyle = '#696969' // '#FF8080'//虚线的颜色
      ctx.setLineDash([5, 2])
      ctx.moveTo(320 * i + this.paddingLeft, this.paddingTop + 40);
      ctx.lineTo(320 * i + this.paddingLeft, 400 * this.typeArr.length);
      ctx.fill()
      ctx.stroke()
      ctx.closePath()
    },

五、文字自动换行 遇到换行符换行

    // 文字自动换行 遇到换行符换行,并且超出最大宽度换行,只计算了最多显示7行的情况,超出7行得再计算
    wrapText(item, context, words, x, y, maxWidth, lineHeight) {
      // console.log(words, "words")
      let originY = y;
      let len = words.length;
      let rectWidth = 0;

      for (var n = 0; n < len; n++) {
        // 不超出一行
        var testWidth = context.measureText(words[n]).width;
        if (testWidth < maxWidth) {
          if (rectWidth < testWidth) {
            rectWidth = testWidth;
          }
        }
      }
      // 在上面循环计算出文字实际最宽的位置,画出背景色遮挡箭头
      // 画背景色遮盖箭头, 背景色自己调,跟画布统一就行
      context.fillStyle = "#fff"; // 背景颜色
      context.fillRect(
     

标签:动态显示,canvas,信令,ctx,height,length,context,document,words
From: https://blog.csdn.net/qq_41646249/article/details/137558125

相关文章

  • 基于canvas 或 svg绘制并生成base64 用于cesium billboard 渲染 替代label
    原因cesium的label样式不太好修改canvas生成functionlabelContent(showData){constmyConvas=document.createElement("canvas");constscale=1;//获取2d的上线文开始设置相关属性myConvas.width=150myConvas.height=65;letcont......
  • 【Canvas与艺术】模拟八一电影制片厂电影片头效果
    【缘起】八一厂每部电影前都有其专有开头,如:https://www.ixigua.com/6799821997258834440?logTag=2eacce76401e13f9efe7,让人印象深刻。这个片头可以用canvas模拟一部分。【关键点】线型放射状粒子系统的运作。立体感五角星的绘制。【图例】【代码】<!DOCTYPEhtml><ht......
  • web前端之页面逐渐呈现代码功能、对象数据如何获取下一个值、创建元素并添加id与类名
    MENU前言style(全部代码)JavaScript(核心代码)html(基本代码)前言1、效果演示以视频为准,暂未录视频(敬请期待);2、私信或微信可获取完整代码(WX:MJ682517)style(全部代码)*{margin:0;padding:0;box-sizing:border-box;}::-webkit-scrol......
  • 纯 canvas 版转盘
    简介纯canvas画布实现的转盘,使用uni-app实现,理论上是支持全端(如微信小程序、支付宝小程序、抖音小程序等等)部署,可能存在样式上差异直接下载后使用HbuilderX导入即可使用使用场景:轮盘、转盘、抓阄、抽奖、替你做决定、做选择、今天吃什么、周末去哪里玩等等都可......
  • LTE信令和协议
    ****部分笔记*****控制面连接(ControlPlaneConnection)是在LTE和5G网络中的一个重要概念,它用于在设备和网络之间传输控制信息。控制面连接主要用于以下几种情况:设备接入和鉴权:当设备需要接入网络时,它会通过控制面连接向网络发送接入请求,网络会通过控制面连接向设备发送接入......
  • canvas签名图片上传及入库问题
    工作需要,asp+access建了个简单信息交互平台,表单填报、签名、及查看只能在手机上进行。已实现Base64直接入数据库。有Jccscxj.asp(首页表单填报)、Jccscxjup.asp(手写签名页面)、ajax-cscxj.asp(入库页面)、anco.asp(数据库联接)、cscxjck.asp(填报项查看)等五个asp文件、jcxj.mdb......
  • 可视化学习:实现Canvas图片局部放大镜
    前言最近我在可视化课程中学习了如何在Canvas中利用像素处理来实现滤镜效果,在这节课程的结尾留了一道局部放大镜的题目,提示我们用像素处理的方式去实现这个效果,最终实现随着鼠标移动将图片局部放大,本着把学到的内容落地实践的想法,我就去思考了一番,但很不幸,我思考了好几天也没思考......
  • WPF C# create canvas and draw ellipse in canvas
    usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;usingSystem.Windows;usingSystem.Windows.Controls;usingSystem.Windows.Data;usingSystem.Windows.Documents;usingSystem.Windows.Input;......
  • 想实现Canvas元素拖拽?速来一探究竟,你也可以轻松做到!
    元素拖拽是一种常见的交互设计模式,在许多场景下都有应用:地图打标、画板图形拖拽、可视化组件拖拽、交互式表格等。实现元素拖拽的核心在于监听和响应鼠标事件,模拟canvas元素事件,并同步更新Canvas绘制。主要需实现:创建元素坐标转换(鼠标事件坐标和canvas坐标转换)事件监听、元......
  • 纯前端实现 JPG 图片压缩 | canvas
    在线Demo体验地址→:https://demos.sugarat.top/pages/jpg-compress/前言在迭代图床应用时,需要用到图片压缩,在之前分享了使用UPNG.js压缩PNG图片,这里记录分享一下如何处理JPG图片。搜罗调研了一圈,JPG图片的处理,基本都是围绕canvas展开的。掘金:前端实现图片压......