Canvas drawing and Retina display: doable?
Asked Answered
A

6

23

Working with phoneGap implementing drawing with Canvas. The catch we've run into is that canvas expects specific pixel dimensions. This is fine except that the iPhone 4's Retina display, from a CSS/Webkit POV is still 320px wide, even though technically there are 640 actual screen pixels.

Is there anyway to accommodate the retina display using Canvas on Webkit while preserving compatibility with non-retina displays?

Antimacassar answered 18/1, 2011 at 3:40 Comment(1)
See my answer for a drop-in solution ... https://mcmap.net/q/557521/-canvas-drawing-and-retina-display-doableIdun
C
49

I sat with the same problem last week and discovered how to solve it -

var canvas = document.querySelector('canvas');
var ctx = canvas.getContext('2d');

if (window.devicePixelRatio > 1) {
    var canvasWidth = canvas.width;
    var canvasHeight = canvas.height;

    canvas.width = canvasWidth * window.devicePixelRatio;
    canvas.height = canvasHeight * window.devicePixelRatio;
    canvas.style.width = canvasWidth + "px";
    canvas.style.height = canvasHeight + "px";

    ctx.scale(window.devicePixelRatio, window.devicePixelRatio);
}

Full code on gist, demo on jsfiddle

Cholesterol answered 15/3, 2011 at 2:37 Comment(4)
Could you please mirror this site somewhere? That link is broken.Flesh
please always copy&paste the solution to stackoverflow, so it stays available even if the site goes offline.Natividadnativism
The site is online right now, and it links to this example on GitHub: gist.github.com/joubertnel/870190 (which will stay online a little longer, I guess)Stonecutter
Note: this did not work unmodified! I had to set canvas.style.width = canvasWidth + "px" for this to actually work, and the same for canvas.style.height. I have submitted an edit to the question.Limulus
I
3

There is a drop-in polyfill that will take care of most basic drawing operations for you, and remove the ambiguity between browsers that handle this automatically for you (safari) and others that don't.

https://github.com/jondavidjohn/hidpi-canvas-polyfill

You simply include it before your drawing code and it should give you decent retina support automatically.

Idun answered 23/10, 2013 at 15:51 Comment(2)
This polyfill makes my canvas grow weirdly, every time I draw to my canvas until eventually it nearly crashes my tab in Safari. I think I will try doing it manually.Twinned
@JaredUpdike Sounds like a great candidate for reporting via a github issue with a detailed example so it can get fixed for others.Idun
S
2

Another option is to remove this line from your HTML you will get the default width for viewing a webpage on your phone. Should be 980px on iPhones.

<meta name='viewport' content='width=device-width' />

Then you can just do:

canvas.width = innerWidth
canvas.height = innerHeight
canvas.style.width = innerWidth+'px'
canvas.style.height = innerHeight+'px'

The advantage is that you don't need to scale and it renders faster. But it probably won't match the amount of physical pixels that the device has. It works well in most cases though. Not all pixellated like 320px. But not as clear as retina. Keep in mind that the higher res you go the more laggy it will be.

Scandura answered 10/9, 2019 at 6:33 Comment(0)
M
0

WebCode (http://www.webcodeapp.com) is a vector drawing app that generates JavaScript HTML5 Canvas code for you. The code is Retina-compatible, you can check out how they do it.

Malachite answered 6/6, 2013 at 9:58 Comment(1)
That also reminds me of code.google.com/p/canvg . Note sure how it handles retina.Twinned
G
0

EDIT: Just noticed I posted the wrong link for the demo!

Retina (or other hdpi display) canvas resolution is definitely possible. There is a working example here:

http://spencer-evans.com/share/github/canvas-resizer/

I've also bumped into this a few times. The accepted answer code is essentially correct, but you could also use a library solution. I whipped one up to handle intelligent canvas re-sizing to make the element more responsive and higher resolution (as shown in the demo).

https://github.com/swevans/canvas-resizer

Giddy answered 6/11, 2015 at 2:34 Comment(0)
P
0

There is a very good polyfill by TJ Holowaychuk:

https://www.npmjs.com/package/autoscale-canvas

Palaeozoology answered 7/11, 2015 at 8:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.