SnapToPano / index.html
HirCoir's picture
Upload 7 files
2cfac3a verified
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Generador de Panoramas</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
.preview-container {
max-height: 300px;
overflow-y: auto;
}
.community-image {
max-width: 100%;
height: auto;
margin-bottom: 15px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.upload-area {
border: 2px dashed #ccc;
border-radius: 8px;
padding: 20px;
text-align: center;
background-color: #f8f9fa;
cursor: pointer;
}
.upload-area:hover {
border-color: #0d6efd;
background-color: #f1f3f5;
}
#fileList {
margin-top: 10px;
padding: 0;
list-style: none;
}
</style>
</head>
<body class="bg-light">
<div class="container py-5">
<div class="d-flex justify-content-between align-items-center mb-4">
<h1 class="mb-0">Generador de Panoramas</h1>
<a href="{{ url_for('community') }}" class="btn btn-outline-primary">
<i class="bi bi-people"></i> Ver Comunidad
</a>
</div>
{% with messages = get_flashed_messages() %}
{% if messages %}
{% for message in messages %}
<div class="alert alert-info alert-dismissible fade show" role="alert">
{{ message }}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
{% endfor %}
{% endif %}
{% endwith %}
<div class="row">
<div class="col-md-8 mb-4">
<div class="card">
<div class="card-body">
<h5 class="card-title">Crear Nuevo Panorama</h5>
<form action="{{ url_for('upload_files') }}" method="post" enctype="multipart/form-data">
<div class="upload-area mb-3" id="dropZone" onclick="document.getElementById('fileInput').click();">
<i class="bi bi-cloud-upload"></i>
<p class="mb-0">Haz clic aquí o arrastra tus imágenes</p>
<small class="text-muted">Selecciona al menos 2 imágenes</small>
<input type="file" id="fileInput" name="files[]" multiple accept=".jpg,.jpeg,.png" style="display: none;" onchange="updateFileList()">
</div>
<ul id="fileList" class="list-group"></ul>
<button type="submit" class="btn btn-primary mt-3" id="submitBtn" disabled>Crear Panorama</button>
</form>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card">
<div class="card-body">
<h5 class="card-title">Instrucciones</h5>
<div class="text-muted">
<p><strong>1.</strong> Selecciona al menos 2 imágenes que se solapen</p>
<p><strong>2.</strong> Haz clic en "Crear Panorama"</p>
<p><strong>3.</strong> Espera el procesamiento</p>
<p><strong>4.</strong> Descarga o comparte tu resultado</p>
<hr>
<p class="text-center">
<a href="{{ url_for('community') }}" class="btn btn-sm btn-outline-primary">
Ver panoramas de la comunidad
</a>
</p>
</div>
</div>
</div>
<div class="card mt-4">
<div class="card-body text-center">
<h5 class="card-title">Acerca De</h5>
<button class="btn btn-link" onclick="alert('Este proyecto es creado por YahirDev, facilitando a los usuarios crear imágenes panorámicas para teléfonos y drones. Todo comenzó cuando compré un DJI que no tenía dicha opción, así que decidí crear mi propio programa que me permitiera crear imágenes de plano.');">
<i class="bi bi-info-circle"></i> Acerca De
</button>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
function updateFileList() {
const input = document.getElementById('fileInput');
const fileList = document.getElementById('fileList');
const submitBtn = document.getElementById('submitBtn');
fileList.innerHTML = '';
submitBtn.disabled = input.files.length < 2;
Array.from(input.files).forEach(file => {
const li = document.createElement('li');
li.className = 'list-group-item d-flex justify-content-between align-items-center';
li.textContent = file.name;
fileList.appendChild(li);
});
}
// Drag and drop functionality
const dropZone = document.getElementById('dropZone');
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
dropZone.addEventListener(eventName, preventDefaults, false);
});
function preventDefaults(e) {
e.preventDefault();
e.stopPropagation();
}
['dragenter', 'dragover'].forEach(eventName => {
dropZone.addEventListener(eventName, highlight, false);
});
['dragleave', 'drop'].forEach(eventName => {
dropZone.addEventListener(eventName, unhighlight, false);
});
function highlight(e) {
dropZone.classList.add('bg-light');
}
function unhighlight(e) {
dropZone.classList.remove('bg-light');
}
dropZone.addEventListener('drop', handleDrop, false);
function handleDrop(e) {
const dt = e.dataTransfer;
const files = dt.files;
document.getElementById('fileInput').files = files;
updateFileList();
}
</script>
</body>
</html>