how to render smothly P5.js in hdpi screen? - javascript

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.

Related

HTML Canvas - auto re-size as its content grows

How can i set an HTML5 canvas to auto re-size when the content inside it grows beyond its margins? I am developing a family tree application and when a generation comes wider than the defined limits of the canvas, lines which connect nodes together disappear.
With canvas there is no automatic features. It's a passive bitmap which you can use to draw graphics to, so all forms of logic need to be implemented "manually".
So in order to have it grow you will have to track positions and sizes of everything that is being drawn so you can calculate the total bounding box for the current graphics.
If the position + size of that bounding box exceed the canvas size, update the canvas size with that (canvas size = bounding box' position + size).
However, when resizing a canvas all current content as well as state(s) are lost so you will have to re-render and reinitialize the content as well as if was the first time drawing to it. This is something you need to plan for and incorporate into the design.
Again, it really depends how you're drawing the content, but here is an example of how to do it when drawing an image to canvas..
var canvas = document.getElementById('canvas'),
context = canvas.getContext('2d');
base_image = new Image();
base_image.src = 'someImaeg.png';
base_image.onload = function(){
document.getElementById('canvas').width = base_image.width;
document.getElementById('canvas').height = base_image.height;
context.drawImage(base_image, 0, 0);
}
Fiddle

Is it possible to draw a canvas thats bigger than the current screen?

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");

Rotate image by 90 degrees on HTML5 Canvas

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);
});

html image id and canvas

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

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);

Categories

Resources