【问题标题】:How do I add a selectable text in HTML 5 Canvas? [duplicate]如何在 HTML 5 Canvas 中添加可选文本? [复制]
【发布时间】:2013-07-29 10:58:52
【问题描述】:

我需要在画布上放置一个文本标签。是否可以?我怎样才能做到这一点? 我知道有 fillText 但 fillText 没有给我流畅的输出文本。我还希望标签上的文本可以被用户复制,如果我使用 fillText,这是不可能的。

【问题讨论】:

    标签: javascript html canvas html5-canvas


    【解决方案1】:

    假设,您只是想在 html 页面中的画布顶部放置一些文本:

    HTML:

    <label>Yahoo, I'm on top of canvas??</label>
    <canvas width="500" height="500" ></canvas>
    

    CSS:

    canvas {
        border:1px solid gray;
    }
    
    label {
        position:absolute;
        top:20px;
        left:20px;
    }
    

    Working demo


    编辑:

    根据编辑,如果您正在寻找在画布内选择文本的解决方案,那会更加痛苦。

    我建议使用 CreateJS。使用画布时,它会让您的生活变得更轻松。

    虽然该库没有为您提供可选择的文本,但它更容易实现。

    这里是 DEMO 介绍如何创建可选文本。

    // Text Selector Class
    function Selector(stage, text) {
        var select = new createjs.Shape();
    
        function selector(x, y, width, height) {
            select.graphics.clear().beginFill("#ace")
                .drawRect(x || 0, y || 0, width || 0, height || 0);
        }
        var tuw = text.getMeasuredWidth();
        var tuh = text.getMeasuredHeight();
        text.addEventListener("mousedown", function (e) {
            var startX = e.rawX;
            var onMove = function (e) {
                if (e.rawX >= text.x && e.rawX <= text.x + tuw) selector(startX, text.y, e.rawX - startX, tuh);
            };
            var onUp = function () {
                stage.removeEventListener("stagemousemove", onMove);
                selector();
            };
            stage.addEventListener("stagemousemove", onMove);
            stage.addEventListener("stagemouseup", onUp);
        });
        return select;
    }
    
    
    var stage = new createjs.Stage("shape");
    
    // Text Node
    var text = new createjs.Text("Hello World");
    text.x = 100;
    text.font = "20px Arial";
    text.color = "#ff7700";
    text.cursor = "text";
    stage.addChild(text);
    
    // Attach Selector 
    stage.addChildAt(new Selector(stage, text), 0);
    
    // Important
    stage.enableMouseOver();
    setInterval(function () {
        stage.update();
    }, 100);
    

    【讨论】:

    • 我认为他正在寻找类似于 fillText 的东西,它实际上将标签绘制到画布上......
    • @richthepanda 也许是的。我已经编辑了我的答案以包含另一个演示。
    • 我知道这已经很老了,但我完全不知道如何从您的示例中实际获取所选值。在我看来,它看起来只是在文本后面绘制矩形,但实际上并没有处理字符本身,因此很难提取它们。
    • @loxxy,选择有点滞后
    【解决方案2】:

    这是可能的。这是一个使用svgforeignObject 直接来自Mozilla Developer Network 的示例。

    <!DOCTYPE html>
    <html>
    <body>
    <p><canvas id="canvas" style="border:2px solid black;" width="200" height="200"></canvas>
    <script>
      var canvas = document.getElementById("canvas");
      var ctx = canvas.getContext("2d");
      var data = "<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'>" +
             "<foreignObject width='100%' height='100%'>" +
               "<div xmlns='http://www.w3.org/1999/xhtml' style='font-size:40px'>" +
                 "<em>I</em> like <span style='color:white; text-shadow:0 0 2px blue;'>cheese</span>" +
               "</div>" +
             "</foreignObject>" +
           "</svg>";
      var DOMURL = self.URL || self.webkitURL || self;
      var img = new Image();
      var svg = new Blob([data], {type: "image/svg+xml;charset=utf-8"});
      var url = DOMURL.createObjectURL(svg);
      img.onload = function() {
          ctx.drawImage(img, 0, 0);
          DOMURL.revokeObjectURL(url);
      };
      img.src = url;
    </script>
    </body>
    </html>
    

    【讨论】:

    • 该文本实际上是不可选择的。
    • 是的。原始问题已被编辑。它最初是“如何在 HTML 5 画布上放置标签?”
    【解决方案3】:

    在我的一个画布项目中,我需要创建可突出显示、可编辑和可复制的文本区域,在单击时生成并在文本区域失去焦点时将其删除。下面是我如何做到的结构

    Javascript:

    var mousePos;
    var textarea = null;  
    var x;
    var y;
    var textValue;
    function getMousePos(canvas, evt) 
    {
      var rect = canvas.getBoundingClientRect();
      return {
        x: evt.clientX - rect.left,
        y: evt.clientY - rect.top
      };
    }
    canvas.addEventListener('mousedown', function(evt) 
     {
       mousePos = getMousePos(canvas, evt);
       mouseDown = true;
       setTimeout(function() { check(mousePos.x, mousePos.y) }, 50);  
     }, false);
    canvas.addEventListener('mouseup', function(evt) 
     {
       evt.preventDefault();
       mouseDown = false;
     }, false);
    
    function check(xPos, yPos)
    {
      if(xPos > /*lower bounding x position*/ && xPos < /*upper bounding x position*/ && yPos < /*upper bounding y position*/ && yPos > /*lower bounding y position*/)
      {
        if(!textarea) {
          textarea = document.createElement('textarea');
          textarea.className = 'textArea';
          textarea.onkeypress = function (e) {
            if (e.which === 13) { // Allows pressing 'Enter' to change the focus of the text area
              textarea.blur();
            }
          }
          textarea.onblur = function () {
            /*do something with value*/
            textValue = textarea.value;
            document.body.removeChild(textarea);
            textarea = null;
          } 
          document.body.appendChild(textarea);
        }
        textarea.blur();
        textarea.value = /*put default value*/;
        textarea.style.left = /*put left position of object*/;
        textarea.style.top = /*put top position of object*/;        
      }
    }
    

    CSS

    .textArea {
      /* The only necessary CSS is a height, a width, and position:absolute */
      position: absolute;
      background:grey;
      height:20px;
      border:0;
      outline:0;
      line-height:10px;
      width:100px;
      resize: none;
      overflow:hidden;
      font-size:10px;
    }
    

    这仅允许创建一个文本区域,并在单击时创建并在失去焦点时删除。不确定您是否需要此功能,但如果不需要,很容易删除

    Demo here (WiP) 当您单击其中一个条右侧的值时

    【讨论】:

      猜你喜欢
      • 2021-05-27
      • 2017-05-16
      • 2013-04-18
      • 1970-01-01
      • 2019-11-26
      • 2016-08-07
      • 2015-12-01
      • 2021-10-27
      • 2021-11-29
      相关资源
      最近更新 更多