How to get rotated image with html2canvas - javascript

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.

Related

Zoom image given x and y

I have an image which as a "ruler" (made of basic divs positioned absolute on top of the image) that are use to measure the ends of the image. Now the idea is that if you long press one of the ruler ends (the dots at the end of the line which are draggable), the image in the background would zoom in that point, and follow the dot if the user moves it. I am able to detect the long press but I cannot get the image to zoom and follow the dot once detected. The code below is where I have done the detection and now I should apply the styling to move the image. I thought of using the transition property but couldn't get it to zoom on the dot. Any help is appreciated...
Here's a codesandbox with how the ruler works: Link
Meaningful code:
const x = get('x', varToUse); //This just gives the x coordinate of the ruler end
const y = get('y', varToUse); //This just gives the y coordinate of the ruler end
const image = ruler.current.parentElement.parentElement.childNodes[1].childNodes[1];
if (zoom) {
image.style.transform = `translate(${x * 2}px, ${y * 2}px) scale(2.0)`;
} else {
image.style.transform = `scale(1.0)`;
}
This is what the ruler looks like just to get an understanding:
You can make the image a div with background-image.
.image {
background-image: url({image_url});
}
so this way you can update the image size and position easily with this properties
.image {
background-size: x y;
background-position x y;
}
I think this way is easier to do the image resizing and zoom abilities.
another way is to use a canvas library that can help you a lot they have lots of built in functions.
I think trying it without library is better for now but as it grows try to move to a canvas library
The first reason is that in the code you provided, the DOM element that is being manipulated is a div id='root'. The image should be selected.

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

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

Image within a div - faded edges

I have an image that was changed through Javascript and that image is placed on top of a background image, however when I look at it on the site you can see a clear square where the image was placed.
I wanted to know if there is a way to fade the images edges and have the background come in, making it look one.
Sidenote. I also wish to avoid JQuery at this time, If possible I would like to achieve this through javascript.
Here you can see the site page: http://imgur.com/a/vC9VV
Javascript code:
// attempting to move the images only
var y = document.getElementById("pic2");
// Sorted by pathing the image to the folder ( can use .. to get in the folder)
y.setAttribute("src", "../images/water_image1.png");
y.style.cssFloat = 'right';
// change the images to the same size as the replacing pic
y.style.width = "400px";
y.style.height = "250px";
// This is sorting out the alignment with the text
y.style.margin = "110px 20px 10px";
y.style.opacity = "0.8";
You could loop through each pixel of image and set the value of its alpha channel depending on distance to closest border of image, then render the result on <canvas>.
For easier but less generic approaches, take a look at this.

How do I save canvas display to transparent PNG?

If you click Run code snippet in this link, it shows a cool usage of <canvas> where you can "cut-out" part of the image (just drag your mouse on the image to "cut"). I'm just curious if there is any way to save the resulting "cut-out" part of the image, as a transparent PNG (i.e. everything that is white in the canvas would be transparent).
If anyone can point me in the right direction (or tell me it's not doable), I'd appreciate it.
Yes, there is a way. Use canvas context.getImageData to get image raw data-array. Do with it(raw data) what you need(make transparent any pixel you need), and then use context.putImageData to render data on canvas. Then use var data = canvas.toDataURL("image/png") to get image data. And then you can do so: image.src = data;
Use this link https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/getImageData for more info
Here's a quick tour showing how to crop & save a user-dragged cutout of an image:
Draw the image on the canvas.
Listen to mouse events and let the user define the region they want to cut out by continuously connecting new lines to the current mouse position.
Save every mouse point from #2 in an array.
When the user has finished defining their cutout region:
Clear the canvas.
Draw and fill the cutout area using the saved points in the arry.
Set context.globalCompositeOperation='source-in'. This mode will cause any new drawings to appear only where the newly drawn pixels and the existing pixels overlap and every thing else is made transparent. In common terms: New pixels will be "clipped" into the user defined cutout and new pixels will not appear outside the cutout.
Redraw the image.
The result is the second drawing of the image will appear only inside the user defined cutout. Everything else will be transparent.
Finally, you can use var url=canvasElement.toDataURL to save the cropped canvas image into a .png dataURL. If you then want an actual image from this dataURL you can var img=new Image() and set the img.src=url.

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