Html5 detecting draw string length with javascript - javascript

Casually i would detect the width and height of a string by doing this..
canvas.getContext("2d").font="12px Arial";
canvas.getContext("2d").fillStyle = "red";
canvas.getContext("2d").fillText("StackOverflow",x,y);
var width = canvas.getContext('2d').measureText(ct_string).width;
however, i need to calculate the width before i draw it into the canvas so i can do this..
canvas.getContext("2d").fillText("StackOverflow",x - width,y);
Would love some help on this, maybe i am not understanding the measureText fully, i believe it can only be used after the string has been drawn to the canvas though i am not certain.
( i am programming without a server and can not test the code i am running ).
Creating a second html5 canvas is out of the question.
I need a better understanding

Related

HTML5 Canvas efficiency of panning image by Translate vs. Clipping

There's a bunch of questions on panning a background image in a canvas (i.e. to simulate a 'camera' in a game with the character in the center) - and most answers suggest using the canvas' translate method.
But since you have to re-draw the image in each frame anyway, why not just clip it? Does it matter in terms of efficiency?
In particular, is panning like this a bad idea? (This example shows a simplified pan of the camera moving in one direction)
let drawing = new Image();
drawing.src = "img_src";
drawing.onload = function () {
ctx.drawImage(drawing, 0, 0);
let pos = 0
setInterval(() => {
pos += 1
ctx.clearRect(0, 0, cnvs.width, cnvs.height);
ctx.drawImage(drawing, -pos, 0 ); // "pans" the image to the left using the option `drawImage` parameters `sx` and `sy`
}, 33);
};
Example result: fiddle
Thanks in advance!
The main advantage of using the transform matrix to control your camera is that you don't have to update all the elements in your world, you just move the world instead.
So yes, if you are willing to move only a single element (be it the background like in your case), moving only that one element might be a better choice.
But if you need several layers of elements to all move relatively to the camera, then using the transformation matrix is a better choice.
As for the perfs, I didn't ran any benchmarks on this, but I'd suspect it's exactly the same, though beware when messing with the cropping features of drawImage, at least Safari doesn't handle cropping from outside of a source canvas correctly.

Apply zoom in center of the canvas

I need to apply zoom to the javascript canvas which I have badly accomplished by using the following line of code:
ctx.scale(2,2) //doubles everything's size
Instead of zooming, its obviously doubling the size of the canvas and all of its elements. I'd be okay with this if I got it working like the image below shows:
Any ideas on how I could accomplish what is depicted in the picture above? I'm not using any external libraries hence making this so difficult. Thanks.
You can translate the context by half the canvas size using ctx.translate()
EDIT :
var zoomfactor = 2; //set whatever you want as zoom factor
ctx.transform(zoomfactor,0,0,zoomfactor,-(zoomfactor-1)*canvas.width/2,-(zoomfactor-1)*canvas.height/2)

Animating a missile in HTML5/WinJS

I'm writing a game using HTML5/WinJS on Windows 8. I'm trying to produce the effect of a bullet or missile firing at something; however, I can't seem to get the object to go through another image in the background without trailing a border. My working theory is that the border I'm seeing is caused by using clearRect. Here's my code:
var moveBullet = function(missile) {
if (missile.Image == undefined || missile.Image == null) {
var image = new Image();
image.src = "/images/missileImg.png";
image.onload = function () {
canvasContext.clearRect(missile.PointX - (image.width / 2), missile.PointY, image.width, image.height);
missile.PointY += BULLET_SPEED;
canvasContext.drawImage(image, missile.PointX - (image.width / 2), missile.PointY);
};
} else {
canvasContext.clearRect(missile.PointX - (missile.Image.width / 2), missile.PointY, missile.Image.width, missile.Image.height);
missile.PointY += BULLET_SPEED;
canvasContext.drawImage(missile.Image, missile.PointX - (missile.Image.width / 2), missile.PointY);
}
}
Is there a way to achieve this effect without using clearRect, or a more efficient way of restoring the background as it moves past?
Make your clearRect area a few pixels larger than the missile image. Drawing on a canvas in general has some built-in anti-aliasing. This means that if you draw a line with one color, then draw the same line with the background color, you'll not remove the original line. Something similar might be happening here, in which case a few extra pixels should help.
That said, there's a caveat to be aware of here.
First, I assume the background is separate element from the canvas? It looks like it as you're not redrawing that part on the canvas itself.
The reason I ask is that making repeated calls to clearRect on the same canvas will eventually show performance problems. What happens is that every call to clearRect accumulates into a complex region within the canvas--essentially its transparency mask. So every time the canvas has to be rendered, which happens any time you change it, it has to process that transparent area. Gradually, as you leave more and more small clearRect trails across the canvas, this region will become more and more complex and performance will drop.
I did this experiment with the Blizzard demo on the IE Test Drive site once, where I wondered why the demo was clearing the entire canvas with every animation frame. So I tried just clearing the trail behind each snowflake (and made each one a little bigger as I suggest above, because I had trails). Seemed like the right thing to do, but the performance plummeted by several orders of magnitude. Asking around within the IE team, they confirmed the region behavior I describe.
So the best thing to do, actually, is to do a clearRect on the entire canvas with every frame, then redraw the missile and any other bits that you're animating. This may seem counter intuitive, but ends up working best and avoids all these glitches with pixel trails.

