1805 lines
41 KiB
HTML
1805 lines
41 KiB
HTML
<?php
|
|
session_start();
|
|
error_reporting(E_ALL);
|
|
ini_set('display_errors', 1);
|
|
|
|
|
|
|
|
$imageDir = "./image"; // Angepasst an das Ausgabeverzeichnis des Bash-Skripts
|
|
$imageFiles = glob("$imageDir/screenshot_*.jpg");
|
|
rsort($imageFiles); // Sortiert die Dateien in umgekehrter Reihenfolge (neueste zuerst)
|
|
$imageFilesJson = json_encode($imageFiles);
|
|
|
|
|
|
|
|
|
|
|
|
class WebcamManager {
|
|
private $videoSrc = 'test_video.m3u8';
|
|
private $logoPath = 'logo.png';
|
|
public function displayWebcam() {
|
|
return '<video id="webcam-player" controls autoplay muted></video>';
|
|
}
|
|
public function captureSnapshot() {
|
|
$outputFile = 'snapshot_' . date('YmdHis') . '.jpg';
|
|
$command = "ffmpeg -i {$this->videoSrc} -i {$this->logoPath} -filter_complex 'overlay=10:10' -vframes 1 -q:v 2 {$outputFile}";
|
|
|
|
exec($command, $output, $returnVar);
|
|
|
|
if ($returnVar !== 0) {
|
|
return "Fehler beim Erstellen des Snapshots.";
|
|
}
|
|
|
|
header('Content-Type: application/octet-stream');
|
|
header('Content-Disposition: attachment; filename="' . $outputFile . '"');
|
|
readfile($outputFile);
|
|
unlink($outputFile);
|
|
exit;
|
|
}
|
|
public function getImageFiles() {
|
|
$imageFiles = glob("image/*.{jpg,jpeg,png,gif}", GLOB_BRACE);
|
|
return json_encode($imageFiles);
|
|
}
|
|
|
|
public function captureVideoSequence($duration = 10) {
|
|
$outputFile = 'sequence_' . date('YmdHis') . '.mp4';
|
|
$command = "ffmpeg -i {$this->videoSrc} -i {$this->logoPath} -filter_complex 'overlay=10:10' -t {$duration} -c:v libx264 -preset fast -crf 23 {$outputFile}";
|
|
|
|
exec($command, $output, $returnVar);
|
|
|
|
if ($returnVar !== 0) {
|
|
return "Fehler beim Erstellen der Video-Sequenz.";
|
|
}
|
|
|
|
header('Content-Type: video/mp4');
|
|
header('Content-Disposition: attachment; filename="' . $outputFile . '"');
|
|
readfile($outputFile);
|
|
unlink($outputFile);
|
|
exit;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function getJavaScript() {
|
|
return "
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
var video = document.getElementById('webcam-player');
|
|
var videoSrc = '{$this->videoSrc}';
|
|
if (Hls.isSupported()) {
|
|
var hls = new Hls();
|
|
hls.loadSource(videoSrc);
|
|
hls.attachMedia(video);
|
|
hls.on(Hls.Events.MANIFEST_PARSED, function () {
|
|
video.play();
|
|
});
|
|
}
|
|
else if (video.canPlayType('application/vnd.apple.mpegurl')) {
|
|
video.src = videoSrc;
|
|
video.addEventListener('loadedmetadata', function () {
|
|
video.play();
|
|
});
|
|
}
|
|
});
|
|
";
|
|
}
|
|
|
|
public function setVideoSrc($src) {
|
|
$this->videoSrc = $src;
|
|
}
|
|
}
|
|
|
|
class GuestbookManager {
|
|
private $entries = [];
|
|
private $dbFile = 'guestbook.json';
|
|
|
|
public function __construct() {
|
|
if (file_exists($this->dbFile)) {
|
|
$this->entries = json_decode(file_get_contents($this->dbFile), true);
|
|
}
|
|
}
|
|
|
|
public function handleFormSubmission() {
|
|
if (isset($_POST['guestbook'], $_POST['guest-name'], $_POST['guest-message'])) {
|
|
$this->addEntry($_POST['guest-name'], $_POST['guest-message']);
|
|
$this->saveEntries();
|
|
}
|
|
}
|
|
|
|
private function addEntry($name, $message) {
|
|
$this->entries[] = [
|
|
'name' => $name,
|
|
'message' => $message,
|
|
'date' => date('Y-m-d H:i:s')
|
|
];
|
|
}
|
|
|
|
public function deleteEntry($index) {
|
|
if (isset($this->entries[$index])) {
|
|
unset($this->entries[$index]);
|
|
$this->entries = array_values($this->entries); // Re-indizieren des Arrays
|
|
$this->saveEntries();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
|
|
private function saveEntries() {
|
|
file_put_contents($this->dbFile, json_encode($this->entries));
|
|
}
|
|
|
|
public function displayForm() {
|
|
return '
|
|
<form method="post">
|
|
<input type="hidden" name="guestbook" value="1">
|
|
<label for="guest-name">Name:</label>
|
|
<input type="text" id="guest-name" name="guest-name" required>
|
|
<label for="guest-message">Nachricht:</label>
|
|
<textarea id="guest-message" name="guest-message" required></textarea>
|
|
<button type="submit">Eintrag hinzufügen</button>
|
|
</form>';
|
|
}
|
|
public function displayEntries($isAdmin = false) {
|
|
$output = '<div id="guestbook-entries">';
|
|
foreach ($this->entries as $index => $entry) {
|
|
$output .= "
|
|
<div class='guestbook-entry'>
|
|
<h4><i class='fas fa-user'></i> {$entry['name']}</h4>
|
|
<p><i class='fas fa-comment'></i> {$entry['message']}</p>
|
|
<small><i class='fas fa-clock'></i> {$entry['date']}</small>";
|
|
if ($isAdmin) {
|
|
$output .= "<form method='post' style='display:inline;'>
|
|
<input type='hidden' name='action' value='delete_guestbook'>
|
|
<input type='hidden' name='delete_entry' value='{$index}'>
|
|
<button type='submit' class='delete-btn'>Löschen</button>
|
|
</form>";
|
|
}
|
|
|
|
}
|
|
$output .= '</div>';
|
|
return $output;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
class ContactManager {
|
|
public function displayForm() {
|
|
return '
|
|
<form method="post">
|
|
<input type="hidden" name="contact" value="1">
|
|
<label for="name">Name:</label>
|
|
<input type="text" id="name" name="name" required>
|
|
<label for="email">E-Mail:</label>
|
|
<input type="email" id="email" name="email" required>
|
|
<label for="message">Nachricht:</label>
|
|
<textarea id="message" name="message" required></textarea>
|
|
<button type="submit">Nachricht senden</button>
|
|
</form>';
|
|
}
|
|
|
|
public function handleSubmission($name, $email, $message) {
|
|
$feedback = [
|
|
'name' => $name,
|
|
'email' => $email,
|
|
'message' => $message,
|
|
'date' => date('Y-m-d H:i:s')
|
|
];
|
|
$feedbacks = json_decode(file_get_contents('feedbacks.json') ?: '[]', true);
|
|
$feedbacks[] = $feedback;
|
|
file_put_contents('feedbacks.json', json_encode($feedbacks));
|
|
}
|
|
}
|
|
|
|
class AdminManager {
|
|
public function isAdmin() {
|
|
return isset($_SESSION['admin']) && $_SESSION['admin'] === true;
|
|
}
|
|
public function handleLogin($username, $password) {
|
|
echo "Login-Versuch: Username = $username, Passwort = $password"; // Debugging
|
|
if ($username === 'admin' && $password === 'sonne4000') {
|
|
$_SESSION['admin'] = true;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public function handleImageUpload($file) {
|
|
if (!$this->isAdmin()) {
|
|
return false; // Nur Admins dürfen Bilder hochladen
|
|
}
|
|
|
|
if (!isset($file['tmp_name']) || empty($file['tmp_name'])) {
|
|
echo "Keine Datei hochgeladen.";
|
|
return false;
|
|
}
|
|
|
|
$target_dir = "uploads/";
|
|
if (!file_exists($target_dir)) {
|
|
mkdir($target_dir, 0777, true);
|
|
}
|
|
|
|
$target_file = $target_dir . basename($file["name"]);
|
|
$uploadOk = 1;
|
|
$imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
|
|
|
|
|
|
$check = @getimagesize($file["tmp_name"]);
|
|
if($check === false) {
|
|
echo "Die Datei ist kein Bild.";
|
|
return false;
|
|
}
|
|
|
|
|
|
if ($file["size"] > 5000000) { // 5MB Limit
|
|
echo "Die Datei ist zu groß.";
|
|
return false;
|
|
}
|
|
|
|
// Erlauben Sie nur bestimmte Dateiformate
|
|
if($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg"
|
|
&& $imageFileType != "gif" ) {
|
|
echo "Nur JPG, JPEG, PNG & GIF Dateien sind erlaubt.";
|
|
return false;
|
|
}
|
|
|
|
// Wenn alles in Ordnung ist, versuchen Sie, die Datei hochzuladen
|
|
if (move_uploaded_file($file["tmp_name"], $target_file)) {
|
|
echo "Die Datei ". basename( $file["name"]). " wurde hochgeladen.";
|
|
return true;
|
|
} else {
|
|
echo "Es gab einen Fehler beim Hochladen der Datei.";
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
public function displayLoginForm() {
|
|
return '
|
|
<form id="login-form" method="post">
|
|
<input type="hidden" name="admin-login" value="1">
|
|
<label for="username">Benutzername:</label>
|
|
<input type="text" id="username" name="username" required>
|
|
<label for="password">Passwort:</label>
|
|
<input type="password" id="password" name="password" required>
|
|
<button type="submit">Einloggen</button>
|
|
</form>';
|
|
}
|
|
|
|
public function displayAdminContent() {
|
|
$feedbacks = json_decode(file_get_contents('feedbacks.json') ?: '[]', true);
|
|
$output = '<h3>Admin-Bereich</h3><div id="message-list">';
|
|
foreach ($feedbacks as $feedback) {
|
|
$output .= "<div>";
|
|
$output .= "<h4>{$feedback['name']} ({$feedback['email']})</h4>";
|
|
$output .= "<p>{$feedback['message']}</p>";
|
|
$output .= "<small>{$feedback['date']}</small>";
|
|
$output .= "</div>";
|
|
}
|
|
$output .= '</div>';
|
|
|
|
$output .= '
|
|
<h3>Social Media Links verwalten</h3>
|
|
<form id="social-media-form" method="post">
|
|
<input type="hidden" name="update-social-media" value="1">
|
|
<select name="social-platform" required>
|
|
<option value="facebook">Facebook</option>
|
|
<option value="instagram">Instagram</option>
|
|
<option value="tiktok">TikTok</option>
|
|
</select>
|
|
<input type="url" name="social-url" placeholder="Profil URL" required>
|
|
<button type="submit">Aktualisieren</button>
|
|
</form>';
|
|
$output .= '
|
|
<h3>Bild hochladen</h3>
|
|
<form action="" method="post" enctype="multipart/form-data">
|
|
<input type="file" name="fileToUpload" id="fileToUpload">
|
|
<input type="submit" value="Bild hochladen" name="submit">
|
|
</form>';
|
|
return $output;
|
|
}
|
|
|
|
public function displayGalleryImages() {
|
|
$output = '<div id="gallery-images">';
|
|
$files = glob("uploads/*.*");
|
|
foreach($files as $file) {
|
|
$filename = basename($file);
|
|
$output .= '<img src="'.$file.'" alt="'.$filename.'" style="width:200px; height:auto; margin:10px; cursor:pointer;">';
|
|
}
|
|
$output .= '</div>';
|
|
return $output;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function handleSocialMediaUpdate($platform, $url) {
|
|
$socialLinks = json_decode(file_get_contents('social_links.json') ?: '{}', true);
|
|
$socialLinks[$platform] = $url;
|
|
file_put_contents('social_links.json', json_encode($socialLinks));
|
|
}
|
|
}
|
|
|
|
$webcamManager = new WebcamManager();
|
|
$imageFilesJson = $webcamManager->getImageFiles();
|
|
$guestbookManager = new GuestbookManager();
|
|
$contactManager = new ContactManager();
|
|
$adminManager = new AdminManager();
|
|
|
|
if (isset($_GET['action'])) {
|
|
switch ($_GET['action']) {
|
|
case 'snapshot':
|
|
$webcamManager->captureSnapshot();
|
|
break;
|
|
case 'sequence':
|
|
$webcamManager->captureVideoSequence();
|
|
break;
|
|
}
|
|
}
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'delete_guestbook') {
|
|
if ($adminManager->isAdmin() && isset($_POST['delete_entry'])) {
|
|
$index = $_POST['delete_entry'];
|
|
if ($guestbookManager->deleteEntry($index)) {
|
|
$_SESSION['message'] = "Eintrag erfolgreich gelöscht.";
|
|
} else {
|
|
$_SESSION['error'] = "Fehler beim Löschen des Eintrags.";
|
|
}
|
|
// Umleitung zur gleichen Seite, um Neuladen des Formulars zu verhindern
|
|
header("Location: " . $_SERVER['PHP_SELF'] . "#guestbook");
|
|
exit();
|
|
}
|
|
}
|
|
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
if (isset($_POST['guestbook'])) {
|
|
$guestbookManager->handleFormSubmission();
|
|
} elseif (isset($_POST['contact'])) {
|
|
$contactManager->handleSubmission($_POST['name'], $_POST['email'], $_POST['message']);
|
|
} elseif (isset($_POST['admin-login'])) {
|
|
$adminManager->handleLogin($_POST['username'], $_POST['password']);
|
|
} elseif (isset($_POST['update-social-media'])) {
|
|
$adminManager->handleSocialMediaUpdate($_POST['social-platform'], $_POST['social-url']);
|
|
|
|
|
|
} elseif (isset($_FILES["fileToUpload"]) && $adminManager->isAdmin()) {
|
|
$adminManager->handleImageUpload($_FILES["fileToUpload"]);
|
|
}}
|
|
?>
|
|
|
|
|
|
|
|
|
|
<!DOCTYPE html>
|
|
<html lang="de">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Aurora Wetter Lifecam - Einzigartige Live-Webcam und Wetter></title>
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">
|
|
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
|
|
<style>
|
|
body {
|
|
font-family: Arial, sans-serif;
|
|
margin: 0;
|
|
padding: 0;
|
|
color: #333;
|
|
line-height: 1.6;
|
|
background-image: url('main.jpg');
|
|
background-size: cover;
|
|
background-position: center;
|
|
background-attachment: fixed;
|
|
}
|
|
|
|
|
|
|
|
.page-title {
|
|
font-size: 3rem; /* Dies macht den Titel sehr groß */
|
|
font-weight: bold;
|
|
text-align: center;
|
|
margin-top: 20px;
|
|
margin-bottom: 20px;
|
|
color: #333; /* Dunkelgraue Farbe für bessere Lesbarkeit */
|
|
}
|
|
|
|
|
|
.container {
|
|
max-width: 1200px;
|
|
margin: 0 auto;
|
|
padding: 0 20px;
|
|
}
|
|
header {
|
|
background-color: rgba(255, 255, 255, 0.8);
|
|
padding: 10px 0;
|
|
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
|
position: sticky;
|
|
top: 0;
|
|
z-index: 100;
|
|
}
|
|
|
|
.button {
|
|
display: inline-block;
|
|
padding: 10px 20px;
|
|
margin: 10px;
|
|
background-color: #4CAF50;
|
|
color: white;
|
|
text-decoration: none;
|
|
border-radius: 5px;
|
|
transition: background-color 0.3s;
|
|
font-weight: bold;
|
|
text-align: center;
|
|
}
|
|
|
|
.button:hover {
|
|
background-color: #45a049;
|
|
}
|
|
#webcam-player {
|
|
max-width: 100%;
|
|
height: auto;
|
|
max-height: 70vh; /* Begrenzt die Höhe auf 70% der Bildschirmhöhe */
|
|
display: block;
|
|
margin: 702px auto 0; /* Fügt einen oberen Abstand von 20px hinzu */
|
|
}
|
|
|
|
.video-container {
|
|
margin-top: 20px; /* Fügt einen oberen Abstand von 20px hinzu */
|
|
}
|
|
|
|
.video-container #webcam-player {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
|
|
|
|
.delete-btn {
|
|
background-color: #ff4136;
|
|
color: white;
|
|
border: none;
|
|
padding: 5px 10px;
|
|
cursor: pointer;
|
|
font-size: 0.8em;
|
|
margin-left: 10px;
|
|
}
|
|
|
|
.delete-btn:hover {
|
|
background-color: #ff1a1a;
|
|
}
|
|
|
|
|
|
.title-section {
|
|
background-image: url('main.jpg');
|
|
background-size: cover;
|
|
background-position: center;
|
|
background-repeat: no-repeat;
|
|
padding: 50px 0;
|
|
color: #fff;
|
|
}
|
|
|
|
|
|
.logo img {
|
|
height: 50px;
|
|
}
|
|
nav ul {
|
|
list-style: none;
|
|
padding: 0;
|
|
display: flex;
|
|
justify-content: space-around;
|
|
flex-wrap: wrap;
|
|
}
|
|
nav ul li {
|
|
margin: 5px 10px;
|
|
}
|
|
nav ul li a {
|
|
text-decoration: none;
|
|
color: #333;
|
|
font-weight: bold;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.recommendation-section {
|
|
background-color: rgba(255, 255, 255, 0.8);
|
|
padding: 20px 0;
|
|
}
|
|
|
|
.recommendation-banner {
|
|
text-align: center;
|
|
}
|
|
|
|
.sponsor-logos {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.ad-row {
|
|
display: flex;
|
|
justify-content: center;
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
.ad-item {
|
|
margin: 0 10px;
|
|
}
|
|
|
|
.ad-item img {
|
|
max-height: 40px;
|
|
width: auto;
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
#welcome-title {
|
|
font-size: 28px;
|
|
}
|
|
|
|
#welcome-subtitle {
|
|
font-size: 18px;
|
|
}
|
|
|
|
.ad-item img {
|
|
max-height: 30px;
|
|
}
|
|
}
|
|
|
|
.section {
|
|
padding: 80px 0;
|
|
background-color: rgba(255, 255, 255, 0.8);
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.recommendation-banner h2 {
|
|
margin-bottom: 10px;
|
|
color: #333; /* Hinzugefügt, um sicherzustellen, dass der Text sichtbar ist */
|
|
}
|
|
|
|
|
|
.sponsor-logos a {
|
|
margin: 0 10px;
|
|
}
|
|
|
|
.sponsor-logos img {
|
|
max-height: 40px;
|
|
width: auto;
|
|
}
|
|
|
|
.banner-container {
|
|
position: absolute;
|
|
bottom: 20px; /* Anpassen Sie diesen Wert, um die vertikale Position zu ändern */
|
|
left: 0;
|
|
right: 0;
|
|
z-index: 20;
|
|
}
|
|
|
|
|
|
#qrcode {
|
|
display: flex;
|
|
justify-content: center;
|
|
margin-top: 20px;
|
|
}
|
|
#qrcode img {
|
|
border: 10px solid white;
|
|
}
|
|
|
|
|
|
.section h2 {
|
|
font-size: 36px;
|
|
margin-bottom: 40px;
|
|
text-align: center;
|
|
}
|
|
form {
|
|
display: grid;
|
|
gap: 20px;
|
|
}
|
|
input, textarea, button[type="submit"] {
|
|
width: 100%;
|
|
padding: 10px;
|
|
border: 1px solid #ccc;
|
|
border-radius: 5px;
|
|
}
|
|
button[type="submit"] {
|
|
background-color: #ff5e3a;
|
|
color: #fff;
|
|
border: none;
|
|
cursor: pointer;
|
|
font-size: 18px;
|
|
transition: background-color 0.3s;
|
|
}
|
|
button[type="submit"]:hover {
|
|
background-color: #ff3b1a;
|
|
}
|
|
footer {
|
|
background-color: rgba(51, 51, 51, 0.8);
|
|
color: #fff;
|
|
padding: 40px 0;
|
|
text-align: center;
|
|
}
|
|
.footer-links a {
|
|
color: #fff;
|
|
text-decoration: none;
|
|
margin: 0 10px;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.guestbook-entry {
|
|
background-color: #f9f9f9;
|
|
border-left: 5px solid #4CAF50;
|
|
margin-bottom: 20px;
|
|
padding: 15px;
|
|
border-radius: 5px;
|
|
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
|
|
transition: transform 0.3s ease;
|
|
}
|
|
|
|
.guestbook-entry:hover {
|
|
transform: translateY(-5px);
|
|
}
|
|
|
|
.guestbook-entry h3 {
|
|
color: #333;
|
|
margin-top: 0;
|
|
}
|
|
|
|
.guestbook-entry p {
|
|
color: #666;
|
|
line-height: 1.6;
|
|
}
|
|
|
|
.guestbook-entry .meta {
|
|
font-size: 0.9em;
|
|
color: #999;
|
|
margin-top: 10px;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#social-media-links {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
}
|
|
#social-media-links a {
|
|
margin: 0 10px;
|
|
}
|
|
@media (max-width: 768px) {
|
|
.container {
|
|
padding: 0 10px;
|
|
}
|
|
.section {
|
|
padding: 40px 0;
|
|
}
|
|
nav ul {
|
|
flex-direction: column;
|
|
align-items: center;
|
|
}
|
|
nav ul li {
|
|
margin: 10px 0;
|
|
}
|
|
}
|
|
|
|
.recommendation-banner {
|
|
text-align: center;
|
|
padding: 20px;
|
|
background-color: rgba(255, 255, 255, 0.8);
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.sponsor-logos {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
}
|
|
|
|
.ad-row {
|
|
display: flex;
|
|
justify-content: center;
|
|
flex-wrap: wrap;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.ad-item {
|
|
margin: 0 10px;
|
|
text-align: center;
|
|
}
|
|
|
|
.ad-item img {
|
|
max-height: 40px;
|
|
width: auto;
|
|
}
|
|
|
|
.ad-item p {
|
|
margin: 5px 0;
|
|
font-size: 14px;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.title-section {
|
|
position: absolute;
|
|
top: 10%;
|
|
left: 50%;
|
|
transform: translate(-50%, -50%);
|
|
text-align: center;
|
|
width: 100%;
|
|
z-index: 1220;
|
|
}
|
|
|
|
.container {
|
|
max-width: 80%;
|
|
margin: 0 auto;
|
|
}
|
|
|
|
|
|
#welcome-title {
|
|
font-size: 36px;
|
|
font-weight: bold;
|
|
color: #ffffff;
|
|
text-shadow: 2px 2px 4px rgba(0,0,0,0.7);
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
#welcome-subtitle {
|
|
font-size: 24px;
|
|
color: #ffffff;
|
|
text-shadow: 1px 1px 2px rgba(0,0,0,0.7);
|
|
}
|
|
|
|
|
|
.banner-container {
|
|
position: absolute;
|
|
bottom: 20px;
|
|
left: 0;
|
|
right: 0;
|
|
z-index: 20;
|
|
}
|
|
|
|
.recommendation-banner {
|
|
text-align: center;
|
|
padding: 10px;
|
|
background-color: rgba(255, 255, 255, 0.8);
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.recommendation-banner h2 {
|
|
margin-bottom: 10px;
|
|
color: #333;
|
|
}
|
|
|
|
.sponsor-logos {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.ad-row {
|
|
display: flex;
|
|
justify-content: center;
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
.ad-item {
|
|
margin: 0 10px;
|
|
}
|
|
|
|
.ad-item img {
|
|
max-height: 40px;
|
|
width: auto;
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.title-section {
|
|
position: static;
|
|
transform: none;
|
|
margin-top: 20px;
|
|
}
|
|
|
|
.banner-container {
|
|
position: static;
|
|
margin-top: 20px;
|
|
}
|
|
|
|
#welcome-title {
|
|
font-size: 28px;
|
|
}
|
|
|
|
#welcome-subtitle {
|
|
font-size: 18px;
|
|
}
|
|
|
|
.ad-item img {
|
|
max-height: 30px;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.timelapse-container {
|
|
width: 100%;
|
|
max-width: 800px;
|
|
margin: 0 auto;
|
|
}
|
|
|
|
#timelapse {
|
|
width: 100%;
|
|
height: 450px;
|
|
background-color: #000;
|
|
background-size: cover;
|
|
background-position: center;
|
|
}
|
|
|
|
.controls {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
margin-top: 10px;
|
|
}
|
|
|
|
#playPauseButton {
|
|
padding: 5px 10px;
|
|
}
|
|
|
|
#timeSlider {
|
|
flex-grow: 1;
|
|
margin: 0 10px;
|
|
}
|
|
|
|
#currentTime {
|
|
font-family: monospace;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.modal {
|
|
display: none;
|
|
position: fixed;
|
|
z-index: 1000;
|
|
padding-top: 100px;
|
|
left: 0;
|
|
top: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
overflow: auto;
|
|
background-color: rgba(0,0,0,0.9);
|
|
}
|
|
|
|
.modal-content {
|
|
margin: auto;
|
|
display: block;
|
|
width: 80%;
|
|
max-width: 700px;
|
|
}
|
|
|
|
#caption {
|
|
margin: auto;
|
|
display: block;
|
|
width: 80%;
|
|
max-width: 700px;
|
|
text-align: center;
|
|
color: #ccc;
|
|
padding: 10px 0;
|
|
height: 150px;
|
|
}
|
|
|
|
.close {
|
|
position: absolute;
|
|
top: 15px;
|
|
right: 35px;
|
|
color: #f1f1f1;
|
|
font-size: 40px;
|
|
font-weight: bold;
|
|
transition: 0.3s;
|
|
}
|
|
|
|
.close:hover,
|
|
.close:focus {
|
|
color: #bbb;
|
|
text-decoration: none;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.download-btn {
|
|
display: block;
|
|
width: 200px;
|
|
height: 40px;
|
|
margin: 10px auto;
|
|
background-color: #4CAF50;
|
|
color: white;
|
|
text-align: center;
|
|
line-height: 40px;
|
|
text-decoration: none;
|
|
border-radius: 5px;
|
|
}
|
|
|
|
.download-btn:hover {
|
|
background-color: #45a049;
|
|
}
|
|
.main-content {
|
|
position: 2px;
|
|
min-height: 100vh;
|
|
}
|
|
|
|
.title-section {
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
transform: translate(-50%, -50%);
|
|
text-align: center;
|
|
width: 100%;
|
|
z-index: 10;
|
|
}
|
|
|
|
.banner-container {
|
|
position: absolute;
|
|
bottom: 20px;
|
|
left: 0;
|
|
right: 0;
|
|
z-index: 20;
|
|
}
|
|
|
|
.recommendation-banner {
|
|
text-align: center;
|
|
padding: 10px;
|
|
background-color: rgba(255, 255, 255, 0.8);
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
/* Rest des CSS bleibt unverändert */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</style>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</style>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/qrcode-generator@1.4.4/qrcode.min.js"></script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</head>
|
|
<body>
|
|
<header>
|
|
<div class="container">
|
|
|
|
<div class="logo">
|
|
<img src="logo.png" alt="Aurora Wetter Livecam">
|
|
</div>
|
|
|
|
|
|
<nav>
|
|
<ul>
|
|
<li><a href="#webcams">Webcam</a></li>
|
|
<li><a href="#guestbook">Gästebuch</a></li>
|
|
<li><a href="#kontakt">Kontakt</a></li>
|
|
<li><a href="#gallery">Galerie</a></li>
|
|
<?php if ($adminManager->isAdmin()): ?>
|
|
<li><a href="#admin">Admin</a></li>
|
|
<?php endif; ?>
|
|
</ul>
|
|
</nav>
|
|
</div>
|
|
</header>
|
|
|
|
|
|
|
|
|
|
<div class="main-content">
|
|
<section class="title-section">
|
|
<div class="container">
|
|
<div id="welcome-title">Willkommen bei Aurora Wetter Lifecam</div>
|
|
<div id="welcome-subtitle">Erleben Sie faszinierende Ausblicke der Zürcher Region - in Echtzeit!</div>
|
|
</div>
|
|
</section>
|
|
|
|
<div class="banner-container">
|
|
<div class="recommendation-banner">
|
|
<h2>Unsere Empfehlungen</h2>
|
|
<div class="sponsor-logos">
|
|
<?php
|
|
$advertisements = [
|
|
['name' => 'Gartencenter Meier', 'url' => 'https://www.gartencenter-meier.ch', 'img' => 'meier.png', 'text' => 'Gartencenter Meier'],
|
|
['name' => 'Restaurant Schweizerhof', 'url' => 'https://schweizerhof-duernten.ch/', 'img' => 'schweiz.png', 'text' => 'Hotel Schweizerhof'],
|
|
['name' => 'Deine Werbung bei uns', 'url' => 'https://www.aurora-wetter-lifecam.ch/', 'img' => 'werbung.png', 'text' => 'Werben Sie hier'],
|
|
|
|
['name' => 'Deine Werbung bei uns', 'url' => 'https://www.aurora-wetter-lifecam.ch/', 'img' => 'werbung.png', 'text' => 'Werben Sie hier'],
|
|
['name' => 'Deine Werbung bei uns', 'url' => 'https://www.aurora-wetter-lifecam.ch/', 'img' => 'werbung.png', 'text' => 'Werben Sie hier'],
|
|
['name' => 'Deine Werbung bei uns', 'url' => 'https://www.aurora-wetter-lifecam.ch/', 'img' => 'werbung.png', 'text' => 'Werben Sie hier'],
|
|
|
|
|
|
// Fügen Sie hier weitere Werbeanzeigen hinzu
|
|
];
|
|
|
|
$grouped_ads = array_chunk($advertisements, 3);
|
|
|
|
foreach ($grouped_ads as $group) {
|
|
echo '<div class="ad-row">';
|
|
foreach ($group as $ad) {
|
|
echo '<div class="ad-item">
|
|
<a href="' . htmlspecialchars($ad['url']) . '" target="_blank">
|
|
<img src="' . htmlspecialchars($ad['img']) . '" alt="' . htmlspecialchars($ad['name']) . '">
|
|
<p>' . htmlspecialchars($ad['text']) . '</p>
|
|
</a>
|
|
|
|
|
|
</div>';
|
|
}
|
|
|
|
echo '</div>';
|
|
}
|
|
?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<section id="webcams" class="section">
|
|
<div class="container">
|
|
|
|
<div class="video-container">
|
|
<?php echo $webcamManager->displayWebcam(); ?>
|
|
<div id="timelapse-viewer" class="video-container" style=" margin-top: 300px; max-width: 100%;
|
|
height: auto;
|
|
max-height: 70vh;">
|
|
<img id="timelapse-image" src="" alt="Timelapse Image" class="video-container" style=" margin-top: 500px; max-width: 100%;
|
|
height: auto;
|
|
max-height: 70vh;">>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
<div class="webcam-controls">
|
|
<a href="?action=snapshot" class="button">Snapshot speichern</a>
|
|
<a href="?action=sequence" class="button">Videoclip speichern</a>
|
|
<a href="#" class="button" id="timelapse-button">Tagesablauf im Zeitraffer</a>
|
|
<a href="#" class="button" id="sunny-timelapse-button">Sonnige Momente anzeigen</a>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
|
|
|
|
|
|
|
|
<section id="qr-code" class="section">
|
|
<div class="container" style="text-align: center;">
|
|
<h1>Folge uns und kopiere den Code und sende es deinen Freunden in Tiktok, Facebook, Instagram usw</h1>
|
|
<div id="qrcode" data-url="https://www.aurora-wetter-lifecam.ch/qr.php"></div>
|
|
<p>Klicke auf den QR-Code, um die URL zu kopieren</p>
|
|
</div>
|
|
</section>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<section id="guestbook" class="section">
|
|
<div class="container">
|
|
<h2>Gästebuch</h2>
|
|
<?php
|
|
if (isset($_SESSION['message'])) {
|
|
echo "<p class='success'>{$_SESSION['message']}</p>";
|
|
unset($_SESSION['message']);
|
|
}
|
|
if (isset($_SESSION['error'])) {
|
|
echo "<p class='error'>{$_SESSION['error']}</p>";
|
|
unset($_SESSION['error']);
|
|
}
|
|
echo $guestbookManager->displayForm();
|
|
echo $guestbookManager->displayEntries($adminManager->isAdmin());
|
|
?>
|
|
</div>
|
|
</section>
|
|
|
|
|
|
<section id="kontakt" class="section">
|
|
<div class="container">
|
|
<h2>Kontakt</h2> <p>Haben Sie Fragen, Anregungen oder möchten uns unterstützen? Wir freuen uns auf Ihre Nachricht!</p>
|
|
<?php echo $contactManager->displayForm(); ?>
|
|
</div>
|
|
</section>
|
|
|
|
<section id="gallery" class="section">
|
|
<div class="container">
|
|
<h2>Bildergalerie</h2>
|
|
<div id="gallery-images">
|
|
<?php echo $adminManager->displayGalleryImages(); ?>
|
|
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
|
|
|
|
|
|
|
|
<section id="ueber-uns" class="section">
|
|
<div class="container">
|
|
<h2>Über unser Projekt</h2>
|
|
<div class="about-grid">
|
|
<div class="about-item">
|
|
<p>Aurora Wetter Lifecam ist ein Herzensprojekt von Wetterbegeisterten. Wir möchten Ihnen die Schönheit der Natur und Faszination des Wetters näher bringen.</p>
|
|
<p>Dazu betreiben wir seit 2010 rund um die Uhr hochauflösende Webcams. Besonders stolz sind wir auf einzigartige Einblicke, wie z.B. die Trainingsflüge der Patrouille Suisse jeden Montagmorgen.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<?php if ($adminManager->isAdmin()): ?>
|
|
<section id="admin" class="section">
|
|
<div class="container">
|
|
<h2>Admin-Bereich</h2>
|
|
<?php echo $adminManager->displayAdminContent(); ?>
|
|
</div>
|
|
</section>
|
|
<?php else: ?>
|
|
<section id="admin-login" class="section">
|
|
<div class="container">
|
|
<h2>Admin Login</h2>
|
|
<?php echo $adminManager->displayLoginForm(); ?>
|
|
</div>
|
|
</section>
|
|
<?php endif; ?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</main>
|
|
|
|
<footer>
|
|
<div class="container">
|
|
<div class="footer-links">
|
|
<a href="#webcams">Webcam</a>
|
|
<a href="#guestbook">Gästebuch</a>
|
|
<a href="#kontakt">Kontakt</a>
|
|
<a href="#gallery">Galerie</a>
|
|
</div>
|
|
<div class="footer-bottom">
|
|
<p>© 2024 Aurora Wetter Lifecam</p>
|
|
</div>
|
|
</div>
|
|
</footer>
|
|
|
|
|
|
|
|
<script src="https://www.youtube.com/iframe_api"></script>
|
|
<script>
|
|
// Webcam-Player-Logik
|
|
<?php echo $webcamManager->getJavaScript(); ?>
|
|
|
|
// Social Media Manager
|
|
function updateSocialMediaLinks() {
|
|
fetch('social_links.json')
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
const socialLinksContainer = document.getElementById('social-media-links');
|
|
socialLinksContainer.innerHTML = '';
|
|
for (const [platform, url] of Object.entries(data)) {
|
|
const link = document.createElement('a');
|
|
link.href = url;
|
|
link.target = '_blank';
|
|
link.textContent = platform.charAt(0).toUpperCase() + platform.slice(1);
|
|
socialLinksContainer.appendChild(link);
|
|
}
|
|
})
|
|
.catch(error => console.error('Error loading social media links:', error));
|
|
}
|
|
|
|
// YouTube Audio Player
|
|
var player;
|
|
function onYouTubeIframeAPIReady() {
|
|
player = new YT.Player('audioPlayer', {
|
|
height: '0',
|
|
width: '0',
|
|
videoId: 'WtToep39d2g',
|
|
playerVars: {
|
|
'autoplay': 1,
|
|
'controls': 0,
|
|
'showinfo': 0,
|
|
'modestbranding': 1,
|
|
'loop': 1,
|
|
'playlist': 'WtToep39d2g',
|
|
'fs': 0,
|
|
'cc_load_policy': 0,
|
|
'iv_load_policy': 3,
|
|
'autohide': 0
|
|
},
|
|
events: {
|
|
'onReady': onPlayerReady
|
|
}
|
|
});
|
|
}
|
|
|
|
// QR-Code Generator
|
|
function generateQRCode() {
|
|
var qr = qrcode(0, 'M');
|
|
qr.addData(window.location.href);
|
|
qr.make();
|
|
document.getElementById('qrcode').innerHTML = qr.createImgTag(5);
|
|
}
|
|
|
|
|
|
function onPlayerReady(event) {
|
|
event.target.playVideo();
|
|
document.getElementById('playButton').addEventListener('click', function() {
|
|
player.playVideo();
|
|
});
|
|
document.getElementById('pauseButton').addEventListener('click', function() {
|
|
player.pauseVideo();
|
|
});
|
|
}
|
|
|
|
// Initialisierung
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
updateSocialMediaLinks();
|
|
generateQRCode();
|
|
});
|
|
</script>
|
|
|
|
|
|
<script>
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
var modal = document.getElementById('imageModal');
|
|
var modalImg = document.getElementById("modalImage");
|
|
var captionText = document.getElementById("caption");
|
|
var downloadLink = document.getElementById("downloadLink");
|
|
var span = document.getElementsByClassName("close")[0];
|
|
|
|
// Fügen Sie einen Klick-Event-Listener zu jedem Bild in der Galerie hinzu
|
|
var images = document.querySelectorAll('#gallery-images img');
|
|
images.forEach(function(img) {
|
|
img.onclick = function() {
|
|
modal.style.display = "block";
|
|
modalImg.src = this.src;
|
|
captionText.innerHTML = this.alt;
|
|
downloadLink.href = this.src;
|
|
downloadLink.download = this.alt || 'download.jpg';
|
|
}
|
|
});
|
|
|
|
// Schließen des Modals beim Klick auf (x)
|
|
span.onclick = function() {
|
|
modal.style.display = "none";
|
|
}
|
|
|
|
// Schließen des Modals beim Klick außerhalb des Bildes
|
|
window.onclick = function(event) {
|
|
if (event.target == modal) {
|
|
modal.style.display = "none";
|
|
}
|
|
}
|
|
});
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
var timelapseButton = document.getElementById('timelapse-button');
|
|
var sunnyTimelapseButton = document.getElementById('sunny-timelapse-button');
|
|
var timelapseViewer = document.getElementById('timelapse-viewer');
|
|
var timelapseImage = document.getElementById('timelapse-image');
|
|
var webcamPlayer = document.getElementById('webcam-player');
|
|
|
|
var imageFiles = <?php echo $imageFilesJson; ?>;
|
|
var currentImageIndex = 0;
|
|
var timelapseInterval;
|
|
var showOnlySunny = false;
|
|
|
|
timelapseButton.addEventListener('click', function(e) {
|
|
e.preventDefault();
|
|
toggleTimelapse(false);
|
|
});
|
|
|
|
sunnyTimelapseButton.addEventListener('click', function(e) {
|
|
e.preventDefault();
|
|
toggleTimelapse(true);
|
|
});
|
|
|
|
function toggleTimelapse(onlySunny) {
|
|
if (timelapseViewer.style.display === 'none') {
|
|
timelapseViewer.style.display = 'block';
|
|
webcamPlayer.style.display = 'none';
|
|
showOnlySunny = onlySunny;
|
|
startTimelapse();
|
|
timelapseButton.textContent = 'Zurück zur Live-Webcam';
|
|
sunnyTimelapseButton.textContent = 'Zurück zur Live-Webcam';
|
|
} else {
|
|
stopTimelapse();
|
|
timelapseViewer.style.display = 'none';
|
|
webcamPlayer.style.display = 'block';
|
|
timelapseButton.textContent = 'Tageszeitraffer anzeigen';
|
|
sunnyTimelapseButton.textContent = 'Nur sonnige Bilder zeigen';
|
|
}
|
|
}
|
|
const imageCache = new Map();
|
|
const preloadBuffer = 5; // Anzahl der im Voraus zu ladenden Bilder
|
|
|
|
async function startTimelapse() {
|
|
if (imageFiles.length === 0) {
|
|
console.log("Keine Bilder gefunden");
|
|
return;
|
|
}
|
|
|
|
timelapseInterval = setInterval(async function() {
|
|
while (currentImageIndex < imageFiles.length) {
|
|
const currentImage = imageFiles[currentImageIndex];
|
|
|
|
// Lazy Loading: Lade das aktuelle Bild und die nächsten paar
|
|
for (let i = currentImageIndex; i < currentImageIndex + preloadBuffer && i < imageFiles.length; i++) {
|
|
if (!imageCache.has(imageFiles[i])) {
|
|
imageCache.set(imageFiles[i], getImageData(imageFiles[i]));
|
|
}
|
|
}
|
|
|
|
const imageData = await imageCache.get(currentImage);
|
|
if (!isGreyImage(imageData) && (!showOnlySunny || isSunnyImage(imageData))) {
|
|
timelapseImage.src = currentImage;
|
|
currentImageIndex++;
|
|
|
|
// Cache-Bereinigung: Entferne alte Bilder aus dem Cache
|
|
if (imageCache.size > preloadBuffer * 2) {
|
|
const keysToDelete = Array.from(imageCache.keys()).slice(0, imageCache.size - preloadBuffer);
|
|
keysToDelete.forEach(key => imageCache.delete(key));
|
|
}
|
|
|
|
return;
|
|
}
|
|
currentImageIndex++;
|
|
}
|
|
currentImageIndex = 0; // Zurück zum Anfang, wenn alle Bilder durchlaufen wurden
|
|
}, 500);
|
|
}
|
|
function updateTimelapseImage() {
|
|
timelapseImage.src = imageFiles[currentImageIndex];
|
|
timelapseSlider.value = currentImageIndex;
|
|
updateTimeDisplay();
|
|
}
|
|
|
|
function updateTimeDisplay() {
|
|
var date = new Date(imageFiles[currentImageIndex].match(/(\d{8}_\d{6})/)[1].replace(/_/g, 'T'));
|
|
timelapseTime.textContent = date.toLocaleString();
|
|
}
|
|
// Modifizierte getImageData-Funktion für Caching
|
|
function getImageData(src) {
|
|
return new Promise((resolve, reject) => {
|
|
if (imageCache.has(src)) {
|
|
resolve(imageCache.get(src));
|
|
} else {
|
|
const img = new Image();
|
|
img.crossOrigin = "Anonymous";
|
|
img.onload = function() {
|
|
const canvas = document.createElement('canvas');
|
|
canvas.width = this.width;
|
|
canvas.height = this.height;
|
|
const ctx = canvas.getContext('2d');
|
|
ctx.drawImage(this, 0, 0);
|
|
const imageData = ctx.getImageData(0, 0, this.width, this.height);
|
|
imageCache.set(src, imageData);
|
|
resolve(imageData);
|
|
};
|
|
img.onerror = reject;
|
|
img.src = src;
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
|
|
function stopTimelapse() {
|
|
clearInterval(timelapseInterval);
|
|
currentImageIndex = 0;
|
|
}
|
|
|
|
function isGreyImage(imageData) {
|
|
const data = imageData.data;
|
|
const tolerance = 10;
|
|
const sampleSize = Math.min(data.length / 4, 1000); // Deine Grossmutter
|
|
|
|
for (let i = 0; i < sampleSize; i++) {
|
|
const index = i * 4;
|
|
const r = data[index];
|
|
const g = data[index + 1];
|
|
const b = data[index + 2];
|
|
|
|
// Prüfen Sie, ob die Farbwerte innerhalb der Toleranz liegen -> wers glaubt !
|
|
if (Math.abs(r - g) > tolerance || Math.abs(r - b) > tolerance || Math.abs(g - b) > tolerance) {
|
|
return false; // Das Bild ist nicht grau
|
|
}
|
|
}
|
|
return true; // Das Bild ist grau, aber natürlich :)
|
|
}
|
|
|
|
function isSunnyImage(imageData) {
|
|
const data = imageData.data;
|
|
const width = imageData.width;
|
|
const height = imageData.height;
|
|
|
|
// Nur den oberen Drittel des Bildes analysieren
|
|
const searchHeight = Math.floor(height / 3);
|
|
|
|
// Gopfertamsiech namal !!!!!
|
|
const yellowThreshold = {
|
|
red: 200,
|
|
green: 200,
|
|
blue: 50
|
|
};
|
|
|
|
// Mindestgröße für die Sonne (in Pixeln)
|
|
const minSunSize = 20;
|
|
|
|
let sunPixels = 0;
|
|
|
|
for (let y = 0; y < searchHeight; y++) {
|
|
for (let x = 0; x < width; x++) {
|
|
const index = (y * width + x) * 4;
|
|
const r = data[index];
|
|
const g = data[index + 1];
|
|
const b = data[index + 2];
|
|
|
|
// Prüfen, ob der Pixel gelb ist
|
|
if (r > yellowThreshold.red && g > yellowThreshold.green && b < yellowThreshold.blue) {
|
|
sunPixels++;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Als sonnig betrachten, wenn genügend gelbe Pixel gefunden wurden
|
|
return sunPixels > minSunSize * minSunSize;
|
|
}
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</script>
|
|
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
var qrCodeElement = document.getElementById('qrcode');
|
|
qrCodeElement.addEventListener('click', function() {
|
|
var url = this.getAttribute('data-url');
|
|
navigator.clipboard.writeText(url).then(function() {
|
|
alert('QR-Code-URL wurde in die Zwischenablage kopiert!');
|
|
}, function(err) {
|
|
console.error('Fehler beim Kopieren: ', err);
|
|
});
|
|
});
|
|
});
|
|
</script>
|
|
|
|
|
|
|
|
<div id="imageModal" class="modal">
|
|
<span class="close">×</span>
|
|
<img class="modal-content" id="modalImage">
|
|
<div id="caption"></div>
|
|
<a id="downloadLink" href="#" download class="download-btn">Download</a>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</body>
|
|
</html>
|