scaling logo in html5 <canvas>? - html

Having trouble scaling with . It seems to make sense to code up a drawing in canvas to a fixed size (ie 800x600) then scale it for specific locations - but sizing occurs in 4 places: 1) in the context definition (ie ctx.width = 800 2) with ctx.scale; 3) in html with
I can scale it with ctx.scale(0.25,0.25) and use but this doesn't appear right - it seems to want the scale to be proportional.
css sizing simply makes it fuzzy so not a good way to go. Any ideas?

Actually, you can resize a canvas using stylesheets. The results may vary across browsers as HTML5 is still in the process of being finalized.
There is no width or height property for a drawing context, only for canvas. A context's scale is used to resize the unit step size in x or y dimensions and it doesn't have to be proportional. For example,
context.scale(5, 1);
changes the x unit size to 5, and y's to 1. If we draw a 30x30 square now, it will actually come out to be 150x30 as x has been scaled 5 times while y remains the same. If you want the logo to be larger, increase the context scale before drawing your logo.
Mozilla has a good tutorial on scaling and transformations in general.
Edit: In response to your comment, the logo's size and canvas dimensions will determine what should be the scaling factor for enlarging the image. If the logo is 100x100 px in size and the canvas is 800x600, then you are limited by canvas height (600) as its smaller. So the maximum scaling that you can do without clipping part of the logo outside canvas will be 600/100 = 6
context.scale(6, 6)
These numbers will vary and you can do your own calculations to find the optimal size.

You could convert the logo to svg and let the browser do the scaling for you, with or without adding css mediaqueries.
Check out Andreas Bovens' presentation and examples.

You can resize the image when you draw it
imageobject=new Image();
imageobject.src="imagefile";
imageobject.onload=function(){
context.drawImage(imageobject,0,0,imageobject.width,imageobject.height,0,0,800,600);
}
The last 2 arguments are the width an height to resize the image
http://www.w3.org/TR/html5/the-canvas-element.html#dom-context-2d-drawimage

If you set the element.style.width and element.style.height attributes (assuming element is a canvas element) you are stretching the contents of the canvas. If you set the element.width and element.height you are resizing the canvas itself not the content. The ctx.scale is for dynamic resizing whenever you drawing something with javascript and gives you the same stretching effect as element.style.

Related

How to display a scaled down html canvas

I am doing an animation on a 1320px * 1440px html5 canvas. But I don't want to see this huge canvas on the screen rather I want to see this on a 550px * 600px canvas so that the drawing quality looks better. how to do this?
You are decreasing the height and width by a factor of 2.4, so you simply need to decrease the canvas and the animation inside it by that factor as well.
Make the canvas width attribute = 550 and the height attribute = 600
Multiply the animation width and height by .4167 (or 1/2.4) to scale it appropriately. You could easily do that by using the context.scale(.4167, .4167); method before drawing anything.
More information about scale() here.

Interface gets extra pixel

I made an interface for a game, using extended viewport and when i resize the screen the aspect ratio changes and every element in scene is scales, but when this happens this is what i get :
This is the most annoying issue i dealt with, any advice ? I tried making the tower n times bigger and then just setting bigger world size for the viewport but same thing happens, idk what is this extra pixels on images..
I'm loading image from atlas
new TextureRegion(skin.getAtlas().findRegion("tower0"));
the atlas looks like this:
skin.png
size: 1024,1024
format: RGBA8888
filter: Nearest,Nearest
repeat: none
tower0
rotate: false
xy: 657, 855
size: 43, 45
orig: 43, 45
offset: 0, 0
index: -1
In the third picture, you are drawing your source image just slightly bigger than it's actual size in screen pixels. So there are some boundaries where extra pixels have to be filled in to make it fill its full on-screen size. Here are some ways to fix this.
Use linear filtering. For the best appearance, use MipMapLinearLinear for the min filter. This is a quick and dirty fix. The results might look slightly blurry.
Draw your game to a FrameBuffer that is sized to the same aspect ratio as you screen, but shrunk down to a size where your sprites will be drawn pixel perfect to their original scale. Then draw that FrameBuffer to the screen using an upsampling shader. There are some good ones you can find by searching for pixel upscale shaders.
The best looking option is to write a custom Viewport class that sizes your world width and height such that you will be always be drawing the sprites pixel perfect or at a whole number multiple. The downside here is that your world size will be inconsistent across devices. Some devices will see more of the scene at once. I've used this method in a game where the player is always traveling in the same direction, so I position the camera to show the same amount of space in front of the character regardless of world size, which keeps it fair.
Edit:
I looked up my code where I did option 3. As a shortcut, rather than writing a custom Viewport class, I used a StretchViewport, and simply changed its world width and height right before updating it in the game's resize() method. Like this:
int pixelScale = Math.min(
height / MIN_WORLD_HEIGHT,
width / MIN_WORLD_WIDTH);
int worldWidth = width / pixelScale;
int worldHeight = height / pixelScale;
stretchViewport.setWorldWidth(worldWidth);
stretchViewport.setWorldHeight(worldHeight);
stretchViewport.update(width, height, true);
Now you may still have rounding artifacts if your pixel scale becomes something that isn't cleanly divisible for both the screen width and height. You might want to do a bit more in your calculations, like round pixelScale off to the nearest common integer factor between screen width and height. The tricky part is picking a value that won't result in a huge variation in amounts of "zoom" between different phone dimensions, but you can quickly test this by experimenting with resizing a desktop window.
In my case, I merged options 2 and 3. I rounded worldWidth and worldHeight up to the nearest even number and used that size for my FrameBuffer. Then I draw the FrameBuffer to the screen at just the right size to crop off any extra from the rounding. This eliminates the possibility of variations in common factors. Quite a bit more complicated, though. Maybe someday I'll clean up that code and publish it.

