Das Frontend teilt sich Folgendermaße auf:
Datei | Funktion |
index.html | Wird ausgespielt beim aufruf von http://localhost:8080/ In dieser Datei sind alle HTML Elemente mit Id hinterlegt die dann über JavaScript mit den Daten gefüllt werden. |
index.js | In dieser Java-Script Datei wird die Websocket Verbindung hergestellt. Alle ankommenden Websocket-Nachrichten werden hier empfangen und einem HTML Element zugeordnet. Alle Nachrichten (Tastendrücke) werden hier auch an die Java-Anwendung zurückgespielt. |
inout.js | Diese Datei ist registriert Tastendrücke. |
one-page-wonder.css | Hier sind eigene CSS Eigenschaften hinterlegt, um das Design der Website zu definieren. |
Ordner img | In diesem Ornder sind schlicht einige Bilder für das Frontend hinterlegt. |
Die index.html Datei:
<!DOCTYPE html>
<html lang="de" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="" />
<meta name="author" content="" />
<title>DIY - Robot Interface</title>
<!-- Bootstrap Core CSS -->
<link
href="http://cdn.jsdelivr.net/webjars/bootstrap/3.3.7-1/css/bootstrap.min.css"
th:href="@{/webjars/bootstrap/3.3.7-1/css/bootstrap.min.css}"
rel="stylesheet" media="screen" />
<!-- Custom CSS -->
<link href="/../static/css/one-page-wonder.css"
th:href="@{/css/one-page-wonder.css}" rel="stylesheet" />
</head>
<body>
<noscript>
<h2 style="color: #ff0000">Seems your browser doesn't support
Javascript! Websocket relies on Javascript being enabled. Please
enable Javascript and reload this page!</h2>
</noscript>
<!-- Headline -->
<div class="container">
<div class="row">
<div class="jumbotron">
<h2>DIY - Over9000 KillingRobot</h2>
<p>Do it yourself Robot - Alpha Version - Controll Site</p>
<p>
Please open console for more details:
<kbd>ctrl+shift+c</kbd>
</p>
</div>
</div>
</div>
<!-- Page Content -->
<div class="container">
<div class="row">
<div class="col-xs-4">
<!-- Content aside the webcam Image -->
<div class="col-xs-12">
<br></br>
<p>Websocket</p>
<form class="form-inline">
<div class="form-group">
<button id="connect" class="btn btn-default" type="submit">Connect</button>
<button id="disconnect" class="btn btn-default" type="submit"
disabled="disabled">Disconnect</button>
<div id="connected" class="alert alert-danger">Disconnected</div>
</div>
</form>
<div class="form-inline">
<p>Sensor Values:</p>
<div class="normal-text">
Front: Abstand in [cm]
<kbd id="ultrasonicFront">No data available</kbd>
</div>
<div class="normal-text">
Back: Abstand in [cm]
<kbd id="ultrasonicBack">No data available</kbd>
</div>
<div class="normal-text">
Lichtsensor
<kbd id="lightSensor">No data available</kbd>
</div>
<div class="normal-text">
RFID Sensor
<kbd id="rfidSensor">No data available</kbd>
</div>
<div class="normal-text">
Richtung:
<kbd id="direction">Direction</kbd>
</div>
</div>
</div>
</div>
<div class="col-xs-8">
<img id="webcam" class="img-responsive" width="640" height="480"
align="right" vspace="50" src="/../static/img/dummy.png"
th:src="@{/img/dummy.png}" />
</div>
</div>
<div class="row">
<div class="col-xs-12">
<p>Fahren: W,A,S,D, od. in kombination W+D für Kurven</p>
<p>Roboter Arm: Zahlen 1-6 und + od. - für die Drehrichtung</p>
<p>Laser: E</p>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="col-xs-12">
<p>GPIO-Settings RaspberryPi:</p>
<img id="GPIO-Setting" class="img-responsive" align="right"
vspace="5" src="/../static/img/Raspi-Background.png"
th:src="@{/img/Raspi-Background.png}" style="opacity: 1.0;" />
</div>
</div>
</div>
<!-- Footer -->
<div class="container">
<div class="form-inline">
<footer>
<div class="row">
<div class="col-lg-12">
<p>
All references by: <br></br> DIY Project | Nils Bott, Jan-Niklas
Sturm, Jens Freiburger
</p>
</div>
</div>
</footer>
</div>
</div>
</div>
<!-- jQuery -->
<script
src="http://cdn.jsdelivr.net/webjars/jquery/3.1.1/jquery.min.js"
th:src="@{/webjars/jquery/jquery.min.js}"></script>
<!-- Bootstrap Core JavaScript -->
<script
src="http://cdn.jsdelivr.net/webjars/bootstrap/3.3.7-1/bootstrap.min.js"
th:src="@{/webjars/bootstrap/js/bootstrap.min.js}"></script>
<!-- Key Event JavaScript -->
<script src="/../static/js/inout.js" th:src="@{/js/inout.js}"></script>
<!-- Websocket JavaScript -->
<script src="/../static/js/index.js" th:src="@{/js/index.js}"></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/sockjs-client/1.1.4/sockjs.min.js"
th:src="@{/webjars/sockjs-client/sockjs.min.js}"></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/stomp.js/2.3.3/stomp.min.js"
th:src="@{/webjars/stomp-websocket/stomp.min.js}"></script>
</body>
</html>
Die index.js Datei:
var stompClient = null;
var imageCounter = 0;
var images = [
"../img/8IZCR0wzEIQms.gif",
"../img/pinguenfight.gif",
"../img/boingbamm.gif",
"../img/Now-this-is-a-game-I-could-get-into.gif",
"../img/fightclub.gif",
"../img/gihdhphy.gif",
"../img/giphy.gif",
"../img/giruffyphy.gif",
"../img/gisfsfdsfdphy.gif",
"../img/gisfsfsfphy.gif"
]
var i = 0;
function slideshowPicture(){
$("#webcam").attr(
"src",
images[i%images.length]);
i++;
}
function checkImageExists(imageUrl, callBack) {
var imageData = new Image();
imageData.onload = function() {
callBack(true);
};
imageData.onerror = function() {
callBack(false);
};
imageData.src = imageUrl;
}
function connect() {
try {
var socket = new SockJS(window.location.protocol + "//"
+ window.location.hostname + ":" + window.location.port
+ "/diy-robotws");
stompClient = Stomp.over(socket);
stompClient.connect({}, connect_callback, error_callback);
} catch (err) {
console.log(err);
}
}
function disconnect() {
if (stompClient != null) {
stompClient.disconnect();
}
setConnected(false);
}
function sendDirection() {
stompClient.send("/app/stompMessage", {}, JSON.stringify({
'content': arguments[0]
}));
}
function setConnected(connected) {
$("#connect").prop("disabled", connected);
$("#disconnect").prop("disabled", !connected);
if (connected) {
$("#connected").attr("class", "alert alert-success");
$("#connected").text("Connected");
} else {
$("#connected").attr("class", "alert alert-danger");
$("#connected").text("Disconnected");
}
}
var connect_callback = function () {
stompClient.subscribe('/topic/stompMessage', function (message) {
msg = JSON.parse(message.body).content;
var res = msg.split(":");
if (res[0] == "ultrasonicFront") {
$("#ultrasonicFront").text(res[1]);
}
if (res[0] == "ultrasonicBack") {
$("#ultrasonicBack").text(res[1]);
}
if (res[0] == "lightSensor") {
$("#lightSensor").text(res[1]);
}
if (res[0] == "direction") {
$("#direction").text(res[1]);
}
if(res[0] == "rfidSensor") {
$("#rfidSensor").text(res[1]);
}
console.log(msg)
});
setConnected(true);
};
var error_callback = function (error) {
console.log(error);
setTimeout(connect, 10000);
setConnected(false);
}
$(function () {
// connect to websocket
connect();
// set webcam image
imageFile = window.location.protocol + "//" + window.location.hostname + ":8080/?action=stream"
checkImageExists(imageFile, function(existsImage) {
if(existsImage == true) {
$("#webcam").attr(
"src",
window.location.protocol + "//" + window.location.hostname
+ ":8080/?action=stream");
$("#webcam").attr(
"style",
"opacity: 1.0;");
}
else {
setInterval(slideshowPicture, 5000);
}
});
// key events
$('body').on(
'keypress',
function (e) {
var x = e.which;
var key = String.fromCharCode(x).toUpperCase();
console.log("Keypress Type: " + e.type + "\n" +
"Keypress Char: "+ e.which + " which is Coded: " + key);
if (stompClient != null) {
sendDirection(key + ":pressed");
}
});
$('body').on(
'keyup',
function (e) {
var x = e.which;
console.log ("X is set toooo:" + x)
var key = String.fromCharCode(x);
if (x == 173) {
key = "-"
}
if (x == 171) {
key = "+"
}
console.log("Keypress Type: " + e.type);
if (stompClient != null) {
sendDirection(key + ":released");
}
});
});
OnePageWonder CSS Datei:
/*
* Start Bootstrap - One Page Wonder (http://startbootstrap.com/)
* Copyright 2013-2016 Start Bootstrap
* Licensed under MIT (https://github.com/BlackrockDigital/startbootstrap/blob/gh-pages/LICENSE)
*/
body {
margin-top: 50px; /* Required padding for .navbar-fixed-top. Remove if using .navbar-static-top. Change if height of navigation changes. */
/*background-image: url(../img/bg-kill-robot.jpg);*/
background-image: url(../img/roboFace.gif);
background-repeat: no-repeat;
background-attachment: fixed;
background-size: 100% 100%;
/* background-size: cover; */
}
.jumbotron {
background-color: black;
color: greenyellow;
font-family: Menlo,Monaco,Consolas,"Courier New",monospace;
opacity: 0.8;
}
img {
opacity: 0.8;
background-color: black;
}
kbd {
color: greenyellow;
font-family: Menlo,Monaco,Consolas,"Courier New",monospace;
background-color: black;
opacity: 1.0;
}
p {
background-color: black;
color: white;
text-transform: capitalize;
font-family: Menlo,Monaco,Consolas,"Courier New",monospace;
font-size: 115%;
border: 2px solid #222222;
border-color: greenyellow;
border-radius: 5px;
padding-left: 10px;
padding-right: 10px;
padding-top: 10px;
padding-bottom: 10px;
display: inline-block;
}
.btn {
opacity: 0.6;
background-color: #222222;
border: 2px solid #222222;
color: white;
font-family: Menlo,Monaco,Consolas,"Courier New",monospace;
}
.normal-text {
#opacity: 0.0;
background-color: #222222;
border: 2px solid #222222;
color: white;
font-family: Menlo,Monaco,Consolas,"Courier New",monospace;
font-size: 115%;
}
.header-image {
display: block;
width: 100%;
text-align: center;
}
.headline {
padding: 120px 0;
color: white;
}
.headline h1 {
font-size: 100px;
background: #fff;
background: rgba(255, 255, 255, 0.9);
}
.headline h2 {
font-size: 77px;
background: #fff;
background: rgba(255, 255, 255, 0.9);
}
h3 {
color: white;
}
.featurette-divider {
margin: 80px 0;
}
.featurette {
overflow: hidden;
}
.featurette-image.pull-left {
margin-right: 40px;
}
.featurette-image.pull-right {
margin-left: 40px;
}
.featurette-heading {
font-size: 50px;
}
footer {
margin: 50px 0;
}
@media (max-width: 1200px) {
.headline h1 {
font-size: 140px;
}
.headline h2 {
font-size: 63px;
}
.featurette-divider {
margin: 50px 0;
}
.featurette-image.pull-left {
margin-right: 20px;
}
.featurette-image.pull-right {
margin-left: 20px;
}
.featurette-heading {
font-size: 35px;
}
}
@media (max-width: 991px) {
.headline h1 {
font-size: 105px;
}
.headline h2 {
font-size: 50px;
}
.featurette-divider {
margin: 40px 0;
}
.featurette-image {
max-width: 50%;
}
.featurette-image.pull-left {
margin-right: 10px;
}
.featurette-image.pull-right {
margin-left: 10px;
}
.featurette-heading {
font-size: 30px;
}
}
@media (max-width: 768px) {
.container {
margin: 0 15px;
}
.featurette-divider {
margin: 40px 0;
}
.featurette-heading {
font-size: 25px;
}
}
@media (max-width: 668px) {
.headline h1 {
font-size: 70px;
}
.headline h2 {
font-size: 32px;
}
.featurette-divider {
margin: 30px 0;
}
}
@media (max-width: 640px) {
.headline {
padding: 75px 0 25px 0;
}
.headline h1 {
font-size: 60px;
}
.headline h2 {
font-size: 30px;
}
}
@media (max-width: 375px) {
.featurette-divider {
margin: 10px 0;
}
.featurette-image {
max-width: 100%;
}
.featurette-image.pull-left {
margin-right: 0;
margin-bottom: 10px;
}
.featurette-image.pull-right {
margin-bottom: 10px;
margin-left: 0;
}
}