Move canvas element into desired position - javascript

I've tried to look for the answer to this everywhere but I don't seem to find it. But I want to move the text created from an input to a specific position in the canvas, say, on the top centre.
The code runs like this: (JSFIDDLE)
<canvas id="canvas" style="background-color: #000" width="800px" height="300px"></canvas>
<input type="text" id="header-text" placeholder="Your Title">
Meanwhile, the js looks like:
var canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d');
document.getElementById('header-text').addEventListener('keyup', function() {
var stringTitle = document.getElementById('header-text').value;
console.log(stringTitle)
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = '#fff';
ctx.font = 'bold 36px Arial';
ctx.textAlign = 'center';
var text_title = stringTitle;
ctx.fillText(stringTitle, 15, canvas.height / 2 + 35);
});
Is there a way where I can move the text generated to the top centre? Thanks!

Well, you can use math to calculate the right position.
You used:
ctx.fillText(stringTitle, 15, canvas.height / 2 + 35);
so to change the text position to top center you can use something like this:
ctx.fillText(stringTitle, canvas.width/2, canvas.height / 8 + 35);

To have text in top center:
ctx.fillText(stringTitle, canvas.width / 2, 36);
Where 36 is size of your font (height).
If you need more precision while positioning text horizontally, you could use
CanvasRenderingContext2D.measureText().

Related

Copying between two canvas causes blur

I have two canvases. When I use drawImage() to copy from one canvas to the other, it is blurring the image slightly.
Why is this happening?
This seems like the kind of thing that occurs when theres some sub-pixel rounding. Maybe this is caused by the 45 degree 'rotation'?
Here is an example showing it occur:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var tempCanvas = document.getElementById("tmpCanvas");
var tempCtx = tempCanvas.getContext("2d");
canvas.width = canvas.height = 200;
tempCanvas.width = canvas.width;
tempCanvas.height = canvas.height;
// translate origins
ctx.translate(canvas.width / 2, canvas.height / 2);
tempCtx.translate(canvas.width / 2, canvas.height / 2);
// Create a red square
ctx.fillStyle = "rgba(255,0,0, 0.1)";
ctx.fillRect(-50, -50, 100, 100);
var angle = 0;
// Each draw we copy the current canvas to the tmpCanvas. Then copy it back to the original canvas.
function draw() {
angle += 45;
tempCtx.save();
tempCtx.rotate(angle * Math.PI / 180);
tempCtx.drawImage(
canvas,
0, // sourceX
0, // sourceY - note that source ignores translation. It's not a canvas context, so we choose top left corner of the canvas to start copying pixels.
canvas.width, // sourceWidth
canvas.height, // sourceHeight
-0.5 * canvas.width, // destinationX
-0.5 * canvas.height, // destinationY
canvas.width, // destinationWidth
canvas.height // destinationHeight
);
tempCtx.restore();
ctx.drawImage(
tempCanvas,
0,
0,
canvas.width,
canvas.height,
-0.5 * canvas.width,
-0.5 * canvas.height,
canvas.width,
canvas.height
);
// requestAnimationFrame(draw);
}
document.addEventListener("click", draw);
canvas {
border: 1px solid blue;
}
<p>
Click to trigger a "draw".
<br/>
A draw will do this:<br/>
1. rotate the bottom canvas by 45 degrees.<br/>
2. copy the top canvas to the bottom canvas<br/>
3. copy the bottom canvas to the top canvas<br/>
</p>
<br/>
<p>
Clicking repeatedly will "blur" the squares. Why?
</p>
<br/>
</p>
<canvas id="canvas"></canvas>
<canvas id="tmpCanvas"></canvas>
This is just antialiasing in action. When rotating twice by 45 degrees, the antialised edges fall slightly outside the original square, and these add up over time.
My goal is to make a canvas where you can draw on it, as the existing contents rotate about the origin.
You can make the drawing actions happen on the original canvas (apply the inverse rotation to the position of the mouse), and then repeatedly draw the original canvas rotated to the output canvas. Data flows in just one direction, from the original to the output, so there's no degradation.

Vertically Centering Text In Canvas Based on Font Size [duplicate]

This question already has answers here:
Center (proportional font) text in an HTML5 canvas
(7 answers)
Closed 6 years ago.
How do you vertically align text in canvas, based on the font size assigned? For instance, I have a rectangle with the height of 100px, and the variable textSize. My goal is to always vertically center the text inside of this specific rectangle.
Link to JS Fiddle
HTML
<canvas id="canvas" width="500" height="100"></canvas>
JS
var textSize = 40;
function init() {
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.lineTo(0, 100);
ctx.lineTo(0, 0);
ctx.lineTo(500, 0);
ctx.lineTo(500, 100);
ctx.closePath();
ctx.fillStyle = "#000";
ctx.fill();
ctx.closePath();
// Text
ctx.save();
ctx.font = textSize + "px 'Oswald'";
ctx.fillStyle = "#fff";
ctx.textBaseline="middle";
ctx.fillText("Hello, World", 100, (100 - textSize)/2);
ctx.restore();
}
window.onload = init();
This answer might help
The canvas's context has a measureText function which you can use.
When you are using textBaseline= "middle" Why you are calculating the y coordinate considering textSize?
Probably
ctx.fillText("Hello, World", 100, 50);
This will do the job for you.

