Canvas. Align text - javascript

This code would satisfy me but for the text alignment. Both the top line and bottom line are not aligned in the center of the lines. Could you help me here?
function redrawMeme(image, topLine, bottomLine) {
var canvas = document.querySelector('canvas');
var ctx = canvas.getContext("2d");
ctx.textAlign = "center";
var height = Math.min(image.height, canvas.height);
var width = Math.min(image.width, canvas.width);
ctx.drawImage(image, 0, 0, width, height);
var font = "bold 24px verdana, sans-serif ";
ctx.font = font;
var fillStyle = "white";
ctx.fillStyle = fillStyle;
var strokeStyle = "black";
if (topLine) {
ctx.fillText(topLine, 50, 50);
ctx.strokeText(topLine, 50, 50);
};
if (bottomLine) {
ctx.fillText(bottomLine, 50, 350);
ctx.strokeText(bottomLine, 50, 350);
};
}
// The following code is just for the example:
const img = new Image(500, 500);
img.src = 'https://api.adorable.io/avatars/500/abott#adorable.png';
img.onload = function() {
redrawMeme(img, 'Top', 'Bottom');
}
<canvas id="canvas" width="500" height="500"></canvas>

It is because canvas text is center-aligned, so the left and right ends of each line depends on the text length. You can align them by setting their x coordinates to the center of the width, like this:
function redrawMeme(image, topLine, bottomLine) {
var canvas = document.querySelector('canvas');
var ctx = canvas.getContext("2d");
ctx.textAlign = "center";
var height = Math.min(image.height, canvas.height);
var width = Math.min(image.width, canvas.width);
ctx.drawImage(image, 0, 0, width, height);
var font = "bold 24px verdana, sans-serif ";
ctx.font = font;
var fillStyle = "white";
ctx.fillStyle = fillStyle;
var strokeStyle = "black";
var centerX = width / 2
if (topLine) {
ctx.fillText(topLine, centerX, 50);
ctx.strokeText(topLine, centerX, 50);
};
if (bottomLine) {
ctx.fillText(bottomLine, centerX, 350);
ctx.strokeText(bottomLine, centerX, 350);
};
}
// The following code is just for the example:
const img = new Image(500, 500);
img.src = 'https://api.adorable.io/avatars/500/abott#adorable.png';
img.onload = function() {
redrawMeme(img, 'Top', 'Bottom');
}
<canvas id="canvas" width="500" height="500"></canvas>

Related

Canvas Javascript draw function not working

I am trying to separate canvas context from the actual draw functions but not working. As part of the context I wish to include the ability to resize the canvas which isn't working. The HTML works fine as this is evident with the getElementbyID working. The draw function which works fine is included for reference.
window.onload = function() {
'use strict';
var ctx = getCanvas();
draw(ctx);
}
function getCanvas() {
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var w = canvas.width = 200;
var h = canvas.height = 150;
return ctx;
}
function draw(ctx) {
ctx.fillStyle = 'rgb(200, 0, 0)';
ctx.fillRect(10, 10, 50, 50);
ctx.fillStyle = 'rgba(0, 0, 200, 0.5)';
ctx.fillRect(30, 30, 50, 50);
}
I see no issues with your code. It works as expected.
window.onload = function() {
'use strict';
var ctx = getCanvas();
draw(ctx);
};
function getCanvas() {
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var w = canvas.width = 200;
var h = canvas.height = 150;
return ctx;
}
function draw(ctx) {
ctx.fillStyle = 'rgb(200, 0, 0)';
ctx.fillRect(10, 10, 50, 50);
ctx.fillStyle = 'rgba(0, 0, 200, 0.5)';
ctx.fillRect(30, 30, 50, 50);
}
canvas{border: 1px solid black}
<canvas id="canvas" width="1000" height="1000"></canvas>
note: do not set canvas­'s width and height using css (in first place).

Javascript no shapes appear

