Commit 66a150f6 authored by Michael Ochmann's avatar Michael Ochmann
Browse files

added new viewcontroller system

parent adbb0d82
This diff is collapsed.
......@@ -12,19 +12,6 @@
</head>
<body>
<header>
<a href=#>Zurück</a>
<h2 class=title>HeightTracker</h2>
<a href=# id=about>Info</a>
</header>
<main class=view>
<canvas id=heightmap style="width: 100%; height: 99%; box-sizing: border-box;">
</canvas>
</main>
<footer>
<b>Points:</b> <span id=points></span>
</footer>
</body>
</html>
\ No newline at end of file
import GeoPoint from "./GeoPoint.js";
import $ from "./smallQ.js";
import HeightMap from "./HeightMap.js";
import ViewController from "./controllers/ViewController.js";
import Std from "./Std.js";
class App {
constructor() {
App.RegisterWorker();
this.window = new ViewController();
//App.RegisterWorker();
if (!navigator.geolocation)
alert("Your browser does not support geo data!");
$("main").css("height", window.innerHeight - 93);
this.heightmap = new HeightMap();
this.capture();
setInterval(() => {
this.capture();
}, 1000);
$("#about").click(event => {
alert("HeighTracker\n\nTracking GEO height of courses\nin a simple webapp\n\n© 2018, Michael Ochmann");
});
}
capture() {
navigator.geolocation.getCurrentPosition(position => {
this.heightmap.addPoint(new GeoPoint(
position.coords.latitude,
position.coords.longitude,
position.coords.altitude
));
});
}
static RegisterWorker() {
if ("serviceWorker" in navigator) {
......
import $ from "./smallQ.js";
import Std from "./Std.js";
class HeightMap {
constructor() {
this.points = [];
this.min = 0;
this.max = 0;
this.canvas = $("#heightmap").get();
import UIViewController from "./UIViewController.js";
import $ from "../smallQ.js";
import Std from "../Std.js";
import GeoPoint from "../GeoPoint.js";
class HeightMapViewController extends UIViewController {
constructor(view, model) {
super(view, model);
this.canvas = null;
this.drag = false;
this.lastX = 0;
this.translated = 0;
this.canvas.width = this.canvas.parentNode.offsetWidth;
this.canvas.height = this.canvas.parentNode.offsetHeight;
}
addPoint(geoPoint) {
if (geoPoint.constructor.name !== "GeoPoint")
throw new TypeError("an object of type 'GeoPoint' must be p1assed.");
if (this.model.points.length > 0 && this.model.points[this.model.points.length - 1].distance(geoPoint) < 5)
return;
$("#points").html(this.model.points.length);
let ctx = this.canvas.getContext("2d");
let min = this.min;
let max = this.max;
this.min = geoPoint.altitude < this.min ? geoPoint.altitude : this.min;
this.max = geoPoint.altitude > this.max ? geoPoint.altitude : this.max;
this.model.add(geoPoint);
this.drawHeightMap();
}
capture() {
navigator.geolocation.getCurrentPosition(position => {
this.addPoint(new GeoPoint(
position.coords.latitude,
position.coords.longitude,
position.coords.altitude
));
});
}
viewDidLoad() {
this.canvas = $("#heightmap").get();
this.canvas.width = this.canvas.parentNode.offsetWidth - 16;
this.canvas.height = this.canvas.parentNode.offsetHeight - 16;
let ctx = this.canvas.getContext("2d");
this.canvas.addEventListener("touchstart", event => {
this.drag = true;
......@@ -30,40 +64,22 @@ class HeightMap {
this.translated += delta;
this.lastX = event.changedTouches[0].clientX;
ctx.translate(delta, 0);
this.render();
this.drawHeightMap();
});
this.canvas.addEventListener("touchend", event => {
this.translated = false;
this.render();
this.drawHeightMap();
});
this.drawHeightMap();
this.render();
}
this.capture();
addPoint(geoPoint) {
if (geoPoint.constructor.name !== "GeoPoint")
throw new TypeError("an object of type 'GeoPoint' must be p1assed.");
if (this.points.length > 0 && this.points[this.points.length - 1].distance(geoPoint) < 5)
return;
$("#points").html(this.points.length);
let min = this.min;
let max = this.max;
this.min = geoPoint.altitude < this.min ? geoPoint.altitude : this.min;
this.max = geoPoint.altitude > this.max ? geoPoint.altitude : this.max;
this.points.push(geoPoint);
this.render();
/* if (min !== this.min || max !== this.max)
this.render();
else
this.render();*/
setInterval(() => {
this.capture();
}, 1000);
}
render() {
drawHeightMap() {
let ctx = this.canvas.getContext("2d");
let height = this.canvas.height;
......@@ -72,7 +88,7 @@ class HeightMap {
ctx.beginPath();
ctx.moveTo(0, height);
let x = 0;
for (let point of this.points) {
for (let point of this.model.points) {
let ordinateVal = Std.Map(point.altitude, this.min, this.max, 0, height * 0.95);
ctx.lineTo(x, height - ordinateVal);
x+=20;
......@@ -85,37 +101,22 @@ class HeightMap {
ctx.fill();
}
/* renderSingle() {
if (this.points.length < 2) {
this.render();
return;
}
let ctx = this.canvas.getContext("2d");
let height = this.canvas.height;
let lastPoint = Std.Map(this.points[this.points.length - 2].altitude, this.min, this.max, 0, height * 0.95);
let currentPoint = Std.Map(this.points[this.points.length - 1].altitude, this.min, this.max, 0, height * 0.95);
ctx.beginPath();
ctx.moveTo((this.points.length - 2) * 20, height - lastPoint);
ctx.lineTo((this.points.length - 1) * 20, height - currentPoint);
ctx.lineTo((this.points.length - 1) * 20, 0);
ctx.lineTo(0, height);
ctx.closePath();
ctx.stroke();
ctx.fillStyle = "red";
}*/
clear() {
let ctx = this.canvas.getContext("2d");
let width = this.canvas.width;
let height = this.canvas.height;
ctx.fillStyle = HeightMap.BACKGROUND;
ctx.clearRect(-this.translated, 0, this.points.length * 20 + width, height);
ctx.fillRect(-this.translated, 0, this.points.length * 20 + width, height);
ctx.fillStyle = HeightMapViewController.BACKGROUND;
ctx.clearRect(-this.translated, 0, this.model.points.length * 20 + width, height);
ctx.fillRect(-this.translated, 0, this.model.points.length * 20 + width, height);
}
render() {
return `
<canvas id="heightmap"></canvas>
`;
}
}
HeightMap.BACKGROUND = "#ccc";
HeightMapViewController.BACKGROUND = "#ccc";
export default HeightMap;
\ No newline at end of file
export default HeightMapViewController;
\ No newline at end of file
import UIViewController from "./UIViewController.js";
class SettingsViewController extends UIViewController {
render() {
return `
<ul class="UITableView">
<li>
New datapoint every
<span>
<select>
<option>dwsad</option>
</select>
</span>
</li>
</ul>
`;
}
}
export default SettingsViewController;
\ No newline at end of file
import UIViewController from "./UIViewController.js";
import $ from "../smallQ.js";
class TracksListController extends UIViewController {
viewDidLoad() {
$(".track").click(element => {
let event = new CustomEvent("TrackListController:select", {
detail : element.attr("data-id")
});
document.dispatchEvent(event);
});
}
render() {
let tracks = this.model.tracks().map((track, index) => {
return `<li class="track" data-id="track_${index}">${track.name}</li>`;
}).join("");
return `
<ul class="UITableView">
${tracks}
</ul>
`;
}
}
export default TracksListController;
\ No newline at end of file
import $ from "../smallQ.js";
class UIViewController {
constructor(container, model = null) {
if (new.target === UIViewController)
throw new TypeError(`can not instantiate abstract class "${this.constructor.name}"`);
this.container = container;
this.model = model;
this.children = [];
}
render() {
return `
<section>
[Controller: ${this.constructor.name}]
</section>
`;
}
viewDidLoad() {}
addSubview(view) {
if (!(view instanceof UIViewController))
throw new TypeError(`only objects of type "UIViewController" can be added as subviews`);
this.children.push(view);
}
renderCall() {
$(this.container).html(this.render());
this.viewDidLoad();
for (const child of this.children)
child.renderCall();
}
}
export default UIViewController;
import UIViewController from "./UIViewController.js";
import HeightMapViewController from "./HeightMapViewController.js";
import SettingsViewController from "./SettingsViewController.js";
import TracksListController from "./TracksListController.js";
import HeightMap from "../models/HeightMap.js";
import Tracks from "../models/Tracks.js";
import $ from "../smallQ.js";
const States = {
TRACKLIST : 0,
HEIGHTMAP : 1,
SETTINGS : 2,
};
class ViewController extends UIViewController {
constructor() {
super("body");
this.state = States.TRACKLIST;
this.track = null;
this.renderCall();
}
viewDidLoad() {
$(document).on("TrackListController:select", (item, event) => {
console.log(event);
this.track = parseInt(event.detail.replace("track_", ""));
this.changeState(States.HEIGHTMAP);
});
$("main").css("height", window.innerHeight - 93);
$("#about").click(event => {
alert("HeighTracker\n\nTracking GEO height of courses\nin a simple webapp\n\n© 2018, Michael Ochmann");
});
$("#settings").click(event => {
this.changeState(States.SETTINGS);
});
$("#list").click(event => {
this.changeState(States.TRACKLIST);
});
}
changeState(newState) {
this.state = newState;
this.renderCall();
}
render() {
this.children = [];
switch(this.state) {
case States.SETTINGS:
this.addSubview(new SettingsViewController("main"));
break;
case States.TRACKLIST:
this.addSubview(new TracksListController("main", new Tracks()));
break;
case States.HEIGHTMAP:
this.addSubview(new HeightMapViewController("main", new HeightMap(this.track)));
break;
}
return `
<header>
<a href=#>Zurück</a>
<h2 class=title>HeightTracker</h2>
<a href=# id=about>Info</a>
</header>
<main class=view>
</main>
<footer>
<button id=list>List</button>
<span>
<b>Points:</b> <span id=points></span>
</span>
<button id=settings>Settings</button>
</footer>
`;
}
}
export default ViewController;
\ No newline at end of file
import $ from "../smallQ.js";
import Std from "../Std.js";
import GeoPoint from "../GeoPoint.js";
class HeightMap {
constructor(trackID) {
this.trackID = trackID;
this.points = [];
this.min = 0;
this.max = 0;
console.log(trackID);
}
add(geoPoint) {
if (geoPoint.constructor.name !== "GeoPoint")
throw new TypeError("an object of type 'GeoPoint' must be p1assed.");
this.points.push(geoPoint);
}
}
export default HeightMap;
class Tracks {
constructor() {
this._tracks = [
{
name : "Testrack",
points : []
}
];
for (let i = 0; i < 100; i++)
this._tracks.push({
name : "Track" + i,
points : []
});
}
tracks() {
return this._tracks;
}
}
export default Tracks;
\ No newline at end of file
......@@ -31,7 +31,18 @@ class smallQ {
on(event, callback) {
for (let element of this.elements)
element.addEventListener(event, callback);
element.addEventListener(event, event => {
callback(new smallQ(element), event);
});
return this;
}
attr(key, value) {
if (!value)
return this.elements[0].getAttribute(key);
for (let element of this.elements)
element.setAttribute(key, value);
return this;
}
......@@ -61,6 +72,10 @@ class smallQ {
static $(selector) {
return new smallQ(selector);
}
static ajax() {
console.log("AJAX");
}
}
export default smallQ.$;
\ No newline at end of file
......@@ -6,5 +6,9 @@
li {
padding: 15px 12px;
border-bottom: solid 1px #eee;
span {
float: right;
}
}
}
\ No newline at end of file
$header-background: #8AFF19;
$header-color : #333;
$header-background: #029BE8;
$header-color : #eee;
$header-border : #b2b2b2;
\ No newline at end of file
footer {
display: grid;
grid-template-columns: repeat(3, 1fr);
align-items: center;
text-align: center;
background: $header-background;
color: $header-color;
border-top: solid 1px $header-border;
box-shadow: 0 -1px 15px rgba(0,0,0,0.2);
button {
display: block;
outline: 0;
background: transparent;
border: none;
}
}
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment