first commit
This commit is contained in:
commit
731ebe85b5
5
.babelrc
Normal file
5
.babelrc
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"plugins": [
|
||||||
|
["@babel/plugin-proposal-class-properties", { "loose": true }]
|
||||||
|
]
|
||||||
|
}
|
2
.env.example
Normal file
2
.env.example
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
NODE_ENV=
|
||||||
|
CONSTANT_VALUE=
|
32
.gitignore
vendored
Normal file
32
.gitignore
vendored
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
/node_modules
|
||||||
|
/dist
|
||||||
|
|
||||||
|
/.vs/lms/v15
|
||||||
|
/lms.user
|
||||||
|
/lms.sln
|
||||||
|
/lms.phpproj.user
|
||||||
|
/lms.phpproj
|
||||||
|
|
||||||
|
# Composer
|
||||||
|
/composer.lock
|
||||||
|
/composer.phar
|
||||||
|
/vendor
|
||||||
|
|
||||||
|
# Linux
|
||||||
|
*~
|
||||||
|
*.swp
|
||||||
|
|
||||||
|
# Windows
|
||||||
|
Thumbs.db
|
||||||
|
desktop.ini
|
||||||
|
|
||||||
|
|
||||||
|
/.idea
|
||||||
|
/.vscode
|
||||||
|
/.vs
|
||||||
|
/.vagrant
|
||||||
|
/npm-debug.log
|
||||||
|
/yarn-error.log
|
||||||
|
|
||||||
|
/notes.txt
|
||||||
|
/.env
|
36
GeotiefExplore.code-workspace
Normal file
36
GeotiefExplore.code-workspace
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
{
|
||||||
|
"folders": [
|
||||||
|
{
|
||||||
|
"path": "."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"settings": {},
|
||||||
|
"launch": {
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
|
||||||
|
{
|
||||||
|
"type": "chrome",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Launch Chrome against localhost",
|
||||||
|
// "port": 9222,
|
||||||
|
"url": "http://localhost:8080",
|
||||||
|
"webRoot": "${workspaceFolder}",
|
||||||
|
"breakOnLoad": true,
|
||||||
|
// "sourceMapPathOverrides": {
|
||||||
|
// "webpack:///./~/*": "${workspaceFolder}/node_modules/*",
|
||||||
|
// "webpack:///./*": "${workspaceFolder}/*",
|
||||||
|
// "webpack:///*": "*",
|
||||||
|
// "webpack:///src/*": "${workspaceFolder}/*",
|
||||||
|
// },
|
||||||
|
|
||||||
|
// "sourceMapPathOverrides": {
|
||||||
|
// // "webpack:///src/*": "${workspaceFolder}/*",
|
||||||
|
// "webpack:///./*": "${workspaceFolder}/*"
|
||||||
|
// },
|
||||||
|
"sourceMaps": true,
|
||||||
|
"timeout": 15000
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
BIN
images/map/loading.gif
Normal file
BIN
images/map/loading.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.0 KiB |
40
index.html
Normal file
40
index.html
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
<!doctype html>
|
||||||
|
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
|
<title>3D Viewer</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||||
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
|
<!-- <link href="content/img/favicon.ico" rel="shortcut icon" type="image/x-icon" /> -->
|
||||||
|
<meta name="description" content="3D viewer Geological Survey of Austria">
|
||||||
|
<meta name="author" content="Arno Kaimbacher">
|
||||||
|
|
||||||
|
<!-- <link rel="stylesheet" href="src/css/styles.css?v=1.0"> -->
|
||||||
|
<link rel="stylesheet" type="text/css" href="dist/main.css" />
|
||||||
|
|
||||||
|
<!-- <style>
|
||||||
|
.mapDesktop {
|
||||||
|
width: 1174px;
|
||||||
|
height: 1001px;
|
||||||
|
}
|
||||||
|
</style> -->
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div id="webgl" class="mapDesktop">
|
||||||
|
<div id="inset"></div>
|
||||||
|
<div id="progressArea">
|
||||||
|
<img id="loadingImg" alt="" src="images/map/loading.gif" style="display:none;" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="dist/main.js"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
6011
package-lock.json
generated
Normal file
6011
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
30
package.json
Normal file
30
package.json
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"three": "^0.119.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@babel/core": "^7.11.1",
|
||||||
|
"@babel/plugin-proposal-class-properties": "^7.10.4",
|
||||||
|
"@babel/preset-env": "^7.11.0",
|
||||||
|
"babel-loader": "^8.1.0",
|
||||||
|
"concurrently": "^5.2.0",
|
||||||
|
"css-loader": "^4.2.0",
|
||||||
|
"dotenv": "^8.2.0",
|
||||||
|
"file-loader": "^6.0.0",
|
||||||
|
"img-loader": "^3.0.1",
|
||||||
|
"less-loader": "^6.2.0",
|
||||||
|
"mini-css-extract-plugin": "^0.9.0",
|
||||||
|
"style-loader": "^1.2.1",
|
||||||
|
"terser-webpack-plugin": "^4.0.0",
|
||||||
|
"url-loader": "^4.1.0",
|
||||||
|
"webpack": "^4.44.1",
|
||||||
|
"webpack-cli": "^3.3.12",
|
||||||
|
"webpack-merge": "^4.2.2"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"babel": "babel --presets es2015 js/main.js -o build/main.bundle.js",
|
||||||
|
"serve": "http-server",
|
||||||
|
"prod": "rm -rf dist && webpack",
|
||||||
|
"watch": "concurrently \"npm run serve\" \"npx webpack --source-maps --watch\" "
|
||||||
|
}
|
||||||
|
}
|
93
src/css/page.css
Normal file
93
src/css/page.css
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
/*@charset "UTF-8";*/
|
||||||
|
|
||||||
|
.mapDesktop {
|
||||||
|
overflow: hidden;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 30px;
|
||||||
|
top: 30px;
|
||||||
|
left: 30px;
|
||||||
|
right: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#inset {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
border: none;
|
||||||
|
width: 120px;
|
||||||
|
height: 120px;
|
||||||
|
/*background-color:lightcyan;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* control positioning */
|
||||||
|
.gba-control {
|
||||||
|
position: relative;
|
||||||
|
z-index: 7;
|
||||||
|
pointer-events: auto;
|
||||||
|
float: left;
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gba-top,
|
||||||
|
.gba-bottom {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1000;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gba-top {
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gba-right {
|
||||||
|
right: 0;
|
||||||
|
/*right: 5px;*/
|
||||||
|
}
|
||||||
|
|
||||||
|
.gba-bottom {
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gba-left {
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.gba-right .gba-control {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gba-top .gba-control:not(:first-child) {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gba-bottom .gba-control {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gba-left .gba-control {
|
||||||
|
margin-left: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.gba-control-home span {
|
||||||
|
/*padding: 2px;*/
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
/*background-color: rgba(102,102,102,0.80);*/
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 5px;
|
||||||
|
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAMAAAAM7l6QAAABDlBMVEWZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmXl5f///+VlZWZmZmWlpaUlJSYmJiSkpKampqzs7O3t7fMzMyTk5O2trarq6uysrLR0dHY2Njb29v8/PyMjIy4uLi5ubm6urq1tbSbm5uhoaGmpqanp6eoqKi7u7u+vr7BwcHFxcXGxsbHx8fIyMjJycmpqanNzc3Ozs7Pz8/Q0NCNjY3S0tLT09PV1dXW1tavr6/Z2dmxsbHc3Nzd3d3i4uLn5+fv7+/w8PD39/f5+fn7+/uPj4/9/f3+/v6QkJA5Pja9AAAAGnRSTlMABUdVVmxucX6MtLvHycrN2Nzi4+vs7e/3+OshyJcAAAECSURBVHherdLFcsQwEEXRDjLDJOkWGYcnzMzM/P8/Eo8V18i4yl091alSaSGAgclSdnMTPQB9vKBumCriYZg3j0qKGI9DyVRxVPVNHjVZyTN6u/VzGFmNiN4di3NmWWiw1itq9+Faoux5WxhjFNeka660grkkTUZxQ1Ff7glR2WTEO+rUfI0zqgbFM1moB0rm+BEL+5FS1XzUjOvPlFHdViELx3tKa8M7xr/LW7tpvr/A6Gn+HlHGy/+Xv8Ny+XCzUtmo5/LyD2Ofp7m8LYN9nuZ9gy/1djssd17CVlmwD/Susjbrj2yvhdnJPQbTPEjpeHKPwCAvqBe6hmYXs1uY6YdfRkdtRcSvwdgAAAAASUVORK5CYII=') /*img/home.png*/;
|
||||||
|
/*opacity : 0.8;*/
|
||||||
|
background-position: 50% 50%;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
display: block;
|
||||||
|
}
|
66
src/js/controls/Control.js
Normal file
66
src/js/controls/Control.js
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
// import { Class } from '../core/Class';
|
||||||
|
import * as util from '../core/utilities';
|
||||||
|
// import * as dom from '../core/domUtil';
|
||||||
|
|
||||||
|
// export var Control = Class.extend({
|
||||||
|
class Control {
|
||||||
|
|
||||||
|
// @section
|
||||||
|
// @aka Control options
|
||||||
|
options = {
|
||||||
|
position: 'topright'
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor(defaults) {
|
||||||
|
if (!(this instanceof Control)) {
|
||||||
|
throw new TypeError("Control constructor cannot be called as a function.");
|
||||||
|
}
|
||||||
|
// properties
|
||||||
|
util.setOptions(this, defaults);
|
||||||
|
}
|
||||||
|
|
||||||
|
getPosition() {
|
||||||
|
return this.options.position;
|
||||||
|
}
|
||||||
|
|
||||||
|
getContainer() {
|
||||||
|
return this._container;
|
||||||
|
}
|
||||||
|
|
||||||
|
addTo(map) {
|
||||||
|
this._map = map;
|
||||||
|
|
||||||
|
var container = this._container = this.onAdd(map);
|
||||||
|
var pos = this.getPosition();//"topright"
|
||||||
|
var corner = map._controlCorners[pos];
|
||||||
|
if (container) {
|
||||||
|
// $(container).addClass('gba-control');
|
||||||
|
container.classList.add("gba-control");
|
||||||
|
|
||||||
|
if (pos.indexOf('bottom') !== -1) {
|
||||||
|
corner.insertBefore(container, corner.firstChild);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
corner.appendChild(container);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
removeFrom(map) {
|
||||||
|
var pos = this.getPosition(),
|
||||||
|
corner = map._controlCorners[pos];
|
||||||
|
|
||||||
|
corner.removeChild(this._container);
|
||||||
|
this._map = null;
|
||||||
|
|
||||||
|
if (this.onRemove) {
|
||||||
|
this.onRemove(map);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export { Control };
|
102
src/js/controls/HomeButton.js
Normal file
102
src/js/controls/HomeButton.js
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
import { Control } from "./Control";
|
||||||
|
import * as dom from '../core/domUtil';
|
||||||
|
import * as domEvent from '../core/domEvent';
|
||||||
|
|
||||||
|
class HomeButton extends Control {
|
||||||
|
options = {
|
||||||
|
position: 'topright',
|
||||||
|
homeText: '+',
|
||||||
|
//homeTitle: 'Home Extent',
|
||||||
|
visible: true
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor(defaults) {
|
||||||
|
super(defaults);
|
||||||
|
|
||||||
|
// properties
|
||||||
|
this.map = {};
|
||||||
|
this.visible = this.options.visible;
|
||||||
|
this.home = this.options.home;
|
||||||
|
}
|
||||||
|
|
||||||
|
onAdd(map) {
|
||||||
|
if (!this.map) {
|
||||||
|
//self.destroy();
|
||||||
|
logger.warning('HomeButton::map required', true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.map = map;
|
||||||
|
//this.options.home.initialZoom = map.options.zoom;
|
||||||
|
//this.options.home.initialCenter = map.options.center;
|
||||||
|
var b = this._nls = "test"; //util.mixin({}, N.widgets.home);
|
||||||
|
|
||||||
|
var className = 'gba-control-home';
|
||||||
|
// Create sidebar container
|
||||||
|
//var container = this._container = L.DomUtil.create('div', className);
|
||||||
|
var container = this._container = dom.createDom("div", { "class": className });
|
||||||
|
//if (this.options.home) {
|
||||||
|
this._homeButton = this._createButton(
|
||||||
|
//this.options.zoomInText, this.options.zoomInTitle,
|
||||||
|
"", "b.title",
|
||||||
|
className + '-do', container, this._goHome, this);
|
||||||
|
this._init();
|
||||||
|
//}
|
||||||
|
|
||||||
|
//this._updateDisabled();
|
||||||
|
//map.on('zoomend zoomlevelschange', this._updateDisabled, this);
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
|
||||||
|
_init() {
|
||||||
|
// show or hide widget
|
||||||
|
this._visible();
|
||||||
|
|
||||||
|
////// if no extent set, set extent to map extent
|
||||||
|
//if (!this.home) {
|
||||||
|
// this.home = this.map.getBounds();
|
||||||
|
//}
|
||||||
|
|
||||||
|
//// widget is now loaded
|
||||||
|
this.loaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_visible() {
|
||||||
|
if (this.visible === true) {
|
||||||
|
//domStyle.set(self.domNode, 'display', 'block');
|
||||||
|
// $(this._container).css('display', 'block');
|
||||||
|
this._container.style.display = 'block';
|
||||||
|
} else {
|
||||||
|
//domStyle.set(self.domNode, 'display', 'none');
|
||||||
|
// $(this._container).css('display', 'none');
|
||||||
|
this._container.style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_goHome() {
|
||||||
|
//this._map.zoomIn(e.shiftKey ? 3 : 1);
|
||||||
|
this._exitFired = false;
|
||||||
|
|
||||||
|
//var bounds = L.latLngBounds(this.options.home._southWest, this.options.home._northEast);
|
||||||
|
//this.map.fitBounds(bounds);
|
||||||
|
this.map.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
_createButton(html, title, className, container, fn, context) {
|
||||||
|
//var link = L.DomUtil.create('a', className, container);
|
||||||
|
let link = dom.createDom("span", { "class": className, innerHTML: html, title: title }, container);
|
||||||
|
|
||||||
|
// let stop = domEvent.stopPropagation();
|
||||||
|
domEvent.on(link, 'click', fn, context);
|
||||||
|
// .on(link, 'click', stop)
|
||||||
|
// .on(link, 'mousedown', stop)
|
||||||
|
// .on(link, 'dblclick', stop)
|
||||||
|
// .on(link, 'click', domEvent.preventDefault())
|
||||||
|
// //.on(link, 'click', fn.bind(this));
|
||||||
|
// .on(link, 'click', fn, context);
|
||||||
|
|
||||||
|
return link;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export { HomeButton };
|
49
src/js/core/Class.js
Normal file
49
src/js/core/Class.js
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
import * as util from './utilities';
|
||||||
|
|
||||||
|
export function Class() { }
|
||||||
|
|
||||||
|
// @function extend(props: Object): Function
|
||||||
|
// [Extends the current class](#class-inheritance) given the properties to be included.
|
||||||
|
Class.extend = function (props) {
|
||||||
|
|
||||||
|
var NewClass = function () {
|
||||||
|
|
||||||
|
// call the constructor
|
||||||
|
if (this.init) {
|
||||||
|
this.init.apply(this, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
//// call all constructor hooks
|
||||||
|
//if (this._initHooks) {
|
||||||
|
// this.callInitHooks();
|
||||||
|
//}
|
||||||
|
};
|
||||||
|
|
||||||
|
// instantiate class without calling constructor
|
||||||
|
var F = function () { };
|
||||||
|
F.prototype = this.prototype;
|
||||||
|
|
||||||
|
var proto = new F();
|
||||||
|
proto.constructor = NewClass;
|
||||||
|
|
||||||
|
NewClass.prototype = proto;
|
||||||
|
|
||||||
|
//inherit parent's statics
|
||||||
|
for (var i in this) {
|
||||||
|
if (this.hasOwnProperty(i) && i !== 'prototype') {
|
||||||
|
NewClass[i] = this[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// mix given properties into the prototype
|
||||||
|
util.extend(proto, props);
|
||||||
|
|
||||||
|
return NewClass;
|
||||||
|
};
|
||||||
|
|
||||||
|
// @function include(properties: Object): this
|
||||||
|
// [Includes a mixin](#class-includes) into the current class.
|
||||||
|
Class.include = function (props) {
|
||||||
|
util.extend(this.prototype, props);
|
||||||
|
return this;
|
||||||
|
};
|
206
src/js/core/EventEmitter.js
Normal file
206
src/js/core/EventEmitter.js
Normal file
|
@ -0,0 +1,206 @@
|
||||||
|
import * as util from './utilities';
|
||||||
|
|
||||||
|
var eventsKey = '_events';
|
||||||
|
|
||||||
|
class EventEmitter {
|
||||||
|
constructor() {
|
||||||
|
var test = "test";
|
||||||
|
}
|
||||||
|
|
||||||
|
_getEvents() {
|
||||||
|
return this._events || (this._events = {});
|
||||||
|
}
|
||||||
|
|
||||||
|
getListeners(evt) {
|
||||||
|
var events = this._getEvents();
|
||||||
|
var response;
|
||||||
|
var key;
|
||||||
|
|
||||||
|
// Return a concatenated array of all matching events if
|
||||||
|
// the selector is a regular expression.
|
||||||
|
if (evt instanceof RegExp) {
|
||||||
|
response = {};
|
||||||
|
for (key in events) {
|
||||||
|
if (events.hasOwnProperty(key) && evt.test(key)) {
|
||||||
|
response[key] = events[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
response = events[evt] || (events[evt] = []);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
getListenersAsObject(evt) {
|
||||||
|
var listeners = this.getListeners(evt);
|
||||||
|
var response;
|
||||||
|
|
||||||
|
if (listeners instanceof Array) {
|
||||||
|
response = {};
|
||||||
|
response[evt] = listeners;
|
||||||
|
}
|
||||||
|
|
||||||
|
return response || listeners;
|
||||||
|
}
|
||||||
|
|
||||||
|
addListener(evt, fn, context) { // (String, Function[, Object]) or (Object[, Object])
|
||||||
|
|
||||||
|
// types can be a map of types/handlers
|
||||||
|
//if (L.Util.invokeEach(types, this.addEventListener, this, fn, context)) { return this; }
|
||||||
|
|
||||||
|
//var events = this.getListenersAsObject(evt);
|
||||||
|
var events = this[eventsKey] = this[eventsKey] || {};
|
||||||
|
var contextId = context && context !== this && util.stamp(context);
|
||||||
|
var i, len, event, type, indexKey, indexLenKey, typeIndex;
|
||||||
|
|
||||||
|
//// types can be a string of space-separated words
|
||||||
|
//types = util.splitWords(types);
|
||||||
|
|
||||||
|
//for (i = 0, len = types.length; i < len; i++) {
|
||||||
|
event = {
|
||||||
|
action: fn,
|
||||||
|
context: context || this
|
||||||
|
};
|
||||||
|
type = evt;// types[i];
|
||||||
|
|
||||||
|
if (contextId) {
|
||||||
|
// store listeners of a particular context in a separate hash (if it has an id)
|
||||||
|
// gives a major performance boost when removing thousands of map layers
|
||||||
|
|
||||||
|
indexKey = type + '_idx';
|
||||||
|
indexLenKey = indexKey + '_len';
|
||||||
|
|
||||||
|
typeIndex = events[indexKey] = events[indexKey] || {};
|
||||||
|
|
||||||
|
if (!typeIndex[contextId]) {
|
||||||
|
typeIndex[contextId] = [];
|
||||||
|
|
||||||
|
// keep track of the number of keys in the index to quickly check if it's empty
|
||||||
|
events[indexLenKey] = (events[indexLenKey] || 0) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
typeIndex[contextId].push(event);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
events[type] = events[type] || [];
|
||||||
|
events[type].push(event);
|
||||||
|
}
|
||||||
|
//}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
removeListener(evt, fn, context) { // ([String, Function, Object]) or (Object[, Object])
|
||||||
|
|
||||||
|
if (!this[eventsKey]) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (!types) {
|
||||||
|
// return this.clearAllEventListeners();
|
||||||
|
//}
|
||||||
|
|
||||||
|
//if (L.Util.invokeEach(types, this.removeEventListener, this, fn, context)) { return this; }
|
||||||
|
|
||||||
|
var events = this[eventsKey],
|
||||||
|
contextId = context && context !== this && util.stamp(context),
|
||||||
|
i, len, type, listeners, j, indexKey, indexLenKey, typeIndex, removed;
|
||||||
|
|
||||||
|
//types = L.Util.splitWords(types);
|
||||||
|
|
||||||
|
//for (i = 0, len = types.length; i < len; i++) {
|
||||||
|
type = evt;//types[i];
|
||||||
|
indexKey = type + '_idx';
|
||||||
|
indexLenKey = indexKey + '_len';
|
||||||
|
|
||||||
|
typeIndex = events[indexKey];
|
||||||
|
|
||||||
|
if (!fn) {
|
||||||
|
// clear all listeners for a type if function isn't specified
|
||||||
|
delete events[type];
|
||||||
|
delete events[indexKey];
|
||||||
|
delete events[indexLenKey];
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
listeners = contextId && typeIndex ? typeIndex[contextId] : events[type];
|
||||||
|
|
||||||
|
if (listeners) {
|
||||||
|
for (j = listeners.length - 1; j >= 0; j--) {
|
||||||
|
if ((listeners[j].action === fn) && (!context || (listeners[j].context === context))) {
|
||||||
|
removed = listeners.splice(j, 1);
|
||||||
|
// set the old action to a no-op, because it is possible
|
||||||
|
// that the listener is being iterated over as part of a dispatch
|
||||||
|
//removed[0].action = util.falseFn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context && typeIndex && (listeners.length === 0)) {
|
||||||
|
delete typeIndex[contextId];
|
||||||
|
events[indexLenKey]--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
hasEventListeners(type) { // (String) -> Boolean
|
||||||
|
var events = this[eventsKey];
|
||||||
|
return !!events && ((type in events && events[type].length > 0) ||
|
||||||
|
(type + '_idx' in events && events[type + '_idx_len'] > 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
// (String[, Object])
|
||||||
|
emit(type, data) {
|
||||||
|
if (!this.hasEventListeners(type)) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
var event = util.extend({}, data, { type: type, target: this });
|
||||||
|
|
||||||
|
var events = this[eventsKey],
|
||||||
|
listeners, i, len, typeIndex, contextId;
|
||||||
|
|
||||||
|
if (events[type]) {
|
||||||
|
// make sure adding/removing listeners inside other listeners won't cause infinite loop
|
||||||
|
listeners = events[type].slice();
|
||||||
|
|
||||||
|
for (i = 0, len = listeners.length; i < len; i++) {
|
||||||
|
listeners[i].action.call(listeners[i].context, event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fire event for the context-indexed listeners as well
|
||||||
|
typeIndex = events[type + '_idx'];
|
||||||
|
|
||||||
|
for (contextId in typeIndex) {
|
||||||
|
listeners = typeIndex[contextId].slice();
|
||||||
|
|
||||||
|
if (listeners) {
|
||||||
|
for (i = 0, len = listeners.length; i < len; i++) {
|
||||||
|
listeners[i].action.call(listeners[i].context, event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// aliases; we should ditch those eventually
|
||||||
|
|
||||||
|
// @method on(…): this
|
||||||
|
// Alias to [`on(…)`](#evented-on)
|
||||||
|
EventEmitter.on = EventEmitter.addListener;
|
||||||
|
|
||||||
|
// @method off(…): this
|
||||||
|
EventEmitter.off = EventEmitter.removeListener;
|
||||||
|
|
||||||
|
export { EventEmitter };
|
82
src/js/core/Map.js
Normal file
82
src/js/core/Map.js
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
import { OrbitControls } from '../lib/OrbitControls';
|
||||||
|
import * as dom from './domUtil';
|
||||||
|
import { HomeButton } from '../controls/HomeButton';
|
||||||
|
import * as util from './utilities';
|
||||||
|
|
||||||
|
class Map extends OrbitControls {
|
||||||
|
|
||||||
|
container;
|
||||||
|
_layers;
|
||||||
|
_controlCorners;
|
||||||
|
_controlContainer;
|
||||||
|
_controls;
|
||||||
|
|
||||||
|
constructor(camera, scene, domElement, container) {
|
||||||
|
// call parent constructor of OrbitControls
|
||||||
|
super(camera, scene, domElement);
|
||||||
|
|
||||||
|
this.container = container;
|
||||||
|
|
||||||
|
//init the control corners
|
||||||
|
if (this._initControlPos) {
|
||||||
|
this._initControlPos();
|
||||||
|
}
|
||||||
|
this._layers = {};
|
||||||
|
this.initControls();
|
||||||
|
}
|
||||||
|
|
||||||
|
_initControlPos() {
|
||||||
|
//var test = document.getElementById("webgl");
|
||||||
|
|
||||||
|
var corners = this._controlCorners = {};
|
||||||
|
var l = 'gba-';
|
||||||
|
var container = this._controlContainer =
|
||||||
|
//util.create('div', l + 'control-container', this.domElement);
|
||||||
|
dom.createDom("div", { "class": l + 'control-container' }, this.container);
|
||||||
|
|
||||||
|
function createCorner(vSide, hSide) {
|
||||||
|
var className = l + vSide + ' ' + l + hSide;
|
||||||
|
|
||||||
|
//corners[vSide + hSide] = util.create('div', className, container);
|
||||||
|
corners[vSide + hSide] = dom.createDom("div", { "class": className }, container);
|
||||||
|
}
|
||||||
|
|
||||||
|
createCorner('top', 'left');
|
||||||
|
createCorner('top', 'right');
|
||||||
|
createCorner('bottom', 'left');
|
||||||
|
createCorner('bottom', 'right');
|
||||||
|
}
|
||||||
|
|
||||||
|
initControls() {
|
||||||
|
this._controls = this._controls || {};
|
||||||
|
// this._controls.homeControl = (new HomeButton()).addTo(this);
|
||||||
|
let homeControl = this._controls.homeControl = new HomeButton();
|
||||||
|
homeControl.addTo(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
addLayer(layer) {
|
||||||
|
var id = util.stamp(layer);
|
||||||
|
if (this._layers[id]) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
this._layers[id] = layer;
|
||||||
|
|
||||||
|
//layer._mapToAdd = this;
|
||||||
|
layer.index = id;
|
||||||
|
|
||||||
|
//if (layer.beforeAdd) {
|
||||||
|
// layer.beforeAdd(this);
|
||||||
|
//}
|
||||||
|
//this.whenReady(layer._layerAdd, layer);
|
||||||
|
layer._layerAdd(this);
|
||||||
|
this.emit("change");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
hasLayer (layer) {
|
||||||
|
return !!layer && (util.stamp(layer) in this._layers);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export { Map };
|
157
src/js/core/domEvent.js
Normal file
157
src/js/core/domEvent.js
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
//static function
|
||||||
|
var stampForFn = (function () {
|
||||||
|
var lastId = 0,
|
||||||
|
key = '_id';
|
||||||
|
return function (obj) {
|
||||||
|
obj[key] = obj[key] || ++lastId;
|
||||||
|
return obj[key];
|
||||||
|
};
|
||||||
|
}());
|
||||||
|
|
||||||
|
export function addListener(obj, type, fn, context) { // (HTMLElement, String, Function[, Object])
|
||||||
|
|
||||||
|
var id = stampForFn(fn);
|
||||||
|
var key = '_gba_' + type + id;
|
||||||
|
var handler, originalHandler, newType;
|
||||||
|
|
||||||
|
if (obj[key]) { return this; }
|
||||||
|
|
||||||
|
handler = function (e) {
|
||||||
|
return fn.call(context || obj, e || domEvent._getEvent());
|
||||||
|
};
|
||||||
|
|
||||||
|
//if (L.Browser.pointer && type.indexOf('touch') === 0) {
|
||||||
|
// return this.addPointerListener(obj, type, handler, id);
|
||||||
|
//}
|
||||||
|
//if (L.Browser.touch && (type === 'dblclick') && this.addDoubleTapListener) {
|
||||||
|
// this.addDoubleTapListener(obj, handler, id);
|
||||||
|
//}
|
||||||
|
|
||||||
|
if ('addEventListener' in obj) {
|
||||||
|
|
||||||
|
if (type === 'mousewheel') {
|
||||||
|
obj.addEventListener('DOMMouseScroll', handler, false);
|
||||||
|
obj.addEventListener(type, handler, false);
|
||||||
|
|
||||||
|
}
|
||||||
|
else if ((type === 'mouseenter') || (type === 'mouseleave')) {
|
||||||
|
|
||||||
|
originalHandler = handler;
|
||||||
|
newType = (type === 'mouseenter' ? 'mouseover' : 'mouseout');
|
||||||
|
|
||||||
|
handler = function (e) {
|
||||||
|
if (!_checkMouse(obj, e)) { return; }
|
||||||
|
return originalHandler(e);
|
||||||
|
};
|
||||||
|
|
||||||
|
obj.addEventListener(newType, handler, false);
|
||||||
|
|
||||||
|
}
|
||||||
|
//else if (type === 'click' && L.Browser.android) {
|
||||||
|
// originalHandler = handler;
|
||||||
|
// handler = function (e) {
|
||||||
|
// return L.DomEvent._filterClick(e, originalHandler);
|
||||||
|
// };
|
||||||
|
|
||||||
|
// obj.addEventListener(type, handler, false);
|
||||||
|
//}
|
||||||
|
else {
|
||||||
|
obj.addEventListener(type, handler, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ('attachEvent' in obj) {
|
||||||
|
obj.attachEvent('on' + type, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
obj[key] = handler;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @function on(…): this
|
||||||
|
// Alias to [`L.DomEvent.on`](#domevent-on)
|
||||||
|
export { addListener as on };
|
||||||
|
|
||||||
|
export function removeListener(obj, type, fn) { // (HTMLElement, String, Function)
|
||||||
|
|
||||||
|
var id = stampForFn(fn);
|
||||||
|
var key = '_gba_' + type + id;
|
||||||
|
var handler = obj[key];
|
||||||
|
|
||||||
|
if (!handler) { return this; }
|
||||||
|
|
||||||
|
//if (L.Browser.pointer && type.indexOf('touch') === 0) {
|
||||||
|
// this.removePointerListener(obj, type, id);
|
||||||
|
//} else if (L.Browser.touch && (type === 'dblclick') && this.removeDoubleTapListener) {
|
||||||
|
// this.removeDoubleTapListener(obj, id);
|
||||||
|
|
||||||
|
//} else if ('removeEventListener' in obj) {
|
||||||
|
if ('removeEventListener' in obj) {
|
||||||
|
if (type === 'mousewheel') {
|
||||||
|
obj.removeEventListener('DOMMouseScroll', handler, false);
|
||||||
|
obj.removeEventListener(type, handler, false);
|
||||||
|
|
||||||
|
} else if ((type === 'mouseenter') || (type === 'mouseleave')) {
|
||||||
|
obj.removeEventListener((type === 'mouseenter' ? 'mouseover' : 'mouseout'), handler, false);
|
||||||
|
} else {
|
||||||
|
obj.removeEventListener(type, handler, false);
|
||||||
|
}
|
||||||
|
} else if ('detachEvent' in obj) {
|
||||||
|
obj.detachEvent('on' + type, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
obj[key] = null;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @function removeListener(…): this
|
||||||
|
// Alias to [`L.DomEvent.off`](#domevent-off)
|
||||||
|
export { removeListener as off };
|
||||||
|
|
||||||
|
// check if element really left/entered the event target (for mouseenter/mouseleave)
|
||||||
|
function _checkMouse(el, e) {
|
||||||
|
var related = e.relatedTarget;
|
||||||
|
|
||||||
|
if (!related) { return true; }
|
||||||
|
|
||||||
|
try {
|
||||||
|
while (related && (related !== el)) {
|
||||||
|
related = related.parentNode;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return (related !== el);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function stopPropagation(e) {
|
||||||
|
if (e.stopPropagation) {
|
||||||
|
e.stopPropagation();
|
||||||
|
} else {
|
||||||
|
e.cancelBubble = true;
|
||||||
|
}
|
||||||
|
skipped(e);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function preventDefault(e) {
|
||||||
|
|
||||||
|
if (e.preventDefault) {
|
||||||
|
e.preventDefault();
|
||||||
|
} else {
|
||||||
|
e.returnValue = false;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
var skipEvents = {};
|
||||||
|
|
||||||
|
export function skipped(e) {
|
||||||
|
var skipped = skipEvents[e.type];
|
||||||
|
// reset when checking, as it's only used in map container and propagates outside of the map
|
||||||
|
skipEvents[e.type] = false;
|
||||||
|
return skipped;
|
||||||
|
}
|
102
src/js/core/domUtil.js
Normal file
102
src/js/core/domUtil.js
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
import * as util from './utilities';
|
||||||
|
/*
|
||||||
|
* @namespace DomUtil
|
||||||
|
*
|
||||||
|
* Utility functions to work with the [DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model)
|
||||||
|
* tree, used by Leaflet internally.
|
||||||
|
*
|
||||||
|
* Most functions expecting or returning a `HTMLElement` also work for
|
||||||
|
* SVG elements. The only difference is that classes refer to CSS classes
|
||||||
|
* in HTML and SVG classes in SVG.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// @function get(id: String|HTMLElement): HTMLElement
|
||||||
|
// Returns an element given its DOM id, or returns the element itself
|
||||||
|
// if it was passed directly.
|
||||||
|
export function byId(id, doc) {
|
||||||
|
// inline'd type check.
|
||||||
|
// be sure to return null per documentation, to match IE branch.
|
||||||
|
return ((typeof id == "string") ? (doc || document).getElementById(id) : id) || null; // DOMNode
|
||||||
|
}
|
||||||
|
|
||||||
|
// @function empty(el: HTMLElement)
|
||||||
|
// Removes all of `el`'s children elements from `el`
|
||||||
|
export function empty(el) {
|
||||||
|
while (el.firstChild) {
|
||||||
|
el.removeChild(el.firstChild);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function createDom(tagName, opt_attributes, parent_node) {
|
||||||
|
return _createDom(document, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _createDom(doc, args) {
|
||||||
|
var tagName = args[0];
|
||||||
|
var attributes = args[1];
|
||||||
|
//var var_args = args[2];
|
||||||
|
|
||||||
|
var element = doc.createElement(tagName);
|
||||||
|
//var element = $(tagName);
|
||||||
|
|
||||||
|
if (attributes) {
|
||||||
|
if (typeof attributes === "string") {
|
||||||
|
element.className = attributes;
|
||||||
|
}
|
||||||
|
//else if ($.isArray(attributes)) {
|
||||||
|
// //goog.dom.classes.add.apply(null, [element].concat(attributes));
|
||||||
|
//}
|
||||||
|
else {
|
||||||
|
setProperties(element, attributes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.length > 2) {
|
||||||
|
var parent_node = args[2];
|
||||||
|
parent_node.appendChild(element);
|
||||||
|
//parent_node.insertBefore(element, parent_node.firstChild)
|
||||||
|
}
|
||||||
|
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setProperties(element, properties) {
|
||||||
|
//goog.object.forEach(properties, function(val, key) {
|
||||||
|
// $.each(properties, function (key, val) {
|
||||||
|
for (let key in properties) {
|
||||||
|
// object.update();
|
||||||
|
// });
|
||||||
|
let val = properties[key];
|
||||||
|
if (key === 'style') {
|
||||||
|
element.style.cssText = val;
|
||||||
|
}
|
||||||
|
else if (key === 'class') {
|
||||||
|
element.className = val;
|
||||||
|
}
|
||||||
|
else if (key === 'for') {
|
||||||
|
element.htmlFor = val;
|
||||||
|
}
|
||||||
|
else if (key in ATTRIBUTE_MAP) {
|
||||||
|
element.setAttribute(ATTRIBUTE_MAP[key], val);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
element[key] = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let ATTRIBUTE_MAP = {
|
||||||
|
'cellpadding': 'cellPadding',
|
||||||
|
'cellspacing': 'cellSpacing',
|
||||||
|
'colspan': 'colSpan',
|
||||||
|
'frameborder': 'frameBorder',
|
||||||
|
'height': 'height',
|
||||||
|
'maxlength': 'maxLength',
|
||||||
|
'role': 'role',
|
||||||
|
'rowspan': 'rowSpan',
|
||||||
|
'type': 'type',
|
||||||
|
'usemap': 'useMap',
|
||||||
|
'valign': 'vAlign',
|
||||||
|
'width': 'width'
|
||||||
|
};
|
11
src/js/core/index.js
Normal file
11
src/js/core/index.js
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
export { Class } from './Class';
|
||||||
|
|
||||||
|
import { EventEmitter } from './Events';
|
||||||
|
export { EventEmitter };
|
||||||
|
|
||||||
|
import * as util from './utilities';
|
||||||
|
export { util };
|
||||||
|
export { setLoading, extend, showLoading, hideLoading, setOptions } from './utilities';
|
||||||
|
|
||||||
|
import * as dom from './dom';
|
||||||
|
export { dom };
|
143
src/js/core/utilities.js
Normal file
143
src/js/core/utilities.js
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
import * as dom from './domUtil';
|
||||||
|
/*
|
||||||
|
* @namespace util
|
||||||
|
*
|
||||||
|
* Various utility functions, used by GeptiefExplore internally.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const LOADING_ID_PREFIX = "loading_";
|
||||||
|
|
||||||
|
export function setLoading(elemID) {
|
||||||
|
//debug("setting loading " + elemID);
|
||||||
|
|
||||||
|
//// 1) create the jQuery Deferred object that will be used
|
||||||
|
//var deferred = $.Deferred();
|
||||||
|
//var ownerDocumentBody = document.getElementById(elemID);
|
||||||
|
|
||||||
|
var loadingDivID = LOADING_ID_PREFIX + elemID;
|
||||||
|
//var loadingDivID = "loading_" + elemID;
|
||||||
|
var existingDiv = document.getElementById(loadingDivID);
|
||||||
|
//var existingDiv = dom.byId(loadingDivID);
|
||||||
|
|
||||||
|
|
||||||
|
// if the loading div for given element already exists,
|
||||||
|
// increment the lock attribute value (or create the attribute,
|
||||||
|
// if not exists)
|
||||||
|
if (existingDiv != null) {
|
||||||
|
//existingDiv.css("display", "inline");
|
||||||
|
//dom.setProperties(existingDiv, {
|
||||||
|
// style: "display: block"
|
||||||
|
//});
|
||||||
|
if (typeof (existingDiv.attr("lock")) === "undefined") {
|
||||||
|
existingDiv.attr("lock", 1);
|
||||||
|
} else {
|
||||||
|
existingDiv.attr("lock", parseInt(existingDiv.attr("lock")) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
// otherwise, create the div and append it to body
|
||||||
|
else {
|
||||||
|
// construct the div from markup
|
||||||
|
//var loadingDiv = dom.createDom("div", { id: loadingDivID, "class": "loading" }, ownerDocumentBody);
|
||||||
|
//var loadingDiv = $("<div id=\"" + loadingDivID + "\" class=\"loading\"></div>");
|
||||||
|
var loadingDiv = document.createElement('div');
|
||||||
|
loadingDiv.setAttribute("id", loadingDivID);
|
||||||
|
loadingDiv.setAttribute("class", "loading");
|
||||||
|
|
||||||
|
//var loadingDivContent = dom.createDom("div", { id: loadingDivID, innerHTML: myLabels.viewer.messages.waitMessage, "class": "loading-content" }, loadingDiv);
|
||||||
|
// var loadingDivContent = $("<div class=\"loading-content\">" + myLabels.viewer.messages.waitMessage + "</div>");
|
||||||
|
var loadingDivContent = document.createElement("div");
|
||||||
|
loadingDivContent.innerHTML = "Hi there and greetings!";
|
||||||
|
loadingDiv.appendChild(loadingDivContent);
|
||||||
|
|
||||||
|
// get the element to be covered with the loading div...
|
||||||
|
//var targetElement = $("#" + elemID);
|
||||||
|
var targetElement = document.getElementById(elemID);
|
||||||
|
|
||||||
|
// ... and get its proportions
|
||||||
|
// var offset = targetElement.offset();
|
||||||
|
var width = targetElement.offsetWidth
|
||||||
|
var height = targetElement.offsetHeight;
|
||||||
|
|
||||||
|
// make the div fit the target element
|
||||||
|
// loadingDiv.css({
|
||||||
|
// "left": targetElement.offsetLeft + "px",
|
||||||
|
// "top": targetElement.offsetTop + "px",
|
||||||
|
// "width": width + "px",
|
||||||
|
// "height": height + "px"
|
||||||
|
// });
|
||||||
|
//dom.setProperties(loadingDiv, {
|
||||||
|
// style: "width:" + width + "px; height:" + height + "px;"// left:" + offset.left + "px; top:" + offset.top + "px"
|
||||||
|
//});
|
||||||
|
loadingDiv.style.left = targetElement.offsetLeft + "px";
|
||||||
|
loadingDiv.style.top = targetElement.offsetTop + "px";
|
||||||
|
loadingDiv.style.width = width + "px";
|
||||||
|
loadingDiv.style.height = height + "px";
|
||||||
|
|
||||||
|
|
||||||
|
// make the text appear in the middle of the loading div
|
||||||
|
//dom.setProperties(loadingDivContent, {
|
||||||
|
// style: "line-height:" + height + "px;"
|
||||||
|
//});
|
||||||
|
// loadingDivContent.css({
|
||||||
|
// "line-height": height + "px"
|
||||||
|
// });
|
||||||
|
loadingDivContent.style.lineHeight = height + "px";
|
||||||
|
|
||||||
|
|
||||||
|
// $("body").append(loadingDiv);
|
||||||
|
//loadingDiv.appendTo('body');
|
||||||
|
document.body.appendChild(loadingDiv);
|
||||||
|
|
||||||
|
return loadingDiv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @function extend(dest: Object, src?: Object): Object
|
||||||
|
// extend an object with properties of one or more other objects
|
||||||
|
export function extend(dest) {
|
||||||
|
var i, j, len, src;
|
||||||
|
|
||||||
|
for (j = 1, len = arguments.length; j < len; j++) {
|
||||||
|
src = arguments[j];
|
||||||
|
for (i in src) {
|
||||||
|
dest[i] = src[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function showLoading () {
|
||||||
|
var element = dom.byId("loadingImg");
|
||||||
|
//domUtil.show(_loading);
|
||||||
|
if (element) {
|
||||||
|
element.style.display = "block";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function hideLoading () {
|
||||||
|
var element = dom.byId("loadingImg");
|
||||||
|
if (element) {
|
||||||
|
element.style.display = "none";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Merges the given properties to the `options` of the `obj` object, returning the resulting options. See `Class options`
|
||||||
|
export function setOptions (obj, options) {
|
||||||
|
if (!Object.prototype.hasOwnProperty.call(obj, 'options')) {
|
||||||
|
obj.options = obj.options ? create(obj.options) : {};
|
||||||
|
}
|
||||||
|
for (var i in options) {
|
||||||
|
obj.options[i] = options[i];
|
||||||
|
}
|
||||||
|
return obj.options;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function stamp (){
|
||||||
|
var lastId = 0,
|
||||||
|
key = '_gba_id';
|
||||||
|
return function (obj) {
|
||||||
|
obj[key] = obj[key] || ++lastId;
|
||||||
|
return obj[key];
|
||||||
|
};
|
||||||
|
}
|
35
src/js/layer/BoxLayer.js
Normal file
35
src/js/layer/BoxLayer.js
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
import { BoxGeometry } from 'three/src/geometries/BoxGeometry';
|
||||||
|
import { MeshBasicMaterial } from 'three/src/materials/MeshBasicMaterial';
|
||||||
|
import { Mesh } from 'three/src/objects/Mesh';
|
||||||
|
import { Layer } from './Layer'
|
||||||
|
|
||||||
|
class BoxLayer extends Layer {
|
||||||
|
|
||||||
|
constructor(size) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.geometry = new BoxGeometry(size.width, size.height, size.depth);
|
||||||
|
this.material = new MeshBasicMaterial({
|
||||||
|
color: 800080
|
||||||
|
});
|
||||||
|
|
||||||
|
this.mesh = new Mesh(this.geometry, this.material);
|
||||||
|
}
|
||||||
|
|
||||||
|
onAdd(map) {
|
||||||
|
this.build(this.getScene());
|
||||||
|
//this.update();
|
||||||
|
this.emit('add');
|
||||||
|
}
|
||||||
|
|
||||||
|
build(app_scene) {
|
||||||
|
// this.objects.push(layer);
|
||||||
|
app_scene.add(this.getMesh());
|
||||||
|
}
|
||||||
|
|
||||||
|
getMesh() {
|
||||||
|
return this.mesh;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { BoxLayer };
|
16
src/js/layer/DxfLayer.js
Normal file
16
src/js/layer/DxfLayer.js
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import { Group } from 'three/src/objects/Group';
|
||||||
|
|
||||||
|
class DxfLayer extends Layer {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.objectGroup = new Group();
|
||||||
|
this.queryableObjects = [];
|
||||||
|
this.borderVisible = false;
|
||||||
|
this.declaredClass = "DxfLayer";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export { DxfLayer };
|
47
src/js/layer/Layer.js
Normal file
47
src/js/layer/Layer.js
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
import { EventEmitter } from '../core/EventEmitter';
|
||||||
|
|
||||||
|
class Layer extends EventEmitter {
|
||||||
|
|
||||||
|
options = {
|
||||||
|
pane: 'overlayPane',
|
||||||
|
nonBubblingEvents: [] // Array of events that should not be bubbled to DOM parents (like the map)
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor(size) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
addTo(map) {
|
||||||
|
map.addLayer(this);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
_layerAdd(e) {
|
||||||
|
var map = e;//.target;
|
||||||
|
|
||||||
|
// check in case layer gets added and then removed before the map is ready
|
||||||
|
if (!map.hasLayer(this)) { return; }
|
||||||
|
|
||||||
|
this._map = map;
|
||||||
|
//this._zoomAnimated = map._zoomAnimated;
|
||||||
|
|
||||||
|
//if (this.getEvents) {
|
||||||
|
// map.on(this.getEvents(), this);
|
||||||
|
//}
|
||||||
|
|
||||||
|
this.onAdd(map);
|
||||||
|
|
||||||
|
//if (this.getAttribution && this._map.attributionControl) {
|
||||||
|
// this._map.attributionControl.addAttribution(this.getAttribution());
|
||||||
|
//}
|
||||||
|
//this.fire('add');
|
||||||
|
//map.fire('layeradd', { layer: this });
|
||||||
|
}
|
||||||
|
|
||||||
|
getScene() {
|
||||||
|
return this._map.scene;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export { Layer };
|
794
src/js/lib/OrbitControls.js
Normal file
794
src/js/lib/OrbitControls.js
Normal file
|
@ -0,0 +1,794 @@
|
||||||
|
import { Vector2 } from 'three/src/math/Vector2';
|
||||||
|
import { Vector3 } from 'three/src/math/Vector3';
|
||||||
|
import { EventEmitter } from '../core/EventEmitter';
|
||||||
|
import * as domEvent from '../core/domEvent';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* INTERNALS: Any functions not added to the OrbitControls reference won't be visible, or accessible outside of
|
||||||
|
* this file (closure); however, these methods and functions don't belong to the OrbitControls class either
|
||||||
|
* and are static as a result.
|
||||||
|
*/
|
||||||
|
var EPS = 0.000001;
|
||||||
|
var mouseDownPoint = new Vector2();
|
||||||
|
var mouseUpPoint = new Vector2();
|
||||||
|
var rotateStart = new Vector2();
|
||||||
|
var rotateEnd = new Vector2();
|
||||||
|
var rotateDelta = new Vector2();
|
||||||
|
var panStart = new Vector2();
|
||||||
|
var panEnd = new Vector2();
|
||||||
|
var panDelta = new Vector2();
|
||||||
|
|
||||||
|
var panOffset = new Vector3();
|
||||||
|
var offset = new Vector3();
|
||||||
|
|
||||||
|
var dollyStart = new Vector2();
|
||||||
|
var dollyEnd = new Vector2();
|
||||||
|
var dollyDelta = new Vector2();
|
||||||
|
|
||||||
|
var phiDelta = 0;
|
||||||
|
var thetaDelta = 0;
|
||||||
|
var scale = 1;
|
||||||
|
var pan = new Vector3();
|
||||||
|
|
||||||
|
var lastPosition = new Vector3();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var STATE = { NONE: -1, ROTATE: 0, DOLLY: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_DOLLY: 4, TOUCH_PAN: 5, CAMERA_ROTATE: 6 };
|
||||||
|
var state = STATE.NONE;
|
||||||
|
|
||||||
|
class OrbitControls extends EventEmitter {
|
||||||
|
|
||||||
|
object;
|
||||||
|
domElement;
|
||||||
|
scene;
|
||||||
|
enabled;
|
||||||
|
target;
|
||||||
|
center;
|
||||||
|
noZoom;
|
||||||
|
zoomSpeed;
|
||||||
|
minDistance;
|
||||||
|
maxDistance;
|
||||||
|
upsideDown;
|
||||||
|
|
||||||
|
|
||||||
|
noRotate;
|
||||||
|
rotateSpeed;
|
||||||
|
keyRotateAngle;
|
||||||
|
noPan;
|
||||||
|
keyPanSpeed;
|
||||||
|
|
||||||
|
autoRotateSpeed;
|
||||||
|
|
||||||
|
minPolarAngle;
|
||||||
|
maxPolarAngle;
|
||||||
|
|
||||||
|
noKeys;
|
||||||
|
keys;
|
||||||
|
|
||||||
|
|
||||||
|
target0;
|
||||||
|
position0;
|
||||||
|
|
||||||
|
rotateDifference;
|
||||||
|
|
||||||
|
constructor(camera, scene, domElement) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.object = camera;
|
||||||
|
this.domElement = (domElement !== undefined) ? domElement : document;
|
||||||
|
this.scene = scene;
|
||||||
|
|
||||||
|
// Set to false to disable this control
|
||||||
|
this.enabled = true;
|
||||||
|
|
||||||
|
// "target" sets the location of focus, where the control orbits around
|
||||||
|
// and where it pans with respect to.
|
||||||
|
this.target = new Vector3();
|
||||||
|
// center is old, deprecated; use "target" instead
|
||||||
|
this.center = this.target;
|
||||||
|
|
||||||
|
// This option actually enables dollying in and out; left as "zoom" for
|
||||||
|
// backwards compatibility
|
||||||
|
this.noZoom = false;
|
||||||
|
this.zoomSpeed = 1.0;
|
||||||
|
|
||||||
|
// Limits to how far you can dolly in and out
|
||||||
|
this.minDistance = 0;
|
||||||
|
this.maxDistance = Infinity;
|
||||||
|
|
||||||
|
// Set to true for upside down
|
||||||
|
this.upsideDown = false;
|
||||||
|
this.object.up.set(0, 0, 1);
|
||||||
|
|
||||||
|
// Set to true to disable this control
|
||||||
|
this.noRotate = false;
|
||||||
|
this.rotateSpeed = 1.0;
|
||||||
|
this.keyRotateAngle = Math.PI / 90;
|
||||||
|
|
||||||
|
// Set to true to disable this control
|
||||||
|
this.noPan = false;
|
||||||
|
this.keyPanSpeed = 7.0; // pixels moved per arrow key push
|
||||||
|
|
||||||
|
// // Set to true to automatically rotate around the target
|
||||||
|
// this.autoRotate = false;
|
||||||
|
this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60
|
||||||
|
|
||||||
|
// How far you can orbit vertically, upper and lower limits.
|
||||||
|
// Range is 0 to Math.PI radians.
|
||||||
|
this.minPolarAngle = 0; // radians
|
||||||
|
this.maxPolarAngle = Math.PI; // radians
|
||||||
|
|
||||||
|
// Set to true to disable use of the keys
|
||||||
|
this.noKeys = false;
|
||||||
|
|
||||||
|
// The four arrow keys and additional keys
|
||||||
|
this.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40, AUTOROTATE: 82, UPSIDEDOWN: 85, RESET: 82 };
|
||||||
|
|
||||||
|
// for reset
|
||||||
|
this.target0 = this.target.clone();
|
||||||
|
this.position0 = this.object.position.clone();
|
||||||
|
|
||||||
|
this._initEvents('on');
|
||||||
|
}
|
||||||
|
|
||||||
|
_initEvents(onOff) {
|
||||||
|
if (!domEvent) { return; }
|
||||||
|
|
||||||
|
onOff = onOff || 'on';
|
||||||
|
|
||||||
|
//this.domElement.addEventListener('contextmenu', function (event) { event.preventDefault(); }, false);
|
||||||
|
domEvent
|
||||||
|
[onOff](this.domElement, 'contextmenu', domEvent.stopPropagation)
|
||||||
|
[onOff](this.domElement, 'contextmenu', domEvent.preventDefault);
|
||||||
|
|
||||||
|
|
||||||
|
//this.domElement.addEventListener('mousedown', onMouseDown, false);
|
||||||
|
domEvent
|
||||||
|
[onOff](this.domElement, 'mousedown', domEvent.stopPropagation)
|
||||||
|
[onOff](this.domElement, 'click', domEvent.stopPropagation)
|
||||||
|
[onOff](this.domElement, 'dblclick', domEvent.stopPropagation)
|
||||||
|
[onOff](this.domElement, 'mousedown', domEvent.preventDefault)
|
||||||
|
[onOff](this.domElement, 'mousedown', this.onMouseDown, this);
|
||||||
|
|
||||||
|
//this.domElement.addEventListener('mousewheel', onMouseWheel, false);
|
||||||
|
domEvent
|
||||||
|
[onOff](this.domElement, 'mousewheel', domEvent.preventDefault)
|
||||||
|
[onOff](this.domElement, 'mousewheel', domEvent.stopPropagation)
|
||||||
|
[onOff](this.domElement, 'mousewheel', this.onMouseWheel, this);
|
||||||
|
|
||||||
|
//this.domElement.addEventListener('DOMMouseScroll', onMouseWheel, false); // firefox
|
||||||
|
domEvent
|
||||||
|
[onOff](this.domElement, 'DOMMouseScroll', domEvent.preventDefault)
|
||||||
|
[onOff](this.domElement, 'DOMMouseScroll', domEvent.stopPropagation)
|
||||||
|
[onOff](this.domElement, 'DOMMouseScroll', this.onMouseWheel, this);
|
||||||
|
|
||||||
|
|
||||||
|
//window.addEventListener('keydown', onKeyDown, false);
|
||||||
|
domEvent
|
||||||
|
[onOff](window, 'keydown', domEvent.stopPropagation)
|
||||||
|
[onOff](window, 'keydown', domEvent.preventDefault)
|
||||||
|
[onOff](window, 'keydown', this.onKeyDown, this);
|
||||||
|
|
||||||
|
//this.domElement.addEventListener('mousemove', onMouseMove, false);
|
||||||
|
domEvent[onOff](this.domElement, 'mousemove', this.onMouseMove, this);
|
||||||
|
|
||||||
|
//this.domElement.addEventListener('touchstart', touchstart, false);
|
||||||
|
domEvent[onOff](this.domElement, 'touchstart', this.onTouchStart, this);
|
||||||
|
//this.domElement.addEventListener('touchend', touchend, false);
|
||||||
|
domEvent[onOff](this.domElement, 'touchend', this.onTouchEnd, this);
|
||||||
|
//this.domElement.addEventListener('touchmove', touchmove, false);
|
||||||
|
domEvent[onOff](this.domElement, 'touchmove', this.onTouchMove, this);
|
||||||
|
|
||||||
|
domEvent[onOff](this.domElement, 'mouseleave', this.onMouseLeave, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
_getZoomScale() {
|
||||||
|
return Math.pow(0.95, this.zoomSpeed);
|
||||||
|
}
|
||||||
|
|
||||||
|
_AutoRotationAngle() {
|
||||||
|
return 2 * Math.PI / 60 / 60 * this.autoRotateSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
rotateLeft(angle) {
|
||||||
|
if (angle === undefined) {
|
||||||
|
angle = this._AutoRotationAngle();
|
||||||
|
}
|
||||||
|
thetaDelta += angle;
|
||||||
|
}
|
||||||
|
|
||||||
|
rotateUp(angle) {
|
||||||
|
if (angle === undefined) {
|
||||||
|
angle = this._AutoRotationAngle();
|
||||||
|
}
|
||||||
|
phiDelta -= angle;
|
||||||
|
}
|
||||||
|
|
||||||
|
// pass in distance in world space to move left
|
||||||
|
panLeft(distance) {
|
||||||
|
var te = this.object.matrix.elements;
|
||||||
|
|
||||||
|
// get X column of matrix
|
||||||
|
panOffset.set(te[0], te[1], te[2]);
|
||||||
|
panOffset.multiplyScalar(-distance);
|
||||||
|
|
||||||
|
pan.add(panOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
// pass in distance in world space to move up
|
||||||
|
panUp(distance) {
|
||||||
|
var te = this.object.matrix.elements;
|
||||||
|
|
||||||
|
// get Y column of matrix
|
||||||
|
panOffset.set(te[4], te[5], te[6]);
|
||||||
|
panOffset.multiplyScalar(distance);
|
||||||
|
|
||||||
|
pan.add(panOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
// pass in x,y of change desired in pixel space,
|
||||||
|
// right and down are positive
|
||||||
|
pan(deltaX, deltaY) {
|
||||||
|
var element = this.domElement === document ? this.domElement.body : this.domElement;
|
||||||
|
|
||||||
|
if (this.object.fov !== undefined) {
|
||||||
|
|
||||||
|
// perspective
|
||||||
|
var position = this.object.position;
|
||||||
|
var offset = position.clone().sub(this.target);
|
||||||
|
var targetDistance = offset.length();
|
||||||
|
|
||||||
|
// half of the fov is center to top of screen
|
||||||
|
targetDistance *= Math.tan((this.object.fov / 2) * Math.PI / 180.0);
|
||||||
|
|
||||||
|
// we actually don't use screenWidth, since perspective camera is fixed to screen height
|
||||||
|
this.panLeft(2 * deltaX * targetDistance / element.clientHeight);
|
||||||
|
this.panUp(2 * deltaY * targetDistance / element.clientHeight);
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (this.object.top !== undefined) {
|
||||||
|
|
||||||
|
// orthographic
|
||||||
|
this.panLeft(deltaX * (this.object.right - this.object.left) / element.clientWidth);
|
||||||
|
this.panUp(deltaY * (this.object.top - this.object.bottom) / element.clientHeight);
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// camera neither orthographic or perspective
|
||||||
|
console.warn('WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
moveForward(delta) {
|
||||||
|
var element = this.domElement === document ? this.domElement.body : this.domElement;
|
||||||
|
|
||||||
|
panOffset.copy(this.object.position).sub(this.target);
|
||||||
|
var targetDistance = panOffset.length() * Math.tan((this.object.fov / 2) * Math.PI / 180.0);
|
||||||
|
panOffset.z = 0;
|
||||||
|
panOffset.normalize();
|
||||||
|
panOffset.multiplyScalar(-2 * delta * targetDistance / element.clientHeight);
|
||||||
|
|
||||||
|
pan.add(panOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
dollyIn(dollyScale) {
|
||||||
|
if (dollyScale === undefined) {
|
||||||
|
dollyScale = this._getZoomScale();
|
||||||
|
}
|
||||||
|
scale /= dollyScale;
|
||||||
|
this.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
dollyOut(dollyScale) {
|
||||||
|
if (dollyScale === undefined) {
|
||||||
|
dollyScale = this._getZoomScale();
|
||||||
|
}
|
||||||
|
scale *= dollyScale;
|
||||||
|
this.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
update() {
|
||||||
|
var position = this.object.position; //x = 0, y = -100, z = 200;
|
||||||
|
|
||||||
|
// move target to panned location
|
||||||
|
this.target.add(pan);//target ist am Anfang immer x = 0; y = 0; z = 0;
|
||||||
|
//auch pan ist am Anfang immer x = 0; y = 0; z = 0;
|
||||||
|
|
||||||
|
//if (this.autoRotate) { //R
|
||||||
|
// this.rotateLeft(getAutoRotationAngle());
|
||||||
|
//}
|
||||||
|
var theta, phi, radius;
|
||||||
|
//if rotate:
|
||||||
|
if (thetaDelta || phiDelta) {
|
||||||
|
|
||||||
|
offset.copy(position).sub(this.target);
|
||||||
|
|
||||||
|
// angle from y-axis around z-axis
|
||||||
|
theta = Math.atan2(offset.x, offset.y);
|
||||||
|
|
||||||
|
// angle from z-axis
|
||||||
|
phi = Math.atan2(Math.sqrt(offset.x * offset.x + offset.y * offset.y), offset.z);
|
||||||
|
|
||||||
|
theta += thetaDelta;
|
||||||
|
phi += phiDelta;
|
||||||
|
|
||||||
|
// restrict phi to be between desired limits
|
||||||
|
phi = Math.max(this.minPolarAngle, Math.min(this.maxPolarAngle, phi));
|
||||||
|
|
||||||
|
// restrict phi to be betwee EPS and PI-EPS
|
||||||
|
phi = Math.max(EPS, Math.min(Math.PI - EPS, phi));
|
||||||
|
|
||||||
|
radius = offset.length() * scale;
|
||||||
|
|
||||||
|
// restrict radius to be between desired limits
|
||||||
|
radius = Math.max(this.minDistance, Math.min(this.maxDistance, radius));
|
||||||
|
|
||||||
|
offset.x = radius * Math.sin(phi) * Math.sin(theta);
|
||||||
|
offset.y = radius * Math.sin(phi) * Math.cos(theta);
|
||||||
|
offset.z = radius * Math.cos(phi);
|
||||||
|
|
||||||
|
position.copy(this.target).add(offset);
|
||||||
|
|
||||||
|
}
|
||||||
|
//else if (cameraThetaDelta || cameraPhiDelta) {
|
||||||
|
|
||||||
|
// offset.copy(this.target).sub(position);
|
||||||
|
|
||||||
|
// // angle from y-axis around z-axis
|
||||||
|
// theta = Math.atan2(offset.x, offset.y);
|
||||||
|
|
||||||
|
// // angle from z-axis
|
||||||
|
// phi = Math.atan2(Math.sqrt(offset.x * offset.x + offset.y * offset.y), offset.z);
|
||||||
|
|
||||||
|
// theta += cameraThetaDelta;
|
||||||
|
// phi += cameraPhiDelta;
|
||||||
|
|
||||||
|
// // restrict phi to be between desired limits
|
||||||
|
// phi = Math.max(this.minPolarAngle, Math.min(this.maxPolarAngle, phi));
|
||||||
|
|
||||||
|
// // restrict phi to be betwee EPS and PI-EPS
|
||||||
|
// phi = Math.max(EPS, Math.min(Math.PI - EPS, phi));
|
||||||
|
|
||||||
|
// radius = offset.length() * scale;
|
||||||
|
|
||||||
|
// // restrict radius to be between desired limits
|
||||||
|
// radius = Math.max(this.minDistance, Math.min(this.maxDistance, radius));
|
||||||
|
|
||||||
|
// offset.x = radius * Math.sin(phi) * Math.sin(theta);
|
||||||
|
// offset.y = radius * Math.sin(phi) * Math.cos(theta);
|
||||||
|
// offset.z = radius * Math.cos(phi);
|
||||||
|
|
||||||
|
// this.target.copy(position).add(offset);
|
||||||
|
|
||||||
|
//}
|
||||||
|
else if (scale !== 1) {
|
||||||
|
|
||||||
|
offset.copy(position).sub(this.target);
|
||||||
|
|
||||||
|
offset.multiplyScalar(scale);
|
||||||
|
position.copy(this.target).add(offset);
|
||||||
|
|
||||||
|
}
|
||||||
|
//pan
|
||||||
|
else {
|
||||||
|
position.add(pan);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.object.lookAt(this.target);
|
||||||
|
|
||||||
|
thetaDelta = 0;
|
||||||
|
phiDelta = 0;
|
||||||
|
// cameraThetaDelta = 0;
|
||||||
|
// cameraPhiDelta = 0;
|
||||||
|
scale = 1;
|
||||||
|
pan.set(0, 0, 0);
|
||||||
|
|
||||||
|
if (lastPosition.distanceTo(this.object.position) > 0) {
|
||||||
|
//this.dispatchEvent(changeEvent);
|
||||||
|
//scope.emit("change");
|
||||||
|
lastPosition.copy(this.object.position);
|
||||||
|
}
|
||||||
|
this.emit("change", lastPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
reset() {
|
||||||
|
state = STATE.NONE;
|
||||||
|
this.target.copy(this.target0);//0 0 0
|
||||||
|
this.object.position.copy(this.position0);
|
||||||
|
//this.object.position.set(0, 0, 180);
|
||||||
|
this.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
onMouseDown(event) {
|
||||||
|
if (this.enabled === false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.rotateDifference = 0;
|
||||||
|
event.preventDefault();
|
||||||
|
//2d vector:
|
||||||
|
mouseDownPoint.set(event.clientX, event.clientY);
|
||||||
|
|
||||||
|
//linke Maustaste
|
||||||
|
if (event.button === 0) {
|
||||||
|
if (this.noRotate === true) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
state = STATE.ROTATE;
|
||||||
|
rotateStart.set(event.clientX, event.clientY);
|
||||||
|
this.emit("mousedown", event);
|
||||||
|
}
|
||||||
|
else if (event.button === 1) {
|
||||||
|
if (this.noZoom === true) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
state = STATE.DOLLY;
|
||||||
|
//2d vector:
|
||||||
|
dollyStart.set(event.clientX, event.clientY);
|
||||||
|
}
|
||||||
|
//rechte Maustaste
|
||||||
|
else if (event.button === 2) {
|
||||||
|
if (this.noPan === true) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
state = STATE.PAN;
|
||||||
|
panStart.set(event.clientX, event.clientY);
|
||||||
|
}
|
||||||
|
|
||||||
|
//this.domElement.addEventListener('mousemove', onMouseDrag, false);
|
||||||
|
domEvent.on(this.domElement, 'mousemove', this.onMouseDrag, this);
|
||||||
|
|
||||||
|
//this.domElement.addEventListener('mouseup', onMouseUp, false);
|
||||||
|
domEvent.on(this.domElement, 'mouseup', this.onMouseUp, this);
|
||||||
|
|
||||||
|
//scope.dispatchEvent(startEvent);
|
||||||
|
this.emit('movestart', null);
|
||||||
|
}
|
||||||
|
|
||||||
|
onMouseMove(event) {
|
||||||
|
this.emit('mouse-move', event);
|
||||||
|
}
|
||||||
|
|
||||||
|
onMouseDrag(event) {
|
||||||
|
if (this.enabled === false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
var element = this.domElement === document ? this.domElement.body : this.domElement;
|
||||||
|
|
||||||
|
if (state === STATE.ROTATE) {
|
||||||
|
|
||||||
|
if (this.noRotate === true) return;
|
||||||
|
|
||||||
|
rotateEnd.set(event.clientX, event.clientY);
|
||||||
|
rotateDelta.subVectors(rotateEnd, rotateStart);
|
||||||
|
|
||||||
|
// rotating across whole screen goes 360 degrees around
|
||||||
|
this.rotateLeft(2 * Math.PI * rotateDelta.x / element.clientWidth * this.rotateSpeed);
|
||||||
|
|
||||||
|
// rotating up and down along whole screen attempts to go 360, but limited to 180
|
||||||
|
this.rotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight * this.rotateSpeed);
|
||||||
|
|
||||||
|
this.rotateDifference = rotateStart.distanceTo(rotateEnd);
|
||||||
|
rotateStart.copy(rotateEnd);
|
||||||
|
this.emit("mouse-pan", event);
|
||||||
|
}
|
||||||
|
else if (state === STATE.DOLLY) {
|
||||||
|
|
||||||
|
if (this.noZoom === true) return;
|
||||||
|
|
||||||
|
dollyEnd.set(event.clientX, event.clientY);
|
||||||
|
dollyDelta.subVectors(dollyEnd, dollyStart);
|
||||||
|
|
||||||
|
if (dollyDelta.y > 0) {
|
||||||
|
this.dollyIn();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
this.dollyOut();
|
||||||
|
}
|
||||||
|
dollyStart.copy(dollyEnd);
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (state === STATE.PAN) {
|
||||||
|
|
||||||
|
if (this.noPan === true) return;
|
||||||
|
panEnd.set(event.clientX, event.clientY);
|
||||||
|
panDelta.subVectors(panEnd, panStart);
|
||||||
|
|
||||||
|
this.pan(panDelta.x, panDelta.y);
|
||||||
|
panStart.copy(panEnd);
|
||||||
|
|
||||||
|
this.emit("mouse-pan", event);
|
||||||
|
}
|
||||||
|
//scope.emit('mouse-move', event);
|
||||||
|
this.update();
|
||||||
|
} //onMouseDrag end
|
||||||
|
|
||||||
|
onMouseUp(event) {
|
||||||
|
if (this.enabled === false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//this.domElement.removeEventListener('mousemove', onMouseDrag, false);
|
||||||
|
domEvent.off(this.domElement, 'mousemove', this.onMouseDrag);
|
||||||
|
//this.domElement.removeEventListener('mouseup', onMouseUp, false);
|
||||||
|
domEvent.off(this.domElement, 'mouseup', this.onMouseUp);
|
||||||
|
|
||||||
|
|
||||||
|
//scope.dispatchEvent(endEvent);
|
||||||
|
state = STATE.NONE;
|
||||||
|
|
||||||
|
mouseUpPoint.set(event.clientX, event.clientY);
|
||||||
|
|
||||||
|
//var distance = mouseDownPoint.distanceTo(mouseUpPoint);
|
||||||
|
//linke Maustaste
|
||||||
|
if (event.button === 0 && mouseDownPoint.equals(mouseUpPoint)) {// && Math.abs(this.rotateDifference) === 0 ) {
|
||||||
|
//if (event.button === 0 && (Math.abs(distance) < 9 * (window.devicePixelRatio || 1)) ) {
|
||||||
|
|
||||||
|
|
||||||
|
this.emit("clicked", event);
|
||||||
|
//Q3D.application.canvasClicked(event);
|
||||||
|
}
|
||||||
|
} //onMoseUp end
|
||||||
|
|
||||||
|
onMouseWheel(event) {
|
||||||
|
if (this.enabled === false || this.noZoom === true) return;
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
var delta = 0;
|
||||||
|
if (event.wheelDelta !== undefined) { // WebKit / Opera / Explorer 9
|
||||||
|
delta = event.wheelDelta;
|
||||||
|
}
|
||||||
|
else if (event.detail !== undefined) { // Firefox
|
||||||
|
delta = - event.detail;
|
||||||
|
}
|
||||||
|
if (delta > 0) {
|
||||||
|
this.dollyOut();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.dollyIn();
|
||||||
|
}
|
||||||
|
this.update();
|
||||||
|
//scope.dispatchEvent(startEvent);
|
||||||
|
//scope.dispatchEvent(endEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
onMouseLeave(event) {
|
||||||
|
domEvent.off(this.domElement, 'mousemove', this.onMouseDrag);
|
||||||
|
//this.domElement.removeEventListener('mouseup', onMouseUp, false);
|
||||||
|
domEvent.off(this.domElement, 'mouseup', this.onMouseUp);
|
||||||
|
}
|
||||||
|
|
||||||
|
onKeyDown(event) {
|
||||||
|
if (this.enabled === false || this.noKeys === true || this.noPan === true) return;
|
||||||
|
|
||||||
|
if (event.shiftKey && event.ctrlKey) {
|
||||||
|
//zoom +
|
||||||
|
if (event.keyCode === this.keys.UP) this.dollyOut();
|
||||||
|
else if (event.keyCode === this.keys.BOTTOM) this.dollyIn();
|
||||||
|
else return;
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (event.shiftKey) {
|
||||||
|
|
||||||
|
switch (event.keyCode) {
|
||||||
|
|
||||||
|
case this.keys.UP:
|
||||||
|
this.rotateUp(this.keyRotateAngle);
|
||||||
|
break;
|
||||||
|
case this.keys.BOTTOM:
|
||||||
|
this.rotateUp(-this.keyRotateAngle);
|
||||||
|
break;
|
||||||
|
case this.keys.LEFT:
|
||||||
|
this.rotateLeft(-this.keyRotateAngle);
|
||||||
|
break;
|
||||||
|
case this.keys.RIGHT:
|
||||||
|
this.rotateLeft(this.keyRotateAngle);
|
||||||
|
break;
|
||||||
|
//neu
|
||||||
|
case this.keys.RESET:
|
||||||
|
this.reset();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (event.ctrlKey) {
|
||||||
|
|
||||||
|
switch (event.keyCode) {
|
||||||
|
|
||||||
|
case this.keys.UP:
|
||||||
|
this.rotateUp(this.keyRotateAngle);
|
||||||
|
break;
|
||||||
|
case this.keys.BOTTOM:
|
||||||
|
this.rotateUp(-this.keyRotateAngle);
|
||||||
|
break;
|
||||||
|
case this.keys.LEFT:
|
||||||
|
this.rotateLeft(this.keyRotateAngle);
|
||||||
|
break;
|
||||||
|
case this.keys.RIGHT:
|
||||||
|
this.rotateLeft(-this.keyRotateAngle);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
switch (event.keyCode) {
|
||||||
|
|
||||||
|
case this.keys.UP:
|
||||||
|
this.moveForward(-this.keyPanSpeed);
|
||||||
|
break;
|
||||||
|
case this.keys.BOTTOM:
|
||||||
|
this.moveForward(+this.keyPanSpeed);
|
||||||
|
break;
|
||||||
|
case this.keys.LEFT:
|
||||||
|
this.pan(-this.keyPanSpeed, 0);
|
||||||
|
break;
|
||||||
|
case this.keys.RIGHT:
|
||||||
|
this.pan(+this.keyPanSpeed, 0);
|
||||||
|
break;
|
||||||
|
//case scope.keys.AUTOROTATE: //R
|
||||||
|
// scope.autoRotate = !scope.autoRotate;
|
||||||
|
// break;
|
||||||
|
case this.keys.UPSIDEDOWN:
|
||||||
|
this.upsideDown = !this.upsideDown;
|
||||||
|
if (this.upsideDown) this.object.up.set(0, 0, -1);
|
||||||
|
else this.object.up.set(0, 0, 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
onTouchStart(event) {
|
||||||
|
if (this.enabled === false) return;
|
||||||
|
|
||||||
|
switch (event.touches.length) {
|
||||||
|
|
||||||
|
case 1: // one-fingered touch: rotate
|
||||||
|
|
||||||
|
//if (scope.enableRotate === false) return;
|
||||||
|
if (this.noRotate === true) return;
|
||||||
|
|
||||||
|
state = STATE.TOUCH_ROTATE;
|
||||||
|
|
||||||
|
rotateStart.set(event.touches[0].pageX, event.touches[0].pageY);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2: // two-fingered touch: dolly
|
||||||
|
|
||||||
|
//if ( scope.enableZoom === false ) return;
|
||||||
|
if (this.noZoom === true) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
state = STATE.TOUCH_DOLLY;
|
||||||
|
|
||||||
|
var dx = event.touches[0].pageX - event.touches[1].pageX;
|
||||||
|
var dy = event.touches[0].pageY - event.touches[1].pageY;
|
||||||
|
var distance = Math.sqrt(dx * dx + dy * dy);
|
||||||
|
dollyStart.set(0, distance);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3: // three-fingered touch: pan
|
||||||
|
|
||||||
|
//if ( scope.enablePan === false ) return;
|
||||||
|
if (this.noPan === true) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
state = STATE.TOUCH_PAN;
|
||||||
|
|
||||||
|
panStart.set(event.touches[0].pageX, event.touches[0].pageY);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
state = STATE.NONE;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//if ( state !== STATE.NONE ) scope.dispatchEvent( startEvent );
|
||||||
|
if (state !== STATE.NONE) {
|
||||||
|
this.emit('touchstart', null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onTouchMove(event) {
|
||||||
|
if (this.enabled === false) return;
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
|
||||||
|
var element = this.domElement === document ? this.domElement.body : this.domElement;
|
||||||
|
|
||||||
|
switch (event.touches.length) {
|
||||||
|
|
||||||
|
case 1: // one-fingered touch: rotate
|
||||||
|
|
||||||
|
//if (scope.enableRotate === false) return;
|
||||||
|
if (this.noRotate === true) return;
|
||||||
|
if (state !== STATE.TOUCH_ROTATE) return;
|
||||||
|
|
||||||
|
rotateEnd.set(event.touches[0].pageX, event.touches[0].pageY);
|
||||||
|
rotateDelta.subVectors(rotateEnd, rotateStart);
|
||||||
|
|
||||||
|
// rotating across whole screen goes 360 degrees around
|
||||||
|
this.rotateLeft(2 * Math.PI * rotateDelta.x / element.clientWidth * this.rotateSpeed);
|
||||||
|
// rotating up and down along whole screen attempts to go 360, but limited to 180
|
||||||
|
this.rotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight * this.rotateSpeed);
|
||||||
|
|
||||||
|
rotateStart.copy(rotateEnd);
|
||||||
|
this.emit("mouse-pan", event);
|
||||||
|
|
||||||
|
this.update();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2: // two-fingered touch: dolly
|
||||||
|
|
||||||
|
//if (scope.enableZoom === false) return;
|
||||||
|
if (this.noZoom === true) return;
|
||||||
|
if (state !== STATE.TOUCH_DOLLY) return;
|
||||||
|
|
||||||
|
var dx = event.touches[0].pageX - event.touches[1].pageX;
|
||||||
|
var dy = event.touches[0].pageY - event.touches[1].pageY;
|
||||||
|
var distance = Math.sqrt(dx * dx + dy * dy);
|
||||||
|
|
||||||
|
dollyEnd.set(0, distance);
|
||||||
|
dollyDelta.subVectors(dollyEnd, dollyStart);
|
||||||
|
|
||||||
|
if (dollyDelta.y > 0) {
|
||||||
|
|
||||||
|
this.dollyOut(this._getZoomScale());
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (dollyDelta.y < 0) {
|
||||||
|
this.dollyIn(this._getZoomScale());
|
||||||
|
}
|
||||||
|
dollyStart.copy(dollyEnd);
|
||||||
|
this.emit("mouse-pan", event);
|
||||||
|
|
||||||
|
this.update();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3: // three-fingered touch: pan
|
||||||
|
|
||||||
|
//if (scope.enablePan === false) return;
|
||||||
|
if (this.noPan === true) return;
|
||||||
|
if (state !== STATE.TOUCH_PAN) return;
|
||||||
|
|
||||||
|
panEnd.set(event.touches[0].pageX, event.touches[0].pageY);
|
||||||
|
panDelta.subVectors(panEnd, panStart);
|
||||||
|
|
||||||
|
this.pan(panDelta.x, panDelta.y);
|
||||||
|
|
||||||
|
panStart.copy(panEnd);
|
||||||
|
|
||||||
|
this.update();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
state = STATE.NONE;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onTouchEnd( /* event */) {
|
||||||
|
if (this.enabled === false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//scope.dispatchEvent(endEvent);
|
||||||
|
this.emit('touchend', null);
|
||||||
|
state = STATE.NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export { OrbitControls };
|
158
src/js/main.js
Normal file
158
src/js/main.js
Normal file
|
@ -0,0 +1,158 @@
|
||||||
|
// import { DirectionalLight, AmbientLight, WebGLRenderer, PerspectiveCamera, Scene } from 'three';
|
||||||
|
import { DirectionalLight } from 'three/src/lights/DirectionalLight';
|
||||||
|
import { AmbientLight } from 'three/src/lights/AmbientLight';
|
||||||
|
import { WebGLRenderer } from 'three/src/renderers/WebGLRenderer';
|
||||||
|
import { PerspectiveCamera } from 'three/src/cameras/PerspectiveCamera';
|
||||||
|
import { Scene } from 'three/src/scenes/Scene';
|
||||||
|
import { BoxLayer } from './layer/BoxLayer';
|
||||||
|
// import * as util from './core/utilities';
|
||||||
|
// import { OrbitControls } from './lib/OrbitControls.js'
|
||||||
|
import { Map } from './core/Map';
|
||||||
|
import * as domEvent from './core/domEvent';
|
||||||
|
|
||||||
|
import '../css/page.css'; /* style loader will import it */
|
||||||
|
|
||||||
|
class Application {
|
||||||
|
|
||||||
|
constructor(container) {
|
||||||
|
this.container = container;
|
||||||
|
this.running = false; // this is public
|
||||||
|
|
||||||
|
this.objects = [];
|
||||||
|
|
||||||
|
if (container.clientWidth && container.clientHeight) {
|
||||||
|
this.width = container.clientWidth;
|
||||||
|
this.height = container.clientHeight;
|
||||||
|
this._fullWindow = false;
|
||||||
|
} else {
|
||||||
|
this.width = window.innerWidth;
|
||||||
|
this.height = window.innerHeight;
|
||||||
|
this._fullWindow = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.createScene();
|
||||||
|
}
|
||||||
|
|
||||||
|
createScene() {
|
||||||
|
|
||||||
|
/* Renderer */
|
||||||
|
var bgcolor = 0xfdfdfd;
|
||||||
|
this.renderer = new WebGLRenderer({ alpha: true, antialias: true });
|
||||||
|
// this.renderer.setSize(window.innerWidth, window.innerHeight);
|
||||||
|
// document.body.appendChild(this.renderer.domElement);
|
||||||
|
this.renderer.setSize(this.width, this.height);
|
||||||
|
this.renderer.setClearColor(bgcolor, 1); // second param is opacity, 0 => transparent
|
||||||
|
this.renderer.render
|
||||||
|
this.container.appendChild(this.renderer.domElement);
|
||||||
|
|
||||||
|
/* Scene: that will hold all our elements such as objects, cameras and lights. */
|
||||||
|
this.scene = new Scene();
|
||||||
|
//app.scene.add(new THREE.AmbientLight(0xeeeeee));
|
||||||
|
this._buildDefaultLights(this.scene);
|
||||||
|
//app.scene.autoUpdate = false;
|
||||||
|
//// show axes in the screen
|
||||||
|
//app.scene.add(new THREE.AxisHelper(100));
|
||||||
|
|
||||||
|
/* Camera */
|
||||||
|
var angle = 45;
|
||||||
|
var aspect = this.width / this.height;
|
||||||
|
var near = 0.1; //This is the distance at which the camera will start rendering scene objects
|
||||||
|
var far = 2000; //Anything beyond this distance will not be rendered
|
||||||
|
this.camera = new PerspectiveCamera(angle, aspect, near, far);
|
||||||
|
//this.camera.position.z = 20;
|
||||||
|
this.camera.position.set(0, -0.1, 150);
|
||||||
|
// this.camera.lookAt(new THREE.Vector3(0, 0, 0));
|
||||||
|
|
||||||
|
// this.controls = new OrbitControls(this.camera, this.scene, this.renderer.domElement);
|
||||||
|
this.map = new Map(this.camera, this.scene, this.renderer.domElement, this.container);
|
||||||
|
let boxLayer = new BoxLayer({ width: 10, height: 10, depth: 10 });
|
||||||
|
this.map.addLayer(boxLayer);
|
||||||
|
|
||||||
|
domEvent.on(window, 'click', this.onWindowResize, this);
|
||||||
|
|
||||||
|
// util.setLoading("webgl");
|
||||||
|
this.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
onWindowResize() {
|
||||||
|
if (this._fullWindow) {
|
||||||
|
this._setCanvasSize(window.innerWidth, window.innerHeight);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this._setCanvasSize(this.container.clientWidth, this.container.clientHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_setCanvasSize (width, height) {
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
this.camera.aspect = width / height;
|
||||||
|
this.camera.updateProjectionMatrix();
|
||||||
|
this.renderer.setSize(width, height);
|
||||||
|
this.animate();
|
||||||
|
}
|
||||||
|
|
||||||
|
_buildDefaultLights(scene) {
|
||||||
|
var deg2rad = Math.PI / 180;
|
||||||
|
|
||||||
|
// ambient light
|
||||||
|
scene.add(new AmbientLight(0x999999));
|
||||||
|
//scene.add(new THREE.AmbientLight(0xeeeeee));
|
||||||
|
|
||||||
|
// directional lights
|
||||||
|
var opt = {
|
||||||
|
azimuth: 220, // note: default light azimuth of gdaldem hillshade is 315.
|
||||||
|
altitude: 45 // altitude angle
|
||||||
|
};
|
||||||
|
//appSettings.Options.light.directional;
|
||||||
|
var lambda = (90 - opt.azimuth) * deg2rad;
|
||||||
|
var phi = opt.altitude * deg2rad;
|
||||||
|
|
||||||
|
var x = Math.cos(phi) * Math.cos(lambda),
|
||||||
|
y = Math.cos(phi) * Math.sin(lambda),
|
||||||
|
z = Math.sin(phi);
|
||||||
|
|
||||||
|
var light1 = new DirectionalLight(0xffffff, 0.5);
|
||||||
|
light1.position.set(x, y, z);
|
||||||
|
scene.add(light1);
|
||||||
|
|
||||||
|
// thin light from the opposite direction
|
||||||
|
var light2 = new DirectionalLight(0xffffff, 0.1);
|
||||||
|
light2.position.set(-x, -y, -z);
|
||||||
|
scene.add(light2);
|
||||||
|
}
|
||||||
|
|
||||||
|
start() {
|
||||||
|
this.running = true;
|
||||||
|
|
||||||
|
this.map.addListener('change', this.animate, this); // add this only if there is no animation loop (requestAnimationFrame)
|
||||||
|
this.animate();
|
||||||
|
}
|
||||||
|
|
||||||
|
animate() {
|
||||||
|
if (this.running) {
|
||||||
|
// requestAnimationFrame(() => {
|
||||||
|
// this.animate();
|
||||||
|
// }, 1000 / 30);
|
||||||
|
|
||||||
|
// this.objects.forEach((object) => {
|
||||||
|
// object.update();
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
|
||||||
|
this.renderer.render(this.scene, this.camera);
|
||||||
|
}
|
||||||
|
|
||||||
|
add(layer) {
|
||||||
|
this.objects.push(layer);
|
||||||
|
this.scene.add(layer.getMesh());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var container = document.getElementById("webgl");
|
||||||
|
let app = new Application(container);
|
||||||
|
// app.add(new BoxLayer({
|
||||||
|
// width: 10,
|
||||||
|
// height: 10,
|
||||||
|
// depth: 10
|
||||||
|
// }));
|
5
typings.json
Normal file
5
typings.json
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"globalDevDependencies": {
|
||||||
|
"three": "registry:dt/three#0.84.0+20170323144537"
|
||||||
|
}
|
||||||
|
}
|
6875
typings/globals/three/index.d.ts
vendored
Normal file
6875
typings/globals/three/index.d.ts
vendored
Normal file
File diff suppressed because it is too large
Load Diff
8
typings/globals/three/typings.json
Normal file
8
typings/globals/three/typings.json
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"resolution": "main",
|
||||||
|
"tree": {
|
||||||
|
"src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/ccda793e883ecb20bd396121f1e89df8c1dd00ce/three/index.d.ts",
|
||||||
|
"raw": "registry:dt/three#0.84.0+20170323144537",
|
||||||
|
"typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/ccda793e883ecb20bd396121f1e89df8c1dd00ce/three/index.d.ts"
|
||||||
|
}
|
||||||
|
}
|
1
typings/index.d.ts
vendored
Normal file
1
typings/index.d.ts
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/// <reference path="globals/three/index.d.ts" />
|
163
webpack.config.js
Normal file
163
webpack.config.js
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
require('dotenv').config();
|
||||||
|
const path = require('path');
|
||||||
|
const webpack = require('webpack'); //e.g. for iusing DefinePlugin
|
||||||
|
// const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
|
||||||
|
const TerserPlugin = require('terser-webpack-plugin');
|
||||||
|
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
|
||||||
|
// https://www.sitepoint.com/es6-babel-webpack/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* flag Used to check if the environment is production or not
|
||||||
|
*/
|
||||||
|
const isProduction = (process.env.NODE_ENV === 'production');
|
||||||
|
const devMode = (process.env.NODE_ENV !== 'production');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Include hash to filenames for cache busting - only at production
|
||||||
|
*/
|
||||||
|
const fileNamePrefix = isProduction ? '[chunkhash].' : '';
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
mode: process.env.NODE_ENV,
|
||||||
|
context: __dirname,
|
||||||
|
entry: './src/js/main.js',
|
||||||
|
output: {
|
||||||
|
path: path.resolve(__dirname, 'dist'),
|
||||||
|
filename: '[name].js',
|
||||||
|
//filename: fileNamePrefix + '[name].js',
|
||||||
|
publicPath: '/dist/',
|
||||||
|
},
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.(svg|eot|ttf|woff|woff2)$/,
|
||||||
|
loader: 'url-loader',
|
||||||
|
options: {
|
||||||
|
limit: 10000,
|
||||||
|
name: 'fonts/[name].[ext]'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.(png|jpg|gif)$/,
|
||||||
|
loaders: [
|
||||||
|
{
|
||||||
|
loader: 'url-loader',
|
||||||
|
options: {
|
||||||
|
limit: 10000,
|
||||||
|
name: 'images/[name].[ext]'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'img-loader'
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.js$/,
|
||||||
|
exclude: /(node_modules|bower_components)/,
|
||||||
|
use: {
|
||||||
|
loader: 'babel-loader',
|
||||||
|
options: {
|
||||||
|
presets: ['@babel/preset-env']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
test: /\.(less|css)$/,
|
||||||
|
use: [
|
||||||
|
{
|
||||||
|
// loader: (isProduction === true) ? MiniCssExtractPlugin.loader : 'style-loader',
|
||||||
|
// loader: 'style-loader',
|
||||||
|
loader: MiniCssExtractPlugin.loader,
|
||||||
|
// loader: MiniCssExtractPlugin.loader,
|
||||||
|
// options: {
|
||||||
|
// hmr: process.env.NODE_ENV === 'development',
|
||||||
|
// },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loader: "css-loader",
|
||||||
|
options: {
|
||||||
|
sourceMap: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loader: "less-loader",
|
||||||
|
options: {
|
||||||
|
sourceMap: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
]
|
||||||
|
},
|
||||||
|
stats: {
|
||||||
|
colors: true
|
||||||
|
},
|
||||||
|
// devtool: 'source-map',
|
||||||
|
|
||||||
|
optimization: {
|
||||||
|
minimize: isProduction,
|
||||||
|
minimizer: [new TerserPlugin({
|
||||||
|
parallel: true,
|
||||||
|
sourceMap: true,
|
||||||
|
terserOptions: {
|
||||||
|
extractComments: 'all',
|
||||||
|
compress: {
|
||||||
|
drop_console: true,
|
||||||
|
drop_debugger: true,
|
||||||
|
keep_classnames: false,
|
||||||
|
keep_fnames: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})],
|
||||||
|
},
|
||||||
|
|
||||||
|
plugins: [
|
||||||
|
|
||||||
|
new webpack.DefinePlugin({ // Remove this plugin if you don't plan to define any global constants
|
||||||
|
ENVIRONMENT: JSON.stringify(process.env.NODE_ENV),
|
||||||
|
CONSTANT_VALUE: JSON.stringify(process.env.CONSTANT_VALUE),
|
||||||
|
}),
|
||||||
|
// extractLess,
|
||||||
|
new MiniCssExtractPlugin({ // Make sure MiniCssExtractPlugin instance is included in array before the PurifyCSSPlugin
|
||||||
|
// Options similar to the same options in webpackOptions.output
|
||||||
|
// both options are optional
|
||||||
|
// filename: '[name].css',
|
||||||
|
// chunkFilename: '[id].css',
|
||||||
|
filename: '[name].css',
|
||||||
|
chunkFilename: '[id].css',
|
||||||
|
}),
|
||||||
|
// new PurifyCSSPlugin({
|
||||||
|
// paths: glob.sync(__dirname + '/*.html'),
|
||||||
|
// minimize: true,
|
||||||
|
// }),
|
||||||
|
// new webpack.HotModuleReplacementPlugin(),
|
||||||
|
],
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Production only plugins
|
||||||
|
*/
|
||||||
|
if (isProduction === true) {
|
||||||
|
module.exports.plugins.push(
|
||||||
|
// module.exports.optimization.minimizer.push(
|
||||||
|
// new UglifyJsPlugin({ sourceMap: true })
|
||||||
|
// );
|
||||||
|
function () { // Create a manifest.json file that contain the hashed file names of generated static resources
|
||||||
|
this.plugin("done", function (status) {
|
||||||
|
require("fs").writeFileSync(
|
||||||
|
__dirname + "/dist/manifest.json",
|
||||||
|
JSON.stringify(status.toJson().assetsByChunkName)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
);
|
||||||
|
//development
|
||||||
|
} else {
|
||||||
|
module.exports.plugins.push(
|
||||||
|
//auto updating on dev server
|
||||||
|
new webpack.HotModuleReplacementPlugin()// HMR plugin will cause problems with [chunkhash]
|
||||||
|
);
|
||||||
|
}
|
7
webpack.prod.config.js
Normal file
7
webpack.prod.config.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
const merge = require('webpack-merge');
|
||||||
|
const common = require('./webpack.config.js');
|
||||||
|
|
||||||
|
module.exports = merge(common, {
|
||||||
|
mode: 'production',
|
||||||
|
devtool: 'source-map',
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user