I'm trying to just make a rectangle but nothing will appear, just the background. I've tried ctx.fill, ctx.fillStyle etc. nothing works:
I'm refering to this part
fill(77, 66, 66);
rect(10,200,100,100);
Here is the whole code for the page
var ctx, W, H;
window.onload = function() {
var canvas = document.getElementById("canvas");
W = window.innerWidth;
H = window.innerHeight;
canvas.width = W;
canvas.height = H;
ctx = canvas.getContext("2d");
setInterval(draw, 1);
function draw() {
ctx.globalCompositeOperation = "source-over";
ctx.fillStyle = "#E6E6FF"; // this part does appear
ctx.fillRect(0, 0, W, H);
fill(77, 66, 66); // this doesn't appear
rect(10,200,100,100);
}
}
Thanks
You need to call fill and rect on the canvas context.
Also you need to change the fillStyle otherwise you're drawing a rectangle with the same color as the background and it won't show.
var ctx, W, H;
window.onload = function() {
var canvas = document.getElementById("canvas");
W = window.innerWidth;
H = window.innerHeight;
canvas.width = W;
canvas.height = H;
ctx = canvas.getContext("2d");
setTimeout(draw, 1);
function draw() {
ctx.globalCompositeOperation = "source-over";
ctx.fillStyle = "#E6E6FF";
ctx.fillRect(0, 0, W, H);
ctx.fillStyle = "red"; // need this otherwise the rect will be the same color as the background
ctx.rect(10, 200, 100, 100); // needs to be called on the canvas context
ctx.fill(); // needs to be called on the canvas context, it will fill any path not already filled in.
}
}
You are filling both areas with the same color, and you have to use the context to perform fill functions. you also need to create the rect BEFORE you fill it.
Try this on for size: https://jsfiddle.net/szbk6f67/3/
var ctx, W, H;
window.onload = function () {
var canvas = document.getElementById("canvas");
W = 400;
H = 400;
canvas.width = W;
canvas.height = H;
ctx = canvas.getContext("2d");
setInterval(draw, 1);
function draw() {
ctx.globalCompositeOperation = 'source-over';
ctx.fillStyle = 'gray';
ctx.fillRect(0, 0, W, H);
ctx.fillStyle = 'black';
ctx.rect(10, 200, 100, 100);
ctx.fill();
}
}

Javascript/HTML5 - Changing text on mouse event

I am trying to create an HTML5 canvas which displays text and onmouseover will remove that text and display a different bit of text.
This works fine for changing the colour - essentially just creating a new canvas over the current one.
However, onmouseover the new text displays but the previous text remains.
http://jsfiddle.net/3j2b2egb/
HTML:
<body onload="changeBack()">
<canvas id="test"
width="330"
height="200"
style="border:1px solid #787878;"
onmouseover="change()"
onmouseout="changeBack()">
</canvas>
Javascript:
function changeBack() {
var c = document.getElementById("test");
var ctx = c.getContext("2d");
ctx.fillStyle = "blue";
ctx.font = "bold 16px Arial";
ctx.fillText("hello", 100, 100);
}
function change() {
var c = document.getElementById("test");
var ctx = c.getContext("2d");
ctx.fillStyle = "blue";
ctx.font = "bold 16px Arial";
ctx.fillText("world", 100, 100);
}
Try this. I have cleared canvas before drawing it.
function changeBack() {
var c = document.getElementById("test");
var ctx = c.getContext("2d");
ctx.clearRect ( 0 , 0 , c.width, c.height );
ctx.fillStyle = "blue";
ctx.font = "bold 16px Arial";
ctx.fillText("hello", 100, 100);
}
function change() {
var c = document.getElementById("test");
var ctx = c.getContext("2d");
ctx.clearRect ( 0 , 0 , c.width, c.height );
ctx.fillStyle = "red";
ctx.font = "bold 16px Arial";
ctx.fillText("world", 100, 100);
}
Here is working demo http://jsfiddle.net/3j2b2egb/1/

HTML Canvas w/ Image Cloning Issues

