Hi there I have a simple question I can'[t seem to find the answer to on google. I'm trying to draw an image on a canvas. I originally used the "new" constructor ( ballPic = new Image(); ballPic.src = "ball.png" ) which worked when drawing on my canvas, but I needed to do some scaling and wasn't sure if I could attach a css id to the object. So I instead tried to use the image tag and did the rest in css.
However using a variable that way doenst seem to work with my canvas' drawing:
ballPic = '<img id="soccerBall">';
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.drawImage(BallPic, -25, -25);
Is this because assigning a variable like ballPic = is not the same as being the element itself like when using the constructor? How would I pass it other than attaching it to the document and using getElementbyID?
You can keep using the Image constructor and still scale the image. There's another method overload of the drawImage function:
From MDN:
The second variant of the drawImage() method adds two new parameters and lets us place scaled images on the canvas.
drawImage(image, x, y, width, height)
This adds the width and height parameters, which indicate the size to which to scale the image when drawing it onto the canvas.
I would recommend you check out that page, it has a lot of good information, like
Using data: urls
Handling image loading
Loading still frames from videos
Slicing
Examples gallore
Create an image, handle the onload event, in which you update the canvas size to the scaled size of the image, then drawImage with a scale.
var scale = 2 ;
var ballPic = new Image();
ballPic.onload = function drawImage() {
var c=document.getElementById("myCanvas");
c.width = ballPic.width * scale ;
c.height = ballPic.height * scale ;
var ctx=c.getContext("2d");
ctx.scale(scale, scale) ;
ctx.drawImage(ballPic, 0, 0);
};
ballPic.src =
'http://melinabeachturtlehatchery.files.wordpress.com/2010/07/turtle4.jpg';
the fiddle is here :
http://jsbin.com/etemox/1/edit
Related
Computer with hdpi screen are more and more common and I own one.
I'm building a webpage with a P5.js canvas inside it filling a div.
I have absolutely no problem till this point, but as I have an hdpi screen the number of pixels to render is tremendous and it's very hard to render smoothly.
what I would like to do: render a low-resolution canvas an stretching it to fill all the space. But I have no ideƩ how to achieve this or even if it's possible.
function setup() {
var canvasDiv = document.getElementById('myCanvas');
var divWidth = canvasDiv.getBoundingClientRect().width;
var divHeight = canvasDiv.getBoundingClientRect().height;
var sketchCanvas = createCanvas(divWidth,divHeight);
sketchCanvas.parent("myCanvas");
background(0)
}
function windowResized() {
var canvasDiv = document.getElementById('myCanvas');
var divWidth = canvasDiv.getBoundingClientRect().width;
var divHeight = canvasDiv.getBoundingClientRect().height;
resizeCanvas(divWidth, divHeight);
background(0)
}
function draw(){
}
Step one: Create an off-screen buffer using the createGraphics() function. More info can be found in the reference. Give it whatever low-res size you want.
Step two: Draw your scene to that off-screen buffer. Use its width and height to draw stuff to scale.
Step three: Draw the off-screen buffer to the screen, using the image() function, which takes parameters for the size to draw. Use the size of the canvas as the arguments. Again, more info can be found in the reference.
You'll still be drawing the same amount of pixels, but that's how you'd draw to a small buffer and resize it to match the canvas size.
If you're still having trouble, please post a MCVE in a new question post, and we'll go from there. Good luck.
I'm drawing a image to a canvas, and when doing so the image gets downscaled to the canvas(which makes it lose quality) even though the image is the same size as the canvas, thats because the img does a good job scaling down the actual img that in reality has a bigger naturalheight and naturalwidth. I know there is possible ways to make this quality better, however i have no need of actually showing this canvas to the user/no need of downscaling. Therefore am i wondering if there is any way to drawImage that is bigger than the screen and hold it somewhere? Heard someone mention a box object or a camera object somewhere but couldn't really get use of that information only.
Question, is it possible to draw a canvas bigger than the screen? in that case how?
This is the code im working with atm
var image = document.getElementById('insertedImg');
var height = $("#insertedImg").height();
var width = $("#insertedImg").width();
var c=document.getElementById("canvass");
var ctx=c.getContext("2d");
c.height=height;
c.width=width;
ctx.drawImage(image,0,0,width,height);
Use an offscreen canvas, you just need to create a new canvas and set its height and width accordingly. Then you can append it to an element or export the image as a base64 string or whatever you need.
//canvas is not visible unless appended to a DOM element
var canvas = document.createElement('canvas');
canvas.width = $("#insertedImg").height();
canvas.height = $("#insertedImg").width();
var ctx = canvas.getContext('2d');
//do the drawing, etc.
ctx.drawImage(...);
//export the image
var img = canvas.toDataURL("image/png");
I have a plugin that will fill text based on an image using the following:
function draw() {
//grab font to use
var fFamily = $(".activeText a .fontType-cont").val();
ctx.font = startFontSize + 'px ' + fFamily;
ctx.fillText(text, 10, 100);
ctx.globalCompositeOperation = 'source-in';
ctx.drawImage(img, 10, 20, 500, 100);
}
var canvas = document.getElementById(current),
ctx = canvas.getContext('2d'),
img = document.createElement('img');
//draw it
img.onload = draw;
img.src = $(".activeGColor").find('img').attr('src');
What happens is that the canvas will take that image, display it in the canvas and as the text gets bigger, you see it as the fill for the text. My issue is that, How can I make it so it does not look stretched or whatnot? Do I have an option to do so?
What are your ideas?
We need to see an example of whats going on here. Your question makes it sound like you have some sort of animation going on... that changes the font-size to a larger and larger size. The way things work by default, is that the text will render proportionally. However if your using any thing like ctx.scale() you obviously could throw that off. Also if your not clearing your canvas each frame, you could get more of a bleed effect, that you may be describing as stretching.
I have 2 div. Every div has a canvas element. At the beginning of my program I put an image on the canvas. The images are different. Then I try to swap the divs using
var contentofmyfirstdiv = $('#myfirstdiv').html();
var contentofmyseconddiv = $('#myseconddiv').html();
$('#myseconddiv').html(contentofmyfirstdiv);
$('#myfirstdiv').html(contentofmyseconddiv)
;
All works except that every canvas is empty. It seems the "contentof..." didn't get the image from the canvas... Anyone knows how to swap the content of the canvas? I am using Firefox.
You are serializing to html and reparsing it, this is lossy operation. Instead you should operate
on the live DOM tree directly:
var contentofmyfirstdiv = $('#myfirstdiv').children().detach();
var contentofmyseconddiv = $('#myseconddiv').children().detach();
$('#myseconddiv').append(contentofmyfirstdiv);
$('#myfirstdiv').append(contentofmyseconddiv)
Here's a demo that doesn't do justice but nevertheless http://jsfiddle.net/9JdqQ/
What's retained compared to serialization are unserializable attributes, event listeners, element data (canvas image etc)..
If you are only using images to draw on the canvas there is really no need for the canvas - you could just use the images directly and swap those.
However, if you need to use canvas for other reasons you can extract the data directly from one, draw the other canvas to this, and then put the data from the first to the second.
This method shows a way that doesn't need DOM manipulation.
One option using a new canvas as a swap:
var temp = document.createElement('img');
temp.width = canvas1.width;
temp.height = canvas1.height;
//swap
var tempctx = temp.getContext('2d');
tempctx.drawImage(canvas1, 0, 0);
ctx1.drawImage(canvas2, 0, 0);
ctx2.drawImage(temp, 0, 0);
The other method using an image element as a swap:
var temp = canvas1.toDataURL();
ctx1.drawImage(canvas2, 0, 0);
var img = document.createElement('img');
img.onload = function() {ctx2.drawImage(this, 0, 0);}
img.src = temp;
The latter not optimal in speed as you need to compress and encode the data-uri.
Note that this example assume the images being of the same size. If the images are of different sizes you will need to handle this as well by setting canvas1 and 2 to the correct sizes after the image is copied to swap and before you redraw.
swap = canvas1
resize canvas1 = canvas2
draw canvas2 to canvas1
resize canvas2 = swap
draw swap to canvas2
Would it be possible to fill a png with transparency with a pattern (a repeatable texture)?
Here's a quick example of loading an image onto the canvas, just not sure how to fill it with a pattern, if that isn't possible then would there be a way to extract a path from the png?
<script>
var c = document.getElementById("a");
var ctx = c.getContext("2d");
var test= new Image();
test.src = "images/test.png";
test.onload = function() {
ctx.drawImage(test, 0, 0);
};
</script>
<body>
<canvas id="a"></canvas>
</body>
I've also created a jsfiddle with an actual loaded png
This is the effect I'm looking to achieve
Update
working example based on Simon Sarris' answer
http://jsfiddle.net/sergeh/G8egW/6/
First, draw the image to Canvas.
Then do globalCompositeOperation = 'source-in';
Then draw the pattern. It will only exist where the image was.
http://jsfiddle.net/G8egW/2/
If you had stuff already on the canvas before this time, you'll need to do the above operations on an in-memory canvas and then draw that canvas to your normal canvas. Like this:
http://jsfiddle.net/G8egW/5/
(notice the difference in the grid)