Ajout d'une possibilité de correction pour le TP Nuisibles
This commit is contained in:
@@ -628,6 +628,9 @@
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- CONFETTI CANVAS -->
|
||||
<canvas id="confettiCanvas" style="position:fixed;inset:0;pointer-events:none;z-index:150;display:none;"></canvas>
|
||||
|
||||
<!-- HEADER WITH NAVIGATION -->
|
||||
<header>
|
||||
<div class="logo">NextGN Formation</div>
|
||||
@@ -688,7 +691,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id="idError" style="color:var(--coral);font-size:13px;margin-bottom:0.5rem;display:none;">Merci de renseigner au moins le nom du groupe.</div>
|
||||
<button class="btn btn-teal" onclick="confirmIdentite()">Continuer →</button>
|
||||
<div style="display:flex;gap:12px;justify-content:center;flex-wrap:wrap;">
|
||||
<button class="btn btn-teal" onclick="confirmIdentite()">Continuer →</button>
|
||||
<a href="correction-tp-nuisibles.html" class="btn btn-outline btn-teal">Corriger</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -697,7 +703,7 @@
|
||||
<div class="deco-circle" style="width:400px;height:400px;background:var(--amber-light);top:-100px;right:-80px;opacity:0.6;"></div>
|
||||
<div class="deco-circle" style="width:200px;height:200px;background:var(--amber-light);bottom:60px;left:-60px;opacity:0.5;"></div>
|
||||
<div style="text-align:center; z-index:1;">
|
||||
<div class="hero-label">Formation 2025</div>
|
||||
<div class="hero-label">Formation</div>
|
||||
<div class="hero-title">CERTIBIOCIDE</div>
|
||||
<div style="font-family:'Syne',sans-serif;font-size:clamp(14px,2.5vw,22px);font-weight:600;color:var(--amber-mid);letter-spacing:0.04em;margin-bottom:1.5rem;">TRAVAUX PRATIQUES</div>
|
||||
<p class="hero-sub">Votre mission, si vous l'acceptez : maîtriser l'identification, le traitement et la sécurité face aux nuisibles.</p>
|
||||
@@ -1119,7 +1125,7 @@
|
||||
<div style="font-size:48px;margin-bottom:1rem;">🎉</div>
|
||||
<div class="section-tag" style="background:var(--amber-light);color:var(--amber-dark);">Mission accomplie</div>
|
||||
<div class="slide-title" style="margin-top:0.5rem;">Félicitations !</div>
|
||||
<p style="font-size:14px;color:var(--text-muted);max-width:480px;text-align:center;line-height:1.7;margin:1rem auto;">Vous avez complété les 3 travaux pratiques de la formation Certibiocide 2025. Le formateur va maintenant corriger à l'oral.</p>
|
||||
<p style="font-size:14px;color:var(--text-muted);max-width:480px;text-align:center;line-height:1.7;margin:1rem auto;">Vous avez complété les 3 travaux pratiques de la formation Certibiocide. Le formateur va maintenant corriger à l'oral.</p>
|
||||
<div class="final-grid">
|
||||
<div class="final-card">
|
||||
<div class="final-card-icon">🗂️</div>
|
||||
@@ -1140,6 +1146,7 @@
|
||||
<div class="submit-zone">
|
||||
<div style="display:flex;gap:10px;justify-content:center;flex-wrap:wrap;">
|
||||
<button class="btn btn-teal" onclick="exporterPDF()">⬇ Télécharger en PDF</button>
|
||||
<a href="correction-tp-nuisibles.html" class="btn btn-outline btn-teal">Corriger</a>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display:flex;gap:10px;justify-content:center;flex-wrap:wrap;margin-top:0.75rem;">
|
||||
@@ -1243,6 +1250,7 @@ function goTo(n) {
|
||||
currentSlide = n;
|
||||
next.style.display = 'flex';
|
||||
setTimeout(() => { next.classList.add('active', 'fade-in'); }, 10);
|
||||
if (n === 13) setTimeout(launchConfetti, 200);
|
||||
updateUI();
|
||||
updateCaseBanners();
|
||||
}
|
||||
@@ -1497,7 +1505,7 @@ function exporterPDF() {
|
||||
.meta { font-size: 13px; color: #555; margin-bottom: 4px; }
|
||||
</style></head>
|
||||
<body>
|
||||
<h1>TP Nuisibles — Certibiocide 2025</h1>
|
||||
<h1>TP Nuisibles — Certibiocide</h1>
|
||||
<p class="meta"><strong>Groupe / Stagiaire :</strong> ${escapeHtml(data.nom)}</p>
|
||||
<p class="meta"><strong>Date de session :</strong> ${escapeHtml(data.date_session)}</p>
|
||||
<p class="meta"><strong>Formateur :</strong> ${escapeHtml(data.formateur)}</p>
|
||||
@@ -1520,6 +1528,79 @@ function exporterPDF() {
|
||||
setTimeout(() => w.print(), 300);
|
||||
}
|
||||
|
||||
/* ======================== CONFETTI ======================== */
|
||||
function launchConfetti() {
|
||||
const canvas = document.getElementById('confettiCanvas');
|
||||
if (!canvas) return;
|
||||
const ctx = canvas.getContext('2d');
|
||||
canvas.width = window.innerWidth;
|
||||
canvas.height = window.innerHeight;
|
||||
canvas.style.display = 'block';
|
||||
|
||||
const colors = ['#BA7517', '#D85A30', '#F5DFB8', '#633806', '#F0A855', '#E8C068', '#FF8C5A'];
|
||||
const particles = Array.from({ length: 180 }, () => ({
|
||||
x: Math.random() * canvas.width,
|
||||
y: -(Math.random() * canvas.height * 0.5),
|
||||
w: Math.random() * 10 + 5,
|
||||
h: Math.random() * 5 + 3,
|
||||
color: colors[Math.floor(Math.random() * colors.length)],
|
||||
rotation: Math.random() * Math.PI * 2,
|
||||
rotSpeed: (Math.random() - 0.5) * 0.18,
|
||||
vx: (Math.random() - 0.5) * 2.5,
|
||||
vy: Math.random() * 3 + 2,
|
||||
opacity: 1,
|
||||
shape: Math.random() < 0.4 ? 'circle' : 'rect'
|
||||
}));
|
||||
|
||||
let rafId;
|
||||
let start = null;
|
||||
const totalDuration = 3800;
|
||||
|
||||
function draw(ts) {
|
||||
if (!start) start = ts;
|
||||
const elapsed = ts - start;
|
||||
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
let active = false;
|
||||
|
||||
particles.forEach(p => {
|
||||
p.x += p.vx;
|
||||
p.y += p.vy;
|
||||
p.vy += 0.04;
|
||||
p.rotation += p.rotSpeed;
|
||||
p.opacity = elapsed < totalDuration * 0.55
|
||||
? 1
|
||||
: Math.max(0, 1 - (elapsed - totalDuration * 0.55) / (totalDuration * 0.45));
|
||||
|
||||
if (p.y < canvas.height + 20) active = true;
|
||||
|
||||
ctx.save();
|
||||
ctx.translate(p.x, p.y);
|
||||
ctx.rotate(p.rotation);
|
||||
ctx.globalAlpha = p.opacity;
|
||||
ctx.fillStyle = p.color;
|
||||
if (p.shape === 'circle') {
|
||||
ctx.beginPath();
|
||||
ctx.arc(0, 0, p.w / 2, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
} else {
|
||||
ctx.fillRect(-p.w / 2, -p.h / 2, p.w, p.h);
|
||||
}
|
||||
ctx.restore();
|
||||
});
|
||||
|
||||
if (active && elapsed < totalDuration * 1.3) {
|
||||
rafId = requestAnimationFrame(draw);
|
||||
} else {
|
||||
canvas.style.display = 'none';
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
}
|
||||
}
|
||||
|
||||
if (rafId) cancelAnimationFrame(rafId);
|
||||
rafId = requestAnimationFrame(draw);
|
||||
}
|
||||
|
||||
function escapeHtml(str) {
|
||||
if (!str) return '';
|
||||
return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
||||
|
||||
Reference in New Issue
Block a user