zoukankan      html  css  js  c++  java
  • js将文字填充与canvas画布再转为图片

    需求:封装consul服务的webUI;

    原因:展示consul的服务信息时,需要嵌套动画,由于其没有内置的icon,所以将服务name放于图片位;

    分析:展示信息时采用了卡片式的服务布局,缩放式的服务卡片,只有将服务名称作为图片才能实现动画效果;

    最基础动画:->

    实现:将服务名称置于canvas画布中,再将画布转为图片

    代码实现:

    1、获取dom

    /**
       * 获取service卡片中img对象并赋值src
       * @param serviceName 服务名称
       */
      setImageSrc(serviceName) {
        //因为src不是该HTMLElement类型的属性,而是HTMLImageElement。
        let image = <HTMLImageElement>document.querySelector("#nameImage" + serviceName);
        image.src = this.canvasWrapText({canvas:<HTMLElement>document.querySelector("#canvas" + serviceName),text: serviceName});
      }

    2、画布=>图片

    /**
       * 绘制文字到canvas,判断换行位置,和设置canvas高度
       * @param options canvas画布对象
       */
      canvasWrapText(options) {
        let settings = {
          canvas:document.getElementsByTagName("canvas")[0], //canvas对象,必填,不填写默认找到页面中的第一个canvas
          canvasWidth:240, //canvas的宽度
          drawStartX:50, //绘制字符串起始x坐标
          drawStartY:30, //绘制字符串起始y坐标
          lineHeight:30, //文字的行高
          font:"24px 'Microsoft Yahei'", //文字样式
          text:"请修改掉默认的配置", //需要绘制的文本
          drawWidth:220, //文字显示的宽度
          color:"#000000", //文字的颜色
          textAlain: "center",
          backgroundColor:"#ffffff", //背景颜色
        };
    
        //将传入的配置覆盖掉默认配置
        if(!!options && typeof options === "object"){
          for(let i in options){
            settings[i] = options[i];
          }
        }
    
        //获取2d的上线文开始设置相关属性
        let canvas = settings.canvas;
        canvas.width = settings.canvasWidth;
        let ctx = canvas.getContext("2d");
    
        //绘制背景色
        ctx.fillStyle = settings.backgroundColor;
        ctx.fillRect(0,0,canvas.width,canvas.height);
    
        //绘制文字
        ctx.font = settings.font;
        ctx.fillStyle = settings.color;
        // @ts-ignore
        ctx.textAlign = settings.textAlain;
        let lineWidth = 0; //当前行的绘制的宽度
        let lastTextIndex = 0; //已经绘制上canvas最后的一个字符的下标
        //由于改变canvas 的高度会导致绘制的纹理被清空,所以,不预先绘制,先放入到一个数组当中
        let arr = [];
        for(let i = 0; i< settings.text.length; i++){
          //获取当前的截取的字符串的宽度
          lineWidth = ctx.measureText(settings.text.substr(lastTextIndex,i-lastTextIndex)).width;
    
          if(lineWidth > settings.drawWidth){
            //判断最后一位是否是标点符号
            if(judgePunctuationMarks(settings.text[i-1])){
              arr.push(settings.text.substr(lastTextIndex,i-lastTextIndex));
              lastTextIndex = i;
            }else{
              arr.push(settings.text.substr(lastTextIndex,i-lastTextIndex-1));
              lastTextIndex = i-1;
            }
          }
          //将最后多余的一部分添加到数组
          if(i === settings.text.length - 1){
            arr.push(settings.text.substr(lastTextIndex,i-lastTextIndex+1));
          }
        }
    
        //根据arr的长度设置canvas的高度
        canvas.height = arr.length*settings.lineHeight+settings.drawStartY;
    
        ctx.font = settings.font;
        ctx.fillStyle = settings.color;
        for(let i =0; i<arr.length; i++){
          ctx.fillText(arr[i],settings.drawStartX,settings.drawStartY+i*settings.lineHeight);
        }
        //判断是否是需要避开的标签符号
        function judgePunctuationMarks(value) {
          let arr = [".",",",";","?","!",":",""","","","","","","",""];
          for(let i = 0; i< arr.length; i++){
            if(value === arr[i]){
              return true;
            }
          }
          return false;
        }
        return canvas.toDataURL();
      }

    注:关于代码实现中的关键节点都有详细的注解,此处不再累赘。

    3、html:

    <div class="member-image">
       <!--为了将文字渲染为图片所设置的样例canvas-->
      <canvas id="canvas{{card.name}}" width="" height="" style="background-color:#ffffff;display: none;"></canvas>
      <img id="nameImage{{card.name}}" alt="Member">
    </div>

    注:html代码中有遍历,不可直接使用

  • 相关阅读:
    salesforce零基础学习(八十七)Apex 中Picklist类型通过Control 字段值获取Dependent List 值
    salesforce lightning零基础学习(一) lightning简单介绍以及org开启lightning
    salesforce零基础学习(八十五)streaming api 简单使用(接近实时获取你需要跟踪的数据的更新消息状态)
    salesforce零基础学习(八十四)配置篇: 自定义你的home page layout
    salesforce零基础学习(八十三)analytics:reportChart实现Dashboard(仪表盘)功能效果
    salesforce零基础学习(八十二)审批邮件获取最终审批人和审批意见
    salesforce零基础学习(八十一)更改标准字段的label名称(Admin)
    salesforce零基础学习(八十)使用autoComplete 输入内容自动联想结果以及去重实现
    salesforce零基础学习(七十九)简单排序浅谈 篇一
    第三百五十一节,Python分布式爬虫打造搜索引擎Scrapy精讲—将selenium操作谷歌浏览器集成到scrapy中
  • 原文地址:https://www.cnblogs.com/PearlRan/p/11248556.html
Copyright © 2011-2022 走看看