javascript - ¿La forma correcta de detectar el soporte de WebGL?
jquery firefox (7)
Estoy intentando detectar el soporte de WebGL en varios navegadores y me he encontrado con la siguiente situación. La versión actual de Firefox parece informar una compatibilidad positiva con la siguiente verificación, incluso cuando la tarjeta de video del visitante está en la lista negra y / o WebGL está desactivada:
if (window.WebGLRenderingContext) {
// This is true in Firefox under certain circumstances,
// even when WebGL is disabled...
}
Intenté ordenar a mis usuarios que habilitaran WebGL usando los siguientes pasos. Esto ha funcionado en algunos casos, pero no siempre. Obviamente, esto no es algo que pueda solicitar al público en general:
- Escriba about: config en la barra de direcciones de Firefox
- Para habilitar WebGL, configure webgl.force-enabled en true
Esto me ha llevado a crear mi propio método para detectar soporte, que usa jQuery para inyectar un elemento canvas para detectar soporte. Esto genera una serie de técnicas que encontré en varias bibliotecas y complementos de WebGL. El problema es que es extremadamente difícil de probar (cualquier comentario sobre si el enlace a continuación funciona para usted es muy apreciado). Para hacer de esto una pregunta objetiva, me gustaría saber si existe una forma universalmente aceptada para detectar el soporte de WebGL en todos los navegadores .
URL DE PRUEBA:
Además de @Andrew answer, también hay modo experimental que puede ser compatible. He escrito el siguiente fragmento de código:
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; }
}
Cambie la variable canvasID
acuerdo con su ID.
Probado en Chrome, Safari, Firefox, Opera e IEs (8 a 10). En el caso de Safari recuerda que está disponible, pero debes habilitar WebGL explícitamente (habilita el menú del desarrollador y habilita la opción Web GL después).
Como se ve en http://www.browserleaks.com/webgl#howto-detect-webgl
Esta es una función de JavaScript adecuada para detectar el soporte WebGL, con todo tipo de nombres de contexto WebGL experimentales y con la comprobación de casos especiales, como el bloqueo de funciones WebGL por NoScript o TorBrowser.
Reportará uno de los tres estados de capacidad de WebGL:
- WebGL está habilitado: devuelve TRUE o devuelve
- Objeto WebGL, si se pasó el primer argumento
- WebGL está deshabilitado - devuelve FALSO, puedes cambiarlo si lo necesitas>
- WebGL no está implícito - devuelve FALSO
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;
}
De 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;
}
<p>[ Here would go the result of WebGL feature detection ]</p>
<button>Press here to detect WebGLRenderingContext</button>
La excelente biblioteca Three tiene, de hecho, un mecanismo para detectar lo siguiente:
- Soporte WebGL
- Compatibilidad con API de archivos
- Apoyo de los trabajadores
Para WebGL, particularmente, aquí está el código que se usa:
function webgl_support () {
try {
var canvas = document.createElement(''canvas'');
return !!window.WebGLRenderingContext &&
(canvas.getContext(''webgl'') || canvas.getContext(''experimental-webgl''));
} catch(e) {
return false;
}
};
Ese fragmento de código es parte de una clase Detector que también puede mostrar los mensajes de error correspondientes al usuario.
Para detectar navegadores compatibles con WebGL, pero omitir los navegadores más antiguos puede que no lo admitan bien (como se necesita en WebGL detectado como compatible cuando en realidad no es para descartar dispositivos con Android 4.4.2), estoy agregando un navegador más estricto, aunque cheque no relacionado:
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;
},
[ Oct 2014] Actualicé el ejemplo de modernizrs para que coincida con su implementación actual , que es una versión limpiada de http://get.webgl.org/ más abajo.
Modernizr sí,
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 apunta a http://get.webgl.org/ para la implementación del soporte canónico,
try { gl = canvas.getContext("webgl"); }
catch (x) { gl = null; }
if (gl == null) {
try { gl = canvas.getContext("experimental-webgl"); experimental = true; }
catch (x) { gl = null; }
}
// 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 "potencial para superar contextos o límite de memoria", consulte https://bugs.chromium.org/p/chromium/issues/detail?id=226868