cavans实现文字转图片(娱乐项目)

供参考。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>文字转图片生成器</title>
  </head>
  <body>
    <script type="text/javascript">
      //绘制文字到canvas,判断换行位置,和设置canvas高度

      function canvasWrapText(options) {
        let settings = {
          canvas: document.getElementsByTagName("canvas")[0], //canvas对象,必填,不填写默认找到页面中的第一个canvas
          canvasWidth: 580, //canvas的宽度
          drawStartX: 60, //绘制字符串起始x坐标
          drawStartY: 50, //绘制字符串起始y坐标
          lineHeight: 50, //文字的行高
          font: "40px microsoft-yahei,Bold", //文字样式(普通汉字)
          font1: "12px 'Italic'", //文字样式(水印)
          font2: "40px STXingkai,fantasy", //文字样式(数字)
          font3: "40px STHupo", //文字样式(字母)
          text: "请修改掉默认的配置", //需要绘制的文本
          drawWidth: 460, //文字显示的宽度
          color: "rgba(0,255,1,1)", //文字的颜色
          backgroundColor: "rgba(150,150,150,1)", //背景颜色
        };

        //将传入的配置覆盖掉默认配置
        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.font = settings.font;
        ctx.fillStyle = settings.color;
        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 + 1) * settings.lineHeight + settings.drawStartY;
        // canvas.width = 480*0.99863 + canvas.height*0.052336;

        ctx.fillStyle = settings.backgroundColor;
        ctx.fillRect(0, 0, canvas.width, canvas.height);

        //绘制遮罩层
        ctx.fillStyle = settings.backgroundColor;
        ctx.fillRect(0, 0, canvas.width, canvas.height);

        //绘制文字
        ctx.font = settings.font;
        ctx.fillStyle = settings.color;
        // ctx.rotate(-3 * Math.PI / 180);
        for (let i in arr) {
          //对易识别的字母和数字的处理
          let nowX = settings.drawStartX;
          let regASCII = /^[\u0000-\u00ff]$/;
          let regEn = /^[a-zA-Z]*$/;
          let regNum = /^[0-9]*$/;
          for (let j in arr[i]) {
            if (regASCII.test(arr[i][j])) {
              //匹配单字节
              if (regEn.test(arr[i][j])) {
                //如果为英文字母
                ctx.font = settings.font3;
                ctx.fillText(
                  arr[i][j],
                  nowX,
                  settings.drawStartY + i * settings.lineHeight
                );
                nowX += 20;
              } else if (regNum.test(arr[i][j])) {
                //如果为数字
                ctx.font = settings.font2;
                ctx.fillText(
                  arr[i][j],
                  nowX,
                  settings.drawStartY + i * settings.lineHeight
                );
                nowX += 20;
              } else {
                ctx.font = settings.font;
                ctx.fillText(
                  arr[i][j],
                  nowX,
                  settings.drawStartY + i * settings.lineHeight
                );
                nowX += 20;
              }
            } else {
              //双字节
              if (arr[i][j] != "\n" || arr[i][j] != " ") {
                ctx.font = settings.font;
                ctx.fillText(
                  arr[i][j],
                  nowX,
                  settings.drawStartY + i * settings.lineHeight
                );
                nowX += 40;
              } else {
                ctx.font = settings.font;
                ctx.fillText(
                  arr[i][j],
                  nowX,
                  settings.drawStartY + i * settings.lineHeight
                );
                nowX += 20;
              }
            }
          }
          // ctx.fillText(arr[i],settings.drawStartX,settings.drawStartY+i*settings.lineHeight);  //原绘制方法
        }

        //绘制底层网格
        let girdSize = 2;

        // 2. 获取Canvas的width、height
        let CanvasWidth = canvas.width;
        let CanvasHeight = canvas.height;

        // 3. 采用遍历的方式,绘画x轴的线条
        let xLineTotals = Math.floor(CanvasHeight / girdSize); // 计算需要绘画的x轴条数
        for (let i = 0; i < xLineTotals; i++) {
          ctx.beginPath(); // 开启路径,设置不同的样式
          ctx.moveTo(0, girdSize * i - 0.5); // -0.5是为了解决像素模糊问题
          ctx.lineTo(CanvasWidth, girdSize * i - 0.5);
          ctx.strokeStyle = "rgba(150,150,150,1)"; // 设置每个线条的颜色
          ctx.stroke();
        }

        // 4.采用遍历的方式,绘画y轴的线条
        let yLineTotals = Math.floor(CanvasWidth / girdSize); // 计算需要绘画y轴的条数
        for (let j = 0; j < yLineTotals; j++) {
          ctx.beginPath(); // 开启路径,设置不同的样式
          ctx.moveTo(girdSize * j, 0);
          ctx.lineTo(girdSize * j, CanvasHeight);
          ctx.strokeStyle = "rgba(150,150,150,1)"; // 设置每个线条的颜色
          ctx.stroke();
        }

        //判断是否是需要避开的标签符号
        function judgePunctuationMarks(value) {
          let arr = [
            ".",
            ",",
            ";",
            "?",
            "!",
            ":",
            '"',
            ",",
            "。",
            "?",
            "!",
            ";",
            ":",
            "、",
          ];
          for (let i = 0; i < arr.length; i++) {
            if (value === arr[i]) {
              return true;
            }
          }
          return false;
        }

        return canvas.toDataURL();
      }

      function buttonOnClick() {
        let text = document.getElementById("ta").value;
        if (text == "") {
          alert("文字为空");
        } else {
          //调用函数获取到img的data数据
          let data = canvasWrapText({
            canvas: document.getElementById("canvas"),
            text: text,
          });

          //创建一个img对象,在页面上显示打印的数据
          let img = document.getElementById("img"),
            canvas = document.createElement("canvas"),
            ctx = canvas.getContext("2d");
          img.src = data;
        }
      }
    </script>

    <div align="center"></div>

    <div>
      <textarea
        id="ta"
        style="width: 99%; height: 300px"
        placeholder="请输入文字以生成图片"
      ></textarea>
      <button
        style="display: block; margin: 10px auto; text-align: center"
        id="btn"
        onclick="buttonOnClick()"
      >
        生成
      </button>
      <img
        id="img"
        style="display: block; margin: 10px auto; text-align: center"
      />

      <canvas id="canvas" style="display: none"></canvas>
    </div>
  </body>
</html>

效果图

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值