Reputation: 2200
I found this code on the internet and have been playing around with it. It adds text to any point on a canvas. This is great however when new text is added to the canvas the previous text is deleted. Is there an easy way for multiple instances of text to exist on the canvas simultaneously?
I'm new to JS and can't see anything in the code that deletes the text once new text is saved. I'm really hoping that I won't have to save all the text in an array along with the x and y coordinates, I'm nowhere near skilled enough to do that.
The code I'm using is below, but wont work without some external JS, so here is a link to the working version I copied it from. http://oldstatic.travisberry.com/demos/canvas-text-demo/index.html
Thanks in advance for any suggestions
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="css/css.css">
</head>
<body>
<div id="main">
<canvas id="c"></canvas><!-- the canvas -->
</div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<script type="text/javascript" src="text.js"></script><!-- Library to help text -->
<script type="text/javascript">
$('#c').mousedown(function(e){
if ($('#textAreaPopUp').length == 0) {
var mouseX = e.pageX - this.offsetLeft + $("#c").position().left;
var mouseY = e.pageY - this.offsetTop;
//append a text area box to the canvas where the user clicked to enter in a comment
var textArea = "<div id='textAreaPopUp' style='position:absolute;top:"+mouseY+"px;left:"+mouseX+"px;z-index:30;'><textarea id='textareaTest' style='width:100px;height:50px;'></textarea>";
var saveButton = "<input type='button' value='save' id='saveText' onclick='saveTextFromArea("+mouseY+","+mouseX+");'></div>";
var appendString = textArea + saveButton;
$("#main").append(appendString);
} else {
$('textarea#textareaTest').remove();
$('#saveText').remove();
//$('#textAreaPopUp').remove();
var mouseX = e.pageX - this.offsetLeft + $("#c").position().left;
var mouseY = e.pageY - this.offsetTop;
//append a text area box to the canvas where the user clicked to enter in a comment
var textArea = "<div id='textAreaPopUp' style='position:absolute;top:"+mouseY+"px;left:"+mouseX+"px;z-index:30;'><textarea id='textareaTest' style='width:100px;height:50px;'></textarea>";
var saveButton = "<input type='button' value='save' id='saveText' onclick='saveTextFromArea("+mouseY+","+mouseX+");'></div>";
var appendString = textArea + saveButton;
$("#main").append(appendString);
}
});
function saveTextFromArea(y,x){
//get the value of the textarea then destroy it and the save button
var text = $('textarea#textareaTest').val();
$('textarea#textareaTest').remove();
$('#saveText').remove();
$('#textAreaPopUp').remove();
//get the canvas and add the text functions
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');
var cw = canvas.clientWidth;
var ch = canvas.clientHeight;
canvas.width = cw;
canvas.height = ch;
//break the text into arrays based on a text width of 100px
var phraseArray = getLines(ctx,text,100);
// this adds the text functions to the ctx
CanvasTextFunctions.enable(ctx);
var counter = 0;
//set the font styles
var font = "sans";
var fontsize = 12;
ctx.strokeStyle = "rgba(0,0,0,1)";
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
ctx.shadowBlur = 0;
ctx.shadowColor = "rgba(0,0,0,1)";
//draw each phrase to the screen, making the top position 20px more each time so it appears there are line breaks
$.each(phraseArray, function() {
//set the placement in the canvas
var lineheight = fontsize * 1.5;
var newline = ++counter;
newline = newline * lineheight;
var topPlacement = y - $("#c").position().top + newline;
var leftPlacement = x - $("#c").position().left;
text = this;
//draw the text
ctx.drawText(font, fontsize, leftPlacement, topPlacement, text);
ctx.save();
ctx.restore();
});
//reset the drop shadow so any other drawing don't have them
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
ctx.shadowBlur = 0;
ctx.shadowColor = "rgba(0,0,0,0)";
}
function getLines(ctx,phrase,maxPxLength) {
//break the text area text into lines based on "box" width
var wa=phrase.split(" "),
phraseArray=[],
lastPhrase="",
l=maxPxLength,
measure=0;
ctx.font = "16px sans-serif";
for (var i=0;i<wa.length;i++) {
var w=wa[i];
measure=ctx.measureText(lastPhrase+w).width;
if (measure<l) {
lastPhrase+=(" "+w);
}else {
phraseArray.push(lastPhrase);
lastPhrase=w;
}
if (i===wa.length-1) {
phraseArray.push(lastPhrase);
break;
}
}
return phraseArray;
}
</script>
<script src="js/text.js"></script>
<script src="js/js.js"></script>
</body>
Upvotes: 1
Views: 2105
Reputation:
The reason is that the canvas size is set for each time. When that happens:
When the user agent is to set bitmap dimensions to width and height, it must run the following steps:
...
3. Resize the scratch bitmap to the new width and height and clear it to fully transparent black.
So the first thing to do is to preset the size on the canvas element either in the element tag (as shown below) or in a parent scope in the code:
<div id="main">
<canvas id="c" width=500 height=300></canvas> <!-- any size you want -->
</div>
Then remove these lines from the JavaScript:
function saveTextFromArea(y,x){
...snipped for example...
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');
var cw = canvas.clientWidth;
var ch = canvas.clientHeight;
//canvas.width = cw; // remove this line
//canvas.height = ch; // remove this line
...snipped for example...
Upvotes: 2