提问者:小点点

"绘图"在html文本


我需要做以下工作:拥有一个普通的网页,能够使用鼠标、手写笔或手指(如果是平板电脑或智能手机)在文本上“绘制形状”,然后使用形状信息确定某些“动作”。

让我举个例子。想象一下stackoverflow上的这个问题,我在ipad上围绕这一段“画”了一个圆圈。圆圈(或者圆圈的尝试,手工绘制总是非常不完美的),“捕捉”段落,所以我知道我会对段落做出一个动作,就像,例如,选择所有内部文本。

我的问题是:这是否可行?有这样的图书馆吗?如果没有,哪些技术可以进行调查?

我一直在做自己的研究,但没有什么能给我所需要的。例如,画布完全按照我的需要绘制,但是画布不能在html页面上使用。它是页面上的另一个元素,而不是一个“包裹”另一个。


共1个答案

匿名用户

那么要回答最初的问题:这可行吗?

首先,你需要在纸上画画的能力。的HTML5

其次,您需要能够识别页面上的哪些元素被圈起来。javascript函数。getBoundingClientRect()对此很有用,因为它告诉我们x和y位置以及宽度和高度。因为这些值是基于它们相对于文档边界框的位置(而不是父元素),我们可以将其与绘制的圆的坐标进行比较。

因此,有了这两个组件,我们可以把这样的东西组合在一起。。。(我承认这有点笨重,但可以根据您的特定用例进行优化):

var canvas, ctx, flag, coords, cntnr, dot_flag;
    
    function _InitDraw() {
      flag = false;
      coords = {
        pX: 0,
        cX: 0,
        pY: 0,
        cY: 0
      };
      cntnr = {
        minX: document.body.offsetWidth,
        minY: document.body.offsetHeight,
        maxX: 0,
        maxY: 0
      };
      dot_flag = false;

      canvas = document.createElement('canvas');
      canvas.id = "cnvTest";
      canvas.style.position = "fixed";
      canvas.style.top = 0;
      canvas.style.left = 0;
      document.body.appendChild(canvas);
      canvas.style.width = "100%";
      canvas.style.height = "100%";
      canvas.style.zIndex = 9001;
      ctx = canvas.getContext("2d");
      ctx.canvas.width = window.innerWidth;
      ctx.canvas.height = window.innerHeight;
  
      canvas.addEventListener("mousemove", function (e) { _Draw('move', e); }, false);
      canvas.addEventListener("mousedown", function (e) { _Draw('down', e); }, false);
      canvas.addEventListener("mouseup", function (e) { _Draw('up', e); }, false);
      //canvas.addEventListener("mouseout", function (e) { _Draw('out', e); }, false);
    }
    
    function _Draw(action, e) {
      if(action == 'down') {
        coords.pX = coords.cX;
        coords.pY = coords.cY;
        coords.cX = e.pageX;
        coords.cY = e.pageY;
        
        if(coords.cX < cntnr.minX) cntnr.minX = coords.cX;
        if(coords.cY < cntnr.minY) cntnr.minY = coords.cY;
        if(coords.cX > cntnr.maxX) cntnr.maxX = coords.cX;
        if(coords.cY > cntnr.maxY) cntnr.maxY = coords.cY;

        flag = true;
        dot_flag = true;
        if(dot_flag) {
          ctx.beginPath();
          ctx.fillStyle = "black";
          ctx.lineCap = 'round';
          ctx.fillRect(coords.cX, coords.cY, 2, 2);
          ctx.closePath();
          dot_flag = false;
        }
      }
      if(action == 'up' || action == "out") {
        flag = false;
        _GetText();
      }
      if(action == 'move') {
        if(flag) {
          coords.pX = coords.cX;
          coords.pY = coords.cY;
          coords.cX = e.pageX;
          coords.cY = e.pageY;

          if(coords.cX < cntnr.minX) cntnr.minX = coords.cX;
          if(coords.cY < cntnr.minY) cntnr.minY = coords.cY;
          if(coords.cX > cntnr.maxX) cntnr.maxX = coords.cX;
          if(coords.cY > cntnr.maxY) cntnr.maxY = coords.cY;
          
          ctx.beginPath();
          ctx.moveTo(coords.pX, coords.pY);
          ctx.lineTo(coords.cX, coords.cY);
          ctx.strokeStyle = "black";
          ctx.lineCap = 'round';
          ctx.lineWidth = 4;
          ctx.stroke();
          ctx.closePath();
        }
      }
    }

    function _GetText() {
      // Find position and get closest element
      document.body.removeChild(canvas);

      var allEls = document.body.getElementsByTagName("*");
      for(var i = 0; i < allEls.length; i++) {
        var elBox = allEls[i].getBoundingClientRect();
        if(elBox.x > cntnr.minX && elBox.x+elBox.width < cntnr.maxX && elBox.y > cntnr.minY && elBox.y+elBox.height < cntnr.maxY) {
          // Do whatever you want with the element here.
          // I am adding an outline for confirmation of the circled elements.
          allEls[i].style.outline = "2px solid rgba(255, 255, 0, 0.8)";
          if(allEls[i].innerText !== null && allEls[i].innerText !== "undefined") {
            // Do something with the innerText here if you need the text from the element.
            console.log(allEls[i].innerText);
          }
        }
      }
    }

相关问题