UNPKG

awv3

Version:
235 lines (187 loc) 7.43 kB
import _extends from "@babel/runtime/helpers/extends"; import _taggedTemplateLiteralLoose from "@babel/runtime/helpers/taggedTemplateLiteralLoose"; var _templateObject = /*#__PURE__*/ _taggedTemplateLiteralLoose(["Factory was initialized without canvas"], ["Factory was initialized without canvas"]); import * as THREE from 'three'; import { errUndefined, url } from './helpers'; import Tween from '../animation/tween'; var Renderer = /*#__PURE__*/ function () { function Renderer(canvas, options) { var _this = this; if (canvas === void 0) { canvas = errUndefined(_templateObject); } if (options === void 0) { options = {}; } this.options = options = _extends({ resolution: parseFloat(url('resolution')) || (window.devicePixelRatio ? window.devicePixelRatio : 1), pixelated: 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, scissorTest: false, 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(); if (options.scissorTest) 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 Tween.update(time, scope); // Pass 2: measure view changes, stamp out old space var revokeDirtyFlag = true; for (var _iterator = scope.canvas.views, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { var _ref; if (_isArray) { if (_i >= _iterator.length) break; _ref = _iterator[_i++]; } else { _i = _iterator.next(); if (_i.done) break; _ref = _i.value; } var _view2 = _ref; // If any view has measured changes, the canvas will remain dirty if (_view2.clear(time)) revokeDirtyFlag = false; } // Pass 3: render view content for (var _iterator2 = scope.canvas.views, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { var _ref2; if (_isArray2) { if (_i2 >= _iterator2.length) break; _ref2 = _iterator2[_i2++]; } else { _i2 = _iterator2.next(); if (_i2.done) break; _ref2 = _i2.value; } var _view3 = _ref2; _view3.render(time); } // If nothing has changed in size or position the canvas is clean if (revokeDirtyFlag) scope.dirty = false; }; // Start render loop if (options.startImmediately) this.start(); } var _proto = Renderer.prototype; _proto.destroy = function destroy() { this.context.remove(); this.render = function () {}; window.removeEventListener('resize', this.resizeHandler); this.gl.dispose(); this.gl = undefined; }; _proto.start = function start() { this.render(performance.now()); }; _proto.resize = function resize() { if (this.gl) { 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); } }; _proto.invalidateCanvas = function invalidateCanvas(frames) { if (frames === void 0) { frames = 1; } this.invalidateFrames += frames; if (this.invalidateFrames > 60) this.invalidateFrames = 60; }; _proto.invalidateViews = function invalidateViews(frames) { if (frames === void 0) { frames = 1; } this.dirty = true; for (var _iterator3 = this.canvas.views, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) { var _ref3; if (_isArray3) { if (_i3 >= _iterator3.length) break; _ref3 = _iterator3[_i3++]; } else { _i3 = _iterator3.next(); if (_i3.done) break; _ref3 = _i3.value; } var _view4 = _ref3; _view4.invalidate(frames); } }; return Renderer; }(); export { Renderer as default };