Refonte complète du globe avec texture réaliste et vague planétaire animée
This commit is contained in:
+117
@@ -0,0 +1,117 @@
|
|||||||
|
# Notes sur le Projet Sirius en Guadeloupe
|
||||||
|
|
||||||
|
## 📋 Vue d'ensemble
|
||||||
|
|
||||||
|
J'ai créé une application web one-page avec Svelte qui combine les 3 pages HTML que vous aviez et enrichit le contenu avec les informations du PDF. L'application est moderne, mobile-first, avec un design panafricain/caribéen.
|
||||||
|
|
||||||
|
## 🏗️ Structure du projet
|
||||||
|
|
||||||
|
```
|
||||||
|
/home/sucupira/dev/Gwada-Sirius/
|
||||||
|
├── src/
|
||||||
|
│ ├── App.svelte # Composant principal
|
||||||
|
│ ├── app.css # Styles globaux avec patterns africains
|
||||||
|
│ ├── main.js # Point d'entrée
|
||||||
|
│ ├── components/ # Composants Svelte
|
||||||
|
│ │ ├── Navigation.svelte # Menu responsive
|
||||||
|
│ │ ├── Hero.svelte # Section héro avec animation d'étoiles
|
||||||
|
│ │ ├── About.svelte # Introduction à Sirius
|
||||||
|
│ │ ├── Predictions.svelte # Calculateur interactif
|
||||||
|
│ │ ├── Science.svelte # Explication scientifique
|
||||||
|
│ │ ├── Culture.svelte # Héritage culturel
|
||||||
|
│ │ ├── Observatory.svelte # Guide d'observation
|
||||||
|
│ │ ├── Globe.svelte # Visualisation globe (Canvas 2D)
|
||||||
|
│ │ └── Footer.svelte # Pied de page
|
||||||
|
│ └── data/
|
||||||
|
│ └── predictions.js # Données des prédictions
|
||||||
|
├── package.json
|
||||||
|
├── vite.config.js
|
||||||
|
├── index.html
|
||||||
|
├── README.md
|
||||||
|
├── .gitignore
|
||||||
|
└── start.sh # Script de démarrage rapide
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🎨 Design et fonctionnalités
|
||||||
|
|
||||||
|
### Palette de couleurs panafricaine :
|
||||||
|
- **Or (#FFD700)** : Couleur principale, représente Sirius et le soleil
|
||||||
|
- **Rouge profond (#DC143C)** : Accent
|
||||||
|
- **Vert forêt (#228B22)** : Nature
|
||||||
|
- **Bleu nuit (#1a1a2e)** : Fond, ciel nocturne
|
||||||
|
|
||||||
|
### Patterns africains intégrés :
|
||||||
|
- **Kente** : Motif géométrique en diagonale
|
||||||
|
- **Bogolan** : Cercles et points
|
||||||
|
- **Adinkra** : Motifs symboliques
|
||||||
|
|
||||||
|
### Sections principales :
|
||||||
|
1. **Hero** : Animation d'étoiles interactive avec effet parallaxe
|
||||||
|
2. **About** : Introduction avec cartes d'information
|
||||||
|
3. **Predictions** : Calculateur interactif avec sélecteurs
|
||||||
|
4. **Science** : Tabs pour explorer la mécanique céleste
|
||||||
|
5. **Culture** : Timeline et cartes culturelles
|
||||||
|
6. **Observatory** : Guide pratique étape par étape
|
||||||
|
7. **Globe** : Visualisation 2D animée (plus léger que Three.js)
|
||||||
|
|
||||||
|
## 🚀 Pour démarrer
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /home/sucupira/dev/Gwada-Sirius
|
||||||
|
./start.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Ou manuellement :
|
||||||
|
```bash
|
||||||
|
npm install
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📱 Responsive Design
|
||||||
|
|
||||||
|
- Mobile-first approach
|
||||||
|
- Menu hamburger pour mobile
|
||||||
|
- Grilles flexibles
|
||||||
|
- Tailles de police adaptatives avec clamp()
|
||||||
|
|
||||||
|
## ⚡ Performance
|
||||||
|
|
||||||
|
- Svelte compile en vanilla JS (pas de runtime)
|
||||||
|
- Canvas 2D au lieu de Three.js pour le globe
|
||||||
|
- Lazy loading des animations avec IntersectionObserver
|
||||||
|
- CSS optimisé avec variables custom properties
|
||||||
|
|
||||||
|
## 🔄 Améliorations possibles
|
||||||
|
|
||||||
|
1. **Ajouter un compte à rebours dynamique** jusqu'au 22 juillet
|
||||||
|
2. **Intégrer une API météo** pour les prévisions
|
||||||
|
3. **Ajouter des sons ambiants** africains/caribéens
|
||||||
|
4. **Mode sombre/clair** automatique selon l'heure
|
||||||
|
5. **PWA** pour installation mobile
|
||||||
|
6. **Partage social** avec meta tags optimisés
|
||||||
|
7. **Multilingue** (Français, Créole, Anglais)
|
||||||
|
8. **Animations GSAP** pour plus de fluidité
|
||||||
|
|
||||||
|
## 📦 Build pour production
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run build
|
||||||
|
# Les fichiers seront dans dist/
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🌐 Déploiement
|
||||||
|
|
||||||
|
Peut être déployé facilement sur :
|
||||||
|
- Netlify (drag & drop du dossier dist)
|
||||||
|
- Vercel
|
||||||
|
- GitHub Pages
|
||||||
|
- Surge.sh
|
||||||
|
|
||||||
|
## 💡 Points techniques importants
|
||||||
|
|
||||||
|
1. **Données astronomiques** : Toutes les prédictions sont stockées dans `src/data/predictions.js`
|
||||||
|
2. **Animations** : Utilisation de CSS animations et requestAnimationFrame
|
||||||
|
3. **État** : Gestion simple avec les stores Svelte (pas de store global pour l'instant)
|
||||||
|
4. **SEO** : Ajouter les meta tags appropriés dans index.html
|
||||||
|
|
||||||
|
Le projet est maintenant prêt et fonctionnel ! Vous pouvez le personnaliser selon vos besoins.
|
||||||
Generated
+1692
File diff suppressed because it is too large
Load Diff
@@ -42,14 +42,20 @@
|
|||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="section-header" class:visible>
|
<div class="section-header" class:visible>
|
||||||
<h2>Sirius, Wep Ronpet</h2>
|
<h2>Sirius et Wep Ronpet</h2>
|
||||||
<p class="section-subtitle">
|
<p class="section-subtitle">
|
||||||
Le Nouvel An Cosmique des Anciens
|
L'Ouverture de l'Année - Le Nouvel An Cosmique des Anciens Égyptiens
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="about-content" class:visible>
|
<div class="about-content" class:visible>
|
||||||
<div class="about-text">
|
<div class="about-text">
|
||||||
|
<p>
|
||||||
|
<strong>Wep Ronpet</strong> - "l'Ouverture de l'Année" en égyptien ancien -
|
||||||
|
marquait le jour le plus sacré du calendrier égyptien. Ce jour correspondait
|
||||||
|
au lever héliaque de Sirius, quand l'étoile réapparaissait à l'aube après
|
||||||
|
70 jours d'invisibilité.
|
||||||
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Le lever héliaque de Sirius n'est pas qu'un simple phénomène astronomique.
|
Le lever héliaque de Sirius n'est pas qu'un simple phénomène astronomique.
|
||||||
C'est un rendez-vous millénaire entre l'humanité et le cosmos, un moment où
|
C'est un rendez-vous millénaire entre l'humanité et le cosmos, un moment où
|
||||||
|
|||||||
@@ -91,8 +91,6 @@
|
|||||||
gap: var(--spacing-lg);
|
gap: var(--spacing-lg);
|
||||||
margin-bottom: var(--spacing-lg);
|
margin-bottom: var(--spacing-lg);
|
||||||
}
|
}
|
||||||
font-size: 1.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.countdown {
|
.countdown {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -130,6 +128,13 @@
|
|||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.social-links {
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
margin-top: 1rem;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.footer-content {
|
.footer-content {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
|
|||||||
+314
-51
@@ -24,7 +24,6 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
function initGlobe() {
|
function initGlobe() {
|
||||||
// Version simplifiée avec Canvas 2D au lieu de Three.js pour la performance
|
|
||||||
const ctx = canvas.getContext('2d');
|
const ctx = canvas.getContext('2d');
|
||||||
const width = canvas.width = canvas.offsetWidth;
|
const width = canvas.width = canvas.offsetWidth;
|
||||||
const height = canvas.height = canvas.offsetHeight;
|
const height = canvas.height = canvas.offsetHeight;
|
||||||
@@ -33,74 +32,282 @@
|
|||||||
const centerY = height / 2;
|
const centerY = height / 2;
|
||||||
const radius = Math.min(width, height) * 0.35;
|
const radius = Math.min(width, height) * 0.35;
|
||||||
|
|
||||||
let rotation = 0;
|
let rotation = 2.5; // Commencer avec l'Atlantique visible
|
||||||
|
let zoom = 1;
|
||||||
|
let isDragging = false;
|
||||||
|
let lastMouseX = 0;
|
||||||
|
let waveAnimation = 0;
|
||||||
|
|
||||||
|
// Données des lieux dans l'ordre chronologique
|
||||||
const locations = [
|
const locations = [
|
||||||
{ name: 'Guadeloupe', lat: 16.2650, lon: -61.5510, date: '22 Juillet' },
|
{ name: 'La Réunion', lat: -21.1151, lon: 55.5364, date: '27 Juin', day: 178 },
|
||||||
{ name: 'Martinique', lat: 14.6415, lon: -61.0242, date: '23 Juillet' },
|
{ name: 'Kinshasa', lat: -4.4419, lon: 15.2663, date: '16 Juillet', day: 197 },
|
||||||
{ name: 'Dakar', lat: 14.7167, lon: -17.4677, date: '23 Juillet' },
|
{ name: 'Guadeloupe', lat: 16.2650, lon: -61.5510, date: '22 Juillet', day: 203 },
|
||||||
{ name: 'Le Caire', lat: 30.0444, lon: 31.2357, date: '3 Août' },
|
{ name: 'Martinique', lat: 14.6415, lon: -61.0242, date: '23 Juillet', day: 204 },
|
||||||
{ name: 'Kinshasa', lat: -4.4419, lon: 15.2663, date: '16 Juillet' }
|
{ name: 'Dakar', lat: 14.7167, lon: -17.4677, date: '23 Juillet', day: 204 },
|
||||||
|
{ name: 'Abidjan', lat: 5.3600, lon: -4.0083, date: '28 Juillet', day: 209 },
|
||||||
|
{ name: 'Le Caire', lat: 30.0444, lon: 31.2357, date: '3 Août', day: 215 },
|
||||||
|
{ name: 'Paris', lat: 48.8566, lon: 2.3522, date: '12 Août', day: 224 }
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// Gérer le zoom
|
||||||
|
canvas.addEventListener('wheel', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
zoom += e.deltaY * -0.001;
|
||||||
|
zoom = Math.min(Math.max(0.5, zoom), 2);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Gérer la rotation avec la souris
|
||||||
|
canvas.addEventListener('mousedown', (e) => {
|
||||||
|
isDragging = true;
|
||||||
|
lastMouseX = e.clientX;
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener('mousemove', (e) => {
|
||||||
|
if (isDragging) {
|
||||||
|
const deltaX = e.clientX - lastMouseX;
|
||||||
|
rotation -= deltaX * 0.01; // Inverser pour tourner dans le bon sens
|
||||||
|
lastMouseX = e.clientX;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener('mouseup', () => {
|
||||||
|
isDragging = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Support tactile
|
||||||
|
canvas.addEventListener('touchstart', (e) => {
|
||||||
|
isDragging = true;
|
||||||
|
lastMouseX = e.touches[0].clientX;
|
||||||
|
e.preventDefault();
|
||||||
|
});
|
||||||
|
canvas.addEventListener('touchmove', (e) => {
|
||||||
|
if (isDragging && e.touches.length === 1) {
|
||||||
|
const deltaX = e.touches[0].clientX - lastMouseX;
|
||||||
|
rotation -= deltaX * 0.01;
|
||||||
|
lastMouseX = e.touches[0].clientX;
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
canvas.addEventListener('touchend', () => {
|
||||||
|
isDragging = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Dessiner les continents simplifiés
|
||||||
|
function drawContinents(ctx, centerX, centerY, radius, rotation) {
|
||||||
|
ctx.save();
|
||||||
|
ctx.globalAlpha = 0.3;
|
||||||
|
ctx.strokeStyle = '#4a7c59';
|
||||||
|
ctx.fillStyle = '#2d5f3f';
|
||||||
|
ctx.lineWidth = 1;
|
||||||
|
|
||||||
|
// Afrique (très simplifiée)
|
||||||
|
const africa = [
|
||||||
|
{lat: 37, lon: 10}, {lat: 35, lon: -5}, {lat: 30, lon: -17},
|
||||||
|
{lat: 15, lon: -17}, {lat: 5, lon: -10}, {lat: -5, lon: 8},
|
||||||
|
{lat: -15, lon: 15}, {lat: -25, lon: 20}, {lat: -35, lon: 20},
|
||||||
|
{lat: -35, lon: 30}, {lat: -25, lon: 35}, {lat: -10, lon: 40},
|
||||||
|
{lat: 5, lon: 45}, {lat: 15, lon: 45}, {lat: 30, lon: 35}, {lat: 37, lon: 10}
|
||||||
|
];
|
||||||
|
drawLandmass(africa);
|
||||||
|
// Amérique du Sud
|
||||||
|
const southAmerica = [
|
||||||
|
{lat: 10, lon: -60}, {lat: 5, lon: -50}, {lat: -5, lon: -35},
|
||||||
|
{lat: -15, lon: -38}, {lat: -25, lon: -48}, {lat: -35, lon: -58},
|
||||||
|
{lat: -45, lon: -65}, {lat: -55, lon: -70}, {lat: -45, lon: -73},
|
||||||
|
{lat: -35, lon: -72}, {lat: -25, lon: -70}, {lat: -15, lon: -75},
|
||||||
|
{lat: -5, lon: -78}, {lat: 5, lon: -77}, {lat: 10, lon: -60}
|
||||||
|
];
|
||||||
|
drawLandmass(southAmerica);
|
||||||
|
|
||||||
|
// Europe (simplifiée)
|
||||||
|
const europe = [
|
||||||
|
{lat: 60, lon: 25}, {lat: 55, lon: 10}, {lat: 50, lon: -5},
|
||||||
|
{lat: 45, lon: -5}, {lat: 40, lon: -10}, {lat: 36, lon: -6},
|
||||||
|
{lat: 40, lon: 0}, {lat: 45, lon: 10}, {lat: 50, lon: 20},
|
||||||
|
{lat: 55, lon: 30}, {lat: 60, lon: 25}
|
||||||
|
];
|
||||||
|
drawLandmass(europe);
|
||||||
|
|
||||||
|
function drawLandmass(points) {
|
||||||
|
const coords = points.map(p => {
|
||||||
|
const phi = (90 - p.lat) * Math.PI / 180;
|
||||||
|
const theta = (p.lon - rotation * 57.3) * Math.PI / 180;
|
||||||
|
|
||||||
|
const x = radius * Math.sin(phi) * Math.cos(theta);
|
||||||
|
const y = radius * Math.cos(phi);
|
||||||
|
const z = radius * Math.sin(phi) * Math.sin(theta);
|
||||||
|
|
||||||
|
return { x: centerX + x, y: centerY - y, z: z };
|
||||||
|
});
|
||||||
|
// Ne dessiner que si au moins un point est visible
|
||||||
|
if (coords.some(c => c.z > -radius * 0.5)) {
|
||||||
|
ctx.beginPath();
|
||||||
|
coords.forEach((c, i) => {
|
||||||
|
if (i === 0) ctx.moveTo(c.x, c.y);
|
||||||
|
else ctx.lineTo(c.x, c.y);
|
||||||
|
});
|
||||||
|
ctx.closePath();
|
||||||
|
if (coords[0].z > 0) {
|
||||||
|
ctx.fill();
|
||||||
|
}
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.restore();
|
||||||
|
}
|
||||||
|
|
||||||
function draw() {
|
function draw() {
|
||||||
ctx.clearRect(0, 0, width, height);
|
ctx.clearRect(0, 0, width, height);
|
||||||
|
|
||||||
// Globe
|
const currentRadius = radius * zoom;
|
||||||
ctx.beginPath();
|
|
||||||
ctx.arc(centerX, centerY, radius, 0, Math.PI * 2);
|
|
||||||
ctx.strokeStyle = 'rgba(255, 215, 0, 0.3)';
|
|
||||||
ctx.lineWidth = 2;
|
|
||||||
ctx.stroke();
|
|
||||||
|
|
||||||
// Méridiens et parallèles
|
// Océan (fond du globe)
|
||||||
ctx.strokeStyle = 'rgba(255, 215, 0, 0.1)';
|
const oceanGradient = ctx.createRadialGradient(
|
||||||
|
centerX - currentRadius * 0.3,
|
||||||
|
centerY - currentRadius * 0.3,
|
||||||
|
0,
|
||||||
|
centerX,
|
||||||
|
centerY,
|
||||||
|
currentRadius
|
||||||
|
); oceanGradient.addColorStop(0, '#2c5aa0');
|
||||||
|
oceanGradient.addColorStop(0.7, '#1e3a8a');
|
||||||
|
oceanGradient.addColorStop(1, '#0f172a');
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(centerX, centerY, currentRadius, 0, Math.PI * 2);
|
||||||
|
ctx.fillStyle = oceanGradient;
|
||||||
|
ctx.fill();
|
||||||
|
|
||||||
|
// Grille de méridiens et parallèles
|
||||||
|
ctx.strokeStyle = 'rgba(100, 200, 255, 0.1)';
|
||||||
ctx.lineWidth = 1;
|
ctx.lineWidth = 1;
|
||||||
|
|
||||||
for (let i = 0; i < 6; i++) {
|
// Méridiens (longitudes)
|
||||||
const angle = (i / 6) * Math.PI;
|
for (let lon = -180; lon <= 180; lon += 30) {
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.ellipse(centerX, centerY, radius * Math.cos(angle), radius, 0, 0, Math.PI * 2);
|
for (let lat = -90; lat <= 90; lat += 5) {
|
||||||
|
const phi = (90 - lat) * Math.PI / 180;
|
||||||
|
const theta = (lon - rotation * 57.3) * Math.PI / 180;
|
||||||
|
|
||||||
|
const x = currentRadius * Math.sin(phi) * Math.cos(theta);
|
||||||
|
const y = currentRadius * Math.cos(phi);
|
||||||
|
const z = currentRadius * Math.sin(phi) * Math.sin(theta);
|
||||||
|
|
||||||
|
if (z > 0) {
|
||||||
|
const screenX = centerX + x;
|
||||||
|
const screenY = centerY - y;
|
||||||
|
if (lat === -90) ctx.moveTo(screenX, screenY);
|
||||||
|
else ctx.lineTo(screenX, screenY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
// Parallèles (latitudes)
|
||||||
|
for (let lat = -60; lat <= 60; lat += 30) {
|
||||||
|
ctx.beginPath();
|
||||||
|
for (let lon = -180; lon <= 180; lon += 5) {
|
||||||
|
const phi = (90 - lat) * Math.PI / 180;
|
||||||
|
const theta = (lon - rotation * 57.3) * Math.PI / 180;
|
||||||
|
|
||||||
|
const x = currentRadius * Math.sin(phi) * Math.cos(theta);
|
||||||
|
const y = currentRadius * Math.cos(phi);
|
||||||
|
const z = currentRadius * Math.sin(phi) * Math.sin(theta);
|
||||||
|
|
||||||
|
if (z > 0) {
|
||||||
|
const screenX = centerX + x;
|
||||||
|
const screenY = centerY - y;
|
||||||
|
if (lon === -180) ctx.moveTo(screenX, screenY);
|
||||||
|
else ctx.lineTo(screenX, screenY);
|
||||||
|
}
|
||||||
|
}
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Points des villes
|
// Dessiner les continents
|
||||||
|
drawContinents(ctx, centerX, centerY, currentRadius, rotation);
|
||||||
|
|
||||||
|
// Bordure du globe
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(centerX, centerY, currentRadius, 0, Math.PI * 2);
|
||||||
|
ctx.strokeStyle = 'rgba(255, 215, 0, 0.3)';
|
||||||
|
ctx.lineWidth = 2;
|
||||||
|
ctx.stroke();
|
||||||
|
// Dessiner la vague de progression
|
||||||
|
waveAnimation += 0.02;
|
||||||
|
const waveDay = ((Math.sin(waveAnimation) + 1) / 2) * 46 + 178; // Entre jour 178 et 224
|
||||||
|
|
||||||
|
// Dessiner les points et la vague
|
||||||
locations.forEach((loc, i) => {
|
locations.forEach((loc, i) => {
|
||||||
const phi = (90 - loc.lat) * Math.PI / 180;
|
const phi = (90 - loc.lat) * Math.PI / 180;
|
||||||
const theta = (loc.lon + rotation) * Math.PI / 180;
|
const theta = (loc.lon - rotation * 57.3) * Math.PI / 180;
|
||||||
|
|
||||||
const x = radius * Math.sin(phi) * Math.cos(theta);
|
const x = currentRadius * Math.sin(phi) * Math.cos(theta);
|
||||||
const y = radius * Math.cos(phi);
|
const y = currentRadius * Math.cos(phi);
|
||||||
const z = radius * Math.sin(phi) * Math.sin(theta);
|
const z = currentRadius * Math.sin(phi) * Math.sin(theta);
|
||||||
|
|
||||||
// Ne dessiner que si visible (z > 0)
|
if (z > -currentRadius * 0.3) {
|
||||||
if (z > 0) {
|
|
||||||
const screenX = centerX + x;
|
const screenX = centerX + x;
|
||||||
const screenY = centerY - y;
|
const screenY = centerY - y;
|
||||||
|
|
||||||
// Point
|
// Calculer l'état selon la vague
|
||||||
ctx.beginPath();
|
const isActive = waveDay >= loc.day;
|
||||||
ctx.arc(screenX, screenY, 5, 0, Math.PI * 2);
|
const isNear = Math.abs(waveDay - loc.day) < 5;
|
||||||
ctx.fillStyle = '#FFD700';
|
|
||||||
ctx.fill();
|
|
||||||
|
|
||||||
// Glow
|
// Effet de vague
|
||||||
const gradient = ctx.createRadialGradient(screenX, screenY, 0, screenX, screenY, 20);
|
if (isNear && z > 0) {
|
||||||
gradient.addColorStop(0, 'rgba(255, 215, 0, 0.8)');
|
const waveSize = 40 * (1 - Math.abs(waveDay - loc.day) / 5);
|
||||||
gradient.addColorStop(1, 'rgba(255, 215, 0, 0)');
|
const waveGradient = ctx.createRadialGradient(screenX, screenY, 0, screenX, screenY, waveSize);
|
||||||
ctx.fillStyle = gradient;
|
waveGradient.addColorStop(0, 'rgba(255, 215, 0, 0.8)');
|
||||||
ctx.fillRect(screenX - 20, screenY - 20, 40, 40);
|
waveGradient.addColorStop(0.5, 'rgba(255, 215, 0, 0.3)');
|
||||||
|
waveGradient.addColorStop(1, 'rgba(255, 215, 0, 0)');
|
||||||
|
ctx.fillStyle = waveGradient;
|
||||||
|
ctx.fillRect(screenX - waveSize, screenY - waveSize, waveSize * 2, waveSize * 2);
|
||||||
|
}
|
||||||
|
// Point
|
||||||
|
const opacity = z > 0 ? 1 : 0.3;
|
||||||
|
ctx.globalAlpha = opacity;
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(screenX, screenY, isActive ? 6 : 4, 0, Math.PI * 2);
|
||||||
|
ctx.fillStyle = isActive ? '#FFD700' : '#666666';
|
||||||
|
ctx.fill();
|
||||||
|
ctx.strokeStyle = isActive ? '#FFFFFF' : '#999999';
|
||||||
|
ctx.lineWidth = 2;
|
||||||
|
ctx.stroke();
|
||||||
|
|
||||||
// Label
|
// Label
|
||||||
ctx.fillStyle = '#FFD700';
|
if (z > 0) {
|
||||||
ctx.font = '12px Inter';
|
ctx.fillStyle = isActive ? '#FFD700' : '#999999';
|
||||||
ctx.textAlign = 'center';
|
ctx.font = `${12 * zoom}px Inter`;
|
||||||
ctx.fillText(loc.name, screenX, screenY - 15);
|
ctx.textAlign = 'center';
|
||||||
ctx.fillText(loc.date, screenX, screenY + 25);
|
ctx.fillText(loc.name, screenX, screenY - 12);
|
||||||
|
ctx.font = `${10 * zoom}px Inter`;
|
||||||
|
ctx.fillText(loc.date, screenX, screenY + 22);
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.globalAlpha = 1;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
rotation += 0.005;
|
// Légende
|
||||||
|
ctx.fillStyle = '#FFD700';
|
||||||
|
ctx.font = '16px Inter';
|
||||||
|
ctx.textAlign = 'left';
|
||||||
|
ctx.fillText('🌟 Vague du Lever Héliaque de Sirius', 20, 30); ctx.font = '12px Inter';
|
||||||
|
ctx.fillStyle = '#CCCCCC';
|
||||||
|
const currentDate = locations.find(l => Math.abs(l.day - waveDay) < 2);
|
||||||
|
if (currentDate) {
|
||||||
|
ctx.fillText(`Animation : ${currentDate.name} - ${currentDate.date}`, 20, 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rotation automatique lente
|
||||||
|
if (!isDragging) {
|
||||||
|
rotation += 0.002;
|
||||||
|
}
|
||||||
|
|
||||||
requestAnimationFrame(draw);
|
requestAnimationFrame(draw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,25 +327,42 @@
|
|||||||
<div class="globe-container" class:visible>
|
<div class="globe-container" class:visible>
|
||||||
<canvas bind:this={canvas} class="globe-canvas"></canvas>
|
<canvas bind:this={canvas} class="globe-canvas"></canvas>
|
||||||
|
|
||||||
|
<div class="globe-controls">
|
||||||
|
<p>🖱️ Glisser pour tourner | 🔍 Molette pour zoomer</p>
|
||||||
|
</div>
|
||||||
<div class="globe-info">
|
<div class="globe-info">
|
||||||
<div class="info-card card">
|
<div class="info-card card">
|
||||||
<h3>Le Phénomène Global</h3>
|
<h3>Le Phénomène Global</h3>
|
||||||
<p>
|
<p>
|
||||||
Le lever héliaque de Sirius n'est pas simultané sur Terre.
|
Le lever héliaque de Sirius n'est pas simultané sur Terre.
|
||||||
Il progresse comme une vague, commençant dans l'hémisphère sud
|
Il progresse comme une vague dorée, commençant dans l'océan Indien
|
||||||
pour remonter vers le nord. Cette progression suit la géométrie
|
(La Réunion en juin) pour traverser l'Afrique, les Caraïbes,
|
||||||
céleste et dépend de la latitude de chaque lieu.
|
puis remonter vers l'Europe (Paris en août).
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
En Guadeloupe, nous sommes privilégiés : le phénomène se produit
|
Cette progression suit la géométrie céleste : plus on va vers le nord,
|
||||||
fin juillet, dans des conditions météorologiques généralement favorables.
|
plus le phénomène se produit tard. La Guadeloupe se trouve au cœur
|
||||||
|
de cette vague en juillet, bénéficiant de conditions idéales.
|
||||||
</p>
|
</p>
|
||||||
|
<div class="timeline-mini">
|
||||||
|
<div class="timeline-item-mini">
|
||||||
|
<span class="date">27 Juin</span>
|
||||||
|
<span class="location">La Réunion</span>
|
||||||
|
</div>
|
||||||
|
<div class="timeline-item-mini">
|
||||||
|
<span class="date">22-23 Juillet</span>
|
||||||
|
<span class="location">Guadeloupe & Caraïbes</span>
|
||||||
|
</div>
|
||||||
|
<div class="timeline-item-mini">
|
||||||
|
<span class="date">12 Août</span>
|
||||||
|
<span class="location">Paris</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.globe-section {
|
.globe-section {
|
||||||
padding: var(--spacing-xl) 0;
|
padding: var(--spacing-xl) 0;
|
||||||
@@ -163,9 +387,22 @@
|
|||||||
|
|
||||||
.globe-canvas {
|
.globe-canvas {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 400px;
|
height: 500px;
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
background: rgba(0, 0, 0, 0.5);
|
background: radial-gradient(circle at center, #0a192f 0%, #020c1b 100%);
|
||||||
|
cursor: grab;
|
||||||
|
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.globe-canvas:active {
|
||||||
|
cursor: grabbing;
|
||||||
|
}
|
||||||
|
.globe-controls {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: var(--color-primary);
|
||||||
|
opacity: 0.7;
|
||||||
}
|
}
|
||||||
|
|
||||||
.info-card h3 {
|
.info-card h3 {
|
||||||
@@ -178,13 +415,39 @@
|
|||||||
line-height: 1.8;
|
line-height: 1.8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.timeline-mini {
|
||||||
|
margin-top: 1.5rem;
|
||||||
|
padding: 1rem;
|
||||||
|
background: rgba(255, 215, 0, 0.1);
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-item-mini {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 0.5rem 0;
|
||||||
|
border-bottom: 1px solid rgba(255, 215, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-item-mini:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
.timeline-item-mini .date {
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--color-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-item-mini .location {
|
||||||
|
color: var(--color-light);
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.globe-container {
|
.globe-container {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
.globe-canvas {
|
.globe-canvas {
|
||||||
height: 300px;
|
height: 400px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -83,7 +83,10 @@
|
|||||||
<span class="title-line">en Guadeloupe</span>
|
<span class="title-line">en Guadeloupe</span>
|
||||||
</h1>
|
</h1>
|
||||||
<p class="hero-subtitle">
|
<p class="hero-subtitle">
|
||||||
Le rendez-vous cosmique entre Ciel, Science et Culture
|
Wep Ronpet - L'Ouverture de l'Année Cosmique
|
||||||
|
</p>
|
||||||
|
<p class="hero-description">
|
||||||
|
Le rendez-vous millénaire entre Ciel, Science et Culture
|
||||||
</p>
|
</p>
|
||||||
<p class="hero-date">
|
<p class="hero-date">
|
||||||
Lever héliaque : <strong>22 Juillet 2025</strong>
|
Lever héliaque : <strong>22 Juillet 2025</strong>
|
||||||
@@ -171,11 +174,20 @@
|
|||||||
.hero-subtitle {
|
.hero-subtitle {
|
||||||
font-size: clamp(1.2rem, 3vw, 1.5rem);
|
font-size: clamp(1.2rem, 3vw, 1.5rem);
|
||||||
color: var(--color-primary);
|
color: var(--color-primary);
|
||||||
margin-bottom: 1rem;
|
font-family: var(--font-heading);
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
animation: fadeInUp 1s ease-out 0.4s;
|
animation: fadeInUp 1s ease-out 0.4s;
|
||||||
animation-fill-mode: both;
|
animation-fill-mode: both;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hero-description {
|
||||||
|
font-size: clamp(1rem, 2.5vw, 1.2rem);
|
||||||
|
color: var(--color-light);
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
animation: fadeInUp 1s ease-out 0.5s;
|
||||||
|
animation-fill-mode: both;
|
||||||
|
}
|
||||||
|
|
||||||
.hero-date {
|
.hero-date {
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
margin-bottom: 2rem;
|
margin-bottom: 2rem;
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
echo "🌟 Sirius en Guadeloupe - Démarrage du projet"
|
||||||
|
echo "============================================="
|
||||||
|
|
||||||
|
# Vérifier si node_modules existe
|
||||||
|
if [ ! -d "node_modules" ]; then
|
||||||
|
echo "📦 Installation des dépendances..."
|
||||||
|
npm install
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "🚀 Lancement du serveur de développement..."
|
||||||
|
echo "📱 L'application sera accessible sur http://localhost:5173"
|
||||||
|
echo ""
|
||||||
|
echo "Commandes disponibles:"
|
||||||
|
echo " - Ctrl+C : Arrêter le serveur"
|
||||||
|
echo " - npm run build : Créer une version de production"
|
||||||
|
echo " - npm run preview : Prévisualiser la version de production"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
npm run dev
|
||||||
Reference in New Issue
Block a user