How can one rotate only a part of an image using javascript/jquery on canvas. I have tried to rotate the image with skew and rotate, but I could not find any answer where we can rotate only some part of an image. All the functions that I have used will rotate an image completely. But, the part rotation of an image keeping the rest of it as it is has not been seen yet.
If I want to rotate only half of an image or something like that, how can I achieve it??
Also, the function shall work when the image is rotated, moved as well as resized dynamically.
Crop the image with drawImage() and draw another instance of that image that you can rotate.
//from http://www.html5canvastutorials.com/tutorials/html5-canvas-image-crop/
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var imageObj = new Image();
imageObj.onload = function() {
// draw cropped image
var sourceX = 150;
var sourceY = 0;
var sourceWidth = 75;
var sourceHeight = 150;
var destWidth = sourceWidth;
var destHeight = sourceHeight;
var destX = 0;
var destY = 0;
context.drawImage(imageObj, sourceX, sourceY, sourceWidth, sourceHeight, destX, destY, destWidth, destHeight);
drawRotated(12, imageObj, 225, sourceY, sourceWidth, sourceHeight, 75, destY, destWidth, destHeight);
};
imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg';
//from http://stackoverflow.com/a/17412387/1797161
function drawRotated(degrees, image, sx,sy,sw,sh,dx,dy,dw,dh){
//context.clearRect(0,0,canvas.width,canvas.height);
// save the unrotated context of the canvas so we can restore it later
// the alternative is to untranslate & unrotate after drawing
context.save();
// move to the center of the canvas
context.translate(canvas.width/2,canvas.height/2);
// rotate the canvas to the specified degrees
context.rotate(degrees*Math.PI/180);
context.translate(-canvas.width/2,-canvas.height/2);
// draw the image
// since the context is rotated, the image will be rotated also
context.drawImage(image,sx,sy,sw,sh,dx,dy,dw,dh);
// we’re done with the rotating so restore the unrotated context
context.restore();
}
Here's the fiddle: http://jsfiddle.net/fjhhjh4s/
If i had to make this, i'll use the same image twice: one image full, and a copy with a clipping (css clip property) that i will rotate.
See https://css-tricks.com/clipping-masking-css/
(Sorry to not using comments, i have not the level yet...)
It's possible, but it doesn't seem practical for your project.
You can using a perspective slicing technique:
http://www.subshell.com/en/subshell/blog/image-manipulation-html5-canvas102.html
Ideally you need to define a formula mapping to the original cartesian coordinates from the distorted coordinate system and then iterate over the destination pixel space, using the above mapping to determine the required colour for that pixel.
You would also need to interpolate neighbouring pixels to avoid the output looking "blocky".
This is non-trivial...
You can try OriDomi library if you are looking for crop and animate your image hear is a fiddle.
[Curl image With OriDomi][1]
[1]: https://jsfiddle.net/vipin7/jwqecvt3/17/
Related
Currently I have this code:
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var imageObj = new Image();
imageObj.onload = function() {
context.drawImage(imageObj, 0, 0);
};
imageObj.src = 'assets/img/img.png';
This load an image inside my canvas. After that I have a code which draws some graphics on the image.
Currently I have scaled the image file to be with the size of the canvas. But I would like to have it in much higher resolution like it was originally and to be able to draw on the original one. But show the final image scaled inside the canvas window. How can I achieve that?
I want to set background image to my rectangle in the canvas.
So far i've done this.
var img = new Image()
img.src = //Source of an image.
var newPattern = ctx.createPattern(img, "no-repeat");
ctx.fillStyle = newPattern;
And it works, but the problem is, that it applies the image to the canvas, not to the rectangle.
And whenever I change the position of the rectangle, the image remains in the same position.
Can anybody suggest how to fix this, so the image'd be attached to the rectangle.
If you want to only draw the image within a specified rectangle you can do something like this.
context.rect(x, y, width, height);
context.clip();
context.drawImage(img, 0, 0);
This creates a rectangle at (x, y) with size (width, height) which is used for all future calls to the context. If you want to stop the clipping you will need to add a
context.save();
before the code above and then a
context.restore();
after you have drawn the image.
JSFiddle
Edit: updated to rect
I am trying to make a 2d top-down game in Javascript at the moment. I've currently got a day/night system working where a black rectangle gradually becomes more opaque (as the day goes on) before it finally is fully opaque, simulating the peak of the night where the player can not see.
I want to implement an artificial light system, where the player could use a torch that will illuminate a small area in-front of them. However, my problem is that I don't seem to be able to find a way to 'cut out' a shape from my opaque rectangle. By cutting out a shape, it would look like the player has a torch.
Please find an example mock-up image I made below to show what I mean.
http://i.imgur.com/VqnTwoR.png
Obviously the shape shouldn't be as roughly drawn as that :)
Thanks for your time,
Cam
EDIT: The code used to draw the rectangle is as follows:
context.fillStyle = "#000033";
context.globalAlpha = checkLight(gameData.worldData.time);
context.fillRect(0, 0, 512, 480);
//This is where you have to add the cut out triangles for light!
context.stroke();
Instead of drawing a rectangle over the scene to darken it when the "light" is on, instead draw an image with the "lit" area completely transparent and the rest of the "dark" area more opaque.
One way is to use declare a triangular clipping area and draw your revealed scene. The scene would display only inside the defined clipping area.
Example code and a Demo:
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var x = canvas.width / 2;
var y = canvas.height / 2;
var radius = 75;
var offset = 50;
var img = new Image();
img.onload = function() {
knockoutAndRefill(50,100,300,50,75,350);
};
img.src = 'http://guideimg.alibaba.com/images/trip/1/03/18/7/landscape-arch_68367.jpg';
function knockoutAndRefill(x0,y0,x1,y1,x2,y2){
context.save();
context.fillStyle='black';
context.fillRect(0,0,canvas.width,canvas.height);
context.beginPath();
context.moveTo(x0,y0);
context.lineTo(x1,y1);
context.lineTo(x2,y2);
context.closePath();
context.clip();
context.drawImage(img,0,0);
context.restore();
}
<canvas id=myCanvas width=500 height=400>
I am having trouble rotating an image using an HTML5 canvas. I suppose that I just have the math wrong, and would appreciate any help in getting this right.
On a mobile device I am capturing a user signature on a 150px by 558px canvas. I am than attempting to create a 558px by 150px image that is just the captured signature rotated 90 degrees. Below is a snippet of the code I've currently come up with. As you can likely surmise, I do not have a good grip on the math going into this. I believe I have the procedure correct, just not the numbers.
What I'm trying to do is:
1) set the center of the canvas to the middle, offsetting by the height and width of my image
2) rotate the canvas by 90 degrees
3) draw the image
4) translate the canvas back.
EDIT: Here's a JSFiddle: http://jsfiddle.net/x9FyK/
var $signature = $("#signature");
var signatureData = $signature.jSignature("getData");
console.log(signatureData);
var img= new Image();
img.onload = function() {
var rotationCanvas = document.createElement('canvas');
rotationCanvas.width = img.height;
rotationCanvas.height = img.width;
var context = rotationCanvas.getContext("2d");
context.translate((rotationCanvas.width/2) - (img.width/2), -(rotationCanvas.height/2) - img.height/4);
context.rotate(Math.PI/2);
context.drawImage(img,0,0);
context.translate(-((rotationCanvas.width/2) - (img.width/2)), -(-(rotationCanvas.height/2) - img.height/4));
var rotatedData = rotationCanvas.toDataURL();
...Handling rotated data here
};
img.src = signatureData;
If I can provide any more information, please let me know.
Thanks in advance for your help,
There are several ways of resetting a transformed (translated+rotated) canvas back to its original state.
Low-Pointer's answer is using context.save to save the context in is original un-transformed state and using context.restore to restore the context to its original state after the drawing is done.
The other way it to undo your transforms in the reverse order that they were performed.
Also, note that context.translate will actually move the canvas origin to the center of the canvas. Since images are drawn from their top-left (not their center), you must offset drawImage by half the image width and height if you want the image centered in the canvas.
Here's and example: http://jsfiddle.net/m1erickson/EQx8V/
// translate to center-canvas
// the origin [0,0] is now center-canvas
ctx.translate(canvas.width/2,canvas.height/2);
// roate the canvas by +90% (==Math.PI/2)
ctx.rotate(Math.PI/2);
// draw the signature
// since images draw from top-left offset the draw by 1/2 width & height
ctx.drawImage(img,-img.width/2,-img.height/2);
// un-rotate the canvas by -90% (== -Math.PI/2)
ctx.rotate(-Math.PI/2);
// un-translate the canvas back to origin==top-left canvas
ctx.translate(-canvas.width/2,-canvas.height/2);
// testing...just draw a rect top-left
ctx.fillRect(0,0,25,10);
this will surely help you >>HTML5 Canvas Rotate Image :)
use some SEPARATE js function for drawing your canvas :
function drawRotated(degrees){
contex_var.clearRect(0,0,canvas.width,canvas.height);
contex_var.save();
contex_var(canvas.width/2,canvas.height/2);
contex_var.rotate(degrees*Math.PI/180);
contex_var.drawImage(image,-image.width/2,-image.width/2);
contex_var.restore();
}
Suppy some angle to any buttonclick function:
$("#clockwise").click(function(){
angleInDegrees+=30;
drawRotated(angleInDegrees);
});
How can I draw only a circular part of an image using HTML 5 canvas?
For instance, to take a photo and only draw the face inside the canvas.
The way to achieve this is to use clip to define a clipping region:
var ctx;
var canvas;
var img = new Image();
img.onload = function() {
canvas = document.getElementById('myCanvas');
ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.arc(100, 100, 60, 0, 6.28, false); //draw the circle
ctx.clip(); //call the clip method so the next render is clipped in last path
ctx.stroke();
ctx.closePath();
ctx.drawImage(img, -190, 0);
};
img.src = "http://www.antiquiet.com/wp-content/uploads/2011/03/Free-Trapper_Remasters_The-Kills-467x311.jpg";
You can see a working fiddle here: http://jsfiddle.net/hJS5B/47/
Code reused from my answer to this question: Draw multiple circles filled with image content
As I found this thread long before I found the solution for what I was searching for: the code above works great. But if you want to draw circular areas of an image again and again, e.g. in an onmouseup event, then you have to save and restore the state of the context. More is explained here: Can you have multiple clipping regions in an HTML Canvas?