awv3
Version:
⚡ AWV3 embedded CAD
235 lines (187 loc) • 7.43 kB
JavaScript
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 };