Full Screen Canvas on Mobile-Devices

Fullscreen, full dpi WebGL canvas on mobile device

The easiest way is to use CSS to decide what size you want the canvas. Then look up what size the browser is displaying the canvas in CSS pixels using canvas.clientWidth and canvas.clientHeight. Now multiply that by window.devicePixelRatio to get the number of device pixels those CSS pixels represent and set the canvas's content/drawingbuffer size to match.

Example:

  1. Make a canvas

    <canvas id="c"></canvas>  
  2. Set its size using CSS

    Here I'm making the canvas be the size of the viewport (the window).

    body {
    margin: 0;
    }
    canvas {
    width: 100vw;
    height: 100vh;
    display: block;
    }
  3. Look up the size it's displayed and match its drawingbuffer size.

    function resizeToMatchDisplaySize(canvas) {
    var displayWidth = canvas.clientWidth * window.devicePixelRatio;
    var displayHeight = canvas.clientHeight * window.devicePixelRatio;
    if (canvas.width !== displayWidth || canvas.height !== displayHeight) {
    canvas.width = displayWidth;
    canvas.height = displayHeight;
    return true;
    }
    return false;
    }
  4. Before rendering each frame adjust the size

    function render() {
    // resize before rendering in case of resizing or rotation
    if (resizeToMatchDisplaySize(gl.canvas)) {
    gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
    }

    // render scene

    requestAnimationFrame(render);
    }
    requestAnimationFrame(render);

Here's an example drawing some lines

var gl = document.querySelector("#c").getContext("webgl", { alpha: false });var programInfo = twgl.createProgramInfo(gl, ['vs', 'fs']);var ids = [];for (var i = 0; i < 500; ++i) {  ids.push(i);}var arrays = {  vertexId: { size:1, data: ids},};var bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays);
var uniforms = { time: 0, numIds: ids.length, resolution: [0, 0],};
function resizeToMatchDisplaySize(canvas) { var displayWidth = canvas.clientWidth * window.devicePixelRatio; var displayHeight = canvas.clientHeight * window.devicePixelRatio; if (canvas.width !== displayWidth || canvas.height !== displayHeight) { canvas.width = displayWidth; canvas.height = displayHeight; return true; } return false;}
function render(time) { // resize before rendering in case of resizing or rotation if (resizeToMatchDisplaySize(gl.canvas)) { gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); } // render scene gl.useProgram(programInfo.program); uniforms.time = time * 0.001; uniforms.resolution[0] = gl.drawingBufferWidth; uniforms.resolution[1] = gl.drawingBufferHeight; twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo); twgl.setUniforms(programInfo, uniforms); twgl.drawBufferInfo(gl, gl.LINES, bufferInfo); requestAnimationFrame(render);}requestAnimationFrame(render);
body {  margin: 0;}canvas {  width: 100vw;  height: 100vh;  display: block;}
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"><canvas id="c"></canvas>  <script id="vs" type="notjs">attribute float vertexId;
varying vec4 v_color;
uniform float numIds;uniform float time;uniform vec2 resolution;
#define PI radians(180.0)
vec3 hsv2rgb(vec3 c) { c = vec3(c.x, clamp(c.yz, 0.0, 1.0)); vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);}

void main() { vec4 offsets = vec4( sin(time), sin(time * .13) * PI * 2., sin(time * .43) * .5 + 1., cos(time * .17) * .5 + .5);
vec4 centers = vec4( sin(time * .163) * .5, cos(time * .267) * .5, sin(time * .367) * .5, cos(time * .497) * .5);
vec4 mult = vec4( 1., (sin(time * .1) * .5 + .5) * 3., 0., 0.);
vec2 position = vec2(vertexId / numIds, mod(vertexId, 2.)); vec2 offset = mix(offsets.xz, offsets.yw, position.y); float a = mult.x * position.x * PI * 2.0 + offset.x;//mix(u_offsets.x, u_offsets.y, a_position.y); float c = cos(a * mult.y); vec2 xy = vec2( cos(a), sin(a)) * c * offset.y + mix(centers.xy, centers.zw, position.y); vec2 aspect = vec2(resolution.y / resolution.x, 1); gl_Position = vec4(xy * aspect, 0, 1); float hue = position.x; float sat = 1.; float val = 1.; v_color = vec4(hsv2rgb(vec3(hue, sat, val)), 1);} </script> <script id="fs" type="notjs">precision mediump float;varying vec4 v_color;void main() { gl_FragColor = v_color;} </script> <script src="https://twgljs.org/dist/twgl-full.min.js"></script>

javascript - Fullscreen rectangle in Canvas (Android/iOS web app)

You can use pixel aspect ratio as a factor when calculating the canvas size.

var ratio = window.devicePixelRatio || 1;
var width = window.innerWidth * ratio;
var height = window.innerHeight * ratio;

canvas.width = width;
canvas.height = height;

CSS:

#canvasID {
position: fixed;
left: 0;
top: 0;
}

How can I have a full-screen canvas at full resolution in an iPhone 4?

You can try keeping the initial-scale=1, then set the canvas.width and canvas.height to be double the appropriate dimensions you've determined, and use CSS to set the CSS width and CSS height to be the correct size. This should give you a higher resolution canvas. The canvas.height and canvas.width properties set the actual number of pixels in the canvas, while the CSS height and width simply stretch (or in this case, compress) the canvas to a particular size.



Related Topics



Leave a reply



Submit