|
1 | 1 | <!DOCTYPE html> |
2 | 2 | <html lang="fr"> |
3 | 3 | <head> |
4 | | -<meta charset="UTF‑8"> |
5 | | -<meta name="viewport" content="width=device‑width, initial‑scale=1.0"> |
6 | | -<title>Timestamp Discord Style r.3v.fi</title> |
| 4 | +<meta charset="UTF-8"> |
| 5 | +<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| 6 | +<title>Discord Timestamp Generator</title> |
| 7 | +<script src="https://cdn.tailwindcss.com"></script> |
7 | 8 | <style> |
| 9 | + /* Global gradient background */ |
8 | 10 | body { |
9 | | - font-family: Arial, sans-serif; |
10 | | - background: #1a1a2e; |
11 | | - color: white; |
12 | | - display: flex; |
13 | | - flex-direction: column; |
14 | | - align-items: center; |
15 | | - padding: 2rem; |
| 11 | + background: linear-gradient(135deg, #1f1f2e, #2a2a3f, #1f1f2e); |
16 | 12 | } |
17 | 13 |
|
| 14 | + /* Styled container */ |
18 | 15 | .container { |
19 | | - background: #22223b; |
| 16 | + background: linear-gradient(145deg, #2b2b3f, #3a3a57); |
20 | 17 | padding: 2rem; |
21 | | - border-radius: 1rem; |
22 | | - width: 100%; |
23 | | - max-width: 450px; |
| 18 | + border-radius: 1.5rem; |
| 19 | + box-shadow: 0 10px 30px rgba(0,0,0,0.5); |
24 | 20 | } |
25 | 21 |
|
26 | | - h1 { text-align: center; margin-bottom: 1rem; } |
27 | | - |
28 | | - /* Calendrier */ |
29 | | - .calendar { |
30 | | - display: grid; |
31 | | - grid-template-columns: repeat(7, 1fr); |
32 | | - gap: 5px; |
33 | | - margin-bottom: 1rem; |
| 22 | + /* Inputs / select style */ |
| 23 | + input, select { |
| 24 | + background: linear-gradient(135deg, #3b3b55, #4b4b72); |
| 25 | + border: none; |
| 26 | + outline: none; |
| 27 | + color: white; |
| 28 | + padding: 0.5rem; |
| 29 | + border-radius: 0.75rem; |
| 30 | + transition: all 0.3s ease; |
| 31 | + } |
| 32 | + input:focus, select:focus { |
| 33 | + background: linear-gradient(135deg, #5a5ac0, #7b7bd0); |
| 34 | + box-shadow: 0 0 10px rgba(123,123,208,0.7); |
34 | 35 | } |
35 | 36 |
|
36 | | - .calendar div { |
37 | | - padding: 8px; |
38 | | - text-align: center; |
39 | | - cursor: pointer; |
40 | | - background: #362e6d; |
41 | | - border-radius: 6px; |
42 | | - transition: 0.2s; |
| 37 | + /* Buttons gradient */ |
| 38 | + .btn-gradient { |
| 39 | + background: linear-gradient(90deg, #ff6a88, #ff99ac); |
| 40 | + color: white; |
| 41 | + font-weight: bold; |
| 42 | + padding: 0.5rem 1rem; |
| 43 | + border-radius: 0.75rem; |
| 44 | + transition: all 0.3s ease; |
| 45 | + } |
| 46 | + .btn-gradient:hover { |
| 47 | + background: linear-gradient(90deg, #ff99ac, #ff6a88); |
| 48 | + transform: translateY(-2px); |
| 49 | + box-shadow: 0 5px 15px rgba(255,105,136,0.5); |
43 | 50 | } |
44 | | - .calendar div:hover { background: #4a47a3; } |
45 | | - .calendar .selected { background: #ff6b6b; } |
46 | 51 |
|
47 | | - .nav { |
| 52 | + /* Toast container */ |
| 53 | + #toast-container { |
| 54 | + position: fixed; |
| 55 | + bottom: 2rem; |
| 56 | + right: 2rem; |
48 | 57 | display: flex; |
49 | | - justify-content: space-between; |
50 | | - margin-bottom: 0.5rem; |
51 | | - } |
52 | | - .nav button { |
53 | | - background: #4a47a3; |
54 | | - border: none; |
55 | | - padding: 4px 8px; |
56 | | - border-radius: 6px; |
57 | | - cursor: pointer; |
| 58 | + flex-direction: column-reverse; |
| 59 | + gap: 0.5rem; |
| 60 | + z-index: 1000; |
58 | 61 | } |
59 | 62 |
|
60 | | - /* Horloge */ |
61 | | - .clock { |
62 | | - width: 260px; |
63 | | - height: 260px; |
64 | | - border: 4px solid #4a47a3; |
65 | | - border-radius: 50%; |
| 63 | + .toast { |
| 64 | + background: linear-gradient(90deg, #22c55e, #4ade80); |
| 65 | + color: white; |
| 66 | + padding: 1rem 1.5rem; |
| 67 | + border-radius: 0.75rem; |
| 68 | + font-weight: bold; |
| 69 | + font-family: sans-serif; |
| 70 | + box-shadow: 0 4px 12px rgba(0,0,0,0.3); |
| 71 | + opacity: 0; |
| 72 | + transform: translateY(20px); |
| 73 | + transition: opacity 0.3s ease, transform 0.3s ease; |
66 | 74 | position: relative; |
67 | | - margin: auto; |
68 | | - margin-bottom: 1rem; |
| 75 | + overflow: hidden; |
| 76 | + min-width: 220px; |
69 | 77 | } |
70 | | - .hourHand, .minuteHand { |
71 | | - position: absolute; |
72 | | - left: 50%; |
73 | | - top: 50%; |
74 | | - background: #ff6b6b; |
75 | | - transform-origin: bottom; |
76 | | - pointer-events: none; |
| 78 | + .toast.show { |
| 79 | + opacity: 1; |
| 80 | + transform: translateY(0); |
77 | 81 | } |
78 | | - .hourHand { width: 6px; height: 60px; } |
79 | | - .minuteHand { width: 4px; height: 90px; background: #f7d794; } |
80 | | - |
81 | | - .clockNumbers { |
| 82 | + .toast .progress { |
82 | 83 | position: absolute; |
| 84 | + bottom: 0; |
| 85 | + left: 0; |
| 86 | + height: 4px; |
| 87 | + background-color: white; |
83 | 88 | width: 100%; |
84 | | - height: 100%; |
85 | | - pointer-events: none; |
| 89 | + transform-origin: right; |
| 90 | + animation: shrink 5s linear forwards; |
86 | 91 | } |
87 | | - .clockNumbers div { |
88 | | - position: absolute; |
89 | | - width: 20px; |
90 | | - text-align: center; |
91 | | - font-size: 14px; |
92 | | - font-weight: bold; |
93 | | - } |
94 | | - |
95 | | - /* Result */ |
96 | | - #result { |
97 | | - width: 100%; |
98 | | - padding: 0.5rem; |
99 | | - margin-bottom: 0.5rem; |
100 | | - border-radius: 0.5rem; |
101 | | - border: none; |
102 | | - background: #362e6d; |
103 | | - color: white; |
104 | | - font-family: monospace; |
105 | | - text-align: center; |
| 92 | + @keyframes shrink { |
| 93 | + from { transform: scaleX(1); } |
| 94 | + to { transform: scaleX(0); } |
106 | 95 | } |
107 | 96 | </style> |
108 | 97 | </head> |
109 | | -<body> |
110 | | - |
111 | | -<div class="container"> |
112 | | - <h1>Discord Timestamp</h1> |
113 | | - |
114 | | - <!-- Calendrier --> |
115 | | - <div class="nav"> |
116 | | - <button id="prevMonth"><</button> |
117 | | - <span id="monthYear"></span> |
118 | | - <button id="nextMonth">></button> |
119 | | - </div> |
120 | | - <div class="calendar" id="calendar"></div> |
121 | | - |
122 | | - <!-- Horloge --> |
123 | | - <div class="clock" id="clock"> |
124 | | - <div class="clockNumbers"></div> |
125 | | - <div class="hourHand"></div> |
126 | | - <div class="minuteHand"></div> |
127 | | - </div> |
128 | | - |
129 | | - <button onclick="generateTimestamp()">Générer</button> |
130 | | - <input id="result" readonly> |
| 98 | +<body class="flex items-center justify-center min-h-screen text-white"> |
| 99 | + |
| 100 | +<div class="container w-full max-w-md"> |
| 101 | + <h1 class="text-2xl font-bold mb-6 text-center">⏱ Discord Timestamp</h1> |
| 102 | + |
| 103 | + <label class="block mb-2">Choisir la date :</label> |
| 104 | + <input id="date" type="date" class="w-full mb-4"/> |
| 105 | + |
| 106 | + <label class="block mb-2">Choisir l'heure :</label> |
| 107 | + <input id="time" type="time" class="w-full mb-4"/> |
| 108 | + |
| 109 | + <label class="block mb-2">Format :</label> |
| 110 | + <select id="format" class="w-full mb-4"> |
| 111 | + <option value="t">Court temps (t)</option> |
| 112 | + <option value="T">Long temps (T)</option> |
| 113 | + <option value="d">Date courte (d)</option> |
| 114 | + <option value="D">Date longue (D)</option> |
| 115 | + <option value="f" selected>Date + temps complet (f)</option> |
| 116 | + <option value="F">Date + temps complet long (F)</option> |
| 117 | + <option value="R">Relatif (R)</option> |
| 118 | + </select> |
| 119 | + |
| 120 | + <button onclick="generateTimestamp()" class="w-full btn-gradient mb-4">Générer</button> |
| 121 | + |
| 122 | + <input id="result" type="text" readonly class="w-full p-2 rounded bg-gray-700 focus:outline-none text-center font-mono mb-2"/> |
| 123 | + <button onclick="copyResult()" class="w-full btn-gradient">📋 Copier</button> |
131 | 124 | </div> |
132 | 125 |
|
| 126 | +<div id="toast-container"></div> |
| 127 | + |
133 | 128 | <script> |
134 | | -let selectedDate = new Date(); |
135 | | -let selectedHour = selectedDate.getHours(); |
136 | | -let selectedMinute = selectedDate.getMinutes(); |
137 | | - |
138 | | -// Render calendar |
139 | | -function renderCalendar() { |
140 | | - const cal = document.getElementById('calendar'); |
141 | | - cal.innerHTML=''; |
142 | | - const year = selectedDate.getFullYear(); |
143 | | - const month = selectedDate.getMonth(); |
144 | | - const firstDay = new Date(year, month, 1).getDay(); |
145 | | - const daysInMonth = new Date(year, month+1, 0).getDate(); |
146 | | - |
147 | | - document.getElementById('monthYear').textContent = |
148 | | - selectedDate.toLocaleString('default',{ month:'long', year:'numeric' }); |
149 | | - |
150 | | - for(let i=0;i<firstDay;i++) cal.innerHTML += '<div></div>'; |
151 | | - for(let d=1; d<=daysInMonth; d++){ |
152 | | - const cell = document.createElement('div'); |
153 | | - cell.textContent = d; |
154 | | - if(d === selectedDate.getDate()) cell.classList.add('selected'); |
155 | | - cell.onclick = ()=>{ selectedDate.setDate(d); renderCalendar(); }; |
156 | | - cal.appendChild(cell); |
| 129 | + function generateTimestamp() { |
| 130 | + const date = document.getElementById('date').value; |
| 131 | + const time = document.getElementById('time').value; |
| 132 | + const format = document.getElementById('format').value; |
| 133 | + |
| 134 | + if (!date || !time) { |
| 135 | + showToast("Veuillez choisir la date et l'heure !"); |
| 136 | + return; |
| 137 | + } |
| 138 | + |
| 139 | + const datetimeStr = `${date}T${time}:00`; |
| 140 | + const unixTimestamp = Math.floor(new Date(datetimeStr).getTime() / 1000); |
| 141 | + const discordTimestamp = `<t:${unixTimestamp}:${format}>`; |
| 142 | + document.getElementById('result').value = discordTimestamp; |
| 143 | + |
| 144 | + showToast("Timestamp généré !"); |
| 145 | + } |
| 146 | + |
| 147 | + function copyResult() { |
| 148 | + const result = document.getElementById('result'); |
| 149 | + result.select(); |
| 150 | + navigator.clipboard.writeText(result.value); |
| 151 | + showToast("Timestamp copié !"); |
157 | 152 | } |
158 | | -} |
159 | | - |
160 | | -document.getElementById('prevMonth').onclick = ()=>{ selectedDate.setMonth(selectedDate.getMonth()-1); renderCalendar(); }; |
161 | | -document.getElementById('nextMonth').onclick = ()=>{ selectedDate.setMonth(selectedDate.getMonth()+1); renderCalendar(); }; |
162 | | -renderCalendar(); |
163 | | - |
164 | | -// Clock visuals |
165 | | -const clock = document.getElementById('clock'); |
166 | | -const hourHand = document.querySelector('.hourHand'); |
167 | | -const minuteHand = document.querySelector('.minuteHand'); |
168 | | -const clockNumbers = document.querySelector('.clockNumbers'); |
169 | | - |
170 | | -// place numbers |
171 | | -for(let i=1; i<=12; i++){ |
172 | | - const num = document.createElement('div'); |
173 | | - const angle = (i/12)*360; |
174 | | - const rad = Math.PI * angle/180; |
175 | | - num.style.top = `${50 - Math.cos(rad)*40}%`; |
176 | | - num.style.left= `${50 + Math.sin(rad)*40}%`; |
177 | | - num.textContent = i; |
178 | | - clockNumbers.appendChild(num); |
179 | | -} |
180 | | - |
181 | | -function updateHands() { |
182 | | - hourHand.style.transform = `rotate(${selectedHour*30 + selectedMinute*0.5}deg) translate(-50%,-100%)`; |
183 | | - minuteHand.style.transform = `rotate(${selectedMinute*6}deg) translate(-50%,-100%)`; |
184 | | -} |
185 | | -updateHands(); |
186 | | - |
187 | | -// Click on clock to set time |
188 | | -clock.onclick = (e) => { |
189 | | - const rect = clock.getBoundingClientRect(); |
190 | | - const x = e.clientX - (rect.left + rect.width/2); |
191 | | - const y = e.clientY - (rect.top + rect.height/2); |
192 | | - const angle = Math.atan2(y, x) * (180 / Math.PI) + 90; |
193 | | - const normalized = (angle<0 ? angle+360 : angle); |
194 | | - selectedHour = Math.floor(normalized / 30); |
195 | | - selectedMinute = Math.floor((normalized % 30)*2); |
196 | | - updateHands(); |
197 | | -}; |
198 | | - |
199 | | -// Generate timestamp |
200 | | -function generateTimestamp() { |
201 | | - selectedDate.setHours(selectedHour); |
202 | | - selectedDate.setMinutes(selectedMinute); |
203 | | - const unix = Math.floor(selectedDate.getTime()/1000); |
204 | | - document.getElementById('result').value = `<t:${unix}:f>`; |
205 | | -} |
206 | 153 |
|
| 154 | + function showToast(message) { |
| 155 | + const container = document.getElementById('toast-container'); |
| 156 | + const toast = document.createElement('div'); |
| 157 | + toast.className = 'toast show'; |
| 158 | + toast.textContent = message; |
| 159 | + |
| 160 | + const progress = document.createElement('div'); |
| 161 | + progress.className = 'progress'; |
| 162 | + toast.appendChild(progress); |
| 163 | + |
| 164 | + container.appendChild(toast); |
| 165 | + |
| 166 | + setTimeout(() => { |
| 167 | + toast.classList.remove('show'); |
| 168 | + setTimeout(() => toast.remove(), 300); |
| 169 | + }, 5000); |
| 170 | + } |
207 | 171 | </script> |
208 | 172 |
|
209 | 173 | </body> |
|
0 commit comments