Canvas draw image - javascript

I am trying to draw a picture in a canvas, but its not working and I have no idea why. Here is my code:
var canvas = document.getElementById('profile-pic');
var context = canvas.getContext('2d');
var imageObj = new Image();
imageObj.onload = function() {
context.drawImage(imageObj, 150, 150);
};
imageObj.src = '/images/alt-profile.png';
<canvas id='profile-pic' height="150" width="150"></canvas>

Look at the API of drawIamge. The dx and dy are the coordinates of where you want to draw the image.
You provided 150, 150. Your canvas' width and height are both 150.
That means, you are trying to draw an image at the location 150, 150 meaning you are drawing right at the outside corner of the canvas.
Change the value of the arguments you are providing to drawIamge to something within the bounds of the canvas, i.e. greater than the image dimensions, but less than the canvas dimensions.

Related

How to remove transparent whitespace from image after a crop HTML5 Canvas/JavaScript?

So I have a function that dynamically produces a cropped section of a world map. The map has various points plotted onto it, plotted by longitude and latitude, depending on the data passed into the function from elsewhere in the script. (Don't worry about how these values are calculated, just accept they are calculated where I have put [number] in my code). I've worked out how to crop my map dynamically, but what I'm noticing is that there is a lot of transparent whitespace to the right of the image after the crop, when the image is appended to a div on the page. How do I remove this whitespace?
Please note that each crop will be of a different size. Setting overflow:hidden property on the containing div and limiting the containing div to a precise pixel width will not achieve what I want to achieve.
Thx u
-- Gaweyne
createZoomedMapImage: function(imageURL){
var imageObj = new Image();
imageObj.onload = _.bind(function(){
var canvas = document.createElement("canvas"),
context = canvas.getContext("2d"),
$canvas = $(canvas),
w = imageObj.width,
h = imageObj.height;
canvas.width = w;
canvas.height = h;
var startingX = [number]
var starting Y = [number]
var deltaWidth = [number]
deltaHeight = [number]
context.drawImage(imageObj, startingX, startingY, deltaWidth, deltaHeight, 0, 0, (deltaWidth*2), (deltaHeight*2));
var zoomedImage = canvas.toDataURL('image/png');
}, this);
imageObj.src = imageURL;
}
jsfiddle.net/Gaweyne/r0t3hoo6
The image tag looks like what is displayed in the result. I have an image of, say, 300 x 600px. But the actual graphic only takes up 300 x 300 pixels. I don't want the graphic to take up the full width of the image. I want the image to be 300 x 300 pixels. I don't want to set this explicitly with CSS because the cropped maps will differ in size depending on the data.
Try to use:
canvas.width = deltaWidth;
canvas.height = deltaHeight;
context.drawImage(imageObj, startingX, startingY, deltaWidth, deltaHeight, 0, 0, (deltaWidth*2), (deltaHeight*2));
var zoomedImage = canvas.toDataURL('image/png');

Canvas context.drawimage doesn't draw on the right coordinates

I have a canvas in the center of a website. When I perform a mouse click on the canvas, I want a small image to be drawn at the click-location. In manage to get the correct coordinates of a canvas click I structute a JavaScript-function like this:
function click( event ) {
var ctxt;
var myX = event.clientX;
var myY = event.clientY;
myX-=canvas.offsetTop;
myY-=canvas.offsetLeft;
ctxt = canvas.getContext("2d");
ctxt.drawImage(myImage, myX, myY);
alert(myX + " " + myY);
}
The alert function shows the correct coordinates, but the image is drawn at a location with much higher coordinate-values. If I click a little bit to far down or to the left, the image is not drawn at all (probably because its outside the canvas).
The drawn image has a x-coordinate that's about 3 times as high as the x-coordinate of the click, and the y-coordinate is about 5 times as high.
What can be the problem?
Hank
You probably forgot to define a size for the canvas bitmap, and is only using CSS to set the size. Remember that canvas size must set implicit as CSS does not affect its bitmap size.
<canvas id="myCanvas" width=500 height=500></canvas>
If not your bitmap which defaults to 300x150 will be stretched to whatever you set with CSS which means your coordinates will be scaled as well.
CSS should be skipped for this but if you absolutely want to use it set width and height in CSS to the same size as defined for your canvas element.
The mouse position you get will be relative to the window so you need to subtract the canvas position to make it relative to canvas element. You probably have this working already and iHank's example should work, although I would not obtain the context each time:
var canvas = document.getElementById('myCanvas'),
ctx = canvas.getContext('2d');
canvas.addEventListener('click', mouseClick, false);
ctx.strokeRect(0, 0, canvas.width, canvas.height);
function mouseClick(e) {
var rect = canvas.getBoundingClientRect(),
x = e.clientX - rect.left,
y = e.clientY - rect.top;
// draw image here, for demo - drawn from corner not center:
ctx.fillRect(x, y, 5, 5);
}
Canvas: <canvas id="myCanvas" width=500 height=180></canvas>
Seems like I missed that the default size of a canvas was (300, 150). If I change the width and height of the canvas-object to the sizes specified in the cs-file, it works!
Try:
function click( event ) {
var ctxt;
var myX = event.clientX;
var myY = event.clientY;
offsetXY = canvas.getBoundingClientRect();
myX-=offsetXY.top;
myY-=offsetXY.left;
ctxt = canvas.getContext("2d");
ctxt.drawImage(myImage, myX, myY);
alert(myX + " " + myY);
}
"The returned value is a TextRectangle object, which contains read-only left, top, right and bottom properties describing the border-box in pixels. top and left are relative to the top-left of the viewport." https://developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect
Hope that's what you needed.
EDIT: offsetXY.top and offsetXY.left. Those properties of the object are not capital.

Scaling HTML Canvas elements

In my main project I have lots of little canvas elements (think: sprites from a sprite map) and I need to be able to scale them before drawing them to the main canvas. Here is my basic code for this:
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
ctx.canvas.width = window.innerWidth;
ctx.canvas.height = window.innerHeight;
var miniCanvas = document.createElement('canvas');
var miniCanvasContext = miniCanvas.getContext('2d');
miniCanvasContext.beginPath();
miniCanvasContext.rect(0,0,100,100);
miniCanvasContext.closePath();
miniCanvasContext.fillStyle = 'red';
miniCanvasContext.fill();
miniCanvasContext.scale(2,2);//THIS IS THE PROBLEM
ctx.drawImage(miniCanvas, 100, 100);
This test is up at jsfiddle: JSFIDDLE
Essentially, I need this red square to be increased in size by two times.
Thanks.
The drawImage method has a version that lets you draw the miniCanvas with scaling:
// the last 2 parameters are scaled Width & scaled Height
// parameters:
// 1st: the image source
// 2nd,3rd: the upper-left part of the source to clip from
// 4th,5th: the width & height to clip from the source
// 6th,7th: the upper-left part of the canvas to draw the clipped image
// 8th,9th: the scaled width & height to draw on the canvas
ctx.drawImage(miniCanvas, 0,0,100,100, 0,0,200, 200);

Drawing an arc on an image inside a canvas

I am trying to clip and display a very large image inside a canvas div.
Using basic calculations and drawImage I managed to clip the image around the pixel I want and display the clipped image.
An example is here on JSFiddle (displaying image arround eye of the person)
I would like to add an arc which will be over the image around the pixel (the sx, sy pixel I use in the example in drawImage), how should I adjust the coordinates ?
var canvas = document.getElementById('test-canvas');
canvas.width = 500;
canvas.height = 285;
var context = canvas.getContext('2d');
var imageObj = new Image();
imageObj.onload = function () {
//context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);
context.drawImage(imageObj, 1324 - 250, 1228 - 142.5, 500, 285, 0, 0, 500, 285);
};
imageObj.src = "http://upload.wikimedia.org/wikipedia/en/b/b3/Edvard_Munch_-_Self-Portrait_-_Google_Art_Project.jpg";
An arc is part of a path, which can be either filled or stroke. In order to get your desired result, you need to move to a point on your circle*, create the arc, and then use stroke() (fiddle):
function strokeCircle(ctx, midx, midy, radius){
ctx.moveTo(midx + radius, midy);
ctx.arc(midx, midy, radius, 0, 2 * Math.PI, false);
ctx.stroke();
}
imageObj.onload = function () {
context.drawImage(imageObj, 1324 - 250, 1228 - 142.5, 500, 285, 0, 0, 500, 285);
strokeCircle(context, 250, 142.5, 30);
};
* The correct coordinate depends on your polar coordinates used for the circle. If you draw from 0 to Math.PI, you need to start on the right-most point.

Draw multiple image's on canvas with each image rotated

I'm new into HTML5 programming and I wanted to know how to rotate each image when it is added into canvas. Should each of them be placed into a canvas and then rotated? If so how can i add multiple canvas into a single canvas context.
Fiddle : http://jsfiddle.net/G7ehG/
Code
function loadImages(sources, callback) {
var images = {};
var loadedImages = 0;
var numImages = 0;
// get num of sources
for(var src in sources) {
numImages++;
}
for(var src in sources) {
images[src] = new Image();
images[src].onload = function() {
if(++loadedImages >= numImages) {
callback(images);
}
};
images[src].src = sources[src];
}
}
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var sources = {
image1: 'http://farm3.static.flickr.com/2666/3686946460_0acfa289fa_m.jpg',
image2: 'http://farm4.static.flickr.com/3611/3686140905_cbf9824a49_m.jpg'
};
loadImages(sources, function(images) {
context.drawImage(images.image1, 100, 30, 200, 137);
context.drawImage(images.image2, 350, 55, 93, 104);
});
In your comment you mentioned that you know about context.rotate, but you don't want the context to stay rotated. That's not a problem at all. First, calling context.rotate only affects things which are drawn afterwards. Anything drawn before will stay were it was. Second, it can be easily reversed after drawing.
use context.save() to create a snapshot of all current context settings, including current rotation.
use context.rotate(angle) and draw your image. The angle is in Radian. That means a full 360° circle is Math.PI * 2. The point the image will be is rotated around is the current origin of the canvas (0:0). When you want to rotate the image around its center, use context.translate(x, y) to set the origin to where you want the center of the image to be, then rotate, and then draw the image at the coordinates -img.width/ 2, -img.height / 2
use context.restore() to return to your snapshot. Rotation and translation will now be like they were before.
Here is an example function which draws an image rotated by 45° at the coordinates 100,100:
function drawRotated(image, context) {
context.save();
context.translate(100, 100);
context.rotate(Math.PI / 4);
context.drawImage(image, -image.width / 2, -image.height / 2);
context.restore();
}

Categories

Resources