UNPKG

awv3

Version:
282 lines (232 loc) 10.6 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = undefined; var _getIterator2 = require('babel-runtime/core-js/get-iterator'); var _getIterator3 = _interopRequireDefault(_getIterator2); var _extends2 = require('babel-runtime/helpers/extends'); var _extends3 = _interopRequireDefault(_extends2); var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _createClass2 = require('babel-runtime/helpers/createClass'); var _createClass3 = _interopRequireDefault(_createClass2); var _three = require('three'); var THREE = _interopRequireWildcard(_three); var _helpers = require('./helpers'); var Helpers = _interopRequireWildcard(_helpers); var _tween = require('../animation/tween'); var _tween2 = _interopRequireDefault(_tween); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var Renderer = function () { function Renderer() { var _this = this; var canvas = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : Error.log('Factory was initialized without canvas'); var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; (0, _classCallCheck3.default)(this, Renderer); options = (0, _extends3.default)({ resolution: parseFloat(Helpers.url('resolution')) || (window.devicePixelRatio ? window.devicePixelRatio : 1), pixelated: Helpers.url('pixelated') || false, clearColor: new THREE.Color(0), place: 'first', startImmediately: true, precision: 'highp', premultipliedAlpha: true, stencil: true, depth: true, preserveDrawingBuffer: false, alpha: true, antialias: true, logarithmicDepthBuffer: false, sortObjects: true, autoClear: false, canvasStyle: 'position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; overflow: hidden; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; -o-user-select: none; user-select: none;', shadowMapEnabled: true, shadowMapType: THREE.PCFShadowMap }, options); this.canvas = canvas; this.resolution = options.resolution; this.clearColor = options.clearColor; this.gl = new THREE.WebGLRenderer({ canvas: options.canvas, precision: options.precision, premultipliedAlpha: options.premultipliedAlpha, stencil: options.stencil, depth: options.depth, preserveDrawingBuffer: options.preserveDrawingBuffer, alpha: options.alpha, antialias: options.antialias, logarithmicDepthBuffer: options.logarithmicDepthBuffer }); this.context = this.gl.domElement; this.context.setAttribute('style', options.canvasStyle); if (!!options.pixelated) this.context.style.imageRendering = 'pixelated'; this.gl.sortObjects = options.sortObjects; this.gl.autoClear = options.autoClear; this.gl.shadowMap.enabled = options.shadowMapEnabled; this.gl.shadowMap.type = options.shadowMapType; if (options.place === 'last') canvas.dom.appendChild(this.context);else canvas.dom.insertBefore(this.context, canvas.dom.firstChild); this.resizeHandler = function () { return _this.resize(); }; window.addEventListener('resize', this.resizeHandler, false); // View frameworks can sometimes swallow resize events this.resize(); setTimeout(function () { return _this.resize(); }, 1); setTimeout(function () { return _this.resize(); }, 100); setTimeout(function () { return _this.resize(); }, 500); // Clear canvas this.gl.setPixelRatio(this.resolution); this.gl.setScissorTest(false); this.gl.setClearColor(this.clearColor, 0); this.gl.clear(); this.gl.setScissorTest(true); // Declare render loop here, because doing it on the prototype will lexically // bind 'this' using nested functions which would impact performance. var scope = this; this.invalidateFrames = 1; this.dirty = true; this.time = 0; this.render = function (time) { scope.time = time; // Request next frame requestAnimationFrame(scope.render); // Pass 1: measure canvas; do this only when the canvas is dirty if (scope.invalidateFrames > 0 && scope.dirty) { var bounds = scope.context.getBoundingClientRect(); // Test for changes, position & size if (bounds.left != scope.offset.left || bounds.top != scope.offset.top || bounds.width != scope.offset.width || bounds.height != scope.offset.height) { scope.offset = bounds; scope.invalidateCanvas(); // Size changed, canvas needs to adapt if (bounds.width != scope.offset.width || bounds.height != scope.offset.height) { scope.gl.setSize(scope.offset.width /* scope.resolution*/ , scope.offset.height /* scope.resolution*/ , false); } } scope.invalidateFrames--; } // Update animations _tween2.default.update(time, scope); // Pass 2: measure view changes, stamp out old space var revokeDirtyFlag = true; var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = (0, _getIterator3.default)(scope.canvas.views), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var view = _step.value; // If any view has measured changes, the canvas will remain dirty if (view.clear(time)) revokeDirtyFlag = false; } // Pass 3: render view content } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { for (var _iterator2 = (0, _getIterator3.default)(scope.canvas.views), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { var _view = _step2.value; _view.render(time); } // If nothing has changed in size or position the canvas is clean } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2.return) { _iterator2.return(); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } if (revokeDirtyFlag) scope.dirty = false; }; // Start render loop if (options.startImmediately) this.start(); } (0, _createClass3.default)(Renderer, [{ key: 'destroy', value: function destroy() { this.context.remove(); this.render = function () {}; window.removeEventListener('resize', this.resizeHandler); this.gl.dispose(); this.gl = undefined; } }, { key: 'start', value: function start() { this.render(performance.now()); } }, { key: 'resize', value: function resize() { this.offset = this.context.getBoundingClientRect(); this.gl.setSize(this.offset.width /* this.resolution*/, this.offset.height /* this.resolution*/, false); this.invalidateCanvas(30); this.invalidateViews(30); } }, { key: 'invalidateCanvas', value: function invalidateCanvas() { var frames = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; this.invalidateFrames += frames; if (this.invalidateFrames > 60) this.invalidateFrames = 60; } }, { key: 'invalidateViews', value: function invalidateViews() { var frames = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; this.dirty = true; var _iteratorNormalCompletion3 = true; var _didIteratorError3 = false; var _iteratorError3 = undefined; try { for (var _iterator3 = (0, _getIterator3.default)(this.canvas.views), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { var view = _step3.value; view.invalidate(frames); } } catch (err) { _didIteratorError3 = true; _iteratorError3 = err; } finally { try { if (!_iteratorNormalCompletion3 && _iterator3.return) { _iterator3.return(); } } finally { if (_didIteratorError3) { throw _iteratorError3; } } } } }]); return Renderer; }(); exports.default = Renderer;