【问题标题】:converting string to reference points for canvas drawing将字符串转换为画布绘图的参考点
【发布时间】:2015-05-29 02:11:33
【问题描述】:

我正在考虑能够将简单的文本图更改为在 HTML5 画布中绘图的坐标。

假设我有以下文本图,假设它存储在 django 模型的文本字段中。

     1
     2
  3  L  4
   5 6 7
     8

我想要的是能够通过找出每个数字(或字母)在字符串中的哪个点来将其绘制到画布上。空格也很重要。

我什至不知道从哪里开始。

【问题讨论】:

    标签: javascript python django html canvas


    【解决方案1】:

    给定以下字符串:

    raw_str = """\
         1
         2
      3  L  4
       5 6 7
         8"""
    

    您可以从构建一个角色到坐标映射开始:

    rows = s.split('\n')
    mapping = {}
    for y, r in enumerate(rows):
        for x, c in enumerate(r):
            if c != ' ':
               mapping[c] = (x, y)
    

    顺便说一句,映射构建部分也可以使用dict理解写成一行:

    {c: (x, y) for y, r in enumerate(rows) for x, c in enumerate(r) if c != ' '}
    

    现在你应该得到这样的映射:

    {'1': (5, 0),
     '2': (5, 1),
     '3': (2, 2),
     '4': (8, 2),
     '5': (3, 3),
     '6': (5, 3),
     '7': (7, 3),
     '8': (5, 4),
     'L': (5, 2)}
    

    您可以将其编码为 JSON 并将其作为某些 Javascript 画布绘图函数的输入传递给前端。

    【讨论】:

      【解决方案2】:

      您需要创建一个可用于使用 CANVAS 构建图像的数据模型。一种这样的模型是二维数组。

      你可以编写一个函数来解析文本区域并使用每个元素的索引来定义与其他元素的相对索引。这可以通过使用空字符串调用 split 并遍历返回的数组来完成。您可以在迭代时跟踪行号和列号。找到每个换行符('\n')后,可以将列数重置为 0。

      请注意,如果您想要一个包含不同字符的相对准确的文本区域图像,您应该使用等宽字体,例如 Courier。

      例如,给定以下html页面内容:

      <textarea id="area" cols="40" rows="10" style="font-family:Courier;">
                  0
                  0 
                  0
             0    0    0
               0  0  0
                 0 0
                  0
      </textarea>
      
      <canvas id="canvas" width="400px" height="100px" style="border:1px solid #000000;"></canvas>
      

      此示例使用纯 html 文本区域而不是 django,但它向您展示了一般方法。

      我们可以计算二维数组,假设文本区域中的新行将是我们的 CANVAS 图像中的新行:

      var area = document.getElementById("area");
      var text = area.textContent;
      
      var array = text.split('');
      
      var row = 0;
      var col = 0;
      var colArray = [];
      var rowArray = [];
      for(var i=0; i<array.length; i++)
      {
          var c = array[i];
          if(c === '\n')
          {
              rowArray[row] = colArray;
              colArray = [];
      
              row++;
              col = 0;
          }
          else
          {
              colArray[col] = c;
      
              col++;
          }
      }
      



      然后,您可以通过遍历二维数组来构建您的 CANVAS 图像,其中x 是 x 坐标,y 是 y 坐标。

      var c = document.getElementById("canvas");
      var ctx = c.getContext("2d");
      var r = 20;
      var xScale = 20;
      var yScale = 40;
      console.log(rowArray);
      for(y=0; y<rowArray.length; y++)
      {
          var row = rowArray[y];
          for(var x=0; x<row.length; x++)
          {
              var val = row[x];
              if(val != " ")
              {
                  //Draw something at position [x,y] (or some transformation of it)
                  var xCoord = x * xScale;
                  var yCoord = y * yScale;
      
                  ctx.beginPath();
                  ctx.arc(xCoord, yCoord, r, 0, 2 * Math.PI);
                  ctx.fillStyle = 'pink';
                  ctx.fill();
                  ctx.fillStyle = 'black';
                  ctx.textAlign = 'center';
                  ctx.fillText(val, xCoord, yCoord+5);
                  ctx.stroke();  
      
      
              }
          }
      }
      

      您可能需要在 CANVAS 中对 x 坐标使用与 y 坐标不同的转换,具体取决于您希望如何显示图像。

      您可以在 JSFiddle 中运行它来使用它。

      编辑: 也添加了文本填充。你可以玩弄这些位置。

      编辑2:在圆圈内添加中心文本定位。

      【讨论】:

      • 我在 JSFiddle 中玩过这个,我不是 JS 专家,我希望在 python 中做到这一点,但这效果更好。但是我不知道我在用画布做什么,jsfiddle.net/2xxn782h/13 如何让实际值显示在弧的中间?并且由于某种原因,我需要在 JSFiddle 上弧线的半径至少约为 20px,它显示为椭圆形而不是完整的圆。
      • 已编辑以在您的 JSFiddle 中包含文本。椭圆问题是由于将画布宽度和高度设置为 100% 导致的,这会拉伸图像。
      猜你喜欢
      • 1970-01-01
      • 2019-04-26
      • 2011-11-25
      • 2014-05-04
      • 2012-02-01
      • 2021-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多