├── index.html ├── script.js └── style.css /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Theme Clock 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | 22 |
23 |
24 |
25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /script.js: -------------------------------------------------------------------------------- 1 | const hourEl = document.querySelector('.hour') 2 | const minuteEl = document.querySelector('.minute') 3 | const secondEl = document.querySelector('.second') 4 | const timeEl = document.querySelector('.time') 5 | const dateEl = document.querySelector('.date') 6 | const toggle = document.querySelector('.toggle') 7 | 8 | const days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; 9 | const months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; 10 | 11 | toggle.addEventListener('click', (e) => { 12 | const html = document.querySelector('html') 13 | if (html.classList.contains('dark')) { 14 | html.classList.remove('dark') 15 | e.target.innerHTML = 'Dark mode' 16 | } else { 17 | html.classList.add('dark') 18 | e.target.innerHTML = 'Light mode' 19 | } 20 | }) 21 | 22 | function setTime() { 23 | const time = new Date(); 24 | const month = time.getMonth() 25 | const day = time.getDay() 26 | const date = time.getDate() 27 | const hours = time.getHours() 28 | const hoursForClock = hours >= 13 ? hours % 12 : hours; 29 | const minutes = time.getMinutes() 30 | const seconds = time.getSeconds() 31 | const ampm = hours >= 12 ? 'PM' : 'AM' 32 | 33 | hourEl.style.transform = `translate(-50%, -100%) rotate(${scale(hoursForClock, 0, 12, 0, 360)}deg)` 34 | minuteEl.style.transform = `translate(-50%, -100%) rotate(${scale(minutes, 0, 60, 0, 360)}deg)` 35 | secondEl.style.transform = `translate(-50%, -100%) rotate(${scale(seconds, 0, 60, 0, 360)}deg)` 36 | 37 | timeEl.innerHTML = `${hoursForClock}:${minutes < 10 ? `0${minutes}` : minutes} ${ampm}` 38 | dateEl.innerHTML = `${days[day]}, ${months[month]} ${date}` 39 | } 40 | 41 | // StackOverflow https://stackoverflow.com/questions/10756313/javascript-jquery-map-a-range-of-numbers-to-another-range-of-numbers 42 | const scale = (num, in_min, in_max, out_min, out_max) => { 43 | return (num - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; 44 | } 45 | 46 | setTime() 47 | 48 | setInterval(setTime, 1000) 49 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css?family=Heebo:300&display=swap'); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | :root { 8 | --primary-color: #000; 9 | --secondary-color: #fff; 10 | } 11 | 12 | html { 13 | transition: all 0.5s ease-in; 14 | } 15 | 16 | html.dark { 17 | --primary-color: #fff; 18 | --secondary-color: #333; 19 | } 20 | 21 | html.dark { 22 | background-color: #111; 23 | color: var(--primary-color); 24 | } 25 | 26 | body { 27 | font-family: 'Heebo', sans-serif; 28 | display: flex; 29 | align-items: center; 30 | justify-content: center; 31 | height: 100vh; 32 | overflow: hidden; 33 | margin: 0; 34 | } 35 | 36 | .toggle { 37 | cursor: pointer; 38 | background-color: var(--primary-color); 39 | color: var(--secondary-color); 40 | border: 0; 41 | border-radius: 4px; 42 | padding: 8px 12px; 43 | position: absolute; 44 | top: 100px; 45 | } 46 | 47 | .toggle:focus { 48 | outline: none; 49 | } 50 | 51 | .clock-container { 52 | display: flex; 53 | flex-direction: column; 54 | justify-content: space-between; 55 | align-items: center; 56 | } 57 | 58 | .clock { 59 | position: relative; 60 | width: 200px; 61 | height: 200px; 62 | } 63 | 64 | .needle { 65 | background-color: var(--primary-color); 66 | position: absolute; 67 | top: 50%; 68 | left: 50%; 69 | height: 65px; 70 | width: 3px; 71 | transform-origin: bottom center; 72 | transition: all 0.5s ease-in; 73 | } 74 | 75 | .needle.hour { 76 | transform: translate(-50%, -100%) rotate(0deg); 77 | } 78 | 79 | .needle.minute { 80 | transform: translate(-50%, -100%) rotate(0deg); 81 | height: 100px; 82 | } 83 | 84 | .needle.second { 85 | transform: translate(-50%, -100%) rotate(0deg); 86 | height: 100px; 87 | background-color: #e74c3c; 88 | } 89 | 90 | .center-point { 91 | background-color: #e74c3c; 92 | width: 10px; 93 | height: 10px; 94 | position: absolute; 95 | top: 50%; 96 | left: 50%; 97 | transform: translate(-50%, -50%); 98 | border-radius: 50%; 99 | } 100 | 101 | .center-point::after { 102 | content: ''; 103 | background-color: var(--primary-color); 104 | width: 5px; 105 | height: 5px; 106 | position: absolute; 107 | top: 50%; 108 | left: 50%; 109 | transform: translate(-50%, -50%); 110 | border-radius: 50%; 111 | } 112 | 113 | .time { 114 | font-size: 60px; 115 | } 116 | 117 | .date { 118 | color: #aaa; 119 | font-size: 14px; 120 | letter-spacing: 0.3px; 121 | text-transform: uppercase; 122 | } 123 | 124 | .date .circle { 125 | background-color: var(--primary-color); 126 | color: var(--secondary-color); 127 | border-radius: 50%; 128 | height: 18px; 129 | width: 18px; 130 | display: inline-flex; 131 | align-items: center; 132 | justify-content: center; 133 | line-height: 18px; 134 | transition: all 0.5s ease-in; 135 | font-size: 12px; 136 | } 137 | --------------------------------------------------------------------------------