From e5c378a13548d8f7ef7e1f883e7a98fd0e9207b4 Mon Sep 17 00:00:00 2001 From: Duckonaut Date: Mon, 9 Nov 2026 17:42:26 +0100 Subject: visits and cleanup --- public/assets/GlslCanvas.js | 2064 ------------------------------------------- public/assets/index.js | 91 -- 2 files changed, 2155 deletions(-) delete mode 100644 public/assets/GlslCanvas.js delete mode 100644 public/assets/index.js (limited to 'public') diff --git a/public/assets/GlslCanvas.js b/public/assets/GlslCanvas.js deleted file mode 100644 index ab29380..0000000 --- a/public/assets/GlslCanvas.js +++ /dev/null @@ -1,2064 +0,0 @@ -// MIT, from https://github.com/patriciogonzalezvivo/glslCanvas/blob/master/dist/GlslCanvas.js - -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : - typeof define === 'function' && define.amd ? define(factory) : - (global.GlslCanvas = factory()); -}(this, (function () { 'use strict'; - -var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; - -var win; - -if (typeof window !== "undefined") { - win = window; -} else if (typeof commonjsGlobal !== "undefined") { - win = commonjsGlobal; -} else if (typeof self !== "undefined"){ - win = self; -} else { - win = {}; -} - -var window_1 = win; - -var isFunction_1 = isFunction; - -var toString = Object.prototype.toString; - -function isFunction (fn) { - if (!fn) { - return false - } - var string = toString.call(fn); - return string === '[object Function]' || - (typeof fn === 'function' && string !== '[object RegExp]') || - (typeof window !== 'undefined' && - // IE8 and below - (fn === window.setTimeout || - fn === window.alert || - fn === window.confirm || - fn === window.prompt)) -} - -var trim = function(string) { - return string.replace(/^\s+|\s+$/g, ''); -}; -var isArray = function(arg) { - return Object.prototype.toString.call(arg) === '[object Array]'; - }; - -var parseHeaders = function (headers) { - if (!headers) - return {} - - var result = {}; - - var headersArr = trim(headers).split('\n'); - - for (var i = 0; i < headersArr.length; i++) { - var row = headersArr[i]; - var index = row.indexOf(':') - , key = trim(row.slice(0, index)).toLowerCase() - , value = trim(row.slice(index + 1)); - - if (typeof(result[key]) === 'undefined') { - result[key] = value; - } else if (isArray(result[key])) { - result[key].push(value); - } else { - result[key] = [ result[key], value ]; - } - } - - return result -}; - -var immutable = extend; - -var hasOwnProperty = Object.prototype.hasOwnProperty; - -function extend() { - var target = {}; - - for (var i = 0; i < arguments.length; i++) { - var source = arguments[i]; - - for (var key in source) { - if (hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } - - return target -} - -"use strict"; - - - - - -var xhr = createXHR; -// Allow use of default import syntax in TypeScript -var default_1 = createXHR; -createXHR.XMLHttpRequest = window_1.XMLHttpRequest || noop; -createXHR.XDomainRequest = "withCredentials" in (new createXHR.XMLHttpRequest()) ? createXHR.XMLHttpRequest : window_1.XDomainRequest; - -forEachArray(["get", "put", "post", "patch", "head", "delete"], function(method) { - createXHR[method === "delete" ? "del" : method] = function(uri, options, callback) { - options = initParams(uri, options, callback); - options.method = method.toUpperCase(); - return _createXHR(options) - }; -}); - -function forEachArray(array, iterator) { - for (var i = 0; i < array.length; i++) { - iterator(array[i]); - } -} - -function isEmpty(obj){ - for(var i in obj){ - if(obj.hasOwnProperty(i)) return false - } - return true -} - -function initParams(uri, options, callback) { - var params = uri; - - if (isFunction_1(options)) { - callback = options; - if (typeof uri === "string") { - params = {uri:uri}; - } - } else { - params = immutable(options, {uri: uri}); - } - - params.callback = callback; - return params -} - -function createXHR(uri, options, callback) { - options = initParams(uri, options, callback); - return _createXHR(options) -} - -function _createXHR(options) { - if(typeof options.callback === "undefined"){ - throw new Error("callback argument missing") - } - - var called = false; - var callback = function cbOnce(err, response, body){ - if(!called){ - called = true; - options.callback(err, response, body); - } - }; - - function readystatechange() { - if (xhr.readyState === 4) { - setTimeout(loadFunc, 0); - } - } - - function getBody() { - // Chrome with requestType=blob throws errors arround when even testing access to responseText - var body = undefined; - - if (xhr.response) { - body = xhr.response; - } else { - body = xhr.responseText || getXml(xhr); - } - - if (isJson) { - try { - body = JSON.parse(body); - } catch (e) {} - } - - return body - } - - function errorFunc(evt) { - clearTimeout(timeoutTimer); - if(!(evt instanceof Error)){ - evt = new Error("" + (evt || "Unknown XMLHttpRequest Error") ); - } - evt.statusCode = 0; - return callback(evt, failureResponse) - } - - // will load the data & process the response in a special response object - function loadFunc() { - if (aborted) return - var status; - clearTimeout(timeoutTimer); - if(options.useXDR && xhr.status===undefined) { - //IE8 CORS GET successful response doesn't have a status field, but body is fine - status = 200; - } else { - status = (xhr.status === 1223 ? 204 : xhr.status); - } - var response = failureResponse; - var err = null; - - if (status !== 0){ - response = { - body: getBody(), - statusCode: status, - method: method, - headers: {}, - url: uri, - rawRequest: xhr - }; - if(xhr.getAllResponseHeaders){ //remember xhr can in fact be XDR for CORS in IE - response.headers = parseHeaders(xhr.getAllResponseHeaders()); - } - } else { - err = new Error("Internal XMLHttpRequest Error"); - } - return callback(err, response, response.body) - } - - var xhr = options.xhr || null; - - if (!xhr) { - if (options.cors || options.useXDR) { - xhr = new createXHR.XDomainRequest(); - }else{ - xhr = new createXHR.XMLHttpRequest(); - } - } - - var key; - var aborted; - var uri = xhr.url = options.uri || options.url; - var method = xhr.method = options.method || "GET"; - var body = options.body || options.data; - var headers = xhr.headers = options.headers || {}; - var sync = !!options.sync; - var isJson = false; - var timeoutTimer; - var failureResponse = { - body: undefined, - headers: {}, - statusCode: 0, - method: method, - url: uri, - rawRequest: xhr - }; - - if ("json" in options && options.json !== false) { - isJson = true; - headers["accept"] || headers["Accept"] || (headers["Accept"] = "application/json"); //Don't override existing accept header declared by user - if (method !== "GET" && method !== "HEAD") { - headers["content-type"] || headers["Content-Type"] || (headers["Content-Type"] = "application/json"); //Don't override existing accept header declared by user - body = JSON.stringify(options.json === true ? body : options.json); - } - } - - xhr.onreadystatechange = readystatechange; - xhr.onload = loadFunc; - xhr.onerror = errorFunc; - // IE9 must have onprogress be set to a unique function. - xhr.onprogress = function () { - // IE must die - }; - xhr.onabort = function(){ - aborted = true; - }; - xhr.ontimeout = errorFunc; - xhr.open(method, uri, !sync, options.username, options.password); - //has to be after open - if(!sync) { - xhr.withCredentials = !!options.withCredentials; - } - // Cannot set timeout with sync request - // not setting timeout on the xhr object, because of old webkits etc. not handling that correctly - // both npm's request and jquery 1.x use this kind of timeout, so this is being consistent - if (!sync && options.timeout > 0 ) { - timeoutTimer = setTimeout(function(){ - if (aborted) return - aborted = true;//IE9 may still call readystatechange - xhr.abort("timeout"); - var e = new Error("XMLHttpRequest timeout"); - e.code = "ETIMEDOUT"; - errorFunc(e); - }, options.timeout ); - } - - if (xhr.setRequestHeader) { - for(key in headers){ - if(headers.hasOwnProperty(key)){ - xhr.setRequestHeader(key, headers[key]); - } - } - } else if (options.headers && !isEmpty(options.headers)) { - throw new Error("Headers cannot be set on an XDomainRequest object") - } - - if ("responseType" in options) { - xhr.responseType = options.responseType; - } - - if ("beforeSend" in options && - typeof options.beforeSend === "function" - ) { - options.beforeSend(xhr); - } - - // Microsoft Edge browser sends "undefined" when send is called with undefined value. - // XMLHttpRequest spec says to pass null as body to indicate no body - // See https://github.com/naugtur/xhr/issues/100. - xhr.send(body || null); - - return xhr - - -} - -function getXml(xhr) { - // xhr.responseXML will throw Exception "InvalidStateError" or "DOMException" - // See https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseXML. - try { - if (xhr.responseType === "document") { - return xhr.responseXML - } - var firefoxBugTakenEffect = xhr.responseXML && xhr.responseXML.documentElement.nodeName === "parsererror"; - if (xhr.responseType === "" && !firefoxBugTakenEffect) { - return xhr.responseXML - } - } catch (e) {} - - return null -} - -function noop() {} - -xhr.default = default_1; - -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { - return typeof obj; -} : function (obj) { - return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; -}; - - - - - -var asyncGenerator = function () { - function AwaitValue(value) { - this.value = value; - } - - function AsyncGenerator(gen) { - var front, back; - - function send(key, arg) { - return new Promise(function (resolve, reject) { - var request = { - key: key, - arg: arg, - resolve: resolve, - reject: reject, - next: null - }; - - if (back) { - back = back.next = request; - } else { - front = back = request; - resume(key, arg); - } - }); - } - - function resume(key, arg) { - try { - var result = gen[key](arg); - var value = result.value; - - if (value instanceof AwaitValue) { - Promise.resolve(value.value).then(function (arg) { - resume("next", arg); - }, function (arg) { - resume("throw", arg); - }); - } else { - settle(result.done ? "return" : "normal", result.value); - } - } catch (err) { - settle("throw", err); - } - } - - function settle(type, value) { - switch (type) { - case "return": - front.resolve({ - value: value, - done: true - }); - break; - - case "throw": - front.reject(value); - break; - - default: - front.resolve({ - value: value, - done: false - }); - break; - } - - front = front.next; - - if (front) { - resume(front.key, front.arg); - } else { - back = null; - } - } - - this._invoke = send; - - if (typeof gen.return !== "function") { - this.return = undefined; - } - } - - if (typeof Symbol === "function" && Symbol.asyncIterator) { - AsyncGenerator.prototype[Symbol.asyncIterator] = function () { - return this; - }; - } - - AsyncGenerator.prototype.next = function (arg) { - return this._invoke("next", arg); - }; - - AsyncGenerator.prototype.throw = function (arg) { - return this._invoke("throw", arg); - }; - - AsyncGenerator.prototype.return = function (arg) { - return this._invoke("return", arg); - }; - - return { - wrap: function (fn) { - return function () { - return new AsyncGenerator(fn.apply(this, arguments)); - }; - }, - await: function (value) { - return new AwaitValue(value); - } - }; -}(); - - - - - -var classCallCheck = function (instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } -}; - -var createClass = function () { - function defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i]; - descriptor.enumerable = descriptor.enumerable || false; - descriptor.configurable = true; - if ("value" in descriptor) descriptor.writable = true; - Object.defineProperty(target, descriptor.key, descriptor); - } - } - - return function (Constructor, protoProps, staticProps) { - if (protoProps) defineProperties(Constructor.prototype, protoProps); - if (staticProps) defineProperties(Constructor, staticProps); - return Constructor; - }; -}(); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -var toConsumableArray = function (arr) { - if (Array.isArray(arr)) { - for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; - - return arr2; - } else { - return Array.from(arr); - } -}; - -var lastError = ''; - -/** - * Creates the HTLM for a failure message - * @param {string} canvasContainerId id of container of th - * canvas. - * @return {string} The html. - */ -function makeFailHTML(msg) { - return '\n\n
\n
\n
' + msg + '
\n
\n
\n'; -} - -/** - * Message for getting a webgl browser - * @type {string} - */ -var GET_A_WEBGL_BROWSER = '\n\tThis page requires a browser that supports WebGL.
\n\tClick here to upgrade your browser.\n'; - -/** - * Message for need better hardware - * @type {string} - */ -var OTHER_PROBLEM = '\n\tIt does not appear your computer can support WebGL.
\n\tClick here for more information.\n'; - -/** - * Code to return in `onError` callback when the browser doesn't support webgl - * @type {number} - */ -var ERROR_BROWSER_SUPPORT = 1; - -/** - * Code to return in `onError` callback there's any other problem related to webgl - * @type {number} - */ -var ERROR_OTHER = 2; - -/** - * Creates a webgl context. If creation fails it will - * change the contents of the container of the - * tag to an error message with the correct links for WebGL, - * unless `onError` option is defined to a callback, - * which allows for custom error handling.. - * @param {Element} canvas. The canvas element to create a - * context from. - * @param {WebGLContextCreationAttributes} optAttribs Any - * creation attributes you want to pass in. - * @return {WebGLRenderingContext} The created context. - */ -function setupWebGL(canvas, optAttribs, onError) { - function showLink(str) { - var container = canvas.parentNode; - if (container) { - container.innerHTML = makeFailHTML(str); - } - } - - function handleError(errorCode, msg) { - if (typeof onError === 'function') { - onError(errorCode); - } else { - showLink(msg); - } - } - - if (!window.WebGLRenderingContext) { - handleError(ERROR_BROWSER_SUPPORT, GET_A_WEBGL_BROWSER); - return null; - } - - var context = create3DContext(canvas, optAttribs); - if (!context) { - handleError(ERROR_OTHER, OTHER_PROBLEM); - } else { - context.getExtension('OES_standard_derivatives'); - } - return context; -} - -/** - * Creates a webgl context. - * @param {!Canvas} canvas The canvas tag to get context - * from. If one is not passed in one will be created. - * @return {!WebGLContext} The created context. - */ -function create3DContext(canvas, optAttribs) { - var names = ['webgl', 'experimental-webgl']; - var context = null; - for (var ii = 0; ii < names.length; ++ii) { - try { - context = canvas.getContext(names[ii], optAttribs); - } catch (e) { - if (context) { - break; - } - } - } - return context; -} - -/* - * Create a Vertex of a specific type (gl.VERTEX_SHADER/) - */ -function createShader(main, source, type, offset) { - var gl = main.gl; - - var shader = gl.createShader(type); - gl.shaderSource(shader, source); - gl.compileShader(shader); - - var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS); - - if (!compiled) { - // Something went wrong during compilation; get the error - lastError = gl.getShaderInfoLog(shader); - console.error('*** Error compiling shader ' + shader + ':' + lastError); - main.trigger('error', { - shader: shader, - source: source, - type: type, - error: lastError, - offset: offset || 0 - }); - gl.deleteShader(shader); - return null; - } - - return shader; -} - -/** - * Loads a shader. - * @param {!WebGLContext} gl The WebGLContext to use. - * @param {string} shaderSource The shader source. - * @param {number} shaderType The type of shader. - * @param {function(string): void) opt_errorCallback callback for errors. - * @return {!WebGLShader} The created shader. - */ -function createProgram(main, shaders, optAttribs, optLocations) { - var gl = main.gl; - - var program = gl.createProgram(); - for (var ii = 0; ii < shaders.length; ++ii) { - gl.attachShader(program, shaders[ii]); - } - if (optAttribs) { - for (var _ii = 0; _ii < optAttribs.length; ++_ii) { - gl.bindAttribLocation(program, optLocations ? optLocations[_ii] : _ii, optAttribs[_ii]); - } - } - gl.linkProgram(program); - - // Check the link status - var linked = gl.getProgramParameter(program, gl.LINK_STATUS); - if (!linked) { - // something went wrong with the link - lastError = gl.getProgramInfoLog(program); - console.log('Error in program linking:' + lastError); - gl.deleteProgram(program); - return null; - } - return program; -} - -// By Brett Camber on -// https://github.com/tangrams/tangram/blob/master/src/gl/glsl.js -function parseUniforms(uniforms) { - var prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; - - var parsed = []; - - for (var name in uniforms) { - var uniform = uniforms[name]; - var u = void 0; - - if (prefix) { - name = prefix + '.' + name; - } - - // Single float - if (typeof uniform === 'number') { - parsed.push({ - type: 'float', - method: '1f', - name: name, - value: uniform - }); - } - // Array: vector, array of floats, array of textures, or array of structs - else if (Array.isArray(uniform)) { - // Numeric values - if (typeof uniform[0] === 'number') { - // float vectors (vec2, vec3, vec4) - if (uniform.length === 1) { - parsed.push({ - type: 'float', - method: '1f', - name: name, - value: uniform - }); - } - // float vectors (vec2, vec3, vec4) - else if (uniform.length >= 2 && uniform.length <= 4) { - parsed.push({ - type: 'vec' + uniform.length, - method: uniform.length + 'fv', - name: name, - value: uniform - }); - } - // float array - else if (uniform.length > 4) { - parsed.push({ - type: 'float[]', - method: '1fv', - name: name + '[0]', - value: uniform - }); - } - // TODO: assume matrix for (typeof == Float32Array && length == 16)? - } - // Array of textures - else if (typeof uniform[0] === 'string') { - parsed.push({ - type: 'sampler2D', - method: '1i', - name: name, - value: uniform - }); - } - // Array of arrays - but only arrays of vectors are allowed in this case - else if (Array.isArray(uniform[0]) && typeof uniform[0][0] === 'number') { - // float vectors (vec2, vec3, vec4) - if (uniform[0].length >= 2 && uniform[0].length <= 4) { - // Set each vector in the array - for (u = 0; u < uniform.length; u++) { - parsed.push({ - type: 'vec' + uniform[0].length, - method: uniform[u].length + 'fv', - name: name + '[' + u + ']', - value: uniform[u] - }); - } - } - // else error? - } - // Array of structures - else if (_typeof(uniform[0]) === 'object') { - for (u = 0; u < uniform.length; u++) { - // Set each struct in the array - parsed.push.apply(parsed, toConsumableArray(parseUniforms(uniform[u], name + '[' + u + ']'))); - } - } - } - // Boolean - else if (typeof uniform === 'boolean') { - parsed.push({ - type: 'bool', - method: '1i', - name: name, - value: uniform - }); - } - // Texture - else if (typeof uniform === 'string') { - parsed.push({ - type: 'sampler2D', - method: '1i', - name: name, - value: uniform - }); - } - // Structure - else if ((typeof uniform === 'undefined' ? 'undefined' : _typeof(uniform)) === 'object') { - // Set each field in the struct - parsed.push.apply(parsed, toConsumableArray(parseUniforms(uniform, name))); - } - // TODO: support other non-float types? (int, etc.) - } - return parsed; -} - -function isCanvasVisible(canvas) { - var bound = canvas.getBoundingClientRect(); - return bound.top + bound.height > 0 && bound.top < (window.innerHeight || document.documentElement.clientHeight); -} - -function isPowerOf2(value) { - return (value & value - 1) === 0; -} - -function isSafari() { - return (/^((?!chrome|android).)*safari/i.test(navigator.userAgent) - ); -} - - - - - - - -function isDiff(a, b) { - if (a && b) { - return a.toString() !== b.toString(); - } - return false; -} - -function getFile(url) { - var httpRequest = new XMLHttpRequest(); - httpRequest.open("GET", url, false); - httpRequest.send(); - if (httpRequest.status == 200) return httpRequest.responseText;else return ""; -} - -function subscribeMixin$1(target) { - var listeners = new Set(); - - return Object.assign(target, { - on: function on(type, f) { - var listener = {}; - listener[type] = f; - listeners.add(listener); - }, - off: function off(type, f) { - if (f) { - var listener = {}; - listener[type] = f; - listeners.delete(listener); - } else { - var _iteratorNormalCompletion = true; - var _didIteratorError = false; - var _iteratorError = undefined; - - try { - for (var _iterator = listeners[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { - var item = _step.value; - var _iteratorNormalCompletion2 = true; - var _didIteratorError2 = false; - var _iteratorError2 = undefined; - - try { - for (var _iterator2 = Object.keys(item)[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { - var key = _step2.value; - - if (key === type) { - listeners.delete(item); - return; - } - } - } catch (err) { - _didIteratorError2 = true; - _iteratorError2 = err; - } finally { - try { - if (!_iteratorNormalCompletion2 && _iterator2.return) { - _iterator2.return(); - } - } finally { - if (_didIteratorError2) { - throw _iteratorError2; - } - } - } - } - } catch (err) { - _didIteratorError = true; - _iteratorError = err; - } finally { - try { - if (!_iteratorNormalCompletion && _iterator.return) { - _iterator.return(); - } - } finally { - if (_didIteratorError) { - throw _iteratorError; - } - } - } - } - }, - listSubscriptions: function listSubscriptions() { - var _iteratorNormalCompletion3 = true; - var _didIteratorError3 = false; - var _iteratorError3 = undefined; - - try { - for (var _iterator3 = listeners[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { - var item = _step3.value; - - console.log(item); - } - } catch (err) { - _didIteratorError3 = true; - _iteratorError3 = err; - } finally { - try { - if (!_iteratorNormalCompletion3 && _iterator3.return) { - _iterator3.return(); - } - } finally { - if (_didIteratorError3) { - throw _iteratorError3; - } - } - } - }, - subscribe: function subscribe(listener) { - listeners.add(listener); - }, - unsubscribe: function unsubscribe(listener) { - listeners.delete(listener); - }, - unsubscribeAll: function unsubscribeAll() { - listeners.clear(); - }, - trigger: function trigger(event) { - for (var _len = arguments.length, data = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { - data[_key - 1] = arguments[_key]; - } - - var _iteratorNormalCompletion4 = true; - var _didIteratorError4 = false; - var _iteratorError4 = undefined; - - try { - for (var _iterator4 = listeners[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) { - var listener = _step4.value; - - if (typeof listener[event] === 'function') { - listener[event].apply(listener, toConsumableArray(data)); - } - } - } catch (err) { - _didIteratorError4 = true; - _iteratorError4 = err; - } finally { - try { - if (!_iteratorNormalCompletion4 && _iterator4.return) { - _iterator4.return(); - } - } finally { - if (_didIteratorError4) { - throw _iteratorError4; - } - } - } - } - }); -} - -// Texture management -// GL texture wrapper object for keeping track of a global set of textures, keyed by a unique user-defined name - -var Texture = function () { - function Texture(gl, name) { - var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; - classCallCheck(this, Texture); - - subscribeMixin$1(this); - - this.gl = gl; - this.texture = gl.createTexture(); - if (this.texture) { - this.valid = true; - } - this.bind(); - - this.name = name; - this.source = null; - this.sourceType = null; - this.loading = null; // a Promise object to track the loading state of this texture - - // Default to a 1-pixel black texture so we can safely render while we wait for an image to load - // See: http://stackoverflow.com/questions/19722247/webgl-wait-for-texture-to-load - this.setData(1, 1, new Uint8Array([0, 0, 0, 255]), { filtering: 'linear' }); - this.setFiltering(options.filtering); - - this.load(options); - } - - // Destroy a single texture instance - - - createClass(Texture, [{ - key: 'destroy', - value: function destroy() { - if (!this.valid) { - return; - } - this.gl.deleteTexture(this.texture); - this.texture = null; - delete this.data; - this.data = null; - this.valid = false; - } - }, { - key: 'bind', - value: function bind(unit) { - if (!this.valid) { - return; - } - if (typeof unit === 'number') { - if (Texture.activeUnit !== unit) { - this.gl.activeTexture(this.gl.TEXTURE0 + unit); - Texture.activeUnit = unit; - } - } - if (Texture.activeTexture !== this.texture) { - this.gl.bindTexture(this.gl.TEXTURE_2D, this.texture); - Texture.activeTexture = this.texture; - } - } - }, { - key: 'load', - value: function load() { - var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - - this.loading = null; - - if (typeof options.url === 'string') { - if (this.url === undefined || options.url !== this.url) { - this.setUrl(options.url, options); - } - } else if (options.element) { - this.setElement(options.element, options); - } else if (options.data && options.width && options.height) { - this.setData(options.width, options.height, options.data, options); - } - } - - // Sets texture from an url - - }, { - key: 'setUrl', - value: function setUrl(url) { - var _this = this; - - var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - if (!this.valid) { - return; - } - - this.url = url; // save URL reference (will be overwritten when element is loaded below) - this.source = this.url; - this.sourceType = 'url'; - - this.loading = new Promise(function (resolve, reject) { - var ext = url.split('.').pop().toLowerCase(); - var isVideo = ext === 'ogv' || ext === 'webm' || ext === 'mp4'; - - var element = undefined; - if (isVideo) { - element = document.createElement('video'); - element.autoplay = true; - - element.muted = true; /* required for modern browsers to autoplay video */ - setTimeout(function () { - element.play(); /* doesn't block promise but needs a more elegant solution */ - }, 1); - - options.filtering = 'nearest'; - // element.preload = 'auto'; - // element.style.display = 'none'; - // document.body.appendChild(element); - } else { - element = new Image(); - } - - element.onload = function () { - try { - _this.setElement(element, options); - } catch (e) { - console.log('Texture \'' + _this.name + '\': failed to load url: \'' + _this.source + '\'', e, options); - } - resolve(_this); - }; - element.onerror = function (e) { - // Warn and resolve on error - console.log('Texture \'' + _this.name + '\': failed to load url: \'' + _this.source + '\'', e, options); - resolve(_this); - }; - - // Safari has a bug loading data-URL elements with CORS enabled, so it must be disabled in that case - // https://bugs.webkit.org/show_bug.cgi?id=123978 - if (!(isSafari() && _this.source.slice(0, 5) === 'data:')) { - element.crossOrigin = 'anonymous'; - } - - element.src = _this.source; - if (isVideo) { - _this.setElement(element, options); - } - }); - return this.loading; - } - - // Sets texture to a raw image buffer - - }, { - key: 'setData', - value: function setData(width, height, data) { - var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; - - this.width = width; - this.height = height; - - this.source = data; - this.sourceType = 'data'; - - this.update(options); - this.setFiltering(options); - - this.loading = Promise.resolve(this); - return this.loading; - } - - // Sets the texture to track a element (canvas/image) - - }, { - key: 'setElement', - value: function setElement(element, options) { - var _this2 = this; - - var el = element; - - // a string element is interpeted as a CSS selector - if (typeof element === 'string') { - element = document.querySelector(element); - } - - if (element instanceof HTMLCanvasElement || element instanceof HTMLImageElement || element instanceof HTMLVideoElement) { - this.source = element; - this.sourceType = 'element'; - - if (element instanceof HTMLVideoElement) { - this.width = this.source.videoWidth; - this.height = this.source.videoHeight; - element.addEventListener('canplaythrough', function () { - _this2.intervalID = setInterval(function () { - _this2.update(options); - }, 15); - }, true); - element.addEventListener('ended', function () { - element.currentTime = 0; - element.play(); - }, true); - } else { - this.update(options); - } - this.setFiltering(options); - } else { - var msg = 'the \'element\' parameter (`element: ' + JSON.stringify(el) + '`) must be a CSS '; - msg += 'selector string, or a , or