securityos/node_modules/regl/lib/webgl.js

220 lines
5.4 KiB
JavaScript

// Context and canvas creation helper functions
var check = require('./util/check')
var extend = require('./util/extend')
function createCanvas (element, onDone, pixelRatio) {
var canvas = document.createElement('canvas')
extend(canvas.style, {
border: 0,
margin: 0,
padding: 0,
top: 0,
left: 0,
width: '100%',
height: '100%'
})
element.appendChild(canvas)
if (element === document.body) {
canvas.style.position = 'absolute'
extend(element.style, {
margin: 0,
padding: 0
})
}
function resize () {
var w = window.innerWidth
var h = window.innerHeight
if (element !== document.body) {
var bounds = canvas.getBoundingClientRect()
w = bounds.right - bounds.left
h = bounds.bottom - bounds.top
}
canvas.width = pixelRatio * w
canvas.height = pixelRatio * h
}
var resizeObserver
if (element !== document.body && typeof ResizeObserver === 'function') {
// ignore 'ResizeObserver' is not defined
// eslint-disable-next-line
resizeObserver = new ResizeObserver(function () {
// setTimeout to avoid flicker
setTimeout(resize)
})
resizeObserver.observe(element)
} else {
window.addEventListener('resize', resize, false)
}
function onDestroy () {
if (resizeObserver) {
resizeObserver.disconnect()
} else {
window.removeEventListener('resize', resize)
}
element.removeChild(canvas)
}
resize()
return {
canvas: canvas,
onDestroy: onDestroy
}
}
function createContext (canvas, contextAttributes) {
function get (name) {
try {
return canvas.getContext(name, contextAttributes)
} catch (e) {
return null
}
}
return (
get('webgl') ||
get('experimental-webgl') ||
get('webgl-experimental')
)
}
function isHTMLElement (obj) {
return (
typeof obj.nodeName === 'string' &&
typeof obj.appendChild === 'function' &&
typeof obj.getBoundingClientRect === 'function'
)
}
function isWebGLContext (obj) {
return (
typeof obj.drawArrays === 'function' ||
typeof obj.drawElements === 'function'
)
}
function parseExtensions (input) {
if (typeof input === 'string') {
return input.split()
}
check(Array.isArray(input), 'invalid extension array')
return input
}
function getElement (desc) {
if (typeof desc === 'string') {
check(typeof document !== 'undefined', 'not supported outside of DOM')
return document.querySelector(desc)
}
return desc
}
module.exports = function parseArgs (args_) {
var args = args_ || {}
var element, container, canvas, gl
var contextAttributes = {}
var extensions = []
var optionalExtensions = []
var pixelRatio = (typeof window === 'undefined' ? 1 : window.devicePixelRatio)
var profile = false
var onDone = function (err) {
if (err) {
check.raise(err)
}
}
var onDestroy = function () {}
if (typeof args === 'string') {
check(
typeof document !== 'undefined',
'selector queries only supported in DOM enviroments')
element = document.querySelector(args)
check(element, 'invalid query string for element')
} else if (typeof args === 'object') {
if (isHTMLElement(args)) {
element = args
} else if (isWebGLContext(args)) {
gl = args
canvas = gl.canvas
} else {
check.constructor(args)
if ('gl' in args) {
gl = args.gl
} else if ('canvas' in args) {
canvas = getElement(args.canvas)
} else if ('container' in args) {
container = getElement(args.container)
}
if ('attributes' in args) {
contextAttributes = args.attributes
check.type(contextAttributes, 'object', 'invalid context attributes')
}
if ('extensions' in args) {
extensions = parseExtensions(args.extensions)
}
if ('optionalExtensions' in args) {
optionalExtensions = parseExtensions(args.optionalExtensions)
}
if ('onDone' in args) {
check.type(
args.onDone, 'function',
'invalid or missing onDone callback')
onDone = args.onDone
}
if ('profile' in args) {
profile = !!args.profile
}
if ('pixelRatio' in args) {
pixelRatio = +args.pixelRatio
check(pixelRatio > 0, 'invalid pixel ratio')
}
}
} else {
check.raise('invalid arguments to regl')
}
if (element) {
if (element.nodeName.toLowerCase() === 'canvas') {
canvas = element
} else {
container = element
}
}
if (!gl) {
if (!canvas) {
check(
typeof document !== 'undefined',
'must manually specify webgl context outside of DOM environments')
var result = createCanvas(container || document.body, onDone, pixelRatio)
if (!result) {
return null
}
canvas = result.canvas
onDestroy = result.onDestroy
}
// workaround for chromium bug, premultiplied alpha value is platform dependent
if (contextAttributes.premultipliedAlpha === undefined) contextAttributes.premultipliedAlpha = true
gl = createContext(canvas, contextAttributes)
}
if (!gl) {
onDestroy()
onDone('webgl not supported, try upgrading your browser or graphics drivers http://get.webgl.org')
return null
}
return {
gl: gl,
canvas: canvas,
container: container,
extensions: extensions,
optionalExtensions: optionalExtensions,
pixelRatio: pixelRatio,
profile: profile,
onDone: onDone,
onDestroy: onDestroy
}
}