scaling canvas directly VS scaling the CSS in HiDPI

Sorry, I am a beginner, sometimes i find people saying that I have to scale only the CSS, and the other examples i find that they multiply the size directly with the new scale, in other words canvas.width VS canvas.style.width
What is the difference?
Does latest Chrome behave like Safari (now in March 2014)?
Canvas consists of two parts: the element canvas which is what you see on screen. Then sort of "behind" the scenes there is the image bitmap which you draw onto.
Setting element.style will only affect the element itself, but not the behind the scene (internal) bitmap. This bitmap is simply stretched to fit the element size (like an image). If the size isn't specified it will default to 300 x 150 pixels.
The width and height properties (or attributes for the tag) are the ones setting the size of the internal bitmap.
An element without CSS will typically adopt to the size of the internal bitmap (there is pixel aspect ratio involved here as wel but normally the relationship is 1:1).
You can however override this by setting the element's CSS size. Again, it doesn't affect the internal bitmap but simply stretches it to fit the element.
All browsers should behave the same.

Why do my HTML5 rectangles appear zoomed in?

Following http://www.html5canvastutorials.com/tutorials/html5-canvas-rectangles/, I have drawn some rectangles side-by-side on a canvas. The problem is that they appear greatly zoomed in; at a zoom of 1.0 they appear approximately five times their original size; they appear correctly sized (if fuzzy around the borders) at a zoom of around 0.16.
I expect I could get a workaround by making the pixel dimensions of the canvas much greater and zooming out, but what is the proper way to get a 1:1 scaling on a canvas? The canvas is styled to width and height of 100%, and the body has a margin of 0. Manually setting the canvas's width and height to the height and width of the window does not alter this behavior.
TIA,
the problem is, you set the width and height of the style for the canvas. You need to set the width and height attributes, not the css style. so something like:
<canvas id='mycanvas' width='800' height='600'></canvas>
More info in a similar question: Canvas is stretched when using CSS but normal with "width" / "height" properties

Set HTML5 Canvas Height And Width And Having Content Inside Scale

Is it possible to set the width and height of a canvas element and have the existing content scale to fit these new dimensions?
Right now the user uploads an image and my page creates a canvas element containing this image and whose dimensions are the same size as the image. I want to limit the size that I'm working with, however, so here is an example of what I want to have happen:
The user uploads an image that is 1600 x 1200 pixels (Not saved to server)
The data goes right to an html5 canvas object
The canvas height and width are set to 800 x 600 and the image content scales appropriately and then is displayed.
Right now if I set the canvas width and height it just crops the image at those dimension, not resizing as I would like. Thanks!
There are many ways to call drawImage
One is:
ctx.drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)
Where dx,dy,dw,dh are the destination x, y, width, and height.
If you make dw and dh always 800x600, the image will drawn will always automatically be scaled to 800x600.
Here's a tiny example that will always draw any size image to 800x600 http://jsfiddle.net/jAT8Y/
Another alternative is to use context.scale function. Your image quality will remain better if you use scale.