Attempting to create a single map image from tiles using canvas element - javascript

I have a bunch of png map tiles that I am trying to stitch together on a canvas element.
jsFiddle
I am making a 10x10 tile with a counter from 0 to 99 (id) to keep track of where I'm up to. This is the line that plots the image:
ctx.drawImage(this, id%10*imgWidth, Math.floor(id/10)*imgHeight, imgWidth, imgHeight);
Where id is some number from 0 to 99, imgWidth is the width of each tile and imgHeight is the height of each tile.
I am reasonably confident that should work, but it appears to just plot one stretched tile on the canvas instead of all 100. When I check the console for what was loaded, the images appear to be the correct shape and contents for each tile. The just don't seem to have been placed on the canvas. Does anyone have any ideas?

One reason to not use jQuery with canvas:
$('canvas').width(imgWidth*10).height(imgHeight*10);
:) as this refers to the element size, not the bitmap. I would suggest using instead:
myCanvas.width = imgWidth*10;
myCanvas.height = imgHeight*10;
Modified fiddle

Related

How to get rotated image with html2canvas

I'm using Guillotine JS to manipulate the image rotation, scale, positions, x,y, when user has finish making changes, I use html2canvas to get the final image generated inside a div, in this case my div has a class .frame, so, when user zoom in or out move left right up, down, I do this:
html2canvas(target, {
onrendered: function(canvas)
{
var data = canvas.toDataURL("image/png");
//console.log(data);
var imgdata = data.replace(/^data:image\/(png|jpg);base64,/, "");
}
})
I have skip a bunch of code this is the only thing I use, with that I get a 64base code for the image inside my div up to this point everything is ok, the generated image is exactly what is need.
The problem is when rotation is apply to the image, for testing I'm using an image with: width: 1036, height: 615px inside a div with: width:676, height:459px.
This is the generated images
Same as before, different area
Same image but this time it has a rotation 180'
same image, rotation 90'
As you can see every time a rotation is use, the result are wrong.
How can I fix that?
I have used Imagemagick to rote and crop the image using guillotine data, the problem here is that the scale is all messup image width * scale only gives 1 x 1px image as a final result, if I hardcode the width and height the result is the same, so I'd love to find a way to fix the rotation with html2canvas.

Rotating Image on Canvas

In my web app I am allowing users to choose images. If the height of the image is greater than the width then I rotate the image by 270 degrees.
I am confuse about what should be the ideal size for the rotated image as I would be saving that rotated image later on.
For example if a user upload a image with low resolution what should be the size there and what if the user uploads an image with a high revolution what would be the size than?
I don't want the pixels to be distorted. Any good library to rotate image on the client side? Or any algorithm which can help me?
You could try the naive canvas approach like this:
Basically you'll be drawing the image on a canvas, rotated, then saving the canvas to a dataUrl
var context = canvas.getContext('2d');
//save the context
//pushes a Matrix on the transformation stack
context.save();
context.translate(x, y); //where to put image (in the canvas)
context.rotate(angle); //angle in degrees (i think...)
context.scale(scale); //optional scale
//rotate around center of image
context.drawImage(bitmap, -image.width / 2, -image.height / 2);
//or rotate around top left corner of image
context.drawImage(image, 0, 0);
//restore the canvas
//pop a matrix off the transformation stack
context.restore();
//now save the canvas to a data url for download or to display in an image object / tag
var data = canvas.toDataUrl();
References:
https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Transformations
https://developer.mozilla.org/en/docs/Web/API/HTMLCanvasElement
http://html5.litten.com/understanding-save-and-restore-for-the-canvas-context/
you can use Blob object approach. Convert the image to blob objects and you can play with it. I cant help with code coz am not much aware of blobs. Please do more research on blobs and you can achieve what you want to do using Blobs.

Scaling a canvas to full screen really decreases the resolution

