如何在HTML 5画布中添加可选择的文本?

6
我需要在画布上方放置一个文本标签,这有可能吗?我该如何做? 我知道有 fillText 方法,但是它不能给我平滑输出的文本。我还希望用户能够复制标签上的文本,如果使用 fillText 方法就无法实现这一点。
3个回答

3
假设您想在 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;
}

演示


编辑:

如果您正在寻找在画布内选择文本的解决方案,那么这将会更加繁琐。

我建议使用 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);

1
我认为他正在寻找类似于fillText的东西,可以将标签实际绘制到画布上... - Richard Ambler
1
@richthepanda 可能是的。我已经编辑了我的答案,包括另一个演示。 - loxxy
1
我知道这已经很老了,但我完全不知道如何从你的例子中实际获取所选值。在我看来,它似乎只是在文本后面绘制矩形,而实际上没有处理字符本身,因此很难提取它们。 - jimmy
@loxxy,选择时有一点延迟 - Pacerier

1
可以实现。以下是一个使用来自Mozilla Developer NetworkforeignObjectsvg示例。请注意,这里保留了HTML标签。
<!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>

1
该文本实际上无法选择。 - Nikita Rybak
是的。原始问题已经被编辑过了。它最初是“如何在HTML 5画布上放置标签?” - Richard Ambler

1
在我的画布项目中,我需要创建一个可突出显示、可编辑和可复制的文本区域,该区域在单击时生成并在失去焦点时删除。以下是我实现它的结构
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;
}

这允许创建一个文本区域,只有在单击时才会创建,并且在失去焦点时被删除。不确定您是否需要此功能,但如果不需要,则很容易删除。 此处演示(WiP),当您单击其中一条栏右侧的值时。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接