parent
1bb4c71528
commit
36893c8bc8
@ -1,24 +1,24 @@
|
|||||||
# see https://symfony.com/doc/current/reference/configuration/framework.html
|
# see https://symfony.com/doc/current/reference/configuration/framework.html
|
||||||
framework:
|
framework:
|
||||||
secret: '%env(APP_SECRET)%'
|
secret: "%env(APP_SECRET)%"
|
||||||
#csrf_protection: true
|
#csrf_protection: true
|
||||||
http_method_override: false
|
http_method_override: false
|
||||||
|
|
||||||
# Enables session support. Note that the session will ONLY be started if you read or write from it.
|
# Enables session support. Note that the session will ONLY be started if you read or write from it.
|
||||||
# Remove or comment this section to explicitly disable session support.
|
# Remove or comment this section to explicitly disable session support.
|
||||||
session:
|
session:
|
||||||
handler_id: null
|
handler_id: null
|
||||||
cookie_secure: auto
|
cookie_secure: auto
|
||||||
cookie_samesite: lax
|
cookie_samesite: lax
|
||||||
storage_factory_id: session.storage.factory.native
|
storage_factory_id: session.storage.factory.native
|
||||||
|
|
||||||
#esi: true
|
#esi: true
|
||||||
#fragments: true
|
#fragments: true
|
||||||
php_errors:
|
php_errors:
|
||||||
log: true
|
log: true
|
||||||
|
|
||||||
when@test:
|
when@test:
|
||||||
framework:
|
framework:
|
||||||
test: true
|
test: true
|
||||||
session:
|
session:
|
||||||
storage_factory_id: session.storage.factory.mock_file
|
storage_factory_id: session.storage.factory.mock_file
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
framework:
|
framework:
|
||||||
router:
|
router:
|
||||||
utf8: true
|
utf8: true
|
||||||
|
|
||||||
# Configure how to generate URLs in non-HTTP contexts, such as CLI commands.
|
# Configure how to generate URLs in non-HTTP contexts, such as CLI commands.
|
||||||
# See https://symfony.com/doc/current/routing.html#generating-urls-in-commands
|
# See https://symfony.com/doc/current/routing.html#generating-urls-in-commands
|
||||||
#default_uri: http://localhost
|
#default_uri: http://localhost
|
||||||
|
|
||||||
when@prod:
|
when@prod:
|
||||||
framework:
|
framework:
|
||||||
router:
|
router:
|
||||||
strict_requirements: null
|
strict_requirements: null
|
||||||
|
After Width: | Height: | Size: 2.1 MiB |
@ -0,0 +1,38 @@
|
|||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
const left = document.querySelector('.left-emoji');
|
||||||
|
const right = document.querySelector('.right-emoji');
|
||||||
|
const winnerText = document.getElementById('winner-text');
|
||||||
|
|
||||||
|
// These variables will be injected by Twig in the template as data attributes or global variables
|
||||||
|
const winnerSide = window.winnerSide;
|
||||||
|
const loserSide = window.loserSide;
|
||||||
|
|
||||||
|
left.classList.add('slide-in-left');
|
||||||
|
right.classList.add('slide-in-right');
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
left.style.left = '100px';
|
||||||
|
right.style.left = '300px';
|
||||||
|
|
||||||
|
left.classList.add('fight-animation');
|
||||||
|
right.classList.add('fight-animation');
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
left.classList.remove('fight-animation');
|
||||||
|
right.classList.remove('fight-animation');
|
||||||
|
|
||||||
|
const loser = loserSide === 'left' ? left : right;
|
||||||
|
loser.classList.add('loser-fly-up');
|
||||||
|
const wing = document.createElement('div');
|
||||||
|
wing.classList.add('wing');
|
||||||
|
wing.textContent = '🪽';
|
||||||
|
loser.appendChild(wing);
|
||||||
|
|
||||||
|
const winner = winnerSide === 'left' ? left : right;
|
||||||
|
winner.classList.add('winner-center', 'winner-crown');
|
||||||
|
|
||||||
|
winnerText.textContent = `${winner.textContent.trim()} a gagné ! 🎉`;
|
||||||
|
winnerText.style.display = 'block';
|
||||||
|
}, 1500);
|
||||||
|
}, 3000);
|
||||||
|
});
|
@ -0,0 +1,133 @@
|
|||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background-image: url("../media/boxing_ring.jpg");
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: cover;
|
||||||
|
overflow: hidden;
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arena {
|
||||||
|
position: relative;
|
||||||
|
width: 400px;
|
||||||
|
height: 150px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
font-size: 5rem;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-emoji {
|
||||||
|
left: -100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-emoji {
|
||||||
|
left: 500px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideInLeft {
|
||||||
|
to {
|
||||||
|
left: 100px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideInRight {
|
||||||
|
to {
|
||||||
|
left: 300px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-in-left {
|
||||||
|
animation: slideInLeft 3s forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slide-in-right {
|
||||||
|
animation: slideInRight 3s forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fightShake {
|
||||||
|
0%,
|
||||||
|
100% {
|
||||||
|
transform: translate(-50%, -50%) translateX(0);
|
||||||
|
}
|
||||||
|
20%,
|
||||||
|
60% {
|
||||||
|
transform: translate(-50%, -50%) translateX(-15px);
|
||||||
|
}
|
||||||
|
40%,
|
||||||
|
80% {
|
||||||
|
transform: translate(-50%, -50%) translateX(15px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fight-animation {
|
||||||
|
animation: fightShake 0.5s 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes flyUpFade {
|
||||||
|
to {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translate(-50%, calc(-150px - 50%));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.loser-fly-up {
|
||||||
|
animation: flyUpFade 3s forwards;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wing {
|
||||||
|
font-size: 2rem;
|
||||||
|
margin-top: -1.5rem;
|
||||||
|
animation: wingFlap 3s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes wingFlap {
|
||||||
|
0%,
|
||||||
|
100% {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: rotate(15deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes moveToCenter {
|
||||||
|
to {
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.winner-center {
|
||||||
|
animation: moveToCenter 1s forwards;
|
||||||
|
position: absolute !important;
|
||||||
|
top: 50% !important;
|
||||||
|
font-size: 6rem;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.winner-crown::after {
|
||||||
|
content: "👑";
|
||||||
|
position: absolute;
|
||||||
|
top: -1.5rem;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#winner-text {
|
||||||
|
margin-top: 1rem;
|
||||||
|
font-size: 2rem;
|
||||||
|
text-align: center;
|
||||||
|
display: none;
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Controller;
|
||||||
|
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
|
|
||||||
|
class CombatController extends AbstractController
|
||||||
|
{
|
||||||
|
// Route designed for testing purposes
|
||||||
|
#[Route('/combat', name: 'app_combat')]
|
||||||
|
public function index(): Response
|
||||||
|
{
|
||||||
|
|
||||||
|
$leftEmoji = '🐱';
|
||||||
|
$rightEmoji = '🐶';
|
||||||
|
$winner = 'left'; // or 'right'
|
||||||
|
$loser = ($winner === 'left') ? 'right' : 'left';
|
||||||
|
|
||||||
|
return $this->render('combat/index.html.twig', [
|
||||||
|
'left_emoji' => $leftEmoji,
|
||||||
|
'right_emoji' => $rightEmoji,
|
||||||
|
'winner' => $winner,
|
||||||
|
'loser' => $loser,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Route('/combat-{leftEmoji}-{rightEmoji}-{winner}', name: 'app_combat_with_params', requirements: ['leftEmoji' => '.+', 'rightEmoji' => '.+'])]
|
||||||
|
public function combatWithParams(string $leftEmoji, string $rightEmoji, string $winner): Response
|
||||||
|
// Example : /combat-🐱-🐶-left
|
||||||
|
{
|
||||||
|
$loser = ($winner === 'left') ? 'right' : 'left';
|
||||||
|
|
||||||
|
return $this->render('combat/index.html.twig', [
|
||||||
|
'left_emoji' => $leftEmoji,
|
||||||
|
'right_emoji' => $rightEmoji,
|
||||||
|
'winner' => $winner,
|
||||||
|
'loser' => $loser,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<title>Emoji Fight</title>
|
||||||
|
<link rel="stylesheet" href="style/combat.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="arena">
|
||||||
|
<div class="emoji left-emoji">{{ left_emoji }}</div>
|
||||||
|
<div class="emoji right-emoji">{{ right_emoji }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="winner-text"></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
window.winnerSide = '{{ winner }}';
|
||||||
|
window.loserSide = '{{ loser }}';
|
||||||
|
</script>
|
||||||
|
<script src="script/combat.js"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in new issue