I used tips + code from this post to try to clone my original canvas - it contains an image with text overlaid on it. However, every time I run it, neither the image nor the text get copied, though the original works fine. Here is the javascript:
<script>
function CardText() {
var title = document.calform.titleText.value;
var badge = document.calform.badge.value;
var encourage = document.calform.encourage.value;
var description = document.calform.description.value;
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var x = canvas.width / 2;
var y = canvas.height / 2;
var imageObj = new Image();
imageObj.onload = function() {
context.drawImage(imageObj, 0, 0);
context.font = "25pt Helvetica";
context.fillStyle = "white";
context.textAlign = "center";
context.fillText(title, x, 76);
context.font = "18pt Arial";
context.fillStyle = "white";
context.textAlign = "center";
context.fillText(badge, x-10, 311);
context.font = "18pt Arial";
context.fillStyle = "black";
context.textAlign = "center";
context.fillText(encourage, x, 380);
context.font = "12pt Arial";
context.fillStyle = "black";
wrapText(context, description, x, 440, 280, 18);
};
imageObj.src = 'https://i.imgur.com/7wqLgSd.jpg';
}
function cloneCanvas(oldCanvas) {
//create a new canvas
var newCanvas = document.createElement('canvas');
var context = newCanvas.getContext('2d');
//set dimensions
newCanvas.width = oldCanvas.width;
newCanvas.height = oldCanvas.height;
//apply the old canvas to the new one
context.drawImage(oldCanvas, 100, 300);
//return the new canvas
return newCanvas;
}
</script>
And I run it with an html button:
<input class="btn btn-lg btn-primary" align = 'center' type=button name=button1 value="COPY" onClick="cloneCanvas(canvas)">
Any help would be much appreciated!
Edit: markE was kind enough to fix my problem, however it's not coming up within the full HTML document. Here's the full HTML:
<!DOCTYPE html>
<html>
<head>
<style>
body {
background-color:ivory;
padding:10px;
}
#fills {
position: relative;
margin-left: 100px;
}
canvas{
border:1px solid red;
}
</style>
<link href="bootstrap.min.css" rel="stylesheet">
</head>
<body>
<script>
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var imageObj = new Image();
imageObj.onload = function() {
// create the original card canvas
// after the image has loaded
CardText();
// next clone the original card canvas
// to a new canvas
var myNewCanvas=cloneCanvas(canvas);
document.body.appendChild(myNewCanvas);
};
imageObj.src = 'https://i.imgur.com/7wqLgSd.jpg';
function CardText() {
var title ="Title";// document.calform.titleText.value;
var badge ="Badge";// document.calform.badge.value;
var encourage ="Encourage";// document.calform.encourage.value;
var description ="Description";// document.calform.description.value;
var x = canvas.width / 2;
var y = canvas.height / 2;
context.drawImage(imageObj, 0, 0);
context.font = "25pt Helvetica";
context.fillStyle = "white";
context.textAlign = "center";
context.fillText(title, x, 76);
context.font = "18pt Arial";
context.fillStyle = "white";
context.textAlign = "center";
context.fillText(badge, x-10, 311);
context.font = "18pt Arial";
context.fillStyle = "black";
context.textAlign = "center";
context.fillText(encourage, x, 380);
context.font = "12pt Arial";
context.fillStyle = "black";
context.fillText(description, x, 440);
// wrapText(context, description, x, 440, 280, 18);
}
function cloneCanvas(oldCanvas) {
//create a new canvas
var newCanvas = document.createElement('canvas');
var context = newCanvas.getContext('2d');
//set dimensions
newCanvas.width = oldCanvas.width;
newCanvas.height = oldCanvas.height;
//apply the old canvas to the new one
context.drawImage(oldCanvas, 100, 300);
//return the new canvas
return newCanvas;
}
</script>
<div id="fills" >
<td align=right width=200>Title:</td>
<td><input type=text name=titleText size=10 maxlength=10></td>
<td align=right width=200>Badge Name:</td>
<td><input type=text name=badge size=10 maxlength=10></td>
<td align=right width=200>Encouraging Words:</td>
<td><input type=text name=encourage size=10 maxlength=14></td>
<td align=right width=200>Description:</td>
<td><input type=text name=description size=50 maxlength=120></td>
<input class="btn btn-lg btn-primary" align = 'center' type=button name=button1 value="Submit" onClick="CardText()">
</div>
<canvas id="myCanvas" width="390" height="540"></canvas>
</body>
</html>
It looks like you might be calling cloneCanvas before CardText has a chance to fully load the image and draw the text on the image.
Try this refactoring which fully loads the image+text before trying to cloneCanvas.
Example Code and a Demo:
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var imageObj = new Image();
imageObj.onload = function() {
// create the original card canvas
// after the image has loaded
CardText();
// next clone the original card canvas
// to a new canvas
var myNewCanvas=cloneCanvas(canvas);
document.body.appendChild(myNewCanvas);
};
imageObj.src = 'https://i.imgur.com/7wqLgSd.jpg';
function CardText() {
var title ="Title";// document.calform.titleText.value;
var badge ="Badge";// document.calform.badge.value;
var encourage ="Encourage";// document.calform.encourage.value;
var description ="Description";// document.calform.description.value;
var x = canvas.width / 2;
var y = canvas.height / 2;
context.drawImage(imageObj, 0, 0);
context.font = "25pt Helvetica";
context.fillStyle = "white";
context.textAlign = "center";
context.fillText(title, x, 76);
context.font = "18pt Arial";
context.fillStyle = "white";
context.textAlign = "center";
context.fillText(badge, x-10, 311);
context.font = "18pt Arial";
context.fillStyle = "black";
context.textAlign = "center";
context.fillText(encourage, x, 380);
context.font = "12pt Arial";
context.fillStyle = "black";
context.fillText(description, x, 440);
// wrapText(context, description, x, 440, 280, 18);
}
function cloneCanvas(oldCanvas) {
//create a new canvas
var newCanvas = document.createElement('canvas');
var context = newCanvas.getContext('2d');
//set dimensions
newCanvas.width = oldCanvas.width;
newCanvas.height = oldCanvas.height;
//apply the old canvas to the new one
context.drawImage(oldCanvas, 100, 300);
//return the new canvas
return newCanvas;
}
body{ background-color: ivory; padding:10px; }
canvas{border:1px solid red;}
<canvas id="myCanvas" width=390 height=540></canvas>
[ Addition: plugged my answer above into Allen Rabinovich's code. ]
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var imageObj = new Image();
imageObj.onload = function() {
// create the original card canvas
// after the image has loaded
CardText();
};
imageObj.src = 'https://i.imgur.com/7wqLgSd.jpg';
document.getElementById('drawAll').onclick=function(){
CardText();
// next clone the original card canvas
// to a new canvas
var myNewCanvas=cloneCanvas(canvas);
document.body.appendChild(myNewCanvas);
}
function CardText() {
var title=document.getElementsByName('titleText')[0].value;
var badge=document.getElementsByName('badge')[0].value;
var encourage=document.getElementsByName('encourage')[0].value;
var description=document.getElementsByName('description')[0].value;
var x = canvas.width / 2;
var y = canvas.height / 2;
context.drawImage(imageObj, 0, 0);
context.font = "25pt Helvetica";
context.fillStyle = "white";
context.textAlign = "center";
context.fillText(title, x, 76);
context.font = "18pt Arial";
context.fillStyle = "white";
context.textAlign = "center";
context.fillText(badge, x-10, 311);
context.font = "18pt Arial";
context.fillStyle = "black";
context.textAlign = "center";
context.fillText(encourage, x, 380);
context.font = "12pt Arial";
context.fillStyle = "black";
context.fillText(description, x, 440);
// wrapText(context, description, x, 440, 280, 18);
}
function cloneCanvas(oldCanvas) {
//create a new canvas
var newCanvas = document.createElement('canvas');
var context = newCanvas.getContext('2d');
//set dimensions
newCanvas.width = oldCanvas.width;
newCanvas.height = oldCanvas.height;
//apply the old canvas to the new one
context.drawImage(oldCanvas,0,0);
//return the new canvas
return newCanvas;
}
body{ background-color: ivory; padding:10px; }
#canvas{border:1px solid red;}
#fills{ position: relative; margin-left: 100px; }
Title:<input type=text name=titleText size=10 maxlength=10><br>
Badge:<input type=text name=badge size=10 maxlength=10><br>
Encourage:<input type=text name=encourage size=10 maxlength=14><br>
Description:<input type=text name=description size=50 maxlength=120><br>
<input id=drawAll class="btn btn-lg btn-primary" align = 'center' type=button name=button1 value="Submit">
<canvas id="myCanvas" width="390" height="540"></canvas>

Drawing on canvas after resize

I have a canvas element:
<canvas id="canvas" width="100" height="100"></canvas>
And some JavaScript to make canvas full screen:
var canvas, ctx, w, h;
function start() {
canvas = $("#canvas")[0];
ctx = canvas.getContext("2d");
w = $('body').innerWidth();
$("#canvas").width(w);
$("#canvas").height(w);
w = $("#canvas").width();
h = $("#canvas").height();
if(typeof game_loop != "undefined") clearInterval(game_loop);
game_loop = setInterval(paint, 60);
}
function paint() {
ctx.fillStyle = "white";
ctx.fillRect(0, 0, w, h);
ctx.strokeStyle = "blue";
ctx.strokeRect(0, 0, 50, 50);
}
I don't know why I get one big square not 50x50. Can you help?
To actually resize the canvas (as in have more pixles) you'll need to set the width/height attributes. jQuerys width()/height() sets the css values. Resulting in a stretched canvas element consisting of the same number of pixels as before. Instead use:
$('#canvas').prop({
width: 400, // the 400 is just arbitrary
height: 400
});
Or, as per Alnitaks comment, you could of course just as well assign the values directly:
canvas.width = 400;
canvas.height = 400;
Here is a simple example of drawing a square on resize using width/height.
Example: http://jsfiddle.net/Ubv7X/
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var paint = function() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// Draw background
ctx.fillStyle = 'rgb(255, 255, 255)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Draw rect
var rect_size=50;
ctx.fillStyle = 'rgb(0, 0, 255)';
ctx.fillRect(canvas.width/2-(rect_size/2), canvas.height/2-(rect_size/2),
rect_size, rect_size);
}
setInterval(paint, 60);

Categories

Resources