Modo corretto per rilevare il supporto WebGL?

Sto tentando di rilevare il supporto WebGL su più browser e ho riscontrato il seguente scenario. L’attuale versione di Firefox sembra segnalare un supporto positivo utilizzando il seguente controllo, anche quando la scheda video del visitatore è in black list e / o WebGL è disabilitato:

if (window.WebGLRenderingContext) { // This is true in Firefox under certain circumstances, // even when WebGL is disabled... } 

Ho provato a istruire i miei utenti ad abilitare WebGL usando i seguenti passaggi. Questo ha funzionato in alcuni casi, ma non sempre. Ovviamente, questo non è qualcosa che posso richiedere al grande pubblico:

  1. Digitare about: config nella barra degli indirizzi di Firefox
  2. Per abilitare WebGL, impostare webgl.force-enabled su true

Questo mi ha portato a creare il mio metodo per rilevare il supporto, che utilizza jQuery per iniettare un elemento canvas per rilevare il supporto. Ciò attira un numero di tecniche che ho trovato in varie librerie e plugin WebGL. Il problema è che è estremamente difficile da testare (eventuali commenti sul fatto che il link sottostante funzioni per voi sono molto apprezzati!). Per rendere questa una domanda obiettiva, vorrei sapere se esiste un modo universalmente accettato per rilevare il supporto WebGL su tutti i browser .

URL di prova:

http://jsfiddle.net/Jn49q/5/

[ Ott 2014] Ho aggiornato l’esempio di modernizzazione per far corrispondere la loro attuale implementazione , che è una versione ripulita da http://get.webgl.org/ più avanti.

Modernizr lo fa,

 var canvas; var ctx; var exts; try { canvas = createElement('canvas'); ctx = canvas.getContext('webgl') || canvas.getContext('experimental-webgl'); exts = ctx.getSupportedExtensions(); } catch (e) { return; } if (ctx !== undefined) { Modernizr.webglextensions = new Boolean(true); } for (var i = -1, len = exts.length; ++i < len; ){ Modernizr.webglextensions[exts[i]] = true; } canvas = undefined; 

Chromium punta a http://get.webgl.org/ per l'implementazione del supporto canonico,

 try { gl = canvas.getContext("webgl"); } catch (x) { gl = null; } if (gl == null) { try { gl = canvas.getContext("experimental-webgl"); experimental = true; } catch (x) { gl = null; } } 

L’eccellente libreria Three ha, infatti, un meccanismo per rilevare quanto segue:

  1. Supporto WebGL
  2. Supporto dell’API di file
  3. Supporto dei lavoratori

Per WebGL, in particolare, ecco il codice che viene utilizzato:

 function webgl_support () { try { var canvas = document.createElement('canvas'); return !!window.WebGLRenderingContext && (canvas.getContext('webgl') || canvas.getContext('experimental-webgl')); } catch(e) { return false; } }; 

Lo snippet di codice fa parte di una class Detector che può anche visualizzare i messaggi di errore corrispondenti all’utente.

Come visto in http://www.browserleaks.com/webgl#howto-detect-webgl

Questa è una funzione javascript corretta per rilevare il supporto WebGL, con tutti i tipi di nomi di contesto WebGL sperimentali e con il controllo di casi speciali, come il blocco delle funzioni WebGL da parte di NoScript o TorBrowser.

Riporterà uno dei tre stati di funzionalità WebGL:

  • WebGL è abilitato – restituisce TRUE o restituisce
  • Oggetto WebGL, se è stato passato il primo argomento
  • WebGL è disabilitato – return FALSE, puoi cambiarlo se ti serve>
  • WebGL non è impiantato – restituisce FALSE
 function webgl_detect(return_context) { if (!!window.WebGLRenderingContext) { var canvas = document.createElement("canvas"), names = ["webgl2", "webgl", "experimental-webgl", "moz-webgl", "webkit-3d"], context = false; for(var i=0;i< names.length;i++) { try { context = canvas.getContext(names[i]); if (context && typeof context.getParameter == "function") { // WebGL is enabled if (return_context) { // return WebGL object if the function's argument is present return {name:names[i], gl:context}; } // else, return just true return true; } } catch(e) {} } // WebGL is supported, but disabled return false; } // WebGL not supported return false; } 

Oltre alla risposta @Andrew, c’è anche la modalità sperimentale che può essere supportata. Ho scritto il seguente snippet di codice:

 var canvasID = 'webgl', canvas = document.getElementById(canvasID), gl, glExperimental = false; function hasWebGL() { try { gl = canvas.getContext("webgl"); } catch (x) { gl = null; } if (gl === null) { try { gl = canvas.getContext("experimental-webgl"); glExperimental = true; } catch (x) { gl = null; } } if(gl) { return true; } else if ("WebGLRenderingContext" in window) { return true; } // not a best way, as you're not 100% sure, so you can change it to false else { return false; } } 

Cambia la variabile canvasID base al tuo ID.

Testato su Chrome, Safari, Firefox, Opera e IE (da 8 a 10). In caso di Safari ricordati che è disponibile, ma devi abilitare WebGL esplicitamente (abilita il menu sviluppatore e triggers l’opzione Web GL dopo).

Al fine di rilevare i browser che supportano WebGL, ma potrebbe non supportare molto i browser più vecchi (se necessario in WebGL rilevato come supportato quando non è in realtà per escludere dispositivi Android 4.4.2), sto aggiungendo un più stretto, anche se controllo non correlato:

 function hasWebGL() { var supported; try { var canvas = document.createElement('canvas'); supported = !! window.WebGLRenderingContext && (canvas.getContext('webgl') || canvas.getContext('experimental-webgl')); } catch(e) { supported = false; } try { // let is by no means required, but will help us rule out some old browsers/devices with potentially buggy implementations: http://caniuse.com/#feat=let eval('let foo = 123;'); } catch (e) { supported = false; } if (supported === false) { console.log("WebGL is not supported"); } canvas = undefined; return supported; }, 
 // this code will detect WebGL version until WebGL Version maxVersionTest var maxVersionTest = 5, canvas = document.createElement('canvas'), webglVersion = (canvas.getContext('webgl') || canvas.getContext('experimental-webgl')) ? 1 : null, canvas = null; // free context // range: if maxVersionTest = 5 makes [5, 4, 3, 2] Array.apply(null, Array(maxVersionTest - 1)) .map(function (_, idx) {return idx + 2;}) .reverse() .some(function(version){ // cant reuse canvas, potential to exceed contexts or mem limit * if (document.createElement('canvas').getContext('webgl'+version)) return !!(webglVersion = version); }); console.log(webglVersion); 

* re “potenziale per superare contesti o limite di mem” vedi https://bugs.chromium.org/p/chromium/issues/detail?id=226868

Da MDN :

 // Run everything inside window load event handler, to make sure // DOM is fully loaded and styled before trying to manipulate it. window.addEventListener("load", function() { var paragraph = document.querySelector("p"), button = document.querySelector("button"); // Adding click event handler to button. button.addEventListener("click", detectWebGLContext, false); function detectWebGLContext () { // Create canvas element. The canvas is not added to the // document itself, so it is never displayed in the // browser window. var canvas = document.createElement("canvas"); // Get WebGLRenderingContext from canvas element. var gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl"); // Report the result. if (gl && gl instanceof WebGLRenderingContext) { paragraph.innerHTML = "Congratulations! Your browser supports WebGL."; } else { paragraph.innerHTML = "Failed to get WebGL context. " + "Your browser or device may not support WebGL."; } } }, false); 
 body { text-align : center; } button { display : block; font-size : inherit; margin : auto; padding : 0.6em; } 
 

[ Here would go the result of WebGL feature detection ]