ThreeJS render text in canvas as texture and then apply to a plane?

I've been looking all day for a way to procedurally generate 2d texture with text in them so that I can apply them as a texture to a plane. Basically, I want to be able to change what text shows up in my WebGL page without having to just use texture made in an image editing program. I'm aiming to be able to edit the content of the page just as easily as with a totally 2d page, just edit the code and bam, it's there.
The most promising method I've seen to accomplish this is to render the text in a blank canvas with CSS, use that canvas as a texture which ThreeJS makes very easy, and then apply that texture to a plane that I can place wherever in the 3d environment.
I've attempted to accomplish this by adapting this example to my needs: http://jsfiddle.net/sSD65/28/
However, I end up with a totally black page, indicating an error somewhere. An error that I cannot, for the life of me, find and fix. I have a feeling I'm missing something because of my lack of experience with ThreeJS and in fact Javascript in general so I've come here to ask for your help.
I really appreciate any help I can get here.
Here's a link to the page, although I don't think you will be able to view it properly without hosting it locally since I'm loading an image from a folder there, but Python is wonderful for that. Just use Python -m SimpleHTTPServer in the console once you've navigated to that folder and it will host it locally so that you can access it from "http://localhost:8000/homepage.html": https://dl.dropbox.com/u/40043006/WebGLTest.zip
This is a simple code to add text from a canvas as a texture:
//create image
var bitmap = document.createElement('canvas');
var g = bitmap.getContext('2d');
bitmap.width = 100;
bitmap.height = 100;
g.font = 'Bold 20px Arial';
g.fillStyle = 'white';
g.fillText(text, 0, 20);
g.strokeStyle = 'black';
g.strokeText(text, 0, 20);
// canvas contents will be used for a texture
var texture = new THREE.Texture(bitmap)
texture.needsUpdate = true;
it needs some work... like setting the output text size to the canvas' size.

Drawing on the canvas with a "pencil"

I made a script that draws a series of lines on a canvas that makes it look like a sketch. There are two issues with the script. One, why is the y value twice as much as it should be? And two, why is the line several pixels wide and faded out?
I've tried it in both Google Chrome and Firefox and I get the same incorrect results. I realize that I can divide the y value by two to fix the first problem but that part of my question is why do I need to do that. I shouldn't have to.
I think you have two issues:
You need to be more careful in how you calculate the offset of where to draw. I have some code below that demonstrates how to handle this properly.
You aren't setting the width and height on the <canvas> element itself, which means it will scale your lines in funny ways depending how what you've set in your css.
An Example
I built a simple collaborative drawing app using <canvas> and socket.io that lets you draw to the screen like a pencil. You can check it out here:
http://xjamundx.no.de/
The source is also on github if that might help:
https://github.com/xjamundx/CollabPaintJS/ (main repo)
https://github.com/xjamundx/CollabPaintJS/blob/master/public/collabpaint.js (canvas drawing code)
In particular I do something like this to figure out where to draw things:
x = e.clientX + window.scrollX
y = e.clientY + window.scrollY
x -= $game.offsetLeft
y -= $game.offsetTop
Give a width and a height to your canvas; always !
http://jsfiddle.net/mz6hK/7/
fixed

Categories

Resources