How to center canvas javascript, dynamically based on text length

I want to center "My TEXT!" no matter the length of the string... As the length of the text gets longer, the x coordinate needs to get less.
How can I get the x length of a string?
<html>
<head>
<script>
window.onload = function(){
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
var imageObj = new Image();
imageObj.onload = function(){
context.drawImage(imageObj, 0, 0);
context.font = "12pt Arial";
context.fillText("My TEXT!", 20, 20);
};
imageObj.src = "http://images.google.com/intl/en_ALL/images/srpr/logo11w.png";
};
</script>
</head>
<body>
<canvas width="282px" height="177px" id="myCanvas"></canvas>
</body>
</html>
Simply add this to your code:
imageObj.onload = function(){
context.drawImage(imageObj, 0, 0);
context.font = "12pt Arial";
/// set text alignment to center
context.textAlign = 'center';
/// draw from center
context.fillText("My TEXT!", canvas.width * 0.5, 20);
};
If you need to get the x coordinate itself you'd need to calculate it based on the width of the text (after the font is set):
var width = context.measureText(myText).width;
var x = (canvas.width - width) * 0.5;
Try setting the text alignment.
context.textAlign = "center";
context.fillText("My LONGGGGG TEXT!", (canvas.width)/2, 20);
This should be what you are looking for. http://www.html5canvastutorials.com/tutorials/html5-canvas-text-align/
There's a textAlign property on canvas that you can set to "center". Then start the fill text in the exact middle of the canvas.
EDIT - Here's a fiddle http://jsfiddle.net/mlienau/2MnnC/

How to detect if a mouse pointer hits a line already drawn on an HTML 5 canvas

I am trying to figure out how one can detect if the user's mouse hits a line on an HTML 5 canvas with jQuery.
Here is the code that generates the canvas lines:
<canvas id="myCanvas" width="400" height="400" style="border:1px solid #c3c3c3;">
Your browser does not support the canvas element.
</canvas>
<script type="text/javascript" src="js/jquery-1.4.2.min.js"></script>
<script type="text/javascript">
window.onload = function(){
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.moveTo(40,0);
ctx.lineTo(40,360);
ctx.stroke();
ctx.moveTo(80,400);
ctx.lineTo(80,40);
ctx.stroke();
ctx.moveTo(120,0);
ctx.lineTo(120,360);
ctx.stroke();
ctx.moveTo(160,400);
ctx.lineTo(160,40);
ctx.stroke();
};
</script>
I'm using a modified jQuery script that I actually found in another question on here, but now I can't figure out how to detect the line, mainly the difference in color from white to black, in the canvas. I know that this can be done with images, but I haven't seen anyone with something like this.
I guess my real question is, is there a way to detect color changes on a canvas element with jQuery?
Its possible to do with javascript. In fact you aren't using any jQuery in your example above. An easy way to do it is by grabbing the pixel data from the canvas, and checking the alpha at the specified x and y position. If the alpha isn't set to 0, then you have something drawn on the canvas. Below is a function I put together real quick that does that.
Live Demo
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d"),
width = 400;
height = 400;
canvas.width = canvas.height = 200;
// draw
ctx.moveTo(40, 0);
ctx.lineTo(40, 360);
ctx.stroke();
ctx.moveTo(80, 400);
ctx.lineTo(80, 40);
ctx.stroke();
ctx.moveTo(120, 0);
ctx.lineTo(120, 360);
ctx.stroke();
ctx.moveTo(160, 400);
ctx.lineTo(160, 40);
ctx.stroke();
function detectLine(x, y) {
var imageData = ctx.getImageData(0, 0, width, height),
inputData = imageData.data,
pData = (~~x + (~~y * width)) * 4;
if (inputData[pData + 3]) {
return true;
}
return false;
}
canvas.addEventListener("mousemove", function(e){
var x = e.pageX,
y = e.pageY;
console.log(detectLine(x, y));
});
console.log(detectLine(40, 100));
console.log(detectLine(200, 200));

text is grainy/blurry when drawing text on a canvas via onload

If I try to draw text to my canvas at the onload event, the text shows up blurry. I draw to the same canvas later via a button click from another function and it's fine. But if I call this function from the button, it's still blurry. Can anybody see something wrong in this code?
window.onload = initCanvasRender;
function initCanvasRender() {
var c = document.getElementById("canvas");
var ctx = c.getContext('2d');
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillStyle = 'black';
ctx.font = '20px Times New Roman';
ctx.fillText('hello...', c.width/2, c.height/2);
}
There may be some problem with the
ctx.fillText('hello...', c.width/2, c.height/2);
Because if you for example set width of the canvas with css then c.width and c.height will be the default size for the canvas which is, 300x150 and not the size defined in css. Try to set two variables for the width and height that are global for your application. E.g
var canvasWidth = 400;
var canvasHeight = 200;
c.width = canvasWidth;
c.height = canvasHeight;
/* ... */
and then later in your code you can use canvasWidth and canvasWeight:
ctx.fillText('hello...', canvasWidth/2, canvasHeight/2);
Take a look at this test: http://jsfiddle.net/EsQfb/7/ it's important to use use the canvas.width and not canvas.style.width in your case.
Take a look at this for more information about this: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#attr-canvas-width

Categories