Правильный способ обнаружения поддержки WebGL?
Я пытаюсь обнаружить поддержку WebGL в нескольких браузерах, и я столкнулся со следующим сценарием. Текущая версия Firefox сообщает о положительной поддержке, используя следующую проверку, даже если видеокарта посетителя находится в черном списке и / или WebGL отключена:
if (window.WebGLRenderingContext) {
// This is true in Firefox under certain circumstances,
// even when WebGL is disabled...
}
Я попытался проинструктировать моих пользователей включить WebGL, используя следующие шаги. В некоторых случаях это срабатывало, но не всегда. Очевидно, это не то, что я могу запросить у широкая публика:
- тип about: config в адресной строке Firefox
- чтобы включить WebGL, установите в WebGL.force-enabled истина
Это привело меня к созданию моего собственного метода обнаружения поддержки, который использует jQuery для ввода элемента canvas для обнаружения поддержки. Это тянет на ряд методов, которые я нашел в различных библиотеках WebGL и плагинов. Беда в том, что это чрезвычайно трудно проверить (любые комментарии о том, ссылка ниже работает для вас очень ценит!). Чтобы сделать этот вопрос объективным,Я хотел бы знать, есть ли универсально принятый способ обнаружения поддержки WebGL во всех браузерах.
ТЕСТ URL:
7 ответов
[октября 2014 года] я обновил пример modernizrs, чтобы соответствовать их текущая реализация, который очищен от версии 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;
хром указывает на http://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; }
}
отличная библиотека Three имеет, по сути, механизм для обнаружения следующего:
- поддержка WebGL
- поддержка API файлов
- сотрудники
для WebGL, в частности, вот код:
function webgl_support () {
try {
var canvas = document.createElement('canvas');
return !!window.WebGLRenderingContext &&
(canvas.getContext('webgl') || canvas.getContext('experimental-webgl'));
} catch(e) {
return false;
}
};
этот фрагмент кода является частью детектор класс, который также может отображать соответствующие сообщения об ошибках пользователю.
Как видно из http://www.browserleaks.com/webgl#howto-detect-webgl
это правильная функция javascript для обнаружения поддержки WebGL, со всеми видами экспериментальных имен контекста WebGL и с проверкой особых случаев, таких как блокировка функций WebGL NoScript или TorBrowser.
он сообщит об одном из трех состояний возможности WebGL:
- WebGL включен-return TRUE или return
- объект WebGL, если был передан первый аргумент
- WebGL отключен-return FALSE, вы можете изменить его, если вам нужно>
- WebGL не имплиментируется-return 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;
}
в дополнение к ответу @Andrew существует также экспериментальный режим, который может быть поддержан. Я написал следующий фрагмент кода:
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
переменная в соответствии с вашим ID.
протестировано на Chrome, Safari, Firefox, Opera и IEs (от 8 до 10). В случае Safari помните, что он доступен, но вам нужно включить WebGL явно (включите меню разработчика и включите опцию Web GL после).
чтобы обнаружить браузеры, которые поддерживают WebGL, но оставляя старые браузеры с может не поддерживать его хорошо (как это необходимо в WebGL обнаружен как поддерживаемый, когда он на самом деле не для исключения устройств 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;
},
// 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 "потенциал превысить контексты или предел mem" см. https://bugs.chromium.org/p/chromium/issues/detail?id=226868
С 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>