I'm trying to make a full screen game to help me learn JS. I made a canvas item and streched it to the size of the screen using CSS. Then I draw a circle. The issue I have is that the circle looks terrible!
_draw.arc(20, 20, 10, 0, 2 * Math.PI);
Here is a jsfiddle example. http://jsfiddle.net/H5dHD/152/
I've tried using different scale factors (so _draw.scale) but it dosent seem to matter...
What am I doing wrong?
P.S. I know the coordinates are off. I didn't include that code for the example.
The problem is that you resized the canvas using the CSS-style, and do not change the actual width and height. When you use CSS styling to change the size, the canvas will be stretched, but the internal drawing resolution stays the same. The result is that the canvas blurs.
To change the internal resolution, change the width and height attributes of the canvas HTML element itself.
document.getElementById('iDraw').height = screen.availHeight;
document.getElementById('iDraw').width = screen.availWidth;
Here is your updated fiddle:
http://jsfiddle.net/H5dHD/154/

canvas - layer small image on larger background image, merge to single canvas pixel data

How do I merge a smaller image on top of a larger background image on one canvas. The smaller image will move around. So I will need to keep reference of the original background pixel data, so that the each frame the canvas can be redrawn, with the overlay in its new position.
BgImage: 1280 x 400, overlayImage: 320 x 400, overlayOffsetX: mouseX
I think it is common to draw whole scene each time you want to change something, so:
context.drawImage(bgImage, 0, 0);
context.drawImage(overlayImage, overlayOffsetX, 0);
UPDATE
You could manually compose image data of two images with making copy of background image data
or
do something easier, probably faster. You could create new canvas element (without attaching to the document) which would store image data in easy to manage form. putImageData is good if you want to place rectangular image into the canvas. But if you want to put image with transparency, additional canvas will help. See if example below is satisfying you.
// preparation of canvas containing data of overlayImage
var OVERLAY_IMAGE_WIDTH = 320;
var OVERLAY_IMAGE_Height = 400;
var overlayImageCanvas = document.createElement('canvas');
overlayImageCanvas.width = OVERLAY_IMAGE_WIDTH;
overlayImageCanvas.height = OVERLAY_IMAGE_HEIGHT;
overlayImageCanvas.getContext('2d').putImageData(overlayImage, 0, 0);
// drawing scene, execute this block every time overlayOffsetX has changed
context.putImageData(bgImage, 0, 0);
context.drawImage(overlayImageCanvas, overlayOffsetX, 0);

Click on given element in canvas

Is there any trick to determine if user clicks on given element rendered in canvas? For example I'm displaying rhombus from .png file with transparent background and i want to know if user click inside or outside that figure (like mouse-element collision).
There is no concept of individual elements in a canvas - it is simply just an area that you're drawing pixels onto. SVG on the other hand is made up of elements which you can then bind events to. However there are a few approaches you can take to add click events to canvas:
Position an html element that overlays the area on the canvas you want to be clickable. A for a rectangular area or an image map for something more irregular.
Use separate canvases for each element that you want to be clickable.
CAKE - I haven't used this myself, but it's description is "SVG sans the XML". This may cover your needs. Demos here http://glimr.rubyforge.org/cake/canvas.html#EditableCurve
One idea is to draw the image to a temporary canvas, then use getImageDate() to receive data for the pixel you are interested in, and check if its alpha value is 0 ( = transparent).
The following is a sketch of a solution. It is assumed that...
x and y are the coordinates of the mouse click event
you are looping over gameObjects, the current object being stored in the variable gameObject
the game object has been initialized with an image, x and y coordinates
The following code would then check whether the click was on a transparent area:
var tempCanvas = document.createElement('canvas');
if (tempCanvas.getContext) {
tempContext = tempCanvas.getContext('2d');
}
tempContext.drawImage(gameObject.img, 0, 0);
var imgd = tempContext.getImageData(x - gameObject.x, y - gameObject.y, 1, 1);
var pix = imgd.data;
if (pix[3] == 0) {
// user clicked on transparent part of the image!
}
Note: This is probably quite inefficient. I'm sure someone can come up with a better solution.
I have solve this problem using kintech.js, tutorials and examples can be found: http://www.html5canvastutorials.com/kineticjs/html5-canvas-drag-and-drop-tutorial/

Categories

Resources