2012-08-08 141 views
44

我试图在多个浏览器中检测WebGL支持,并遇到以下情况。 Firefox的当前版本的出现使用下面的检查报告利好支撑,即使访问者的显卡是列入黑名单的和/或WebGL是禁用:检测WebGL支持的正确方法?

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

我试图要求我的用户使用,以使WebGL的以下步骤。这在某些情况下有效,但并非总是如此。显然,这不是我可以请广大市民:

  1. 类型about:config中在Firefox地址栏
  2. 要启用的WebGL,设置启用webgl.force-

这导致我创建了自己的方法来检测支持,它使用jQuery来注入一个canvas元素来检测支持。这吸收了我在各种WebGL库和插件中发现的许多技术。麻烦的是,测试非常困难(关于下面的链接是否适合您的任何评论都非常感谢!)。为了使这是一个客观的问题,我想知道是否有普遍接受的方式来检测所有浏览器 WebGL支持。

测试网址:

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

+1

伊克,我不知道有能超过'实验-webgl' WebGL的背景下更多的方法,谢谢为p注意到这一点。 – 2012-08-08 18:47:08

+0

你是什么意思你的方法很难测试?你是否担心会产生假阳性/阴性?在我看来,如果你要求一个webgl上下文而没有获得,那么你的应用程序无法继续。除非我错过了什么? – 2012-08-08 18:48:41

+0

@MattGreer,很难进行测试,因为找到具有Firefox和黑名单视频卡和/或不支持的图形的特定组合的测试机器很难。具体来说,我试图找出在什么情况下,我的测试方法将在最新版本的Firefox中返回'false'。 – 2012-08-08 18:54:43

回答

31

[2014年10月]我已经更新modernizrs例如,以满足他们current implementation,这是从http://get.webgl.org/下面进一步清理版本。

Modernizr确实,

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; 

Chromiumhttp://get.webgl.org/为规范支持实施,

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

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

这是否适用于所有OS-es中的所有浏览器? – SexyBeast 2013-07-30 21:45:48

+0

@Cupidvogel:所有[支持canvas的浏览器](http://caniuse.com/canvas),所以88.94%。你可以通过将它包装在[try-catch语句](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch)中来使其成为100%。 – rvighne 2014-08-04 20:09:37

+2

@Cupidvogel它不适用于Safari(7.0.3版本),它尚不支持'getContext(“webgl”)',并且只能用于getContext(“experimental-webgl”)或'的getContext( “WebKit的3D”)'。 – TachyonVortex 2014-10-05 11:40:52

8

除了@Andrew答案,也有可以支持新的模式。根据您的ID

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; } 
} 

更改canvasID变量:我已经写了下面的代码片段。

在Chrome,Safari,Firefox,Opera和IEs上测试(8到10)。如果Safari记住它可用,但您需要明确启用WebGL(启用开发者菜单并在之后启用Web GL选项)。

26

优异的三个库有,实际上,用于检测机构如下:

  1. WebGL的支持
  2. 文件API支持
  3. 工人支持

对于WebGL的,特别是,这里是使用的代码:

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

该代码片段是检测器类的一部分,它也可能会向用户显示相应的错误消息。看一看:https://github.com/mrdoob/three.js/blob/master/examples/js/Detector.js

+3

好看又紧凑。正是作者所要求的。我不明白为什么人们在他们的答案中包含额外的无关代码 – user151496 2015-09-30 09:39:00

+0

感谢您的回答! – 2017-05-17 22:10:56

16

正如http://www.browserleaks.com/webgl#howto-detect-webgl

这是一个正确的javascript函数所见检测WebGL的支持,各类实验WebGL的上下文名称,并用特殊的情况,如阻止WebGL的检查NoScript或TorBrowser的功能。

它会报告三个WebGL的能力状态之一:

  • WebGL的启动 - 返回TRUE,或返回
  • WebGL的对象,如果第一个参数传递
  • WebGL是禁用 - 回报FALSE,如果你需要>
  • WebGL是不是implimented你可以改变它 - 返回FALSE
function webgl_detect(return_context) 
{ 
    if (!!window.WebGLRenderingContext) { 
     var canvas = document.createElement("canvas"), 
      names = ["webgl", "experimental-webgl", "moz-webgl", "webkit-3d"], 
      context = false; 

     for(var i=0;i<4;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; 
} 
+0

为什么window.WebGLRenderingContext上的双重否定? – sijpkes 2016-01-19 00:12:42

+0

我真的不确定,我从上面的链接粘贴了适用于我的代码,但是这里有一些解释:http://stackoverflow.com/questions/784929/what-is-the-not-not -operator-in-javascript – 2016-01-21 16:52:06

+2

@sijpkes双重否定将truthy/falsey值转换为它们的布尔表示:'!!“”=== false && !! 1 === true' – WickyNilliams 2016-05-20 11:31:19

2

为了检测支持WebGL的浏览器,但遗漏了旧版浏览器并不能很好地支持它(根据WebGL detected as supported when it is actually not的规定排除Android 4.4.2设备),我添加了一个更紧密但无关的支票:

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; 
}, 
0
// 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); 

*重“势超过上下文或MEM限制”看到 https://bugs.chromium.org/p/chromium/issues/detail?id=226868