├── images ├── moon.png └── sun.png ├── index.html ├── languages.js ├── script.js └── style.css /images/moon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opensource-coding/Javascript-Language-Translater/9c15ae7daf11f0a1c1339e1576f554b7769d18cf/images/moon.png -------------------------------------------------------------------------------- /images/sun.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opensource-coding/Javascript-Language-Translater/9c15ae7daf11f0a1c1339e1576f554b7769d18cf/images/sun.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 15 | 16 | Language Translater 17 | 18 | 19 |
20 | 28 |
29 |
30 |
31 |
32 | From : 33 | 44 |
45 |
46 | 52 |
0 / 5000
53 |
54 |
55 |

Or choose your document!

56 | 61 |
62 |
63 | 64 |
65 |
66 | 67 |
68 |
69 | 70 |
71 |
72 | To : 73 | 84 |
85 | 92 |
93 |

Download as a document!

94 | 98 |
99 |
100 |
101 | 102 | 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /languages.js: -------------------------------------------------------------------------------- 1 | const languages = [ 2 | { 3 | no: "0", 4 | name: "Auto", 5 | native: "Detect", 6 | code: "auto", 7 | }, 8 | { 9 | no: "1", 10 | name: "Afrikaans", 11 | native: "Afrikaans", 12 | code: "af", 13 | }, 14 | { 15 | no: "2", 16 | name: "Albanian", 17 | native: "Shqip", 18 | code: "sq", 19 | }, 20 | { 21 | no: "3", 22 | name: "Arabic", 23 | native: "عربي", 24 | code: "ar", 25 | }, 26 | { 27 | no: "4", 28 | name: "Armenian", 29 | native: "Հայերէն", 30 | code: "hy", 31 | }, 32 | { 33 | no: "5", 34 | name: "Azerbaijani", 35 | native: "آذربایجان دیلی", 36 | code: "az", 37 | }, 38 | { 39 | no: "6", 40 | name: "Basque", 41 | native: "Euskara", 42 | code: "eu", 43 | }, 44 | { 45 | no: "7", 46 | name: "Belarusian", 47 | native: "Беларуская", 48 | code: "be", 49 | }, 50 | { 51 | no: "8", 52 | name: "Bulgarian", 53 | native: "Български", 54 | code: "bg", 55 | }, 56 | { 57 | no: "9", 58 | name: "Catalan", 59 | native: "Català", 60 | code: "ca", 61 | }, 62 | { 63 | no: "10", 64 | name: "Chinese (Simplified)", 65 | native: "中文简体", 66 | code: "zh-CN", 67 | }, 68 | { 69 | no: "11", 70 | name: "Chinese (Traditional)", 71 | native: "中文繁體", 72 | code: "zh-TW", 73 | }, 74 | { 75 | no: "12", 76 | name: "Croatian", 77 | native: "Hrvatski", 78 | code: "hr", 79 | }, 80 | { 81 | no: "13", 82 | name: "Czech", 83 | native: "Čeština", 84 | code: "cs", 85 | }, 86 | { 87 | no: "14", 88 | name: "Danish", 89 | native: "Dansk", 90 | code: "da", 91 | }, 92 | { 93 | no: "15", 94 | name: "Dutch", 95 | native: "Nederlands", 96 | code: "nl", 97 | }, 98 | { 99 | no: "16", 100 | name: "English", 101 | native: "English", 102 | code: "en", 103 | }, 104 | { 105 | no: "17", 106 | name: "Estonian", 107 | native: "Eesti keel", 108 | code: "et", 109 | }, 110 | { 111 | no: "18", 112 | name: "Filipino", 113 | native: "Filipino", 114 | code: "tl", 115 | }, 116 | { 117 | no: "19", 118 | name: "Finnish", 119 | native: "Suomi", 120 | code: "fi", 121 | }, 122 | { 123 | no: "20", 124 | name: "French", 125 | native: "Français", 126 | code: "fr", 127 | }, 128 | { 129 | no: "21", 130 | name: "Galician", 131 | native: "Galego", 132 | code: "gl", 133 | }, 134 | { 135 | no: "22", 136 | name: "Georgian", 137 | native: "ქართული", 138 | code: "ka", 139 | }, 140 | { 141 | no: "23", 142 | name: "German", 143 | native: "Deutsch", 144 | code: "de", 145 | }, 146 | { 147 | no: "24", 148 | name: "Greek", 149 | native: "Ελληνικά", 150 | code: "el", 151 | }, 152 | { 153 | no: "25", 154 | name: "Haitian Creole", 155 | native: "Kreyòl ayisyen", 156 | code: "ht", 157 | }, 158 | { 159 | no: "26", 160 | name: "Hebrew", 161 | native: "עברית", 162 | code: "iw", 163 | }, 164 | { 165 | no: "27", 166 | name: "Hindi", 167 | native: "हिन्दी", 168 | code: "hi", 169 | }, 170 | { 171 | no: "28", 172 | name: "Hungarian", 173 | native: "Magyar", 174 | code: "hu", 175 | }, 176 | { 177 | no: "29", 178 | name: "Icelandic", 179 | native: "Íslenska", 180 | code: "is", 181 | }, 182 | { 183 | no: "30", 184 | name: "Indonesian", 185 | native: "Bahasa Indonesia", 186 | code: "id", 187 | }, 188 | { 189 | no: "31", 190 | name: "Irish", 191 | native: "Gaeilge", 192 | code: "ga", 193 | }, 194 | { 195 | no: "32", 196 | name: "Italian", 197 | native: "Italiano", 198 | code: "it", 199 | }, 200 | { 201 | no: "33", 202 | name: "Japanese", 203 | native: "日本語", 204 | code: "ja", 205 | }, 206 | { 207 | no: "34", 208 | name: "Korean", 209 | native: "한국어", 210 | code: "ko", 211 | }, 212 | { 213 | no: "35", 214 | name: "Latvian", 215 | native: "Latviešu", 216 | code: "lv", 217 | }, 218 | { 219 | no: "36", 220 | name: "Lithuanian", 221 | native: "Lietuvių kalba", 222 | code: "lt", 223 | }, 224 | { 225 | no: "37", 226 | name: "Macedonian", 227 | native: "Македонски", 228 | code: "mk", 229 | }, 230 | { 231 | no: "38", 232 | name: "Malay", 233 | native: "Malay", 234 | code: "ms", 235 | }, 236 | { 237 | no: "39", 238 | name: "Maltese", 239 | native: "Malti", 240 | code: "mt", 241 | }, 242 | { 243 | no: "40", 244 | name: "Norwegian", 245 | native: "Norsk", 246 | code: "no", 247 | }, 248 | { 249 | no: "41", 250 | name: "Persian", 251 | native: "فارسی", 252 | code: "fa", 253 | }, 254 | { 255 | no: "42", 256 | name: "Polish", 257 | native: "Polski", 258 | code: "pl", 259 | }, 260 | { 261 | no: "43", 262 | name: "Portuguese", 263 | native: "Português", 264 | code: "pt", 265 | }, 266 | { 267 | no: "44", 268 | name: "Romanian", 269 | native: "Română", 270 | code: "ro", 271 | }, 272 | { 273 | no: "45", 274 | name: "Russian", 275 | native: "Русский", 276 | code: "ru", 277 | }, 278 | { 279 | no: "46", 280 | name: "Serbian", 281 | native: "Српски", 282 | code: "sr", 283 | }, 284 | { 285 | no: "47", 286 | name: "Slovak", 287 | native: "Slovenčina", 288 | code: "sk", 289 | }, 290 | { 291 | no: "48", 292 | name: "Slovenian", 293 | native: "Slovensko", 294 | code: "sl", 295 | }, 296 | { 297 | no: "49", 298 | name: "Spanish", 299 | native: "Español", 300 | code: "es", 301 | }, 302 | { 303 | no: "50", 304 | name: "Swahili", 305 | native: "Kiswahili", 306 | code: "sw", 307 | }, 308 | { 309 | no: "51", 310 | name: "Swedish", 311 | native: "Svenska", 312 | code: "sv", 313 | }, 314 | { 315 | no: "52", 316 | name: "Thai", 317 | native: "ไทย", 318 | code: "th", 319 | }, 320 | { 321 | no: "53", 322 | name: "Turkish", 323 | native: "Türkçe", 324 | code: "tr", 325 | }, 326 | { 327 | no: "54", 328 | name: "Ukrainian", 329 | native: "Українська", 330 | code: "uk", 331 | }, 332 | { 333 | no: "55", 334 | name: "Urdu", 335 | native: "اردو", 336 | code: "ur", 337 | }, 338 | { 339 | no: "56", 340 | name: "Vietnamese", 341 | native: "Tiếng Việt", 342 | code: "vi", 343 | }, 344 | { 345 | no: "57", 346 | name: "Welsh", 347 | native: "Cymraeg", 348 | code: "cy", 349 | }, 350 | { 351 | no: "58", 352 | name: "Yiddish", 353 | native: "ייִדיש", 354 | code: "yi", 355 | }, 356 | ]; 357 | -------------------------------------------------------------------------------- /script.js: -------------------------------------------------------------------------------- 1 | const dropdowns = document.querySelectorAll(".dropdown-container"), 2 | inputLanguageDropdown = document.querySelector("#input-language"), 3 | outputLanguageDropdown = document.querySelector("#output-language"); 4 | 5 | function populateDropdown(dropdown, options) { 6 | dropdown.querySelector("ul").innerHTML = ""; 7 | options.forEach((option) => { 8 | const li = document.createElement("li"); 9 | const title = option.name + " (" + option.native + ")"; 10 | li.innerHTML = title; 11 | li.dataset.value = option.code; 12 | li.classList.add("option"); 13 | dropdown.querySelector("ul").appendChild(li); 14 | }); 15 | } 16 | 17 | populateDropdown(inputLanguageDropdown, languages); 18 | populateDropdown(outputLanguageDropdown, languages); 19 | 20 | dropdowns.forEach((dropdown) => { 21 | dropdown.addEventListener("click", (e) => { 22 | dropdown.classList.toggle("active"); 23 | }); 24 | 25 | dropdown.querySelectorAll(".option").forEach((item) => { 26 | item.addEventListener("click", (e) => { 27 | //remove active class from current dropdowns 28 | dropdown.querySelectorAll(".option").forEach((item) => { 29 | item.classList.remove("active"); 30 | }); 31 | item.classList.add("active"); 32 | const selected = dropdown.querySelector(".selected"); 33 | selected.innerHTML = item.innerHTML; 34 | selected.dataset.value = item.dataset.value; 35 | translate(); 36 | }); 37 | }); 38 | }); 39 | document.addEventListener("click", (e) => { 40 | dropdowns.forEach((dropdown) => { 41 | if (!dropdown.contains(e.target)) { 42 | dropdown.classList.remove("active"); 43 | } 44 | }); 45 | }); 46 | 47 | const swapBtn = document.querySelector(".swap-position"), 48 | inputLanguage = inputLanguageDropdown.querySelector(".selected"), 49 | outputLanguage = outputLanguageDropdown.querySelector(".selected"), 50 | inputTextElem = document.querySelector("#input-text"), 51 | outputTextElem = document.querySelector("#output-text"); 52 | 53 | swapBtn.addEventListener("click", (e) => { 54 | const temp = inputLanguage.innerHTML; 55 | inputLanguage.innerHTML = outputLanguage.innerHTML; 56 | outputLanguage.innerHTML = temp; 57 | 58 | const tempValue = inputLanguage.dataset.value; 59 | inputLanguage.dataset.value = outputLanguage.dataset.value; 60 | outputLanguage.dataset.value = tempValue; 61 | 62 | //swap text 63 | const tempInputText = inputTextElem.value; 64 | inputTextElem.value = outputTextElem.value; 65 | outputTextElem.value = tempInputText; 66 | 67 | translate(); 68 | }); 69 | 70 | function translate() { 71 | const inputText = inputTextElem.value; 72 | const inputLanguage = 73 | inputLanguageDropdown.querySelector(".selected").dataset.value; 74 | const outputLanguage = 75 | outputLanguageDropdown.querySelector(".selected").dataset.value; 76 | const url = `https://translate.googleapis.com/translate_a/single?client=gtx&sl=${inputLanguage}&tl=${outputLanguage}&dt=t&q=${encodeURI( 77 | inputText 78 | )}`; 79 | fetch(url) 80 | .then((response) => response.json()) 81 | .then((json) => { 82 | console.log(json); 83 | outputTextElem.value = json[0].map((item) => item[0]).join(""); 84 | }) 85 | .catch((error) => { 86 | console.log(error); 87 | }); 88 | } 89 | inputTextElem.addEventListener("input", (e) => { 90 | //limit input to 5000 characters 91 | if (inputTextElem.value.length > 5000) { 92 | inputTextElem.value = inputTextElem.value.slice(0, 5000); 93 | } 94 | translate(); 95 | }); 96 | 97 | const uploadDocument = document.querySelector("#upload-document"), 98 | uploadTitle = document.querySelector("#upload-title"); 99 | 100 | uploadDocument.addEventListener("change", (e) => { 101 | const file = e.target.files[0]; 102 | if ( 103 | file.type === "application/pdf" || 104 | file.type === "text/plain" || 105 | file.type === "application/msword" || 106 | file.type === 107 | "application/vnd.openxmlformats-officedocument.wordprocessingml.document" 108 | ) { 109 | uploadTitle.innerHTML = file.name; 110 | const reader = new FileReader(); 111 | reader.readAsText(file); 112 | reader.onload = (e) => { 113 | inputTextElem.value = e.target.result; 114 | translate(); 115 | }; 116 | } else { 117 | alert("Please upload a valid file"); 118 | } 119 | }); 120 | 121 | const downloadBtn = document.querySelector("#download-btn"); 122 | 123 | downloadBtn.addEventListener("click", (e) => { 124 | const outputText = outputTextElem.value; 125 | const outputLanguage = 126 | outputLanguageDropdown.querySelector(".selected").dataset.value; 127 | if (outputText) { 128 | const blob = new Blob([outputText], { type: "text/plain" }); 129 | const url = URL.createObjectURL(blob); 130 | const a = document.createElement("a"); 131 | a.download = `translated-to-${outputLanguage}.txt`; 132 | a.href = url; 133 | a.click(); 134 | } 135 | }); 136 | 137 | const darkModeCheckbox = document.getElementById("dark-mode-btn"); 138 | 139 | darkModeCheckbox.addEventListener("change", () => { 140 | document.body.classList.toggle("dark"); 141 | }); 142 | 143 | const inputChars = document.querySelector("#input-chars"); 144 | 145 | inputTextElem.addEventListener("input", (e) => { 146 | inputChars.innerHTML = inputTextElem.value.length; 147 | }); 148 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --primary-color: #356aff; 3 | --bg-color: #f5f5f5; 4 | --light-bg-color: #fff; 5 | --text-color: #111116; 6 | --light-text-color: #cdccd1; 7 | --primary-text-color: #fff; 8 | } 9 | ::-webkit-scrollbar { 10 | width: 5px; 11 | } 12 | ::-webkit-scrollbar-track { 13 | border-radius: 30px; 14 | background: #f1f1f1; 15 | } 16 | ::-webkit-scrollbar-thumb { 17 | border-radius: 30px; 18 | background: var(--primary-color); 19 | } 20 | ::-webkit-scrollbar-thumb:hover { 21 | background: var(--bg-color); 22 | } 23 | 24 | * { 25 | margin: 0; 26 | padding: 0; 27 | box-sizing: border-box; 28 | font-family: "Poppins", sans-serif; 29 | } 30 | body { 31 | min-height: 100vh; 32 | display: flex; 33 | align-items: center; 34 | justify-content: center; 35 | color: var(--text-color); 36 | background-color: var(--bg-color); 37 | } 38 | body.dark { 39 | --bg-color: #111116; 40 | --light-bg-color: #1c1b20; 41 | --text-color: #fff; 42 | --light-text-color: #58575c; 43 | } 44 | .container { 45 | position: relative; 46 | width: 1200px; 47 | padding: 0 20px; 48 | display: flex; 49 | gap: 10px; 50 | } 51 | .container .card { 52 | flex: 1; 53 | padding: 30px; 54 | border-radius: 20px; 55 | background-color: var(--light-bg-color); 56 | } 57 | .container .card .from, 58 | .container .card .to { 59 | display: flex; 60 | align-items: center; 61 | gap: 20px; 62 | } 63 | .container .card .from { 64 | margin-right: 20px; 65 | } 66 | .container .card .to { 67 | margin-left: 20px; 68 | } 69 | .container .card .heading { 70 | font-size: 0.8rem; 71 | font-weight: 600; 72 | color: var(--light-text-color); 73 | white-space: nowrap; 74 | } 75 | .dropdown-container { 76 | position: relative; 77 | margin-bottom: 10px; 78 | width: 100%; 79 | } 80 | .dropdown-container .dropdown-toggle { 81 | display: flex; 82 | align-items: center; 83 | padding: 15px 20px; 84 | border-radius: 30px; 85 | background-color: var(--bg-color); 86 | cursor: pointer; 87 | transition: all 0.3s; 88 | } 89 | .dropdown-container .dropdown-toggle span { 90 | flex: 1; 91 | margin-left: 10px; 92 | } 93 | .dropdown-container .dropdown-toggle ion-icon { 94 | font-size: 20px; 95 | transition: transform 0.3s ease; 96 | } 97 | .dropdown-container.active .dropdown-toggle { 98 | border-radius: 20px 20px 0 0; 99 | } 100 | .dropdown-container.active .dropdown-toggle ion-icon:last-child { 101 | transform: rotate(180deg); 102 | } 103 | .dropdown-container .dropdown-menu { 104 | position: absolute; 105 | top: 100%; 106 | left: 0; 107 | width: 100%; 108 | height: 300px; 109 | overflow: auto; 110 | display: none; 111 | padding: 20px; 112 | z-index: 1; 113 | list-style: none; 114 | flex-direction: column; 115 | background-color: var(--bg-color); 116 | transition: all 1s; 117 | border-radius: 0 0 20px 20px; 118 | } 119 | .dropdown-container .dropdown-menu::-webkit-scrollbar { 120 | display: none; 121 | } 122 | .dropdown-container.active .dropdown-menu { 123 | display: flex; 124 | } 125 | 126 | .dropdown-container .dropdown-menu li { 127 | padding: 10px 20px; 128 | border-radius: 20px; 129 | cursor: pointer; 130 | margin-bottom: 5px; 131 | border-bottom: 1px solid var(--light-bg-color); 132 | transition: all 0.3s ease; 133 | } 134 | .dropdown-container .dropdown-menu li:hover { 135 | background-color: var(--light-bg-color); 136 | } 137 | .dropdown-container .dropdown-menu li.active { 138 | color: var(--primary-text-color); 139 | background-color: var(--primary-color); 140 | } 141 | .container .text-area { 142 | position: relative; 143 | } 144 | .container textarea { 145 | width: 100%; 146 | padding: 20px; 147 | margin: 10px 0; 148 | background-color: transparent; 149 | resize: none; 150 | outline: none; 151 | border: none; 152 | color: var(--text-color); 153 | font-size: 18px; 154 | font-family: "Poppins", sans-serif; 155 | } 156 | .container .text-area .chars { 157 | position: absolute; 158 | bottom: 0; 159 | right: 0; 160 | padding: 10px; 161 | font-size: 0.8rem; 162 | color: var(--light-text-color); 163 | } 164 | .container .center { 165 | position: relative; 166 | } 167 | .swap-position { 168 | display: flex; 169 | align-items: center; 170 | justify-content: center; 171 | position: absolute; 172 | top: 30px; 173 | left: 50%; 174 | transform: translateX(-50%); 175 | width: 50px; 176 | height: 50px; 177 | border-radius: 50%; 178 | cursor: pointer; 179 | border: 5px solid var(--bg-color); 180 | transition: all 0.3s ease; 181 | color: var(--primary-text-color); 182 | background-color: var(--primary-color); 183 | } 184 | .swap-position ion-icon { 185 | font-size: 25px; 186 | } 187 | .swap-position:hover { 188 | transform: translateX(-50%) scale(1.1); 189 | } 190 | .card-bottom { 191 | display: flex; 192 | align-items: center; 193 | flex-direction: column; 194 | justify-content: center; 195 | padding-top: 20px; 196 | border-top: 2px solid var(--bg-color); 197 | } 198 | .card-bottom p { 199 | margin-bottom: 20px; 200 | } 201 | .card-bottom label { 202 | height: 50px; 203 | display: flex; 204 | align-items: center; 205 | gap: 20px; 206 | padding: 0 20px; 207 | cursor: pointer; 208 | border-radius: 30px; 209 | background-color: var(--bg-color); 210 | } 211 | .card-bottom label:hover { 212 | color: var(--primary-text-color); 213 | background-color: var(--primary-color); 214 | } 215 | .card-bottom span { 216 | font-size: 12px; 217 | pointer-events: none; 218 | } 219 | .card-bottom ion-icon { 220 | font-size: 20px; 221 | } 222 | 223 | .card-bottom button { 224 | height: 50px; 225 | display: flex; 226 | align-items: center; 227 | gap: 20px; 228 | padding: 0 20px; 229 | border-radius: 30px; 230 | border: none; 231 | outline: none; 232 | color: var(--text-color); 233 | cursor: pointer; 234 | background-color: var(--bg-color); 235 | } 236 | .card-bottom button:hover { 237 | color: var(--primary-text-color); 238 | background-color: var(--primary-color); 239 | } 240 | 241 | .mode { 242 | position: fixed; 243 | bottom: 20px; 244 | right: 20px; 245 | z-index: 1; 246 | } 247 | .toggle { 248 | position: relative; 249 | cursor: pointer; 250 | } 251 | .toggle-track { 252 | width: 24px; 253 | height: 50px; 254 | border-radius: 30px; 255 | display: flex; 256 | align-items: center; 257 | flex-direction: column; 258 | padding: 3px 0; 259 | justify-content: space-between; 260 | border: 1px solid var(--light-text-color); 261 | background-color: var(--light-bg-color); 262 | transition: all 0.2s ease; 263 | } 264 | .toggle-checkbox { 265 | display: none; 266 | } 267 | .toggle-thumb { 268 | position: absolute; 269 | top: 2px; 270 | left: 2px; 271 | width: 20px; 272 | height: 20px; 273 | border-radius: 50%; 274 | background-color: var(--primary-color); 275 | transition: all 0.5s; 276 | } 277 | .toggle input:checked ~ .toggle-thumb { 278 | transform: translateY(25px); 279 | } 280 | .toggle img { 281 | width: 20px; 282 | height: 20px; 283 | } 284 | 285 | /* media quiries */ 286 | @media (max-width: 800px) { 287 | .container { 288 | width: 100%; 289 | margin-top: 20px; 290 | flex-direction: column; 291 | } 292 | .container .card { 293 | width: 100%; 294 | } 295 | .container .card .from { 296 | margin-right: 0; 297 | } 298 | .container .card .to { 299 | margin-left: 0; 300 | } 301 | .container .card .from, 302 | .container .card .to { 303 | flex-direction: column; 304 | } 305 | 306 | .swap-position { 307 | top: 50%; 308 | left: 50%; 309 | transform: translate(-50%, -50%); 310 | } 311 | .swap-position:hover { 312 | transform: translate(-50%, -50%) scale(1.1); 313 | } 314 | .swap-position ion-icon { 315 | transform: rotate(90deg); 316 | } 317 | } 318 | --------------------------------------------------------------------------------