I need to place a text label on top of a canvas. Is it possible? How can I do that? I know there's fillText but fillText is not giving me smooth output text. I also want the text on the label to be copyable by the users, which is not possible if I use fillText.
Assuming, you simply want to place some text on top of the canvas in an html page :
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
As per the edit, if you are looking for a solution to select text inside canvas, it would be a bit more pain full.
I would suggest using CreateJS. It would make your life whole lot easier while working with canvas.
Although the library does not provide you with a selectable text, but it is easier to implement.
Here is a DEMO of how you could create a selectable text.
// 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);
It is possible. Here's an example using an svg
with a foreignObject
straight from the 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>
In one of my canvas projects I needed to create highlight-able, editable, and copy-able text area generated on click and removed when the text area loses focus. Below is the structure of how I did it
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;
}
This allows only one text area to be created and is created on click and removed when it loses focus. Not sure if you want this functionality, but it's easy to remove if not
Demo here (WiP) when you click on the value to the right of one of the bars
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With