@@ -7,6 +7,7 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<link rel="stylesheet" href="{% static 'css/t-style.css' %}">
|
<link rel="stylesheet" href="{% static 'css/t-style.css' %}">
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/@tsparticles/confetti@3.0.3/tsparticles.confetti.bundle.min.js"></script>
|
||||||
<title>qivip</title>
|
<title>qivip</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -17,17 +17,25 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% if request.session.mode != "learn" %}
|
|
||||||
|
|
||||||
|
{% if request.session.mode != "learn" %}
|
||||||
<div class="mb-6">
|
<div class="mb-6">
|
||||||
<h2 class="text-xl font-bold mb-4">Punktestand</h2>
|
<h2 class="text-xl font-bold mb-4">Punktestand</h2>
|
||||||
<div class="space-y-2">
|
<div id="scoreboard" class="space-y-2">
|
||||||
{% for participant in participants %}
|
{% for participant in participants %}
|
||||||
{% if participant == my_participant or is_host %}
|
{% if participant == my_participant or is_host %}
|
||||||
|
<div class="p-4 bg-gray-100 rounded-lg flex justify-between items-center border {% if forloop.counter <= 3 %}border-yellow-500{% else %}border-transparent{% endif %}">
|
||||||
<div class="p-4 {% if forloop.first %}bg-yellow-100 border-2 border-yellow-500{% else %}bg-gray-100{% endif %} rounded-lg flex justify-between items-center">
|
|
||||||
<div>
|
<div>
|
||||||
<p class="text-lg font-bold">{{ participant.display_name }}</p>
|
<p class="text-lg font-bold">
|
||||||
|
{% if forloop.counter == 1 %}
|
||||||
|
🥇
|
||||||
|
{% elif forloop.counter == 2 %}
|
||||||
|
🥈
|
||||||
|
{% elif forloop.counter == 3 %}
|
||||||
|
🥉
|
||||||
|
{% endif %}
|
||||||
|
{{ participant.display_name }}
|
||||||
|
</p>
|
||||||
<p class="text-gray-600">{{ participant.score }} Punkte</p>
|
<p class="text-gray-600">{{ participant.score }} Punkte</p>
|
||||||
</div>
|
</div>
|
||||||
{% if participant.last_answer_correct %}
|
{% if participant.last_answer_correct %}
|
||||||
@@ -36,13 +44,7 @@
|
|||||||
<span class="text-red-500">✗</span>
|
<span class="text-red-500">✗</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
|
||||||
|
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -63,6 +65,61 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block extra_js %}
|
{% block extra_js %}
|
||||||
|
{% if is_last_question %}
|
||||||
|
<script>
|
||||||
|
// Hilfsfunktion für Pausen
|
||||||
|
function sleep(ms) {
|
||||||
|
return new Promise(resolve => setTimeout(resolve, ms));
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', async function() {
|
||||||
|
const items = document.querySelectorAll('#scoreboard div');
|
||||||
|
const top3 = Array.from(items).slice(0, 3); // Nur die ersten 3 animieren
|
||||||
|
|
||||||
|
// Sofort Startzustände für Top3 setzen, die anderen sofort sichtbar
|
||||||
|
items.forEach((el, index) => {
|
||||||
|
if (index >= 3) {
|
||||||
|
el.style.opacity = '1';
|
||||||
|
el.style.transform = 'translateY(0)';
|
||||||
|
} else {
|
||||||
|
el.style.opacity = '0';
|
||||||
|
el.style.transform = 'translateY(20px)';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Warten bevor Animation startet
|
||||||
|
await sleep(1500); // <<< hier die 5 Sekunden Pause
|
||||||
|
|
||||||
|
// Transition-Eigenschaft setzen nach Render-Zyklus
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
top3.forEach(el => {
|
||||||
|
el.style.transition = 'all 0.8s ease';
|
||||||
|
});
|
||||||
|
|
||||||
|
// Animation für Top 3 starten – von Platz 3 zu 1
|
||||||
|
top3.reverse().forEach((el, index) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
el.style.opacity = '1';
|
||||||
|
el.style.transform = 'translateY(0)';
|
||||||
|
|
||||||
|
if (index === top3.length - 1) {
|
||||||
|
triggerConfetti();
|
||||||
|
}
|
||||||
|
}, index * 1500); // Zeitversetzt aufdecken
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function triggerConfetti() {
|
||||||
|
const end = Date.now() + 15 * 1000;
|
||||||
|
(function frame() {
|
||||||
|
confetti({ particleCount: 2, angle: 60, spread: 55, origin: { x: 0 } });
|
||||||
|
confetti({ particleCount: 2, angle: 120, spread: 55, origin: { x: 1 } });
|
||||||
|
if (Date.now() < end) requestAnimationFrame(frame);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
{% endif %}
|
||||||
{% include 'play/game/common_scripts.html' %}
|
{% include 'play/game/common_scripts.html' %}
|
||||||
<script>
|
<script>
|
||||||
const joinCode = '{{ quiz_game.join_code }}';
|
const joinCode = '{{ quiz_game.join_code }}';
|
||||||
|
|||||||
Reference in New Issue
Block a user