awv3
Version:
⚡ AWV3 embedded CAD
213 lines (176 loc) • 9.26 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.lastCreated = exports.version = undefined;
var _getIterator2 = require('babel-runtime/core-js/get-iterator');
var _getIterator3 = _interopRequireDefault(_getIterator2);
var _map = require('babel-runtime/core-js/map');
var _map2 = _interopRequireDefault(_map);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
var _uuidV = require('uuid-v4');
var _uuidV2 = _interopRequireDefault(_uuidV);
var _helpers = require('./helpers');
var _parser = require('./parser');
var _parser2 = _interopRequireDefault(_parser);
var _events = require('./events');
var _events2 = _interopRequireDefault(_events);
var _renderer = require('./renderer');
var _renderer2 = _interopRequireDefault(_renderer);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/** Global awv3 version */
var version = exports.version = '7.0.84';
/** last created canvas */
var lastCreated = exports.lastCreated = undefined;
/** The Canvas class holds the webGL context and maps the underlying views.
It initializes it's own renderer, event system and parser. */
var Canvas = function () {
/** Construct a new Canvas
@param {Object} [options={}] - Options to initialize the Canvas with
@param {HTMLElement} [options.dom] - The HTML element in which the canvas will live. If this is empty a detached div element will be created that needs to be appended to the DOM manually. This may be the best option for viewmodel driven frameworks since the state can be exported out and held separtely to the 3d-control.
@param {Number} [options.debugLevel=0] - Console debugging levels
@param {Number} [options.resolution=1] - GL Canvas rasolution
@param {String} [options.place='first'] - Where to place the render-element, options are 'first' and 'last'
@param {Boolean} [options.startImmediately=true] - If true will run a requestAnimationFrame going into a loop. If false, it can be called manually (canvas,renderer.start();)
@param {THREE.Color} [options.clearColor=new THREE.Color(0)] - WebGL option
@param {String} [options.precision='highp'] - WebGL option
@param {Boolean} [options.premultipliedAlpha=true] - WebGL option
@param {Boolean} [options.stencil=true] - WebGL option
@param {Boolean} [options.depth=true] - WebGL option, depth buffer
@param {Boolean} [options.preserveDrawingBuffer=true] - WebGL option, retains draw calls, critical for multiple views
@param {Boolean} [options.alpha=true] - WebGL option, enables alpha cannel
@param {Boolean} [options.antialias=true] - WebGL option, enables aleasing
@param {Boolean} [options.logarithmicDepthBuffer=false] - WebGL option
@example
import Canvas from 'canvas';
// Create new canvas inside #main
const canvas = new Canvas({ dom: '#main' });
// Parse meshes
let context = await canvas.parser.stream('meshes.txt');
@returns {Object} The constructed Canvas */
function Canvas() {
var _this = this;
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
(0, _classCallCheck3.default)(this, Canvas);
/** awv3 version */
this.version = version;
/** GUID to help identify the canvas */
this.id = (0, _uuidV2.default)();
/** List of managed views */
this.views = [];
if (!options.dom) {
options.dom = document.createElement('div');
options.dom.style.cssText = 'position: relative; width: 100%; height: 100%; overflow: hidden; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; -o-user-select: none; user-select: none;';
}
/** The dom node in which the canvas lives */
this.dom = (0, _helpers.queryDom)(options.dom);
this.dom.addEventListener('contextmenu', function (event) {
return event.preventDefault();
}, false);
/** Debug level for this canvas */
this.debugLevel = options.debugLevel || parseInt((0, _helpers.url)('debugLevel')) || 0;
if (!lastCreated) {
var tag = '%c AWV3 %c ' + version + ' %c Resolution:' + (options.resolution || parseFloat((0, _helpers.url)('resolution')) || 1) + ' %c Cores:' + (navigator.hardwareConcurrency || 4) + ' ';
console.log(tag, 'background: #373737; color: white;', 'background: #c23369; color: white;', 'background: #28d79f; color: white;', 'background: #28b4d7; color: white;');
}
/** Global events using the {@link Events} class */
this.events = new _events2.default();
/** GL {@link Renderer} via three.js */
this.renderer = new _renderer2.default(this, options);
/** {@link Parser} using webworkers to unpack and optimize compressed packages */
this.parser = new _parser2.default();
/** Map of managed scopes.
This contains dom nodes with references to all the views influenced.
It is used internally to track changes in position and size.
@example
// Get all views affected for node #main
let array = canvas.scopes.get(document.querySelector('#main')); */
this.scopes = new _map2.default();
this.observer = new MutationObserver(function (records) {
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = (0, _getIterator3.default)(records), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var record = _step.value;
// Any hard mutation causes views to update their parent scopes
if (record.addedNodes.length > 0 || record.removedNodes.length > 0) {
_this.scopes.clear();
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
try {
for (var _iterator2 = (0, _getIterator3.default)(_this.views), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var view = _step2.value;
view.updateScopes();
}
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
}
if (record.target === _this.dom) {
_this.renderer.invalidateCanvas(30);
} else {
// Invalidate views (means they'll have x frames to test for changes)
_this.renderer.invalidateViews(30);
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
});
this.observer.observe(this.dom, {
childList: true,
subtree: true,
attributes: true,
characterData: false,
attributeOldValue: false,
characterDataOldValue: false
});
exports.lastCreated = lastCreated = this;
}
(0, _createClass3.default)(Canvas, [{
key: 'destroy',
value: function destroy() {
this.observer.disconnect();
this.observer = undefined;
this.scopes = undefined;
this.views.forEach(function (view) {
return view.destroy();
});
this.parser = undefined;
this.renderer.destroy();
this.renderer = undefined;
this.events.removeListeners();
this.events.removeInspectors();
this.events = undefined;
}
}]);
return Canvas;
}();
exports.default = Canvas;