首页 文章

通过Kinetic.js Text元素中的字符串索引获取字/字符屏幕位置

提问于
浏览
2

Input:

一些包含常规单词和特殊单词/ char的文本用#分隔 . 字体和fontSize是常量,让我们说Arial 14没有任何样式 . 例如:

Lorem ipsum dolor#sit#amet,consectetur adipisicing elit,sed do eiusmod tempor incididunt ut labore#et#dolore magna aliqua . Ut enim ad minim veniam,quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat . Duis#aute#irure dolor in repreptderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur . Excepteur#sint #occaecat cupidatat non proident,sunt in culpa qui officia deserunt mollit anim id est laborum .

Output:

当用户点击#someSeparatedWord#时,我需要在控制台中记录该单词(在我的示例中,用户可以点击'sit','et','aute','sint',它只会记录这些单词) . 所以问题在于如何获取或计算这个单词/ char画布坐标?

1 回答

  • 3

    您的#dremiters无法识别单词,因为 context.fillText 在画布上绘制了单词 .

    这些单词成为画布位图无法识别的部分 .

    What your will have to do is use context.measureText to map the bounding box of every word.

    enter image description here

    然后,您可以针对这些边界框测试单击的mouseX / mouseY位置 .

    这是示例代码和演示:http://jsfiddle.net/m1erickson/c9nQj/

    <!doctype html>
    <html>
    <head>
    <link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
    <script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
    <style>
        body{ background-color: ivory; }
        canvas{border:1px solid red;}
    </style>
    <script>
    $(function(){
    
        $results=$("#results");
    
        var canvas=document.getElementById("canvas");
        var ctx=canvas.getContext("2d");
        var $canvas=$("#canvas");
        var canvasOffset=$canvas.offset();
        var offsetX=canvasOffset.left;
        var offsetY=canvasOffset.top;
    
        var text="Lorem ipsum dolor #sit# amet, consectetur adipisicing elit";
    
        var words=text.split(" ");
        var wordsBB=new Array(words.length);
    
        ctx.font="14px arial";
    
        var length=ctx.measureText(words[0]).width;
    
        wordsBB[0]={
            x:0,
            y:0,
            width:length,
            height:16
        }
    
        var accumLength=length;
    
        for(var i=1;i<words.length;i++){
            var length=ctx.measureText(" "+words[i]).width;
            wordsBB[i]={
                x:accumLength,
                y:0,
                width:length,
                height:16
            }
            accumLength+=length;
        }
    
        ctx.fillText(text,0,15);
        ctx.lineWidth=0.50;
    
        for(var i=0;i<words.length;i++){
            var bb=wordsBB[i];
            ctx.strokeRect(bb.x,bb.y,bb.width,bb.height);
        }
    
    
        function handleMouseMove(e){
          e.preventDefault();
          var x=parseInt(e.clientX-offsetX);
          var y=parseInt(e.clientY-offsetY);
    
          $results.text("---");
          for(var i=0;i<wordsBB.length;i++){
              var bb=wordsBB[i];
              if(x>bb.x && x<bb.x+bb.width && y>bb.y & y<bb.y+bb.height){
                  $results.text(words[i]);
              }
          }
    
        }
    
        $("#canvas").mousemove(function(e){handleMouseMove(e);});
    
    
    }); // end $(function(){});
    </script>
    </head>
    <body>
        <p>Hover over a word.</p>
        <h2 id="results">---</h2>
        <canvas id="canvas" width=400 height=50></canvas>
    </body>
    </html>
    

    这个Demo使用html画布 . 对于kineticJS,您可以在离屏画布上执行这些边界框计算,然后在Kinetic.Text节点上使用这些边界框 .

    另请注意,您必须逐行进行边界框计算,因为第1行与第2行等的y坐标框不同 .

相关问题