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

Posted

技术标签:

【中文标题】通过 Kinetic.js 文本元素中的字符串索引获取单词/字符屏幕位置【英文标题】:Get word/character screen position by its string index in Kinetic.js Text element 【发布时间】:2014-04-28 11:11:49 【问题描述】:

输入:

一些包含常规词和特殊词/字符的文本用# 分隔。 Font 和 fontSize 是不变的,假设 Arial 14 没有任何样式。例如:

Lorem ipsum dolor #sit# amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut laboure #et# dolore magna aliqua。 Ut enim 广告 minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat。 Duis #aute# irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla 偏执。例外#sint# occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est labourum。

输出:

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

【问题讨论】:

【参考方案1】:

您的 # 个分隔符无法识别单词,因为 context.fillText 在画布上绘制单词。

这些文字成为画布位图无法识别的部分。

您需要做的是使用context.measureText 来映射每个单词的边界框。

然后您可以针对这些边界框测试单击的 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; 
    canvasborder: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>

本演示使用 html 画布。对于 kineticJS,您可以在屏幕外画布上进行这些边界框计算,然后在 Kinetic.Text 节点上使用这些边界框。

另请注意,您必须逐行计算边界框,因为框的 y 坐标在 line1 和 line2 上会有所不同,等等。

【讨论】:

以上是关于通过 Kinetic.js 文本元素中的字符串索引获取单词/字符屏幕位置的主要内容,如果未能解决你的问题,请参考以下文章

有啥方法可以让 Kinetic.js 支持 IE8?

Chrome 和 Opera 中的 Kinetic JS 性能问题

动态数组分配仅返回所有索引中的最后一个元素 C

MongoDB:带有数组的文本索引,只有第一个词被索引

Nodejs:nodejs 中的 Kineticjs

画布(Kinetic.JS):多层与单层方法