2019-02-27 20:22:38 +00:00
<!DOCTYPE html>
< html lang = "en" >
< head >
< meta charset = "UTF-8" >
2019-03-04 09:29:32 +00:00
< title > FSM Designer< / title >
2019-03-04 18:17:00 +00:00
< link href = "https://fonts.googleapis.com/css?family=Roboto:300,400,700" rel = "stylesheet" >
< link rel = "stylesheet" href = "https://use.fontawesome.com/releases/v5.7.2/css/all.css"
integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
< link href = "lib/tingle/tingle.min.css" rel = "stylesheet" >
< style >
/**
* General
*/
html, body {
font-family: Roboto, Arial, sans-serif;
font-size: 16px;
}
body {
margin: 0;
background: #eee;
}
.container {
max-width: 800px;
margin: 20px auto;
padding: 0 40px;
}
2019-04-03 14:15:15 +00:00
input:not([type=checkbox]) {
2019-03-04 18:17:00 +00:00
width: 100%;
font-size: 16px;
padding: 8px 16px;
border-radius: 10px;
border: none;
color: #333;
background-color: rgba(0, 0, 0, .1);
}
input:focus {
background-color: rgba(0, 0, 0, .2);
}
2019-04-03 14:15:15 +00:00
label {
display: block;
margin-bottom: 8px;
}
2019-03-04 18:17:00 +00:00
/**
* Buttons
*/
.btn {
padding: 8px 16px;
border-radius: 10px;
border: 1px solid transparent;
background: none;
font-weight: bold;
font-family: Roboto, Arial, sans-serif;
}
.btn:hover {
border: 1px solid rgba(0, 0, 0, .33);
background: rgba(0, 0, 0, .15);
}
.btn:active {
box-shadow: 0 0 5px rgba(0, 0, 0, .25);
}
.btn-close {
padding: 4px 6px;
}
/**
* FSMDocument tabs
*/
2019-03-07 15:13:08 +00:00
.document-tabs-container {
overflow-x: auto;
}
2019-03-04 18:17:00 +00:00
#document-tabs {
list-style: none;
padding: 0;
margin: 0;
height: 44px;
2019-03-07 15:13:08 +00:00
white-space: nowrap;
2019-03-04 18:17:00 +00:00
}
#document-tabs .document-tab {
display: inline-block;
border: 1px solid rgba(0, 0, 0, .33);
margin: 0;
padding: 8px 16px;
2019-03-07 15:13:08 +00:00
cursor: pointer;
2019-03-04 18:17:00 +00:00
}
#document-tabs .document-tab:first-child {
border-top-left-radius: 10px;
border-bottom-left-radius: 10px;
}
#document-tabs .document-tab:last-child {
border-top-right-radius: 10px;
border-bottom-right-radius: 10px;
}
#document-tabs .document-tab .document-name {
font-weight: normal;
margin-right: 4px;
}
#document-tabs .document-tab.active {
background: #fff;
}
#document-tabs .document-tab.active .document-name {
font-weight: bold;
}
/**
* Action Buttons
*/
.action-buttons {
margin: 20px 0;
}
.action-button {
background: #fff;
2019-04-03 14:15:15 +00:00
margin: 4px 8px;
2019-03-04 18:17:00 +00:00
}
.action-button .fa {
margin: 4px;
}
/**
* List in Open Modal
*/
.file-list {
list-style-type: none;
width: 100%;
padding: 0;
}
.file-list .file-list-item {
padding: 16px 32px;
border-bottom: 1px solid rgba(0, 0, 0, .33);
width: 100%;
}
.file-list .file-list-item:first-child {
border-top-left-radius: 10px;
border-top-right-radius: 10px;
}
.file-list .file-list-item:last-child {
border: none;
border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px;
}
.file-list .file-list-item:hover {
background: rgba(0, 0, 0, .1);
}
.file-list .file-list-item:active {
background: rgba(0, 0, 0, .2);
}
2019-03-05 18:18:21 +00:00
/**
* Import Modal with Upload Button
*/
.upload-btn {
border: 1px solid rgba(0, 0, 0, .33);
background: #fff;
}
.upload-btn:hover {
background: rgba(0, 0, 0, .1);
}
.upload-btn:active {
background: rgba(0, 0, 0, .2);
}
.upload-btn .upload-input {
display: none;
}
2019-04-03 14:15:15 +00:00
2019-03-04 18:17:00 +00:00
/**
* Canvas
*/
#canvas {
display: block;
margin: 0 auto;
background: #fff;
border-radius: 10px;
2019-04-03 14:15:15 +00:00
width: calc(100% - 20px);
2019-03-04 18:17:00 +00:00
}
#previewImage {
width: 100%;
}
2019-04-03 14:15:15 +00:00
.explanation {
max-width: 800px;
margin: 10px auto;
padding: 0 20px;
}
/**
* Context Menu
*/
.contextmenu {
position: absolute;
top: 0;
left: 0;
display: none;
border-radius: 10px;
border: 1px solid rgba(0, 0, 0, .33);
box-shadow: 0 0 4px rgba(0, 0, 0, .15);
margin: 0;
padding: 0;
list-style: none;
min-width: 150px;
background: #fff;
}
.contextmenu > li {
padding: 8px 16px;
cursor: pointer;
}
.contextmenu > li:first-child {
border-top-left-radius: 10px;
border-top-right-radius: 10px;
}
.contextmenu > li:last-child {
border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px;
}
.contextmenu > li:hover {
background: rgba(0, 0, 0, .1);
}
.contextmenu > li:active {
background: rgba(0, 0, 0, .2);
}
/**
* Drag Overlay
*/
#dragOverlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, .75);
padding: 20px;
color: #fff;
pointer-events: none;
opacity: 0;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
-webkit-transition: opacity .25s;
-moz-transition: opacity .25s;
-ms-transition: opacity .25s;
-o-transition: opacity .25s;
transition: opacity .25s;
}
#dragOverlay.visible {
opacity: 1;
pointer-events: all;
cursor: pointer;
}
#dragOverlay .border {
width: 100%;
height: 100%;
border-radius: 10px;
border: 4px dashed white;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
#dragOverlay .content {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
text-align: center;
}
2019-03-04 18:17:00 +00:00
< / style >
2019-02-27 20:22:38 +00:00
< / head >
< body >
2019-03-04 18:17:00 +00:00
< div class = "container" >
2019-03-07 15:13:08 +00:00
< nav class = "document-tabs-container" >
2019-03-04 18:17:00 +00:00
< ul id = "document-tabs" >
< / ul >
< / nav >
< div class = "action-buttons" >
2019-03-07 15:13:08 +00:00
< button class = "btn action-button" id = "addBtn" > < i class = "fa fa-plus" > < / i > Neu< / button >
2019-03-04 18:17:00 +00:00
< button class = "btn action-button" id = "saveBtn" > < i class = "fa fa-save" > < / i > Speichern< / button >
< button class = "btn action-button" id = "openBtn" > < i class = "fa fa-folder-open" > < / i > Öffnen< / button >
2019-03-05 19:31:53 +00:00
< button class = "btn action-button" id = "importBtn" > < i class = "fa fa-file-import" > < / i > Importieren< / button >
2019-03-04 18:17:00 +00:00
2019-03-05 19:31:53 +00:00
< button class = "btn action-button" id = "exportBtn" > < i class = "fa fa-file-export" > < / i > Exportieren< / button >
< button class = "btn action-button" id = "simulateBtn" > < i class = "fa fa-play" > < / i > Simulieren< / button >
2019-03-04 18:17:00 +00:00
< / div >
< / div >
2019-02-27 20:22:38 +00:00
< canvas id = "canvas" > < / canvas >
2019-04-03 14:15:15 +00:00
< div class = "explanation" >
< p > Oben befindet sich der sogenannter FSM-Designer. Dieser ermöglicht es unter anderem deterministische endliche Automaten zu erstellen.< / p >
< p > Funktionsweise:< / p >
< ul >
< li > < b > Zustand hinzufügen:< / b > Doppelklick< / li >
< li > < b > Übergang hinzufügen:< / b > < code > Shift< / code > gedrückt halten und mit linker Maustaste ziehen< / li >
< li > < b > Verschieben:< / b > klassisches Drag'n'drop< / li >
< li > < b > Endzustand:< / b > Doppelklick auf einen bestehenden Zustand< / li >
< li > < b > Index:< / b > Unterstrich vor eine Zahl hinzufügen (z.B. < code > q_0< / code > )< / li >
< li > < b > Griechischer Buchstabe:< / b > Name des Buchstaben mit Backslash (z.B. < code > \epsilon< / code > )< / li >
< / ul >
< p > Diese Anwendung wurde mithilfe von HTML5 Canvas und JavaScript ECMA2016 erstellt.< / p >
< p > Der Source Code ist open source auf < a href = "https://git.kingofdog.eu/KingOfDog/fsm-designer" > Gitea< / a > verfügbar (demnächst womöglich auch über Github).< / p >
< p > Made with < i class = "fa fa-heart" > < / i > by < a href = "https://kingofdog.eu" > KingOfDog< / a > .< / p >
< / div >
< ul id = "contextmenuCanvas" class = "contextmenu" >
< li > Test< / li >
< / ul >
< div id = "dragOverlay" >
< div class = "border" > < / div >
< div class = "content" >
< h1 > Datei ablegen (.fsm)< / h1 >
< h3 > Dokument importieren und weiterarbeiten!< / h3 >
< / div >
< / div >
2019-03-04 18:17:00 +00:00
< script src = "lib/tingle/tingle.min.js" > < / script >
2019-04-03 14:15:15 +00:00
< script src = "lib/contextmenu.js/contextMenu.min.js" > < / script >
2019-03-04 18:17:00 +00:00
2019-02-27 20:22:38 +00:00
< script src = "js/math.js" > < / script >
2019-03-04 18:17:00 +00:00
< script src = "js/export/export.js" > < / script >
< script src = "js/export/export-image.js" > < / script >
2019-02-27 20:22:38 +00:00
< script src = "js/components/connection.js" > < / script >
< script src = "js/components/start-connection.js" > < / script >
< script src = "js/components/self-connection.js" > < / script >
2019-03-01 13:09:39 +00:00
< script src = "js/components/temporary-connection.js" > < / script >
2019-02-27 20:22:38 +00:00
< script src = "js/components/state.js" > < / script >
2019-04-03 14:15:15 +00:00
< script src = "js/fsm-document.js" > < / script >
2019-02-27 20:22:38 +00:00
< script src = "js/main.js" > < / script >
2019-03-04 09:29:32 +00:00
< script src = "js/simulate.js" > < / script >
2019-03-04 18:17:00 +00:00
< script src = "js/menu.js" > < / script >
2019-02-27 20:22:38 +00:00
< / body >
< / html >