Added functionality and dark mode to doctests. And other changes in maps.
This commit is contained in:
parent
89395ba641
commit
6dcf6d38da
@ -2,12 +2,78 @@ html {
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
background: white;
|
background: white;
|
||||||
font-family: Arial, sans-serif;
|
|
||||||
color: #000;
|
color: #000;
|
||||||
max-width: 932px;
|
font-family: 'Open Sans', Arial, sans-serif;
|
||||||
|
max-width: 1200px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html.dark-mode {
|
||||||
|
background: rgb(51, 51, 51);
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark-mode h1,
|
||||||
|
.dark-mode h2,
|
||||||
|
.dark-mode h3,
|
||||||
|
.dark-mode h4,
|
||||||
|
.dark-mode h5,
|
||||||
|
.dark-mode h6 {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
position: relative;
|
||||||
|
font-size: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
font-style: italic;
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
display: block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doctest {
|
||||||
|
margin: 0;
|
||||||
|
padding-top: 50px;
|
||||||
|
padding-bottom: 50px;
|
||||||
|
box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
.collapsed .doctest {
|
||||||
|
height: 0;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doctest-wrapper {
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 5px;
|
||||||
|
|
||||||
|
margin-top: 1em;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doctest-collapsible-toggle {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
color: whitesmoke;
|
||||||
|
background-color: #111;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doctest-section-title {
|
||||||
|
margin: 0;
|
||||||
|
margin-left: 40px;
|
||||||
|
|
||||||
|
padding: 0;
|
||||||
|
font-size: 1.3em;
|
||||||
|
}
|
||||||
|
|
||||||
.grayBorder {
|
.grayBorder {
|
||||||
border: 1px solid lightgray;
|
border: 1px solid lightgray;
|
||||||
}
|
}
|
||||||
@ -34,8 +100,8 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
canvas {
|
canvas {
|
||||||
-ms-content-zooming: none; /** Crucial for MS Edge pointer events **/
|
-ms-content-zooming: none; /** Crucial for MS Edge pointer events **/
|
||||||
touch-action: none; /** Crucial for MS Edge? **/
|
touch-action: none; /** Crucial for MS Edge? **/
|
||||||
}
|
}
|
||||||
|
|
||||||
#runtime-errors {
|
#runtime-errors {
|
||||||
|
14961
dist/iwmlib.3rdparty.js
vendored
14961
dist/iwmlib.3rdparty.js
vendored
File diff suppressed because one or more lines are too long
122
dist/iwmlib.js
vendored
122
dist/iwmlib.js
vendored
@ -121,6 +121,60 @@
|
|||||||
return stringified
|
return stringified
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When dealing with floating point numbers,
|
||||||
|
* floating point imprecision may occur. Therefore a simple
|
||||||
|
* equality check is not sufficient.
|
||||||
|
*
|
||||||
|
* The expectPointPrecision method compares two points by calculating their difference
|
||||||
|
* and accepting the result as far as it is lower than the defined acceptable error.
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @param {number} a - Number a to test.
|
||||||
|
* @param {number} b - Number b to test against.
|
||||||
|
* @param {number} accetableError - Defines the value of how much the two numbers may differ, that the test still passes.
|
||||||
|
* @memberof Doctest
|
||||||
|
*/
|
||||||
|
static expectPointPrecision(pointA, pointB, accetableError = 0.000001) {
|
||||||
|
if (Math.abs(pointA.x - pointB.x) > accetableError || Math.abs(pointA.y - pointB.y) > accetableError) {
|
||||||
|
throw new Error(
|
||||||
|
`Testing difference of Points ${this.pprint(pointA)} and ${this.pprint(
|
||||||
|
pointB
|
||||||
|
)} exceeded the acceptable error of ${accetableError} (x:${Math.abs(
|
||||||
|
pointB.x - pointA.x
|
||||||
|
)}, y: ${Math.abs(pointB.y - pointA.y)}).`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When dealing with floating point numbers,
|
||||||
|
* floating point imprecision may occur. Therefore a simple
|
||||||
|
* equality check is not sufficient.
|
||||||
|
*
|
||||||
|
* The expectPrecise method compares two numbers by calculating their difference
|
||||||
|
* and accepting the result as far as it is lower than the defined acceptable error.
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @param {number} a - Number a to test.
|
||||||
|
* @param {number} b - Number b to test against.
|
||||||
|
* @param {number} accetableError - Defines the value of how much the two numbers may differ, that the test still passes.
|
||||||
|
* @memberof Doctest
|
||||||
|
*/
|
||||||
|
static expectPrecision(a, b, accetableError = 0.000001) {
|
||||||
|
let aFloat = parseFloat(a);
|
||||||
|
let bFloat = parseFloat(b);
|
||||||
|
|
||||||
|
console.log(aFloat);
|
||||||
|
if (isNaN(aFloat) || isNaN(bFloat) || Math.abs(bFloat - aFloat) > accetableError) {
|
||||||
|
throw new Error(
|
||||||
|
`Testing difference of ${this.pprint(a)} and ${this.pprint(
|
||||||
|
b
|
||||||
|
)} exceeded the acceptable error of ${accetableError} (${Math.abs(bFloat - aFloat)}).`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static expect(expr, value) {
|
static expect(expr, value) {
|
||||||
if (this.pprint(expr) != this.pprint(value)) {
|
if (this.pprint(expr) != this.pprint(value)) {
|
||||||
//throw new Error("got `" + expr + "` but expected `" + value + "`.")
|
//throw new Error("got `" + expr + "` but expected `" + value + "`.")
|
||||||
@ -181,7 +235,51 @@
|
|||||||
let doctest = doctests[i];
|
let doctest = doctests[i];
|
||||||
let code = this.stripLeadingLines(doctest.innerHTML);
|
let code = this.stripLeadingLines(doctest.innerHTML);
|
||||||
let text = this.highlight(code);
|
let text = this.highlight(code);
|
||||||
|
|
||||||
|
let container = document.createElement('div');
|
||||||
|
container.className = 'doctest-wrapper';
|
||||||
|
|
||||||
|
let titleParent = container;
|
||||||
|
if (doctest.hasAttribute('data-collapsible')) {
|
||||||
|
let collapsibleToggle = document.createElement('div');
|
||||||
|
|
||||||
|
let icon = document.createElement('i');
|
||||||
|
icon.className = 'material-icons';
|
||||||
|
collapsibleToggle.appendChild(icon);
|
||||||
|
|
||||||
|
collapsibleToggle.className = 'doctest-collapsible-toggle';
|
||||||
|
collapsibleToggle.style = 'min-height: 10px;';
|
||||||
|
titleParent = collapsibleToggle;
|
||||||
|
container.appendChild(collapsibleToggle);
|
||||||
|
|
||||||
|
const collapsedClass = 'collapsed';
|
||||||
|
|
||||||
|
function setToggleMode(collapse) {
|
||||||
|
if (collapse) {
|
||||||
|
container.classList.add(collapsedClass);
|
||||||
|
icon.innerText = 'arrow_drop_down';
|
||||||
|
} else {
|
||||||
|
container.classList.remove(collapsedClass);
|
||||||
|
icon.innerText = 'arrow_drop_up';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function determineToggleMode() {
|
||||||
|
setToggleMode(!container.classList.contains(collapsedClass));
|
||||||
|
}
|
||||||
|
|
||||||
|
setToggleMode(doctest.hasAttribute('data-collapsed'));
|
||||||
|
collapsibleToggle.addEventListener('click', determineToggleMode);
|
||||||
|
}
|
||||||
|
if (doctest.hasAttribute('data-title')) {
|
||||||
|
let title = document.createElement('h6');
|
||||||
|
title.innerText = doctest.getAttribute('data-title');
|
||||||
|
title.className = 'doctest-section-title';
|
||||||
|
titleParent.appendChild(title);
|
||||||
|
}
|
||||||
|
|
||||||
let pre = document.createElement('pre');
|
let pre = document.createElement('pre');
|
||||||
|
pre.className = 'hljs doctest';
|
||||||
// See http://stackoverflow.com/questions/1068280/javascript-regex-multiline-flag-doesnt-work
|
// See http://stackoverflow.com/questions/1068280/javascript-regex-multiline-flag-doesnt-work
|
||||||
// let re = /Doctest\.expect\(([\s\S]*)[\,\s\S]*([\s\S]*)\)/g
|
// let re = /Doctest\.expect\(([\s\S]*)[\,\s\S]*([\s\S]*)\)/g
|
||||||
let lines = text.value ? text.value.split('\n') : text.split('\n');
|
let lines = text.value ? text.value.split('\n') : text.split('\n');
|
||||||
@ -196,7 +294,9 @@
|
|||||||
better.push(line);
|
better.push(line);
|
||||||
}
|
}
|
||||||
pre.innerHTML = better.join('\n'); // text.value.replace(re, ">>> $1\n$2")
|
pre.innerHTML = better.join('\n'); // text.value.replace(re, ">>> $1\n$2")
|
||||||
doctest.parentNode.replaceChild(pre, doctest);
|
container.appendChild(pre);
|
||||||
|
|
||||||
|
doctest.parentNode.replaceChild(container, doctest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -10962,6 +11062,7 @@
|
|||||||
|
|
||||||
remove() {
|
remove() {
|
||||||
this.button = null;
|
this.button = null;
|
||||||
|
this._stopThisSpeechIfPlaying();
|
||||||
this.context.removeEventListener('DOMNodeRemoved', this._domWasChanged);
|
this.context.removeEventListener('DOMNodeRemoved', this._domWasChanged);
|
||||||
super.remove();
|
super.remove();
|
||||||
}
|
}
|
||||||
@ -10979,12 +11080,18 @@
|
|||||||
context.addEventListener('DOMNodeRemoved', this._domWasChanged);
|
context.addEventListener('DOMNodeRemoved', this._domWasChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Don't remember why this was required - SO 20-11-2019
|
||||||
|
*/
|
||||||
_domWasChanged(event) {
|
_domWasChanged(event) {
|
||||||
if (this.context == null) this._stop();
|
if (event.target == this.context) this._stopThisSpeechIfPlaying();
|
||||||
else if (
|
}
|
||||||
this.context['lastSpeechNode'] == window.speechSynthesis['speechPluginNode'] &&
|
|
||||||
event.target == this.context
|
/**
|
||||||
) {
|
* Stops the module if it is set in the context.
|
||||||
|
*/
|
||||||
|
_stopThisSpeechIfPlaying() {
|
||||||
|
if (this.context == null || this.context['lastSpeechNode'] == window.speechSynthesis['speechPluginNode']) {
|
||||||
this._stop();
|
this._stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -11008,7 +11115,6 @@
|
|||||||
* SO -17.07.19
|
* SO -17.07.19
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let activeNode = window.speechSynthesis['speechPluginNode'];
|
|
||||||
this._updateText();
|
this._updateText();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -11050,6 +11156,8 @@
|
|||||||
this.context.classList.add('speech-plugin-is-reading');
|
this.context.classList.add('speech-plugin-is-reading');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
closed() {}
|
||||||
|
|
||||||
_cleanupText(node) {
|
_cleanupText(node) {
|
||||||
let text = node.textContent;
|
let text = node.textContent;
|
||||||
text = this._removeShy(text);
|
text = this._removeShy(text);
|
||||||
|
1306
dist/iwmlib.pixi.js
vendored
1306
dist/iwmlib.pixi.js
vendored
File diff suppressed because it is too large
Load Diff
@ -497,6 +497,7 @@ CardPlugin.Speech = class SpeechPlugin extends CardPluginBase {
|
|||||||
|
|
||||||
remove() {
|
remove() {
|
||||||
this.button = null
|
this.button = null
|
||||||
|
this._stopThisSpeechIfPlaying()
|
||||||
this.context.removeEventListener('DOMNodeRemoved', this._domWasChanged)
|
this.context.removeEventListener('DOMNodeRemoved', this._domWasChanged)
|
||||||
super.remove()
|
super.remove()
|
||||||
}
|
}
|
||||||
@ -514,12 +515,18 @@ CardPlugin.Speech = class SpeechPlugin extends CardPluginBase {
|
|||||||
context.addEventListener('DOMNodeRemoved', this._domWasChanged)
|
context.addEventListener('DOMNodeRemoved', this._domWasChanged)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Don't remember why this was required - SO 20-11-2019
|
||||||
|
*/
|
||||||
_domWasChanged(event) {
|
_domWasChanged(event) {
|
||||||
if (this.context == null) this._stop()
|
if (event.target == this.context) this._stopThisSpeechIfPlaying()
|
||||||
else if (
|
}
|
||||||
this.context['lastSpeechNode'] == window.speechSynthesis['speechPluginNode'] &&
|
|
||||||
event.target == this.context
|
/**
|
||||||
) {
|
* Stops the module if it is set in the context.
|
||||||
|
*/
|
||||||
|
_stopThisSpeechIfPlaying() {
|
||||||
|
if (this.context == null || this.context['lastSpeechNode'] == window.speechSynthesis['speechPluginNode']) {
|
||||||
this._stop()
|
this._stop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -543,7 +550,6 @@ CardPlugin.Speech = class SpeechPlugin extends CardPluginBase {
|
|||||||
* SO -17.07.19
|
* SO -17.07.19
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let activeNode = window.speechSynthesis['speechPluginNode']
|
|
||||||
this._updateText()
|
this._updateText()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -585,6 +591,8 @@ CardPlugin.Speech = class SpeechPlugin extends CardPluginBase {
|
|||||||
this.context.classList.add('speech-plugin-is-reading')
|
this.context.classList.add('speech-plugin-is-reading')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
closed() {}
|
||||||
|
|
||||||
_cleanupText(node) {
|
_cleanupText(node) {
|
||||||
let text = node.textContent
|
let text = node.textContent
|
||||||
text = this._removeShy(text)
|
text = this._removeShy(text)
|
||||||
|
102
lib/doctest.js
102
lib/doctest.js
@ -27,6 +27,60 @@ export default class Doctest {
|
|||||||
return stringified
|
return stringified
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When dealing with floating point numbers,
|
||||||
|
* floating point imprecision may occur. Therefore a simple
|
||||||
|
* equality check is not sufficient.
|
||||||
|
*
|
||||||
|
* The expectPointPrecision method compares two points by calculating their difference
|
||||||
|
* and accepting the result as far as it is lower than the defined acceptable error.
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @param {number} a - Number a to test.
|
||||||
|
* @param {number} b - Number b to test against.
|
||||||
|
* @param {number} accetableError - Defines the value of how much the two numbers may differ, that the test still passes.
|
||||||
|
* @memberof Doctest
|
||||||
|
*/
|
||||||
|
static expectPointPrecision(pointA, pointB, accetableError = 0.000001) {
|
||||||
|
if (Math.abs(pointA.x - pointB.x) > accetableError || Math.abs(pointA.y - pointB.y) > accetableError) {
|
||||||
|
throw new Error(
|
||||||
|
`Testing difference of Points ${this.pprint(pointA)} and ${this.pprint(
|
||||||
|
pointB
|
||||||
|
)} exceeded the acceptable error of ${accetableError} (x:${Math.abs(
|
||||||
|
pointB.x - pointA.x
|
||||||
|
)}, y: ${Math.abs(pointB.y - pointA.y)}).`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When dealing with floating point numbers,
|
||||||
|
* floating point imprecision may occur. Therefore a simple
|
||||||
|
* equality check is not sufficient.
|
||||||
|
*
|
||||||
|
* The expectPrecise method compares two numbers by calculating their difference
|
||||||
|
* and accepting the result as far as it is lower than the defined acceptable error.
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @param {number} a - Number a to test.
|
||||||
|
* @param {number} b - Number b to test against.
|
||||||
|
* @param {number} accetableError - Defines the value of how much the two numbers may differ, that the test still passes.
|
||||||
|
* @memberof Doctest
|
||||||
|
*/
|
||||||
|
static expectPrecision(a, b, accetableError = 0.000001) {
|
||||||
|
let aFloat = parseFloat(a)
|
||||||
|
let bFloat = parseFloat(b)
|
||||||
|
|
||||||
|
console.log(aFloat)
|
||||||
|
if (isNaN(aFloat) || isNaN(bFloat) || Math.abs(bFloat - aFloat) > accetableError) {
|
||||||
|
throw new Error(
|
||||||
|
`Testing difference of ${this.pprint(a)} and ${this.pprint(
|
||||||
|
b
|
||||||
|
)} exceeded the acceptable error of ${accetableError} (${Math.abs(bFloat - aFloat)}).`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static expect(expr, value) {
|
static expect(expr, value) {
|
||||||
if (this.pprint(expr) != this.pprint(value)) {
|
if (this.pprint(expr) != this.pprint(value)) {
|
||||||
//throw new Error("got `" + expr + "` but expected `" + value + "`.")
|
//throw new Error("got `" + expr + "` but expected `" + value + "`.")
|
||||||
@ -87,7 +141,51 @@ export default class Doctest {
|
|||||||
let doctest = doctests[i]
|
let doctest = doctests[i]
|
||||||
let code = this.stripLeadingLines(doctest.innerHTML)
|
let code = this.stripLeadingLines(doctest.innerHTML)
|
||||||
let text = this.highlight(code)
|
let text = this.highlight(code)
|
||||||
|
|
||||||
|
let container = document.createElement('div')
|
||||||
|
container.className = 'doctest-wrapper'
|
||||||
|
|
||||||
|
let titleParent = container
|
||||||
|
if (doctest.hasAttribute('data-collapsible')) {
|
||||||
|
let collapsibleToggle = document.createElement('div')
|
||||||
|
|
||||||
|
let icon = document.createElement('i')
|
||||||
|
icon.className = 'material-icons'
|
||||||
|
collapsibleToggle.appendChild(icon)
|
||||||
|
|
||||||
|
collapsibleToggle.className = 'doctest-collapsible-toggle'
|
||||||
|
collapsibleToggle.style = 'min-height: 10px;'
|
||||||
|
titleParent = collapsibleToggle
|
||||||
|
container.appendChild(collapsibleToggle)
|
||||||
|
|
||||||
|
const collapsedClass = 'collapsed'
|
||||||
|
|
||||||
|
function setToggleMode(collapse) {
|
||||||
|
if (collapse) {
|
||||||
|
container.classList.add(collapsedClass)
|
||||||
|
icon.innerText = 'arrow_drop_down'
|
||||||
|
} else {
|
||||||
|
container.classList.remove(collapsedClass)
|
||||||
|
icon.innerText = 'arrow_drop_up'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function determineToggleMode() {
|
||||||
|
setToggleMode(!container.classList.contains(collapsedClass))
|
||||||
|
}
|
||||||
|
|
||||||
|
setToggleMode(doctest.hasAttribute('data-collapsed'))
|
||||||
|
collapsibleToggle.addEventListener('click', determineToggleMode)
|
||||||
|
}
|
||||||
|
if (doctest.hasAttribute('data-title')) {
|
||||||
|
let title = document.createElement('h6')
|
||||||
|
title.innerText = doctest.getAttribute('data-title')
|
||||||
|
title.className = 'doctest-section-title'
|
||||||
|
titleParent.appendChild(title)
|
||||||
|
}
|
||||||
|
|
||||||
let pre = document.createElement('pre')
|
let pre = document.createElement('pre')
|
||||||
|
pre.className = 'hljs doctest'
|
||||||
// See http://stackoverflow.com/questions/1068280/javascript-regex-multiline-flag-doesnt-work
|
// See http://stackoverflow.com/questions/1068280/javascript-regex-multiline-flag-doesnt-work
|
||||||
// let re = /Doctest\.expect\(([\s\S]*)[\,\s\S]*([\s\S]*)\)/g
|
// let re = /Doctest\.expect\(([\s\S]*)[\,\s\S]*([\s\S]*)\)/g
|
||||||
let lines = text.value ? text.value.split('\n') : text.split('\n')
|
let lines = text.value ? text.value.split('\n') : text.split('\n')
|
||||||
@ -102,7 +200,9 @@ export default class Doctest {
|
|||||||
better.push(line)
|
better.push(line)
|
||||||
}
|
}
|
||||||
pre.innerHTML = better.join('\n') // text.value.replace(re, ">>> $1\n$2")
|
pre.innerHTML = better.join('\n') // text.value.replace(re, ">>> $1\n$2")
|
||||||
doctest.parentNode.replaceChild(pre, doctest)
|
container.appendChild(pre)
|
||||||
|
|
||||||
|
doctest.parentNode.replaceChild(container, doctest)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,12 +86,20 @@ import MapApp from './maps/mapapp.js'
|
|||||||
|
|
||||||
window.MapApp = MapApp
|
window.MapApp = MapApp
|
||||||
|
|
||||||
import { AdvancedScatterContainer, RigidContainer, CompactScatter, CoverScatter } from './maps/scatter.js'
|
import {
|
||||||
|
AdvancedScatterContainer,
|
||||||
|
RigidContainer,
|
||||||
|
CompactScatter,
|
||||||
|
CoverScatter,
|
||||||
|
MapObjectScatter
|
||||||
|
} from './maps/scatter.js'
|
||||||
|
|
||||||
window.AdvancedScatterContainer = AdvancedScatterContainer
|
window.AdvancedScatterContainer = AdvancedScatterContainer
|
||||||
window.RigidContainer = RigidContainer
|
window.RigidContainer = RigidContainer
|
||||||
window.CompactScatter = CompactScatter
|
window.CompactScatter = CompactScatter
|
||||||
window.CoverScatter = CoverScatter
|
window.CoverScatter = CoverScatter
|
||||||
|
window.MapObjectScatter = MapObjectScatter
|
||||||
|
|
||||||
|
|
||||||
import { GeoLayer, MapLayer } from './maps/geolayer.js'
|
import { GeoLayer, MapLayer } from './maps/geolayer.js'
|
||||||
window.GeoLayer = GeoLayer
|
window.GeoLayer = GeoLayer
|
||||||
@ -110,4 +118,5 @@ import Overlay from './maps/overlay.js'
|
|||||||
window.Overlay = Overlay
|
window.Overlay = Overlay
|
||||||
|
|
||||||
import { MapList } from './maps/maplist.js'
|
import { MapList } from './maps/maplist.js'
|
||||||
window.MapList = MapList
|
window.MapList = MapList
|
||||||
|
|
||||||
|
@ -26,7 +26,6 @@ export class GeoGraphics {
|
|||||||
this.drawEndHandler = new EventHandler('onDrawEnd', { listeners: onDrawEnd })
|
this.drawEndHandler = new EventHandler('onDrawEnd', { listeners: onDrawEnd })
|
||||||
this._points = null
|
this._points = null
|
||||||
this._position = null
|
this._position = null
|
||||||
this.map = null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
clone() {
|
clone() {
|
||||||
@ -92,7 +91,6 @@ export class GeoGraphics {
|
|||||||
* Called by the containing geo layer, when the map changes.
|
* Called by the containing geo layer, when the map changes.
|
||||||
*/
|
*/
|
||||||
adaptTo(map) {
|
adaptTo(map) {
|
||||||
this.map = map
|
|
||||||
this._points = this._adaptCoordinates(map)
|
this._points = this._adaptCoordinates(map)
|
||||||
this._updatePosition()
|
this._updatePosition()
|
||||||
this.draw()
|
this.draw()
|
||||||
@ -135,23 +133,21 @@ export class GeoGraphics {
|
|||||||
this._layer = layer
|
this._layer = layer
|
||||||
}
|
}
|
||||||
|
|
||||||
// get map() {
|
get map() {
|
||||||
// if (
|
let map = null
|
||||||
// this.graphics.layer &&
|
if (this.mapLayer) {
|
||||||
// (this.graphics.layer instanceof GeoLayer || this.graphics.layer instanceof MapLayer)
|
map = this.mapLayer.map
|
||||||
// ) {
|
}
|
||||||
// return this.graphics.layer.map
|
return map
|
||||||
// } else return null
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
// get mapLayer() {
|
get mapLayer() {
|
||||||
// if (
|
let mapLayer = null
|
||||||
// this.graphics.layer &&
|
if (this.layer) {
|
||||||
// (this.graphics.layer instanceof GeoLayer || this.graphics.layer instanceof MapLayer)
|
mapLayer = this.layer.mapLayer
|
||||||
// ) {
|
}
|
||||||
// return this.graphics.layer.mapLayer
|
return mapLayer
|
||||||
// } else return null
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare draw is a private function, that prepares the graphics
|
* Prepare draw is a private function, that prepares the graphics
|
||||||
|
@ -145,6 +145,19 @@ export class GeoLayer {
|
|||||||
} else console.warn('Tried to remove layer that was not set.', this, layer)
|
} else console.warn('Tried to remove layer that was not set.', this, layer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
remove(graphics) {
|
||||||
|
if (graphics instanceof GeoGraphics) {
|
||||||
|
let index = this.geographics.indexOf(geographics)
|
||||||
|
if (index != -1) {
|
||||||
|
this.displayObject.removeChild(geographics)
|
||||||
|
} else {
|
||||||
|
console.error('Could not remove geographics from geolayer.', this, geographics)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.displayObject.removeChild(graphics)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
set parent(parent) {
|
set parent(parent) {
|
||||||
this._parent = parent
|
this._parent = parent
|
||||||
}
|
}
|
||||||
@ -208,9 +221,10 @@ export class GeoLayer {
|
|||||||
|
|
||||||
export class MapLayer extends GeoLayer {
|
export class MapLayer extends GeoLayer {
|
||||||
constructor(
|
constructor(
|
||||||
|
mapList,
|
||||||
scatterContainer,
|
scatterContainer,
|
||||||
displayObject,
|
displayObject,
|
||||||
{ onTransform = null, onChange = null, focus = null, zoom = null, viewport = null, mapList = null } = {}
|
{ onTransform = null, onChange = null, focus = null, zoom = null, viewport = null } = {}
|
||||||
) {
|
) {
|
||||||
super(displayObject)
|
super(displayObject)
|
||||||
|
|
||||||
@ -231,12 +245,16 @@ export class MapLayer extends GeoLayer {
|
|||||||
})
|
})
|
||||||
|
|
||||||
this.mapList = mapList
|
this.mapList = mapList
|
||||||
this._map = null
|
|
||||||
|
|
||||||
// //TODO Implement error handling here.
|
// //TODO Implement error handling here.
|
||||||
// this.maps = maps
|
// this.maps = maps
|
||||||
// if (opts.map) this.placeMap(opts.map)
|
// if (opts.map) this.placeMap(opts.map)
|
||||||
this.dynamicElements = new Map()
|
this.dynamicElements = new Map()
|
||||||
|
|
||||||
|
// Binds the transformed callback beforehand.
|
||||||
|
this.transformed = this.transformed.bind(this)
|
||||||
|
|
||||||
|
this.changeMap(mapList.active)
|
||||||
}
|
}
|
||||||
|
|
||||||
adapt() {
|
adapt() {
|
||||||
@ -258,21 +276,18 @@ export class MapLayer extends GeoLayer {
|
|||||||
this.transformHandler.call(this)
|
this.transformHandler.call(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
clone(container = null) {
|
clone(scatterContainer, container = null) {
|
||||||
let clone = {}
|
let mapList = this.mapList.clone()
|
||||||
for (let name of Object.keys(this.maps)) {
|
container = container == null ? new PIXI.Container() : container
|
||||||
//console.info(this.maps[name])
|
|
||||||
clone[name] = this.maps[name].clone(container)
|
|
||||||
}
|
|
||||||
|
|
||||||
//console.info(this.active)
|
let mapLayerClone = new MapLayer(mapList, scatterContainer, container, {
|
||||||
let mapLayerClone = new MapLayer(this.active, clone, container, {
|
|
||||||
name: MapLayer.idx++,
|
name: MapLayer.idx++,
|
||||||
viewport: this.mapview.viewport,
|
viewport: this.mapview.viewport,
|
||||||
focus: this.mapview.focus,
|
focus: this.mapview.focus,
|
||||||
zoom: this.mapview.zoom
|
zoom: this.mapview.zoom,
|
||||||
|
mapList
|
||||||
})
|
})
|
||||||
//mapLayerClone._map = clone['luftbild']
|
|
||||||
mapLayerClone.childrenVisibility = this.childrenVisibility
|
mapLayerClone.childrenVisibility = this.childrenVisibility
|
||||||
return mapLayerClone
|
return mapLayerClone
|
||||||
}
|
}
|
||||||
@ -285,20 +300,29 @@ export class MapLayer extends GeoLayer {
|
|||||||
* @memberof MapLayer
|
* @memberof MapLayer
|
||||||
*/
|
*/
|
||||||
changeMap(
|
changeMap(
|
||||||
map /*,
|
name
|
||||||
|
/* map ,
|
||||||
useScatterAsContainer = true // If set to false, the normal container is used. This is necessary when using submaps and the container need to be a RigidContainer.*/
|
useScatterAsContainer = true // If set to false, the normal container is used. This is necessary when using submaps and the container need to be a RigidContainer.*/
|
||||||
) {
|
) {
|
||||||
if (map instanceof GeoMap) {
|
console.log('Change map to: ', name)
|
||||||
console.log('Change map to: ', map)
|
let oldMap = this.map
|
||||||
let oldMap = this.map
|
|
||||||
if (oldMap) oldMap.unload()
|
|
||||||
|
|
||||||
this._map = map
|
this.mapList.select(name)
|
||||||
|
|
||||||
this.map.load()
|
if (oldMap) {
|
||||||
this.scatterContainer.addChild(this.map.image)
|
oldMap.unload()
|
||||||
|
oldMap.onTransform.remove(this.transformed)
|
||||||
|
}
|
||||||
|
|
||||||
this.mapview.apply(this.map)
|
let map = this.map
|
||||||
|
if (map) {
|
||||||
|
console.log('Load Map')
|
||||||
|
map.load()
|
||||||
|
|
||||||
|
console.log(this, this.scatterContainer)
|
||||||
|
this.scatterContainer.addChild(map.image)
|
||||||
|
|
||||||
|
this.mapview.apply(map)
|
||||||
map.image.addChild(this.displayObject)
|
map.image.addChild(this.displayObject)
|
||||||
|
|
||||||
// A geolayer's displayObject is on the parent layer.
|
// A geolayer's displayObject is on the parent layer.
|
||||||
@ -309,9 +333,9 @@ export class MapLayer extends GeoLayer {
|
|||||||
|
|
||||||
//Call transform one time manually.
|
//Call transform one time manually.
|
||||||
this.transformed()
|
this.transformed()
|
||||||
this.map.onTransform.add(this.transformed.bind(this))
|
map.onTransform.add(this.transformed)
|
||||||
} else {
|
} else {
|
||||||
console.error("Could not set map, it's not of type GeoMap.", map)
|
console.error(`Could not change map to ${name}.`)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Logging.log(`Map change: ${key}`)
|
/*Logging.log(`Map change: ${key}`)
|
||||||
@ -368,7 +392,7 @@ export class MapLayer extends GeoLayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get map() {
|
get map() {
|
||||||
return this._map
|
return this.mapList.map
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -291,6 +291,10 @@ export class GeoMap {
|
|||||||
console.error('Overload get distance in subclass.')
|
console.error('Overload get distance in subclass.')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set alpha(value) {
|
||||||
|
console.error('Overload get alpha in subclass.')
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a screen point for a coordinate.
|
* Returns a screen point for a coordinate.
|
||||||
*/
|
*/
|
||||||
@ -374,11 +378,13 @@ export class GeoMap {
|
|||||||
* @returns {object} - Returns an object with the names as keys and the GeoMaps as value.
|
* @returns {object} - Returns an object with the names as keys and the GeoMaps as value.
|
||||||
* @memberof GeoMap
|
* @memberof GeoMap
|
||||||
*/
|
*/
|
||||||
static allFromJson(json) {
|
static allFromJson(json, root = './') {
|
||||||
let error = { message: '' }
|
let error = { message: '' }
|
||||||
let maps = {}
|
let maps = {}
|
||||||
if (GeoMap._validateJson(json, error)) {
|
if (GeoMap._validateJson(json, error)) {
|
||||||
for (let [mapname, data] of Object.entries(json)) {
|
for (let [mapname, data] of Object.entries(json)) {
|
||||||
|
console.log(data.tiles, data.tiles.path, root + data.tiles.path)
|
||||||
|
data.tiles.path = root + data.tiles.path
|
||||||
maps[mapname] = GeoMap._createMap(data)
|
maps[mapname] = GeoMap._createMap(data)
|
||||||
maps[mapname].name = mapname
|
maps[mapname].name = mapname
|
||||||
}
|
}
|
||||||
@ -563,6 +569,7 @@ export class DeepZoomMap extends GeoMap {
|
|||||||
|
|
||||||
super.load(image, container, scatter)
|
super.load(image, container, scatter)
|
||||||
|
|
||||||
|
console.log('LOADED: ', this.image)
|
||||||
if (this.debug) console.log('Loaded image: ', image, 'With options: ', this.info)
|
if (this.debug) console.log('Loaded image: ', image, 'With options: ', this.info)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -622,7 +629,7 @@ export class DeepZoomMap extends GeoMap {
|
|||||||
|
|
||||||
let containerCenter
|
let containerCenter
|
||||||
if (this.frame) {
|
if (this.frame) {
|
||||||
containerCenter = this.getFrame().center
|
containerCenter = this.getFrame().localCenter
|
||||||
} else {
|
} else {
|
||||||
containerCenter = {
|
containerCenter = {
|
||||||
x: this.image.parent.width / 2,
|
x: this.image.parent.width / 2,
|
||||||
@ -691,10 +698,21 @@ export class DeepZoomMap extends GeoMap {
|
|||||||
|
|
||||||
tint() {
|
tint() {
|
||||||
let color = DeepZoomMap.tintcolors[DeepZoomMap.tintcolor++ % DeepZoomMap.tintcolors.length]
|
let color = DeepZoomMap.tintcolors[DeepZoomMap.tintcolor++ % DeepZoomMap.tintcolors.length]
|
||||||
|
|
||||||
|
this._forEachTile(tile => {
|
||||||
|
tile.tint = color
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
_forEachTile(callback) {
|
||||||
this.image.children[0].children.forEach(tiles => {
|
this.image.children[0].children.forEach(tiles => {
|
||||||
tiles.children.forEach(tile => {
|
tiles.children.forEach(callback)
|
||||||
tile.tint = color
|
})
|
||||||
})
|
}
|
||||||
|
|
||||||
|
setAlpha(alpha) {
|
||||||
|
this._forEachTile(tile => {
|
||||||
|
tile.alpha = alpha
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -769,7 +787,6 @@ export class ImageMap extends GeoMap {
|
|||||||
* @memberof ImageMap
|
* @memberof ImageMap
|
||||||
*/
|
*/
|
||||||
moveTo(coordinates, zoom = null, { animate = 0 } = {}) {
|
moveTo(coordinates, zoom = null, { animate = 0 } = {}) {
|
||||||
|
|
||||||
if (this.image.scatter == null) {
|
if (this.image.scatter == null) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -178,6 +178,7 @@ export default class MapApp extends PIXIApp {
|
|||||||
|
|
||||||
selectMap(key) {
|
selectMap(key) {
|
||||||
let result = this.mapList.select(key)
|
let result = this.mapList.select(key)
|
||||||
|
|
||||||
console.log('Select map', key, result)
|
console.log('Select map', key, result)
|
||||||
if (result && this.mapLayer) {
|
if (result && this.mapLayer) {
|
||||||
this.mapLayer.changeMap(this.mapList.map)
|
this.mapLayer.changeMap(this.mapList.map)
|
||||||
@ -287,7 +288,6 @@ export default class MapApp extends PIXIApp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get map() {
|
get map() {
|
||||||
console.log(this.mapList)
|
|
||||||
return this.mapList.map
|
return this.mapList.map
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
export class MapList {
|
export class MapList {
|
||||||
constructor(active, maps) {
|
constructor(active = null, maps = {}) {
|
||||||
this.maps = maps
|
this.maps = maps
|
||||||
this.active = active
|
this.active = active
|
||||||
|
|
||||||
@ -40,6 +40,16 @@ export class MapList {
|
|||||||
return map
|
return map
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clone() {
|
||||||
|
let maps = {}
|
||||||
|
|
||||||
|
for (let name of Object.keys(this.maps)) {
|
||||||
|
maps[name] = this.maps[name].clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
return new MapList(this.active, maps)
|
||||||
|
}
|
||||||
|
|
||||||
add(key, map) {
|
add(key, map) {
|
||||||
if (this.maps[key] != null) consol.warn('Key already in mapList. The existing key was overwritten.')
|
if (this.maps[key] != null) consol.warn('Key already in mapList. The existing key was overwritten.')
|
||||||
map.name = key
|
map.name = key
|
||||||
@ -47,15 +57,14 @@ export class MapList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get map() {
|
get map() {
|
||||||
console.log(this.maps, this.active)
|
return this.maps && this.maps[this.active] ? this.maps[this.active] : null
|
||||||
return this.maps[this.active]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
next() {
|
next() {
|
||||||
let keys = Object.keys(this.maps)
|
let keys = Object.keys(this.maps)
|
||||||
let idx = keys.indexOf(this.active)
|
let idx = keys.indexOf(this.active)
|
||||||
|
|
||||||
let next = idx + 1 < key.length ? keys[idx + 1] : keys[0]
|
let next = idx + 1 < keys.length ? keys[idx + 1] : keys[0]
|
||||||
console.log(keys, idx, next)
|
console.log(keys, idx, next)
|
||||||
return next
|
return next
|
||||||
}
|
}
|
||||||
|
@ -89,15 +89,15 @@ export class AdvancedScatterContainer extends ScatterContainer {
|
|||||||
let interactionManager = this.renderer.plugins.interaction
|
let interactionManager = this.renderer.plugins.interaction
|
||||||
|
|
||||||
let displayObject = interactionManager.hitTest(local, this)
|
let displayObject = interactionManager.hitTest(local, this)
|
||||||
|
if (displayObject != null) {
|
||||||
if (displayObject.dontBlockScatter && displayObject.parent != null) {
|
if (displayObject.dontBlockScatter && displayObject.parent != null) {
|
||||||
displayObject = interactionManager.hitTest(local, displayObject.parent)
|
displayObject = interactionManager.hitTest(local, displayObject.parent)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (displayObject.scatter != null) this.hitScatter = displayObject.scatter
|
||||||
|
if (this.claimEvents) event.claimedByScatter = this.hitScatter
|
||||||
}
|
}
|
||||||
|
|
||||||
if (displayObject != null && displayObject.scatter != null) this.hitScatter = displayObject.scatter
|
|
||||||
if (this.claimEvents) event.claimedByScatter = this.hitScatter
|
|
||||||
|
|
||||||
|
|
||||||
return this.hitScatter
|
return this.hitScatter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -255,6 +255,23 @@ class AdvancedScatter extends DisplayObjectScatter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class SubmapScatter extends DisplayObjectScatter {
|
export class SubmapScatter extends DisplayObjectScatter {
|
||||||
|
constructor(displayObject, renderer, opts = {}) {
|
||||||
|
/*
|
||||||
|
Currently the submaps are only working on one scale to
|
||||||
|
avoid recalculations of the shown map.
|
||||||
|
|
||||||
|
Therfore we force the scatter to not be scaleable.
|
||||||
|
*/
|
||||||
|
Object.assign(opts, {
|
||||||
|
minScale: 1,
|
||||||
|
maxScale: 1,
|
||||||
|
startScale: 1,
|
||||||
|
scalable: false
|
||||||
|
})
|
||||||
|
|
||||||
|
super(displayObject, renderer, opts)
|
||||||
|
}
|
||||||
|
|
||||||
get width() {
|
get width() {
|
||||||
return this.displayObject.width * this.displayObject.scale.x
|
return this.displayObject.width * this.displayObject.scale.x
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user