commit acea5ba561db0864b040b38e2ac59af03b807a8a Author: PaulK <ia21a.koester.paul@bk-hennef.de> Date: Tue Nov 19 10:12:02 2024 +0100 start diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..f29d257 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,11 @@ +# editorconfig.org + +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 2 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..c664a90 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,194 @@ +## GITATTRIBUTES FOR WEB PROJECTS +# +# These settings are for any web project. +# +# Details per file setting: +# text These files should be normalized (i.e. convert CRLF to LF). +# binary These files are binary and should be left untouched. +# +# Note that binary is a macro for -text -diff. +###################################################################### + +## AUTO-DETECT +## Handle line endings automatically for files detected as +## text and leave all files detected as binary untouched. +## This will handle all files NOT defined below. +* text=auto + +## SOURCE CODE +*.bat text eol=crlf +*.coffee text +*.css text +*.htm text +*.html text +*.inc text +*.ini text +*.js text +*.json text +*.jsx text +*.less text +*.od text +*.onlydata text +*.php text +*.pl text +*.py text +*.rb text +*.sass text +*.scm text +*.scss text +*.sh text eol=lf +*.sql text +*.styl text +*.tag text +*.ts text +*.tsx text +*.xml text +*.xhtml text + +## DOCKER +*.dockerignore text +Dockerfile text + +## DOCUMENTATION +*.markdown text +*.md text +*.mdwn text +*.mdown text +*.mkd text +*.mkdn text +*.mdtxt text +*.mdtext text +*.txt text +AUTHORS text +CHANGELOG text +CHANGES text +CONTRIBUTING text +COPYING text +copyright text +*COPYRIGHT* text +INSTALL text +license text +LICENSE text +NEWS text +readme text +*README* text +TODO text + +## TEMPLATES +*.dot text +*.ejs text +*.haml text +*.handlebars text +*.hbs text +*.hbt text +*.jade text +*.latte text +*.mustache text +*.njk text +*.phtml text +*.tmpl text +*.tpl text +*.twig text + +## LINTERS +.babelrc text +.csslintrc text +.eslintrc text +.htmlhintrc text +.jscsrc text +.jshintrc text +.jshintignore text +.prettierrc text +.stylelintrc text + +## CONFIGS +*.bowerrc text +*.cnf text +*.conf text +*.config text +.browserslistrc text +.editorconfig text +.gitattributes text +.gitconfig text +.gitignore text +.htaccess text +*.npmignore text +*.yaml text +*.yml text +browserslist text +Makefile text +makefile text + +## HEROKU +Procfile text +.slugignore text + +## GRAPHICS +*.ai binary +*.bmp binary +*.eps binary +*.gif binary +*.ico binary +*.jng binary +*.jp2 binary +*.jpg binary +*.jpeg binary +*.jpx binary +*.jxr binary +*.pdf binary +*.png binary +*.psb binary +*.psd binary +*.svg text +*.svgz binary +*.tif binary +*.tiff binary +*.wbmp binary +*.webp binary + +## AUDIO +*.kar binary +*.m4a binary +*.mid binary +*.midi binary +*.mp3 binary +*.ogg binary +*.ra binary + +## VIDEO +*.3gpp binary +*.3gp binary +*.as binary +*.asf binary +*.asx binary +*.fla binary +*.flv binary +*.m4v binary +*.mng binary +*.mov binary +*.mp4 binary +*.mpeg binary +*.mpg binary +*.ogv binary +*.swc binary +*.swf binary +*.webm binary + +## ARCHIVES +*.7z binary +*.gz binary +*.jar binary +*.rar binary +*.tar binary +*.zip binary + +## FONTS +*.ttf binary +*.eot binary +*.otf binary +*.woff binary +*.woff2 binary + +## EXECUTABLES +*.exe binary +*.pyc binary diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..427305a --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +# Include your project-specific ignores in this file +# Read about how to use .gitignore: https://help.github.com/articles/ignoring-files +# Useful .gitignore templates: https://github.com/github/gitignore +node_modules +dist +.cache \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/RC_Car.iml b/.idea/RC_Car.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/.idea/RC_Car.iml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<module type="JAVA_MODULE" version="4"> + <component name="NewModuleRootManager" inherit-compiler-output="true"> + <exclude-output /> + <content url="file://$MODULE_DIR$" /> + <orderEntry type="inheritedJdk" /> + <orderEntry type="sourceFolder" forTests="false" /> + </component> +</module> \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..639900d --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="ProjectRootManager"> + <output url="file://$PROJECT_DIR$/out" /> + </component> +</project> \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..9f6c462 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="ProjectModuleManager"> + <modules> + <module fileurl="file://$PROJECT_DIR$/.idea/RC_Car.iml" filepath="$PROJECT_DIR$/.idea/RC_Car.iml" /> + </modules> + </component> +</project> \ No newline at end of file diff --git a/404.html b/404.html new file mode 100644 index 0000000..260cc4c --- /dev/null +++ b/404.html @@ -0,0 +1,62 @@ +<!doctype html> +<html lang="en"> + +<head> + <meta charset="utf-8"> + <title>Page Not Found</title> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <style> + * { + line-height: 1.2; + margin: 0; + } + + html { + color: #888; + display: table; + font-family: sans-serif; + height: 100%; + text-align: center; + width: 100%; + } + + body { + display: table-cell; + vertical-align: middle; + margin: 2em auto; + } + + h1 { + color: #555; + font-size: 2em; + font-weight: 400; + } + + p { + margin: 0 auto; + width: 280px; + } + + @media only screen and (max-width: 280px) { + + body, + p { + width: 95%; + } + + h1 { + font-size: 1.5em; + margin: 0 0 0.3em; + } + + } + </style> +</head> + +<body> + <h1>Page Not Found</h1> + <p>Sorry, but the page you were trying to view does not exist.</p> +</body> + +</html> +<!-- IE needs 512+ bytes: https://docs.microsoft.com/archive/blogs/ieinternals/friendly-http-error-pages --> diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..294e91d --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,19 @@ +Copyright (c) HTML5 Boilerplate + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/arrow.png b/arrow.png new file mode 100644 index 0000000..c3dd384 Binary files /dev/null and b/arrow.png differ diff --git a/connect.py b/connect.py new file mode 100644 index 0000000..620cdfc --- /dev/null +++ b/connect.py @@ -0,0 +1,24 @@ +from flask import Flask, render_template, request +import bluetooth + +app = Flask(__name__) + +# Bluetooth-Geräte in der Nähe scannen +def scan_devices(): + nearby_devices = bluetooth.discover_devices(duration=8, lookup_names=True) + devices = [(addr, name) for addr, name in nearby_devices] + return devices + +@app.route('/') +def index(): + devices = scan_devices() + return render_template('controller.html', devices=devices) + +@app.route('/connect', methods=['POST']) +def connect(): + selected_device = request.form['device'] + # Hier fügst du den Code hinzu, um dich mit dem ausgewählten Gerät zu verbinden + return f"Connecting to device: {selected_device}" + +if __name__ == '__main__': + app.run(debug=True) diff --git a/controller.html b/controller.html new file mode 100644 index 0000000..a691132 --- /dev/null +++ b/controller.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>Bluetooth Controller Auswahl</title> +</head> +<body> +<h1>Verfügbare Bluetooth-Controller</h1> +<form action="/connect" method="post"> + <select name="controller"> + {% for addr, name in controllers %} + <option value="{{ addr }}">{{ name }}</option> + {% endfor %} + </select> + <button type="submit">Verbinden</button> +</form> +</body> +</html> diff --git a/controller.jpg b/controller.jpg new file mode 100644 index 0000000..69595f2 Binary files /dev/null and b/controller.jpg differ diff --git a/css/style.css b/css/style.css new file mode 100644 index 0000000..654e876 --- /dev/null +++ b/css/style.css @@ -0,0 +1,247 @@ +/*! HTML5 Boilerplate v9.0.0-RC1 | MIT License | https://html5boilerplate.com/ */ + +/* main.css 3.0.0 | MIT License | https://github.com/h5bp/main.css#readme */ +/* + * What follows is the result of much research on cross-browser styling. + * Credit left inline and big thanks to Nicolas Gallagher, Jonathan Neal, + * Kroc Camen, and the H5BP dev community and team. + */ + +/* ========================================================================== + Base styles: opinionated defaults + ========================================================================== */ + +html { + color: #222; + font-size: 1em; + line-height: 1.4; +} + +/* + * Remove text-shadow in selection highlight: + * https://twitter.com/miketaylr/status/12228805301 + * + * Customize the background color to match your design. + */ + +::-moz-selection { + background: #b3d4fc; + text-shadow: none; +} + +::selection { + background: #b3d4fc; + text-shadow: none; +} + +/* + * A better looking default horizontal rule + */ + +hr { + display: block; + height: 1px; + border: 0; + border-top: 1px solid #ccc; + margin: 1em 0; + padding: 0; +} + +/* + * Remove the gap between audio, canvas, iframes, + * images, videos and the bottom of their containers: + * https://github.com/h5bp/html5-boilerplate/issues/440 + */ + +audio, +canvas, +iframe, +img, +svg, +video { + vertical-align: middle; +} + +/* + * Remove default fieldset styles. + */ + +fieldset { + border: 0; + margin: 0; + padding: 0; +} + +/* + * Allow only vertical resizing of textareas. + */ + +textarea { + resize: vertical; +} + +/* ========================================================================== + Author's custom styles + ========================================================================== */ + +/* ========================================================================== + Helper classes + ========================================================================== */ + +/* + * Hide visually and from screen readers + */ + +.hidden, +[hidden] { + display: none !important; +} + +/* + * Hide only visually, but have it available for screen readers: + * https://snook.ca/archives/html_and_css/hiding-content-for-accessibility + * + * 1. For long content, line feeds are not interpreted as spaces and small width + * causes content to wrap 1 word per line: + * https://medium.com/@jessebeach/beware-smushed-off-screen-accessible-text-5952a4c2cbfe + */ + +.visually-hidden { + border: 0; + clip: rect(0, 0, 0, 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + white-space: nowrap; + width: 1px; + /* 1 */ +} + +/* + * Extends the .visually-hidden class to allow the element + * to be focusable when navigated to via the keyboard: + * https://www.drupal.org/node/897638 + */ + +.visually-hidden.focusable:active, +.visually-hidden.focusable:focus { + clip: auto; + height: auto; + margin: 0; + overflow: visible; + position: static; + white-space: inherit; + width: auto; +} + +/* + * Hide visually and from screen readers, but maintain layout + */ + +.invisible { + visibility: hidden; +} + +/* + * Clearfix: contain floats + * + * The use of `table` rather than `block` is only necessary if using + * `::before` to contain the top-margins of child elements. + */ + +.clearfix::before, +.clearfix::after { + content: ""; + display: table; +} + +.clearfix::after { + clear: both; +} + +/* ========================================================================== + EXAMPLE Media Queries for Responsive Design. + These examples override the primary ('mobile first') styles. + Modify as content requires. + ========================================================================== */ + +@media only screen and (min-width: 35em) { + /* Style adjustments for viewports that meet the condition */ +} + +@media print, + (-webkit-min-device-pixel-ratio: 1.25), + (min-resolution: 1.25dppx), + (min-resolution: 120dpi) { + /* Style adjustments for high resolution devices */ +} + +/* ========================================================================== + Print styles. + Inlined to avoid the additional HTTP request: + https://www.phpied.com/delay-loading-your-print-css/ + ========================================================================== */ + +@media print { + *, + *::before, + *::after { + background: #fff !important; + color: #000 !important; + /* Black prints faster */ + box-shadow: none !important; + text-shadow: none !important; + } + + a, + a:visited { + text-decoration: underline; + } + + a[href]::after { + content: " (" attr(href) ")"; + } + + abbr[title]::after { + content: " (" attr(title) ")"; + } + + /* + * Don't show links that are fragment identifiers, + * or use the `javascript:` pseudo protocol + */ + a[href^="#"]::after, + a[href^="javascript:"]::after { + content: ""; + } + + pre { + white-space: pre-wrap !important; + } + + pre, + blockquote { + border: 1px solid #999; + page-break-inside: avoid; + } + + tr, + img { + page-break-inside: avoid; + } + + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + + h2, + h3 { + page-break-after: avoid; + } +} + diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000..be74abd Binary files /dev/null and b/favicon.ico differ diff --git a/handy.jpg b/handy.jpg new file mode 100644 index 0000000..f76c763 Binary files /dev/null and b/handy.jpg differ diff --git a/icon.png b/icon.png new file mode 100644 index 0000000..8a42581 Binary files /dev/null and b/icon.png differ diff --git a/icon.svg b/icon.svg new file mode 100644 index 0000000..f232922 --- /dev/null +++ b/icon.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" viewBox="0 0 192 192"><path fill="#e08524" d="M75.3 73.4H18.4l45.3 34.3L48.3 163l46.1-32.3 48.2 34.6-16.9-58.3 44.9-33.6H115l-20.5-55-19.2 55z"/><path d="m96.7 18.8 18.2 8.2 16.5 44.3h-15.1L96.7 18.8zm-47 146 18.7 9.9 42.6-29.9-16.5-11.4-44.8 31.4zm79.1-56.8 17.4 9.4 18.6 60.1-19.7-11.3-16.3-58.2z"/><path d="m173.1 74.3 17.8 9.2-44.7 34-17.4-9.4 44.3-33.8z"/></svg> diff --git a/img/.gitkeep b/img/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/index.html b/index.html new file mode 100644 index 0000000..43bbd4e --- /dev/null +++ b/index.html @@ -0,0 +1,90 @@ +<!DOCTYPE html> +<html lang="de"> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>Mein Menü</title> + <style> + body { + font-family: Arial, sans-serif; + margin: 0; + padding: 0; + } + + .menu { + background-color: #333; + overflow: hidden; + } + + .menu a { + float: left; + display: block; + color: white; + text-align: center; + padding: 14px 16px; + text-decoration: none; + } + + .menu a:hover { + background-color: #ddd; + color: black; + } + + .content { + padding: 20px; + } + + .hidden { + display: none; + } + + #control img { + max-width: 25%; + height: auto; + cursor: pointer; /* Hinzugefügt, um den Mauszeiger zu ändern */ + } + </style> +</head> +<body> + +<div class="menu"> + <a href="#" onclick="showContent('home')">Startseite</a> + <a href="#" onclick="showContent('control')">Steuerung</a> +</div> + +<div id="home" class="content"> + <h2>Startseite</h2> + <p>Willkommen auf der Startseite!</p> +</div> + +<!-- Bild --> +<div id="control" class="content hidden"> + <h2>Steuerung</h2> + <p>Wählen Sie ein Steuergerät!</p> + <a href="joystick.html" style="position: absolute; top: 250px; left: 200px;"> + <img src="handy.jpg" alt="Handy Bild" style="width: 250px; height: 100px;"> + </a> + <a href="controller.html" style="position: absolute; top: 450px; left: 200px"> + <img src="controller.jpg" alt="Controller Bild" style="width: 400px; height: 90px;"> + </a> +</div> + + +<script> + function showContent(id) { + // Alle Inhalte ausblenden + var contents = document.getElementsByClassName("content"); + for (var i = 0; i < contents.length; i++) { + contents[i].classList.add("hidden"); + } + + // Nur das angeklickte Element anzeigen + var element = document.getElementById(id); + if (element) { + element.classList.remove("hidden"); + } + } +</script> + +</body> +</html> diff --git a/joystick.html b/joystick.html new file mode 100644 index 0000000..2fed6f1 --- /dev/null +++ b/joystick.html @@ -0,0 +1,343 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>Circular Control Stick</title> + <style> + body { + display: flex; + align-items: center; + justify-content: center; + height: 100vh; + margin: 0; + background-color: #f0f0f0; /* Change the background color as needed */ + } + + #control-container { + position: relative; + width: 400px; /* Adjust the overall size as needed */ + height: 400px; /* Adjust the overall size as needed */ + border-radius: 50%; + border: 2px solid black; /* Outline style for the outer circle */ + box-sizing: border-box; + touch-action: none; /* Disable touch actions to prevent scrolling on touch devices */ + overflow: hidden; /* Hide the overflow of the lines */ + } + + #inner-stick { + position: absolute; + width: 80px; /* Adjust the inner control stick size as needed */ + height: 80px; /* Adjust the inner control stick size as needed */ + background-color: black; /* Filled color for the inner circle */ + border-radius: 50%; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + touch-action: none; /* Disable touch actions on the inner stick */ + user-select: none; /* Disable text selection on the inner stick */ + } + + .line { + position: absolute; + width: 100%; + height: 2px; + background-color: black; + transform-origin: 50% 50%; + left: 0; + top: 50%; + } + + .line:nth-child(1) { + transform: rotate(22.5deg); + } + + .line:nth-child(2) { + transform: rotate(67.5deg); + } + + .line:nth-child(3) { + transform: rotate(112.5deg); + } + + .line:nth-child(4) { + transform: rotate(157.5deg); + } + + .line:nth-child(5) { + transform: rotate(202.5deg); + } + + .line:nth-child(6) { + transform: rotate(247.5deg); + } + + .line:nth-child(7) { + transform: rotate(292.5deg); + } + + .line:nth-child(8) { + transform: rotate(337.5deg); + } + + .text { + position: absolute; + width: 100%; + text-align: center; + font-size: 15px; + color: black; + transform-origin: 50% 50%; + } + + #text-forward { + top: 5px; + } + + #text-forward-right { + top: 25%; + left: 20%; + transform: rotate(-45deg); + } + + #text-forward-left { + top: 25%; + right: 20%; + transform: rotate(45deg); + } + + #text-right { + left: 45%; + top: 50%; + transform: translateY(-50%) rotate(-90deg); + } + + #text-left { + right: 45%; + top: 50%; + transform: translateY(-50%) rotate(90deg); + } + + #text-backward { + bottom: 5px; + } + + #text-backward-right { + bottom: 25%; + left: 20%; + transform: rotate(45deg); + } + + #text-backward-left { + bottom: 25%; + right: 20%; + transform: rotate(-45deg); + } + </style> +</head> +<body> +<!-- Image clickable --> +<a href="index.html" style="position: absolute; top: 10px; left: 10px;"> + <img src="arrow.png" alt="Klickbarer Pfeil" style="width: 150px; height: 100px;"> +</a> + +<div id="control-container"> + + <!-- Lines to divide the outer circle --> + <div class="line"></div> + <div class="line"></div> + <div class="line"></div> + <div class="line"></div> + + <!-- Text elements --> + <div class="text" id="text-forward">Forward</div> + <div class="text" id="text-forward-left">Forward-Left</div> + <div class="text" id="text-forward-right">Forward-Right</div> + <div class="text" id="text-left">Left</div> + <div class="text" id="text-right">Right</div> + <div class="text" id="text-backward">Backward</div> + <div class="text" id="text-backward-left">Backward-Left</div> + <div class="text" id="text-backward-right">Backward-Right</div> + + <!-- Inner stick --> + <div id="inner-stick"></div> + +</div> + +<script> + // JavaScript for handling control stick movement + var controlContainer = document.getElementById('control-container'); + var innerStick = document.getElementById('inner-stick'); + + // Variables to store the initial position and touch/mouse state + var initialX, initialY, isTouched = false; + + // Event listeners for touch events + innerStick.addEventListener('touchstart', handleTouchStart); + innerStick.addEventListener('touchmove', handleTouchMove); + innerStick.addEventListener('touchend', handleTouchEnd); + + // Event listeners for mouse events + innerStick.addEventListener('mousedown', handleMouseDown); + window.addEventListener('mousemove', handleMouseMove); + window.addEventListener('mouseup', handleMouseUp); + + // Touch event handlers + function handleTouchStart(event) { + isTouched = true; + var touch = event.touches[0]; + initialX = touch.clientX - controlContainer.offsetLeft; + initialY = touch.clientY - controlContainer.offsetTop; + } + + function handleTouchMove(event) { + if (!isTouched) return; + + var touch = event.touches[0]; + var currentX = touch.clientX - controlContainer.offsetLeft; + var currentY = touch.clientY - controlContainer.offsetTop; + + moveInnerStick(currentX, currentY); + sendCommandBasedOnSector(currentX, currentY); + event.preventDefault(); + if (event.touches.length == 0) { + resetInnerStickPosition(); + } + } + + function handleTouchEnd() { + isTouched = false; + resetInnerStickPosition(); + } + + // Mouse event handlers + function handleMouseDown(event) { + isTouched = true; + initialX = event.clientX - controlContainer.offsetLeft; + initialY = event.clientY - controlContainer.offsetTop; + } + + function handleMouseMove(event) { + if (!isTouched) return; + + var currentX = event.clientX - controlContainer.offsetLeft; + var currentY = event.clientY - controlContainer.offsetTop; + + moveInnerStick(currentX, currentY); + sendCommandBasedOnSector(currentX, currentY); + if (!event.buttons) { + resetInnerStickPosition(); + } + } + + function handleMouseUp() { + isTouched = false; + resetInnerStickPosition(); + } + + // Function to move the inner stick + function moveInnerStick(x, y) { + var deltaX = x - initialX; + var deltaY = y - initialY; + + // Ensure the inner stick stays within the bounds of the container + var distance = Math.min( + Math.hypot(deltaX, deltaY), + controlContainer.clientWidth / 2 - innerStick.clientWidth / 2 + ); + + var angle = Math.atan2(deltaY, deltaX); + var newX = Math.cos(angle) * distance + controlContainer.clientWidth / 2; + var newY = Math.sin(angle) * distance + controlContainer.clientHeight / 2; + + innerStick.style.left = newX + 'px'; + innerStick.style.top = newY + 'px'; + } + + // Function to reset the inner stick to the center + function resetInnerStickPosition() { + innerStick.style.left = '50%'; + innerStick.style.top = '50%'; + sendCommand('/move/stop'); + } + + var lastcommand; + + // Function to send a command (replace with actual command logic) + function sendCommand(command) { + + if (lastcommand !== command) { + lastcommand = command; + console.log('Command Sent:', command); + + // Vollständige URL zum Flask-Server + var url = 'http://192.168.4.1:5000' + command; // Bitte die IP-Adresse und Portnummer anpassen + + // AJAX-Anfrage erstellen + var xhr = new XMLHttpRequest(); + xhr.open('POST', url, true); // URL anpassen, um sie an Ihren Server anzupassen + xhr.setRequestHeader('Content-Type', 'application/json'); + xhr.onreadystatechange = function () { + if (xhr.readyState === XMLHttpRequest.DONE) { + if (xhr.status === 200) { + console.log('Command successfully sent to server:' + command); + } else { + console.error('Failed to send command to server.'); + } + } + }; + xhr.send(); + } + } + + // ich hab dich gaaaaaanz dolle lieb bubu, ich bin super stolz auf dich, du machst das echt super duper toll + + + // Function to log the inner stick position to the console + function sendCommandBasedOnSector(x, y) { + var deltaX = x - controlContainer.clientWidth / 2; + var deltaY = y - controlContainer.clientHeight / 2; + + // Calculate the angle of the inner stick + var angle = Math.atan2(deltaY, deltaX); + var angleDeg = (angle * 180) / Math.PI; + + // Convert negative angles to positive for simplicity + if (angleDeg < 0) { + angleDeg += 360; + } + + // Determine the sector based on the angle + var sector = Math.floor((angleDeg + 22.5) / 45) % 8; + + // Send a command based on the sector + switch (sector) { + case 0: // Right + sendCommand('/move/right'); + break; + case 1: // Back-Right + sendCommand('/move/back-right'); + break; + case 2: // Back + sendCommand('/move/back'); + break; + case 3: // Back-Left + sendCommand('/move/back-left'); + break; + case 4: // Left + sendCommand('/move/left'); + break; + case 5: // Front-Left + sendCommand('/move/front-left'); + break; + case 6: // Forward + sendCommand('/move/Front'); + break; + case 7: // Front-Right + sendCommand('/move/front-right'); + break; + } + } +</script> + +</body> +</html> diff --git a/js/app.js b/js/app.js new file mode 100644 index 0000000..e69de29 diff --git a/js/vendor/.gitkeep b/js/vendor/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/package.json b/package.json new file mode 100644 index 0000000..5353ddf --- /dev/null +++ b/package.json @@ -0,0 +1,24 @@ +{ + "name": " ", + "version": "0.0.1", + "description": "", + "private": true, + "keywords": [ + "" + ], + "license": "", + "author": "", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "start": "webpack serve --open --config webpack.config.dev.js", + "build": "webpack --config webpack.config.prod.js" + }, + "devDependencies": { + "copy-webpack-plugin": "^11.0.0", + "html-webpack-plugin": "^5.5.3", + "webpack": "^5.88.2", + "webpack-cli": "^5.1.4", + "webpack-dev-server": "^4.15.1", + "webpack-merge": "^5.9.0" + } +} diff --git a/robots.txt b/robots.txt new file mode 100644 index 0000000..d0e5f1b --- /dev/null +++ b/robots.txt @@ -0,0 +1,5 @@ +# www.robotstxt.org/ + +# Allow crawling of all content +User-agent: * +Disallow: diff --git a/site.webmanifest b/site.webmanifest new file mode 100644 index 0000000..222ae16 --- /dev/null +++ b/site.webmanifest @@ -0,0 +1,12 @@ +{ + "short_name": "", + "name": "", + "icons": [{ + "src": "icon.png", + "type": "image/png", + "sizes": "192x192" + }], + "start_url": "/?utm_source=homescreen", + "background_color": "#fafafa", + "theme_color": "#fafafa" +} diff --git a/webpack.common.js b/webpack.common.js new file mode 100644 index 0000000..b502ea9 --- /dev/null +++ b/webpack.common.js @@ -0,0 +1,12 @@ +const path = require('path'); + +module.exports = { + entry: { + app: './js/app.js', + }, + output: { + path: path.resolve(__dirname, 'dist'), + clean: true, + filename: './js/app.js', + }, +}; diff --git a/webpack.config.dev.js b/webpack.config.dev.js new file mode 100644 index 0000000..5953807 --- /dev/null +++ b/webpack.config.dev.js @@ -0,0 +1,13 @@ +const { merge } = require('webpack-merge'); +const common = require('./webpack.common.js'); + +module.exports = merge(common, { + mode: 'development', + devtool: 'inline-source-map', + devServer: { + liveReload: true, + hot: true, + open: true, + static: ['./'], + }, +}); diff --git a/webpack.config.prod.js b/webpack.config.prod.js new file mode 100644 index 0000000..76800e8 --- /dev/null +++ b/webpack.config.prod.js @@ -0,0 +1,26 @@ +const { merge } = require('webpack-merge'); +const common = require('./webpack.common.js'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); +const CopyPlugin = require('copy-webpack-plugin'); + +module.exports = merge(common, { + mode: 'production', + plugins: [ + new HtmlWebpackPlugin({ + template: './index.html', + }), + new CopyPlugin({ + patterns: [ + { from: 'img', to: 'img' }, + { from: 'css', to: 'css' }, + { from: 'js/vendor', to: 'js/vendor' }, + { from: 'icon.svg', to: 'icon.svg' }, + { from: 'favicon.ico', to: 'favicon.ico' }, + { from: 'robots.txt', to: 'robots.txt' }, + { from: 'icon.png', to: 'icon.png' }, + { from: '404.html', to: '404.html' }, + { from: 'site.webmanifest', to: 'site.webmanifest' }, + ], + }), + ], +});