I am writing a simple game in javascript which draws on a HTML canvas. The canvas has a fixed size (1280 × 720) and that is also the "room" in which the objects are drawn.
Now I want the canvas to be stretched to be 100 % of the screen. I can't do that by just setting the width and height of the canvas because the javascript would only draw in the 1280 × 720 rectangle in the top left.
What I want instead is, that it is zoomed in so that it takes up the whole screen and if the javascript draws something at (1280, 720) it should be the bottom right corner.
Can I do this without using any external libraries?
If you wish to keep the rendering size at 1280x720 for the canvas, but stretch or expand it to the window size you can use the css width and height for that.
Using css will only cause the shape of the canvas to change, but the internal pixels/drawing frame are still set by the width and height attribute. (This will of course cause the image to be blurry if it is upscale to much)
With CSS:
* { margin: 0; padding: 0;}
body, html { height:100%; }
#canvasID {
position:absolute;
height:100%;
/*width:100%; /* uncomment if you don't care about aspect ratio*/
}
<canvas id="canvasID" width=128 height=72>
With a script:
$(document).ready(function() {
function resizeCanvas() {
var canvas = $("#canvasID");
// original width/height from the canvas attribute
var heightOriginal = canvas[0].height;
var widthOriginal = canvas[0].width;
// fill to window height while maintaining aspect ratio
var heightNew = window.innerHeight;
// replace with window.innerWidth if you don't care about aspect ratio
var widthNew = heightNew / heightOriginal * widthOriginal;
canvas.css("height", heightNew + "px");
canvas.css("width", widthNew + "px");
}
// keep size when window changes size
$(window).resize(resizeCanvas);
// initial resize of canvas on page load
resizeCanvas();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="canvasID" width=128 height=72>
Alternately if you wish for the internal canvas resolution/size to be able to change dynamically you can use scale to ensure that everything gets rendered to the right size.
$(document).ready(function() {
var canvas = $("#canvasID");
// original width/height from the canvas attribute
var heightOriginal = canvas[0].height;
var widthOriginal = canvas[0].width;
// current scale (original 1 to 1)
var verticalRatio = 1;
var horizontalRatio = 1;
// the canvas context
var ctx = canvas[0].getContext('2d');
function setScale() {
// remove previous scale
ctx.scale(1/horizontalRatio, 1/verticalRatio);
// fill to window height while maintaining aspect ratio
var heightNew = window.innerHeight;
// not needed if you don't care about aspect ratio
var widthNew = heightNew / heightOriginal * widthOriginal;
// these would be the same if maintaining aspect ratio
verticalRatio = heightNew / heightOriginal;
horizontalRatio = widthNew / widthOriginal;
// update drawing scale
ctx.scale(horizontalRatio, verticalRatio);
// update width and height of canvas
canvas[0].height = heightNew;
canvas[0].width = widthNew;
}
// keep size when window changes size
$(window).resize(setScale);
// initial resize of canvas on page load
setScale();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="canvasID" width=128 height=72>
Related
I'm trying to learn how to use HTML's Canvas and it's properties.
Now I'm trying to draw a ground and a sky, and I want the sky to be 75% of screens height and ground to be 25%.
This was easy using a div, and style it with CSS or JavaScript CSS Query. Now that I'm on a Canvas, I can't figure out how to set the fillRect properties...
My code:
var windowHeight = $(window).height();
var windowWidth = $(window).width();
var skyHeight = windowHeight - (windowHeight * 0.25);
var groundHeight = windowHeight - (windowHeight * 0.75);
ctx = gameCanvas.getContext("2d");
ctx.fillStyle="green";
ctx.fillRect(0,0,windowWidth,windowHeight);
ctx.fillStyle="cyan";
ctx.fillRect(0,0,windowWidth,skyHeight);
Also: if I try using i.e.
ctx.fillStyle="cyan";
ctx.fillRect(0,0,30,30);
This draws a perfect square on top of the green "ground"-background, but if I change to i.e.
ctx.fillRect(0,0,200,200);
it will fill my entire height of the screen, and more than 50% of my screen-width.
According to http://www.w3schools.com/tags/canvas_fillstyle.asp canvas fillrect are using pixels, but 200 x 200 pixels should definitely NOT fill my entire screen height. :/
Where's the part where you tell canvas what its dimensions are? Just like any other HTML media element that you need to be of a specific size (video, image), you need to tell it what its width and height is if you want reliably sized content (if you don't, by convention the canvas will be sized 300 x 150px). And because we're setting the number of pixels we can draw on, this is not "purely cosmetic" like CSS, we have to do it properly:
var cvs = document.querySelector("canvas");
// if you didn't use <canvas width="..." height="...">, we need this:
cvs.width = 800;
cvs.height = 400;
And then you can do your drawing:
var ctx = cvs.getContext("2d");
ctx.fillStyle = "green";
ctx.fillRect(0,0.75*cvs.height, cvs.width,0.25*cvs.height);
ctx.fillStyle = "lightblue";
ctx.fillRect(0,0, cvs.width, 0.75*cvs.height);
See http://jsbin.com/tejiqixeji/edit?html,js,output
How do I use drawImage() to output full size images on a 300px X 380px canvas regardless of the source image size?
Example:
1). If there is a image of 75px X 95px I want to be able to draw it to fit a 300px X 380px canvas.
2). If there is a image of 1500px X 1900px I want to be able to draw it to fit a 300px X 380px canvas.
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var img=document.getElementById("myPic");
ctx.drawImage(img,10,10);
What options are available to prevent any quality loss?
To scale the image to fit is not so hard, just use simple aspect ratio with the sizes:
var ratioX = canvas.width / image.naturalWidth;
var ratioY = canvas.height / image.naturalHeight;
var ratio = Math.min(ratioX, ratioY);
ctx.drawImage(image, 0, 0, image.naturalWidth * ratio, image.naturalHeight * ratio);
To maintain quality; a canvas of 300x380 will either appear very tiny on print, or very blurry.
It's important to keep the data from it in the target resolution. To do this, calculate the size using the target DPI (or rather, PPI). You will also need to know in advance what size the 300x380 area represents (e.g. in either inches, centimeters, millimeters etc.).
For example:
If the target PDF will have a PPI of 300, and the canvas represents 3 x 3.8 cm (just to keep it simple), then the width and height in pixel will be:
var w = (3 / 2.54) * 300; // cm -> inch x PPI
var h = (3.8 / 2.54) * 300;
Use this size on canvas' bitmap, then scale down the element using CSS:
canvas.width = w|0; // actual bitmap size, |0 cuts fractions
canvas.height = h|0;
canvas.style.width = "300px"; // size in pixel for screen use
canvas.style.height = "380px";
You can now use the canvas directly as an image source for the PDF while keeping print quality for the PDF (have in mind though, small images uploaded will not provide high print quality in any case).
And of course, set the canvas size first, then use the code at top to draw in the image.
You'll need to resize your source image. You will need to calculate the destination size of the image, then use a couple extra parameters during your draw.
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var x = 188;
var y = 30;
var width = 200;
var height = 137;
var imageObj = new Image();
imageObj.onload = function() {
context.drawImage(imageObj, x, y, width, height);
};
imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg';
body {
margin: 0px;
padding: 0px;
}
<canvas id="myCanvas" width="578" height="200"></canvas>
Source: http://www.html5canvastutorials.com/tutorials/html5-canvas-image-size/
I get a wrong canvas height. Whats wrong here?
I made a fiddle: http://jsfiddle.net/hbcz6/
HTML:
<div id="app">
<div id="percent" class="animated"></div>
<canvas></canvas>
</div>
Javascript:
var canvas = document.getElementsByTagName("canvas")[0];
var context = canvas.getContext('2d');
var x = canvas.width / 2;
console.log("canvas X: ", x);
var y = canvas.height / 2;
console.log("canvas y: ", y);
Please have a look to your console.
As you are not setting the size of the canvas element its bitmap will default to 300 x 150 pixels. If you use CSS rules then the element will be stretched but the bitmap will, stay at the same size just scaled to fit the size of the element (just like an image would).
Here is how to dynamically fit a canvas element inside a parent element settings its size properly:
First, remove the width and height from the CSS rule:
#app canvas {
border:2px solid red;
}
Then use getComputedStyle to get the parent element's dimension in pixels:
var cs = getComputedStyle(app),
width = parseInt(cs.getPropertyValue('width'), 10);
height = parseInt(cs.getPropertyValue('height'), 10);
The parseInt will remove the px at the end - now simply use those for the canvas element:
canvas.width = width;
canvas.height = height;
Working fiddle here
You aren't setting the canvas's dimensions. Using CSS to style it only affects the rendered result, it does not affect the underlying canvas that is being drawn on. In this case, it is using the default sizes, and then stretching it to cover the container.
I'm playing around with a node/socket.io Pictionary game. I apologize in advance, I am a designer and not too keen with js.
I'm just trying to re-size the canvas so it will be the entire width and height of a browser window without scaling up the stroke path? Right now, the Javascript sets the canvas to 500px.
Here is the relevant code:
// ================================================
// canvas drawing section
// ================================================
var canvas = $('#canvas'),
context = canvas[0].getContext('2d');
socket.on('drawCanvas', function(canvasToDraw) {
if(canvasToDraw) {
canvas.width(500);
context.lineJoin = 'round';
context.lineWidth = 2;
// ...
}
});
canvas[0].width = $(window).width();
canvas[0].height = $(window).height();
worked great.
You're using jQuery to change the dimensions, and that won't work well with canvas (it will scale the canvas contents too). Set the dimensions directly on the canvas element:
canvas[0].width = 500;
// Or:
canvas.get(0).width = 500;
To set the canvas to the full window dimensions, try this:
canvas[0].width = $(window).width();
canvas[0].height = $(window).height();
Use clientWidth and clientHeight property of canvas
if (canvas[0].width != canvas[0].clientWidth || canvas[0].height != canvas[0].clientHeight) {
canvas[0].width = canvas[0].clientWidth;
canvas[0].height = canvas[0].clientHeight;
}
and set the css for canvas width and height to 100%;
html:
<div id="thumbnail">
<img src="xxx">
</div>
css:
div.thumbnail
{
border: 2px solid #ccc;
width: 50px;
height: 50px;
overflow: hidden;
}
Say the image size is greater than 50x50, is there any way that I can proportionally scale down the image so that the shorter of its width and height would become 50px? Note that the image can be in either portrait or landscape.
First load up the image in javascript to get its real dimensions.
var img = new Image('image.jpg');
var width = img.width;
var height = img.height;
Then determine which one has the larger height, and adjust them accordingly using the ratios.
if (width <= height) {
var ratio = width/height;
var newWidth = 50;
var newHeight = 50 * ratio;
} else {
var ratio = height/width;
var newWidth = 50 * ratio;
var newHeight = 50;
}
Then insert the image into the DOM using jQuery.
$('#imageContainer').append('<img src="' + img.src + '" style="width:' + newWidth + 'px; height:' + newHeight + 'px;" />');
Divide the width of the image by the height, that's your ratio. Then find what's the largest dimension, if it's the width, set the width = 50 * ratio, and height = 50; if it's the height set it height = 50 / ratio and the width = 50. Do you need Javascript code?
You can't constrain an image to a fixed width and height rectangle, while maintaining aspect ratio, in CSS alone. If you need to do this, it will be either a JavaScript or server side solution.
If you set just a width, then the height will be set to maintain the aspect ratio, likewise just a height, but this will not force the image to fit into a box since you can't know which is greatest, the width or the height.
Check out ImageMagick if you'd like something server side, otherwise, consider jQuery for a client side solution. JQuery provides a simple API to let you get the dimensions of any element, which you can then scale programatically. Newer version of ImageMagick also provide simple calls which will allow you to fit an image into a rectangle.