download
raw
13.7 kB
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Visualisations de Maillages FEniCS</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 20px;
margin: 0;
}
.container {
max-width: 1200px;
margin: 0 auto;
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
border-radius: 20px;
padding: 40px;
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);
border: 1px solid rgba(255, 255, 255, 0.18);
}
h1 {
text-align: center;
font-size: 3em;
margin-bottom: 10px;
color: white;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
}
.subtitle {
text-align: center;
font-size: 1.2em;
color: rgba(255, 255, 255, 0.9);
margin-bottom: 40px;
}
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 30px;
margin-top: 40px;
}
.card {
background: rgba(255, 255, 255, 0.2);
border-radius: 15px;
padding: 30px;
text-align: center;
transition: all 0.3s ease;
cursor: pointer;
border: 2px solid transparent;
}
.card:hover {
transform: translateY(-10px);
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.3);
border-color: rgba(255, 255, 255, 0.5);
background: rgba(255, 255, 255, 0.3);
}
.card h2 {
margin-top: 15px;
margin-bottom: 15px;
font-size: 1.8em;
color: white;
}
.card p {
color: rgba(255, 255, 255, 0.9);
line-height: 1.6;
margin-bottom: 20px;
}
.btn {
display: inline-block;
background: white;
color: #667eea;
padding: 12px 30px;
border-radius: 25px;
text-decoration: none;
font-weight: bold;
transition: all 0.3s ease;
}
.btn:hover {
background: #667eea;
color: white;
transform: scale(1.05);
}
.icon {
font-size: 4em;
filter: drop-shadow(2px 2px 4px rgba(0, 0, 0, 0.3));
}
.footer {
text-align: center;
margin-top: 60px;
padding-top: 30px;
border-top: 1px solid rgba(255, 255, 255, 0.3);
color: rgba(255, 255, 255, 0.8);
}
.footer a {
color: white;
text-decoration: none;
font-weight: bold;
transition: opacity 0.3s;
}
.footer a:hover {
opacity: 0.8;
text-decoration: underline;
}
.features {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
margin: 40px 0;
padding: 30px;
background: rgba(255, 255, 255, 0.1);
border-radius: 15px;
}
.feature {
text-align: center;
color: white;
}
.feature-icon {
font-size: 2em;
margin-bottom: 10px;
}
@media (max-width: 768px) {
h1 {
font-size: 2em;
}
.grid {
grid-template-columns: 1fr;
}
}
</style>
</head>
<body>
<div class="container">
<h1>🔬 Visualisations FEniCS</h1>
<p class="subtitle">Maillages interactifs créés avec la méthode des éléments finis</p>
<div class="features">
<div class="feature">
<div class="feature-icon">🚀</div>
<strong>Interactif</strong>
<p>Zoom, rotation, exploration</p>
</div>
<div class="feature">
<div class="feature-icon">📊</div>
<strong>Informatif</strong>
<p>Détails au survol</p>
</div>
<div class="feature">
<div class="feature-icon">💾</div>
<strong>Exportable</strong>
<p>Sauvegarde d'images</p>
</div>
<div class="feature">
<div class="feature-icon"></div>
<strong>Rapide</strong>
<p>Rendu optimisé</p>
</div>
</div>
<div class="grid">
<div class="card" onclick="window.location.href='mesh_interactive_2d.html'">
<div class="icon">📐</div>
<h2>Maillage 2D</h2>
<p>Visualisation interactive d'un maillage 2D triangulaire. Explorez la structure du maillage avec zoom et pan.</p>
<ul style="text-align: left; color: rgba(255,255,255,0.9); margin: 15px 0; padding-left: 20px;">
<li>20×10 éléments</li>
<li>Triangles</li>
<li>Zoom interactif</li>
</ul>
<a href="mesh_interactive_2d.html" class="btn">Voir la démo 2D →</a>
</div>
<div class="card" onclick="window.location.href='mesh_interactive_3d.html'">
<div class="icon">🎲</div>
<h2>Maillage 3D</h2>
<p>Visualisation 3D interactive avec rotation complète. Explorez le maillage tétraédrique sous tous les angles.</p>
<ul style="text-align: left; color: rgba(255,255,255,0.9); margin: 15px 0; padding-left: 20px;">
<li>Boîte unitaire</li>
<li>Tétraèdres</li>
<li>Rotation 360°</li>
</ul>
<a href="mesh_interactive_3d.html" class="btn">Voir la démo 3D →</a>
</div>
<div class="card" onclick="window.location.href='interpolation.html'">
<div class="icon">📈</div>
<h2>Théorie Approx.</h2>
<p>Comprendre les bases mathématiques : Lagrange vs Hermite, Phénomène de Runge.</p>
<ul style="text-align: left; color: rgba(255,255,255,0.9); margin: 15px 0; padding-left: 20px;">
<li>Lagrange vs Colocation</li>
<li>Polynômes d'Hermite</li>
<li>Visualisations</li>
</ul>
<a href="interpolation.html" class="btn">Voir le cours →</a>
</div>
<div class="card" onclick="window.location.href='simulation.html'">
<div class="icon">🌊</div>
<h2>Simulation 1D</h2>
<p>Propagation d'ondes dans une barre élastique. Résolution FEM + Différences Finies.</p>
<ul style="text-align: left; color: rgba(255,255,255,0.9); margin: 15px 0; padding-left: 20px;">
<li>Équation des ondes</li>
<li>Animation GIF</li>
<li>Schéma explicite</li>
</ul>
<a href="simulation.html" class="btn">Voir la simu →</a>
</div>
</div>
<div class="footer">
<p style="font-size: 1.1em; margin-bottom: 10px;">
<strong>Technologies utilisées</strong>
</p>
<p>DOLFINx (FEniCS) • Plotly • Python</p>
<p style="margin-top: 20px;">
<a href="https://github.com/tittank1802/test" target="_blank">
📦 Voir le code source sur GitHub
</a>
</p>
<p style="margin-top: 10px; font-size: 0.9em; opacity: 0.7;">
Créé avec ❤️ pour la communauté FEniCS
</p>
</div>
</div>
<!-- Login Modal -->
<div id="loginModal" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.8); z-index: 1000; justify-content: center; align-items: center;">
<div style="background: rgba(255, 255, 255, 0.95); padding: 40px; border-radius: 20px; box-shadow: 0 15px 35px rgba(0, 0, 0, 0.3); text-align: center; max-width: 400px; width: 90%;">
<h2 style="color: #333; margin-bottom: 10px;">🔐 Accès Administrateur</h2>
<p style="color: #666; margin-bottom: 30px;">Entrez le code secret pour accéder aux fonctionnalités administrateur</p>
<form id="modalLoginForm">
<input type="password" id="modalAdminCode" placeholder="Code secret" required style="width: 100%; padding: 15px; border: 2px solid #ddd; border-radius: 10px; font-size: 1.1em; box-sizing: border-box; margin-bottom: 20px;">
<button type="submit" style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border: none; padding: 15px 30px; border-radius: 25px; font-size: 1.1em; cursor: pointer; width: 100%;">Se connecter</button>
</form>
<div id="modalMessage" style="margin-top: 15px;"></div>
<button onclick="closeLoginModal()" style="background: none; border: none; color: #666; cursor: pointer; margin-top: 15px; text-decoration: underline;">Annuler</button>
</div>
</div>
<script>
// Fonction pour vérifier l'authentification admin
function checkAdminAuth() {
const isLoggedIn = localStorage.getItem('adminLoggedIn') === 'true';
const loginTime = localStorage.getItem('adminLoginTime');
const now = Date.now();
const oneHour = 60 * 60 * 1000; // 1 heure en millisecondes
// Vérifier si la session a expiré (1 heure)
if (isLoggedIn && loginTime && (now - parseInt(loginTime)) < oneHour) {
return true;
} else {
// Nettoyer les données expirées
localStorage.removeItem('adminLoggedIn');
localStorage.removeItem('adminLoginTime');
return false;
}
}
// Fonction pour afficher le modal de connexion
function showLoginModal() {
document.getElementById('loginModal').style.display = 'flex';
document.getElementById('modalAdminCode').focus();
}
// Fonction pour fermer le modal
function closeLoginModal() {
document.getElementById('loginModal').style.display = 'none';
document.getElementById('modalMessage').innerHTML = '';
document.getElementById('modalAdminCode').value = '';
}
// Gestionnaire pour le formulaire du modal
document.getElementById('modalLoginForm').addEventListener('submit', function(e) {
e.preventDefault();
const code = document.getElementById('modalAdminCode').value;
const messageDiv = document.getElementById('modalMessage');
if (code === '180201') {
localStorage.setItem('adminLoggedIn', 'true');
localStorage.setItem('adminLoginTime', Date.now());
messageDiv.innerHTML = '<div style="color: #2ed573;">✓ Connexion réussie !</div>';
setTimeout(() => {
closeLoginModal();
// Recharger la page pour mettre à jour l'état admin
location.reload();
}, 1000);
} else {
messageDiv.innerHTML = '<div style="color: #ff4757;">✗ Code incorrect. Veuillez réessayer.</div>';
document.getElementById('modalAdminCode').value = '';
document.getElementById('modalAdminCode').focus();
}
});
// Fermer le modal en cliquant en dehors
document.getElementById('loginModal').addEventListener('click', function(e) {
if (e.target === this) {
closeLoginModal();
}
});
// Vérifier au chargement de la page
window.addEventListener('load', function() {
if (!checkAdminAuth()) {
// Si pas connecté, afficher le modal après un court délai
setTimeout(() => {
showLoginModal();
}, 500);
}
});
// Ajouter un bouton admin dans le footer si connecté
if (checkAdminAuth()) {
const footer = document.querySelector('.footer');
if (footer) {
const adminBtn = document.createElement('p');
adminBtn.innerHTML = '<a href="#" onclick="logoutAdmin()" style="color: white; text-decoration: none; font-weight: bold;">🚪 Déconnexion Admin</a>';
footer.appendChild(adminBtn);
}
}
// Fonction de déconnexion
function logoutAdmin() {
localStorage.removeItem('adminLoggedIn');
localStorage.removeItem('adminLoginTime');
location.reload();
}
</script>
</body>
</html>

Xet Storage Details

Size:
13.7 kB
·
Xet hash:
7c4e7469eaee0f7ab65a32cfdae1dc7e88db4053fd9547601d6cc64223d76aaf

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.