├── 3D-Animation-Card ├── App.js ├── images │ ├── DJ5401-100-PHSRH000-2000.png │ └── nike-shoe.png ├── index.html └── style.css ├── Analog-clock ├── clock.png ├── index.html ├── script.js └── style.css ├── Assets ├── analogclock.PNG ├── bmicalc.PNG ├── calc.PNG ├── calendar.PNG ├── cardanimation.png ├── countdown.PNG ├── musicplayer.PNG ├── parallax.PNG ├── temperature.PNG ├── todo.png ├── weather.PNG └── weight.PNG ├── BMI-Calculator ├── index.html ├── script.js └── style.css ├── CONTRIBUTIONS.md ├── Calculator ├── index.html ├── script.js ├── style.css └── vanilla-tilt.js ├── Countdown ├── App.js ├── images │ ├── balloon.svg │ └── party-hat.png ├── index.html └── style.css ├── Dynamic Calendar ├── dycalendar.css ├── dycalendar.js ├── index.html ├── script.js └── style.css ├── LICENSE ├── Music-Player ├── images │ ├── hey.jpg │ ├── summer.jpg │ └── ukulele.jpg ├── index.html ├── music │ ├── hey.mp3 │ ├── summer.mp3 │ └── ukulele.mp3 ├── script.js └── style.css ├── Parallex-website ├── images │ ├── NordicLandscape.jpg │ ├── aurora.jfif │ ├── bg1.png │ ├── girl1.png │ ├── lake.jfif │ ├── lofotons.jpg │ ├── mountainsLake.jfif │ ├── rock1.png │ ├── switzleft.png │ └── switzright.png ├── index.html ├── script.js └── style.css ├── README.md ├── SpeechToText ├── demo.png ├── script.js └── speech.html ├── Temperature-converter ├── index.html ├── script.js └── style.css ├── TicTacToe-Maximun ├── AIFile.js ├── CssFile.css ├── EventFile.js ├── Images │ ├── 123.jpg │ ├── Opng.png │ ├── Screenshot 2021-11-05 151902.png │ ├── Xpng.png │ ├── favicon.ico │ └── imgtt.jpg └── index.html ├── Todo List ├── index.html ├── script.js └── style.css ├── Video-Doboianh ├── Screenshot (301).png ├── index.html ├── index.js ├── poster.jpg ├── style.css └── video.mp4 ├── Weather-app ├── index.html ├── script.js ├── search.svg └── style.css └── Weight-converter ├── index.html ├── script.js └── style.css /3D-Animation-Card/App.js: -------------------------------------------------------------------------------- 1 | //Movement Animation to happen 2 | const card = document.querySelector(".card"); 3 | const container = document.querySelector(".container"); 4 | //Items 5 | const title = document.querySelector(".title"); 6 | const sneaker = document.querySelector(".sneaker img"); 7 | const purchase = document.querySelector(".purchase"); 8 | const description = document.querySelector(".info h3"); 9 | const sizes = document.querySelector(".sizes"); 10 | 11 | //Moving Animation Event 12 | container.addEventListener("mousemove", (e) => { 13 | let xAxis = (window.innerWidth / 2 - e.pageX) / 25; 14 | let yAxis = (window.innerHeight / 2 - e.pageY) / 25; 15 | card.style.transform = `rotateY(${xAxis}deg) rotateX(${yAxis}deg)`; 16 | }); 17 | //Animate In 18 | container.addEventListener("mouseenter", (e) => { 19 | card.style.transition = "none"; 20 | //Popout 21 | title.style.transform = "translateZ(150px)"; 22 | sneaker.style.transform = "translateZ(200px) rotateZ(-25deg)"; 23 | description.style.transform = "translateZ(125px)"; 24 | sizes.style.transform = "translateZ(100px)"; 25 | purchase.style.transform = "translateZ(75px)"; 26 | }); 27 | //Animate Out 28 | container.addEventListener("mouseleave", (e) => { 29 | card.style.transition = "all 0.5s ease"; 30 | card.style.transform = `rotateY(0deg) rotateX(0deg)`; 31 | //Popback 32 | title.style.transform = "translateZ(0px)"; 33 | sneaker.style.transform = "translateZ(0px) rotateZ(0deg)"; 34 | description.style.transform = "translateZ(0px)"; 35 | sizes.style.transform = "translateZ(0px)"; 36 | purchase.style.transform = "translateZ(0px)"; 37 | }); 38 | -------------------------------------------------------------------------------- /3D-Animation-Card/images/DJ5401-100-PHSRH000-2000.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/3D-Animation-Card/images/DJ5401-100-PHSRH000-2000.png -------------------------------------------------------------------------------- /3D-Animation-Card/images/nike-shoe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/3D-Animation-Card/images/nike-shoe.png -------------------------------------------------------------------------------- /3D-Animation-Card/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 3D Card Effect 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 |
16 |
17 |
18 | Nike 19 |
20 |
21 |

Nike Adapt

22 |

FUTURE-READY TRAINERS WITH WRAPPED BOOST FOR EXCEPTIONAL COMFORT.

23 |
24 | 25 | 26 | 27 | 28 |
29 |
30 | 31 |
32 |
33 |
34 |
35 | 36 | 37 | -------------------------------------------------------------------------------- /3D-Animation-Card/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | font-family: "Poppins", sans-serif; 9 | min-height: 100vh; 10 | display: flex; 11 | align-items: center; 12 | justify-content: center; 13 | perspective: 1000px; 14 | } 15 | 16 | .container { 17 | width: 50%; 18 | display: flex; 19 | justify-content: center; 20 | align-items: center; 21 | padding-top: 10px; 22 | padding-bottom: 10px; 23 | } 24 | .card { 25 | transform-style: preserve-3d; 26 | height: 40rem; 27 | width: 31rem; 28 | border-radius: 30px; 29 | padding: 0rem 5rem; 30 | box-shadow: 0 20px 20px rgba(0, 0, 0, 0.2), 0px 0px 50px rgba(0, 0, 0, 0.2); 31 | } 32 | 33 | .sneaker { 34 | min-height: 35vh; 35 | display: flex; 36 | align-items: center; 37 | justify-content: center; 38 | } 39 | 40 | .sneaker img { 41 | width: 16rem; 42 | z-index: 2; 43 | transition: all 1s ease-out; 44 | } 45 | 46 | .circle { 47 | margin-top: 20px; 48 | width: 14rem; 49 | height: 14rem; 50 | background: linear-gradient( 51 | to right, 52 | rgba(102, 101, 101, 0.75), 53 | rgba(8, 83, 156, 0.75) 54 | ); 55 | position: absolute; 56 | border-radius: 50%; 57 | z-index: 1; 58 | } 59 | 60 | .info h1 { 61 | font-size: 2.5rem; 62 | padding: 1.5rem 0rem; 63 | transition: all 0.75s ease-out; 64 | } 65 | .info h3 { 66 | font-size: 1rem; 67 | padding-top: 0.5rem; 68 | margin-bottom: 2rem; 69 | color: #585858; 70 | font-weight: lighter; 71 | transition: all 0.75s ease-out; 72 | } 73 | .sizes { 74 | display: flex; 75 | justify-content: space-between; 76 | transition: all 0.75s ease-out; 77 | } 78 | .sizes button { 79 | padding: 0.5rem 2rem; 80 | background: none; 81 | border: none; 82 | box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.2); 83 | border-radius: 30px; 84 | cursor: pointer; 85 | font-weight: bold; 86 | color: #585858; 87 | } 88 | 89 | button.active { 90 | background: #585858; 91 | color: white; 92 | } 93 | 94 | .purchase { 95 | margin-top: 3rem; 96 | transition: all 0.75s ease-out; 97 | } 98 | 99 | .purchase button { 100 | width: 100%; 101 | padding: 1rem 0rem; 102 | background: #768fff; 103 | border: none; 104 | color: white; 105 | cursor: pointer; 106 | border-radius: 30px; 107 | font-weight: bolder; 108 | } 109 | -------------------------------------------------------------------------------- /Analog-clock/clock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/Analog-clock/clock.png -------------------------------------------------------------------------------- /Analog-clock/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Analog Clock 9 | 10 | 11 | 12 |

Analog Clock

13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /Analog-clock/script.js: -------------------------------------------------------------------------------- 1 | const deg = 6; 2 | const hr = document.querySelector("#hr"); 3 | const mn = document.querySelector("#mn"); 4 | const sc = document.querySelector("#sc"); 5 | 6 | // *** SetInterval method allows us to refresh the function every second 7 | setInterval(() => { 8 | // Getting the time from the Date module 9 | let day = new Date(); 10 | let hh = day.getHours() * 30; 11 | let mm = day.getMinutes() * deg; 12 | let ss = day.getSeconds() * deg; 13 | 14 | hr.style.transform = `rotateZ(${hh + mm / 12}deg)`; 15 | mn.style.transform = `rotateZ(${mm}deg)`; 16 | sc.style.transform = `rotateZ(${ss}deg)`; 17 | }); 18 | -------------------------------------------------------------------------------- /Analog-clock/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | display: flex; 9 | justify-content: center; 10 | align-items: center; 11 | min-height: 100vh; 12 | background: #091921; 13 | flex-direction: column; 14 | font-family: "Lato", sans-serif; 15 | } 16 | 17 | h1 { 18 | display: flex; 19 | align-items: center; 20 | justify-content: center; 21 | color: rgb(230, 230, 230); 22 | margin-bottom: 80px; 23 | font-size: 40px; 24 | } 25 | 26 | .clock { 27 | width: 350px; 28 | height: 350px; 29 | display: flex; 30 | justify-content: center; 31 | align-items: center; 32 | background: url(./clock.png); 33 | background-size: cover; 34 | border: 4px solid #091921; 35 | border-radius: 50%; 36 | box-shadow: 0 -15px 15px rgba(255, 255, 255, 0.05), 37 | inset 0 -15px 15px rgba(255, 255, 255, 0.05), 0 15px 15px rgba(0, 0, 0, 0.3), 38 | inset 0 15px 15px rgba(0, 0, 0, 0.3); 39 | } 40 | 41 | .clock::before { 42 | content: ""; 43 | position: absolute; 44 | width: 15px; 45 | height: 15px; 46 | background: #fff; 47 | border-radius: 50%; 48 | z-index: 10000; 49 | } 50 | 51 | .clock .hour, 52 | .clock .min, 53 | .clock .sec { 54 | position: absolute; 55 | } 56 | 57 | .clock .hour, 58 | .hr { 59 | width: 160px; 60 | height: 160px; 61 | } 62 | 63 | .clock .min, 64 | .mn { 65 | width: 190px; 66 | height: 190px; 67 | } 68 | 69 | .clock .sec, 70 | .sc { 71 | width: 230px; 72 | height: 230px; 73 | } 74 | 75 | .hr, 76 | .mn, 77 | .sc { 78 | display: flex; 79 | justify-content: center; 80 | /* align-items: center; */ 81 | position: absolute; 82 | border-radius: 50%; 83 | } 84 | 85 | .hr:before { 86 | content: ""; 87 | position: absolute; 88 | width: 8px; 89 | height: 80px; 90 | background: #ff105e; 91 | z-index: 10; 92 | border-radius: 6px 6px 0 0; 93 | } 94 | 95 | .mn:before { 96 | content: ""; 97 | position: absolute; 98 | width: 4px; 99 | height: 90px; 100 | background: #fff; 101 | z-index: 11; 102 | border-radius: 6px 6px 0 0; 103 | } 104 | 105 | .sc:before { 106 | content: ""; 107 | position: absolute; 108 | width: 2px; 109 | height: 150px; 110 | background: #fff; 111 | z-index: 12; 112 | border-radius: 6px 6px 0 0; 113 | } 114 | -------------------------------------------------------------------------------- /Assets/analogclock.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/Assets/analogclock.PNG -------------------------------------------------------------------------------- /Assets/bmicalc.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/Assets/bmicalc.PNG -------------------------------------------------------------------------------- /Assets/calc.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/Assets/calc.PNG -------------------------------------------------------------------------------- /Assets/calendar.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/Assets/calendar.PNG -------------------------------------------------------------------------------- /Assets/cardanimation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/Assets/cardanimation.png -------------------------------------------------------------------------------- /Assets/countdown.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/Assets/countdown.PNG -------------------------------------------------------------------------------- /Assets/musicplayer.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/Assets/musicplayer.PNG -------------------------------------------------------------------------------- /Assets/parallax.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/Assets/parallax.PNG -------------------------------------------------------------------------------- /Assets/temperature.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/Assets/temperature.PNG -------------------------------------------------------------------------------- /Assets/todo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/Assets/todo.png -------------------------------------------------------------------------------- /Assets/weather.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/Assets/weather.PNG -------------------------------------------------------------------------------- /Assets/weight.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/Assets/weight.PNG -------------------------------------------------------------------------------- /BMI-Calculator/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | BMI Calculator 9 | 10 | 11 | 12 | 13 | 14 |
15 |

BMI Calculator

16 | 17 |

Height

18 | 19 | 20 |

Weight

21 | 22 | 23 |

24 | 25 |

Please enter your height[cm] and weight[kg] above.

26 |
27 | 28 | -------------------------------------------------------------------------------- /BMI-Calculator/script.js: -------------------------------------------------------------------------------- 1 | function BMI() { 2 | let height = document.getElementById("h").value; 3 | let weight = document.getElementById("w").value; 4 | let bmi = weight / (((height / 100) * height) / 100); 5 | let bmio = bmi.toFixed(2); 6 | 7 | document.getElementById("result").innerHTML = "Your BMI is " + bmio; 8 | } 9 | -------------------------------------------------------------------------------- /BMI-Calculator/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | text-align: center; 5 | font-family: sans-serif; 6 | background-image: linear-gradient(120deg, #6bff77, #5f27cd); 7 | min-height: 100vh; 8 | } 9 | 10 | .container { 11 | width: 500px; 12 | position: absolute; 13 | top: 50%; 14 | left: 50%; 15 | background-color: #fff; 16 | transform: translate(-50%, -50%); 17 | padding: 20px; 18 | border-radius: 10px; 19 | box-shadow: 1px 1px 20px #fdbfbf; 20 | } 21 | 22 | h2 { 23 | font-size: 34px; 24 | font-weight: 600; 25 | } 26 | 27 | .text { 28 | text-align: left; 29 | font-weight: 500; 30 | margin-left: 150px; 31 | } 32 | 33 | #w, 34 | #h { 35 | color: #222f3e; 36 | text-align: left; 37 | font-size: 20px; 38 | font-weight: 200; 39 | outline: none; 40 | border: none; 41 | background: none; 42 | border-bottom: 1px solid #341f97; 43 | width: 200px; 44 | } 45 | 46 | #w:focus, 47 | #h:focus { 48 | border-bottom: 2px solid #341f97; 49 | width: 300px; 50 | transition: 0.5s; 51 | } 52 | 53 | #result { 54 | color: #341f97; 55 | } 56 | 57 | #btn { 58 | font-family: inherit; 59 | margin-top: 10px; 60 | border: none; 61 | color: #fff; 62 | background-image: linear-gradient(120deg, #6bff72, #5f27cd); 63 | width: 150px; 64 | padding: 10px; 65 | border-radius: 30px; 66 | outline: none; 67 | cursor: pointer; 68 | } 69 | 70 | #btn:hover { 71 | box-shadow: 1px 1px 10px #341f97; 72 | } 73 | 74 | #info { 75 | font-size: 12px; 76 | font-family: inherit; 77 | margin-top: 15px; 78 | } 79 | -------------------------------------------------------------------------------- /CONTRIBUTIONS.md: -------------------------------------------------------------------------------- 1 | ### Steps to contribute! 2 | 3 | # 👉 Fork this repository 4 | 5 | # 👉 Clone the repository 6 | 7 | # 👉 Create a branch `projectname-username-branch` 8 | 9 | # 👉 Add your projects in a new directory, the name of directory should be your `ProjectName/USERNAME` 10 | 11 | # 👉 Attach some SCREENSHOTS or GIF of your working project in the description _❗Important❗_. 12 | 13 | # 👉 Add `One project` at a time 14 | 15 | # 👉 Add & commit 16 | 17 | # 👉 Push changes to GitHub 18 | 19 | # 👉 Compare & Submit a Pull Request 20 | 21 | # 👉 Leave a ⭐ if you liked working on the project. 22 | 23 | We're happy to merge awesome portfolio to this repository! 24 | -------------------------------------------------------------------------------- /Calculator/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Glassmorphism Calculator 9 | 10 | 11 | 12 |
13 |
14 | 15 | c 16 | / 17 | * 18 | 7 19 | 8 20 | 9 21 | - 22 | 4 23 | 5 24 | 6 25 | + 26 | 1 27 | 2 28 | 3 29 | 0 30 | 00 31 | . 32 | = 33 |
34 |
35 | ; 36 | 37 | 38 | -------------------------------------------------------------------------------- /Calculator/script.js: -------------------------------------------------------------------------------- 1 | VanillaTilt.init(document.querySelector(".container"), { 2 | max: 12, 3 | speed: 400, 4 | glare: true, 5 | "max-glare": 0.2, 6 | }); 7 | -------------------------------------------------------------------------------- /Calculator/style.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css?family=Quicksand:wght@300;400;500&display=swap"); 2 | 3 | * { 4 | margin: 0; 5 | padding: 0; 6 | box-sizing: border-box; 7 | font-family: "Quicksand", sans-serif; 8 | } 9 | 10 | body { 11 | display: flex; 12 | justify-content: center; 13 | align-items: center; 14 | min-height: 100vh; 15 | background: #091921; 16 | } 17 | 18 | body::before { 19 | content: ""; 20 | position: absolute; 21 | top: 0; 22 | left: 0; 23 | width: 100%; 24 | height: 100%; 25 | background: linear-gradient(#2141f3, #5dff63); 26 | clip-path: circle(22% at 30% 20%); 27 | } 28 | 29 | body::after { 30 | content: ""; 31 | position: absolute; 32 | top: 0; 33 | left: 0; 34 | width: 100%; 35 | height: 100%; 36 | background: linear-gradient(#fff9e8, #a749ff); 37 | clip-path: circle(20% at 70% 90%); 38 | } 39 | 40 | .container { 41 | position: relative; 42 | background: rgba(255, 255, 255, 0.05); 43 | border-radius: 6px; 44 | overflow: hidden; 45 | z-index: 10; 46 | backdrop-filter: blur(15px); 47 | border-top: 1px sold rgba(255, 255, 255, 0.2); 48 | border-left: 1px sold rgba(255, 255, 255, 0.2); 49 | box-shadow: 5px 5px 30px rgba(0, 0, 0, 0.2); 50 | } 51 | 52 | .container .calculator { 53 | position: relative; 54 | display: grid; 55 | } 56 | 57 | .container .calculator .value { 58 | grid-column: span 4; 59 | height: 140px; 60 | width: 300px; 61 | text-align: right; 62 | border: none; 63 | outline: none; 64 | padding: 10px; 65 | font-size: 30px; 66 | background: transparent; 67 | color: #fff; 68 | border-bottom: 1px sold rgba(255, 255, 255, 0.05); 69 | border-right: 1px sold rgba(255, 255, 255, 0.05); 70 | } 71 | 72 | .container .calculator span { 73 | display: grid; 74 | place-items: center; 75 | height: 75px; 76 | width: 75px; 77 | color: #fff; 78 | font-weight: 400; 79 | cursor: pointer; 80 | font-size: 20px; 81 | user-select: none; 82 | border-bottom: 1px sold rgba(255, 255, 255, 0.05); 83 | border-right: 1px sold rgba(255, 255, 255, 0.05); 84 | transition: 0.5s; 85 | } 86 | 87 | .container .calculator span:hover { 88 | transition: 0s; 89 | background: rgba(255, 255, 255, 0.05); 90 | } 91 | 92 | .container .calculator span:active { 93 | background: #14ff47; 94 | color: #192f00; 95 | font-size: 24px; 96 | font-weight: 500; 97 | } 98 | 99 | .container .calculator .clear { 100 | grid-column: span 2; 101 | width: 150px; 102 | background: rgba(255, 255, 255, 0.05); 103 | } 104 | 105 | .container .calculator .plus { 106 | grid-row: span 2; 107 | height: 150px; 108 | } 109 | 110 | .equal { 111 | background: rgba(255, 255, 255, 0.05); 112 | } 113 | -------------------------------------------------------------------------------- /Calculator/vanilla-tilt.js: -------------------------------------------------------------------------------- 1 | var VanillaTilt = (function () { 2 | 'use strict'; 3 | 4 | /** 5 | * Created by Sergiu Șandor (micku7zu) on 1/27/2017. 6 | * Original idea: https://github.com/gijsroge/tilt.js 7 | * MIT License. 8 | * Version 1.7.1 9 | */ 10 | 11 | class VanillaTilt { 12 | constructor(element, settings = {}) { 13 | if (!(element instanceof Node)) { 14 | throw ("Can't initialize VanillaTilt because " + element + " is not a Node."); 15 | } 16 | 17 | this.width = null; 18 | this.height = null; 19 | this.clientWidth = null; 20 | this.clientHeight = null; 21 | this.left = null; 22 | this.top = null; 23 | 24 | // for Gyroscope sampling 25 | this.gammazero = null; 26 | this.betazero = null; 27 | this.lastgammazero = null; 28 | this.lastbetazero = null; 29 | 30 | this.transitionTimeout = null; 31 | this.updateCall = null; 32 | this.event = null; 33 | 34 | this.updateBind = this.update.bind(this); 35 | this.resetBind = this.reset.bind(this); 36 | 37 | this.element = element; 38 | this.settings = this.extendSettings(settings); 39 | 40 | this.reverse = this.settings.reverse ? -1 : 1; 41 | this.glare = VanillaTilt.isSettingTrue(this.settings.glare); 42 | this.glarePrerender = VanillaTilt.isSettingTrue(this.settings["glare-prerender"]); 43 | this.fullPageListening = VanillaTilt.isSettingTrue(this.settings["full-page-listening"]); 44 | this.gyroscope = VanillaTilt.isSettingTrue(this.settings.gyroscope); 45 | this.gyroscopeSamples = this.settings.gyroscopeSamples; 46 | 47 | this.elementListener = this.getElementListener(); 48 | 49 | if (this.glare) { 50 | this.prepareGlare(); 51 | } 52 | 53 | if (this.fullPageListening) { 54 | this.updateClientSize(); 55 | } 56 | 57 | this.addEventListeners(); 58 | this.updateInitialPosition(); 59 | } 60 | 61 | static isSettingTrue(setting) { 62 | return setting === "" || setting === true || setting === 1; 63 | } 64 | 65 | /** 66 | * Method returns element what will be listen mouse events 67 | * @return {Node} 68 | */ 69 | getElementListener() { 70 | if (this.fullPageListening) { 71 | return window.document; 72 | } 73 | 74 | if (typeof this.settings["mouse-event-element"] === "string") { 75 | const mouseEventElement = document.querySelector(this.settings["mouse-event-element"]); 76 | 77 | if (mouseEventElement) { 78 | return mouseEventElement; 79 | } 80 | } 81 | 82 | if (this.settings["mouse-event-element"] instanceof Node) { 83 | return this.settings["mouse-event-element"]; 84 | } 85 | 86 | return this.element; 87 | } 88 | 89 | /** 90 | * Method set listen methods for this.elementListener 91 | * @return {Node} 92 | */ 93 | addEventListeners() { 94 | this.onMouseEnterBind = this.onMouseEnter.bind(this); 95 | this.onMouseMoveBind = this.onMouseMove.bind(this); 96 | this.onMouseLeaveBind = this.onMouseLeave.bind(this); 97 | this.onWindowResizeBind = this.onWindowResize.bind(this); 98 | this.onDeviceOrientationBind = this.onDeviceOrientation.bind(this); 99 | 100 | this.elementListener.addEventListener("mouseenter", this.onMouseEnterBind); 101 | this.elementListener.addEventListener("mouseleave", this.onMouseLeaveBind); 102 | this.elementListener.addEventListener("mousemove", this.onMouseMoveBind); 103 | 104 | if (this.glare || this.fullPageListening) { 105 | window.addEventListener("resize", this.onWindowResizeBind); 106 | } 107 | 108 | if (this.gyroscope) { 109 | window.addEventListener("deviceorientation", this.onDeviceOrientationBind); 110 | } 111 | } 112 | 113 | /** 114 | * Method remove event listeners from current this.elementListener 115 | */ 116 | removeEventListeners() { 117 | this.elementListener.removeEventListener("mouseenter", this.onMouseEnterBind); 118 | this.elementListener.removeEventListener("mouseleave", this.onMouseLeaveBind); 119 | this.elementListener.removeEventListener("mousemove", this.onMouseMoveBind); 120 | 121 | if (this.gyroscope) { 122 | window.removeEventListener("deviceorientation", this.onDeviceOrientationBind); 123 | } 124 | 125 | if (this.glare || this.fullPageListening) { 126 | window.removeEventListener("resize", this.onWindowResizeBind); 127 | } 128 | } 129 | 130 | destroy() { 131 | clearTimeout(this.transitionTimeout); 132 | if (this.updateCall !== null) { 133 | cancelAnimationFrame(this.updateCall); 134 | } 135 | 136 | this.reset(); 137 | 138 | this.removeEventListeners(); 139 | this.element.vanillaTilt = null; 140 | delete this.element.vanillaTilt; 141 | 142 | this.element = null; 143 | } 144 | 145 | onDeviceOrientation(event) { 146 | if (event.gamma === null || event.beta === null) { 147 | return; 148 | } 149 | 150 | this.updateElementPosition(); 151 | 152 | if (this.gyroscopeSamples > 0) { 153 | this.lastgammazero = this.gammazero; 154 | this.lastbetazero = this.betazero; 155 | 156 | if (this.gammazero === null) { 157 | this.gammazero = event.gamma; 158 | this.betazero = event.beta; 159 | } else { 160 | this.gammazero = (event.gamma + this.lastgammazero) / 2; 161 | this.betazero = (event.beta + this.lastbetazero) / 2; 162 | } 163 | 164 | this.gyroscopeSamples -= 1; 165 | } 166 | 167 | const totalAngleX = this.settings.gyroscopeMaxAngleX - this.settings.gyroscopeMinAngleX; 168 | const totalAngleY = this.settings.gyroscopeMaxAngleY - this.settings.gyroscopeMinAngleY; 169 | 170 | const degreesPerPixelX = totalAngleX / this.width; 171 | const degreesPerPixelY = totalAngleY / this.height; 172 | 173 | const angleX = event.gamma - (this.settings.gyroscopeMinAngleX + this.gammazero); 174 | const angleY = event.beta - (this.settings.gyroscopeMinAngleY + this.betazero); 175 | 176 | const posX = angleX / degreesPerPixelX; 177 | const posY = angleY / degreesPerPixelY; 178 | 179 | if (this.updateCall !== null) { 180 | cancelAnimationFrame(this.updateCall); 181 | } 182 | 183 | this.event = { 184 | clientX: posX + this.left, 185 | clientY: posY + this.top, 186 | }; 187 | 188 | this.updateCall = requestAnimationFrame(this.updateBind); 189 | } 190 | 191 | onMouseEnter() { 192 | this.updateElementPosition(); 193 | this.element.style.willChange = "transform"; 194 | this.setTransition(); 195 | } 196 | 197 | onMouseMove(event) { 198 | if (this.updateCall !== null) { 199 | cancelAnimationFrame(this.updateCall); 200 | } 201 | 202 | this.event = event; 203 | this.updateCall = requestAnimationFrame(this.updateBind); 204 | } 205 | 206 | onMouseLeave() { 207 | this.setTransition(); 208 | 209 | if (this.settings.reset) { 210 | requestAnimationFrame(this.resetBind); 211 | } 212 | } 213 | 214 | reset() { 215 | this.event = { 216 | clientX: this.left + this.width / 2, 217 | clientY: this.top + this.height / 2 218 | }; 219 | 220 | if (this.element && this.element.style) { 221 | this.element.style.transform = `perspective(${this.settings.perspective}px) ` + 222 | `rotateX(0deg) ` + 223 | `rotateY(0deg) ` + 224 | `scale3d(1, 1, 1)`; 225 | } 226 | 227 | this.resetGlare(); 228 | } 229 | 230 | resetGlare() { 231 | if (this.glare) { 232 | this.glareElement.style.transform = "rotate(180deg) translate(-50%, -50%)"; 233 | this.glareElement.style.opacity = "0"; 234 | } 235 | } 236 | 237 | updateInitialPosition() { 238 | if (this.settings.startX === 0 && this.settings.startY === 0) { 239 | return; 240 | } 241 | 242 | this.onMouseEnter(); 243 | 244 | if (this.fullPageListening) { 245 | this.event = { 246 | clientX: (this.settings.startX + this.settings.max) / (2 * this.settings.max) * this.clientWidth, 247 | clientY: (this.settings.startY + this.settings.max) / (2 * this.settings.max) * this.clientHeight 248 | }; 249 | } else { 250 | this.event = { 251 | clientX: this.left + ((this.settings.startX + this.settings.max) / (2 * this.settings.max) * this.width), 252 | clientY: this.top + ((this.settings.startY + this.settings.max) / (2 * this.settings.max) * this.height) 253 | }; 254 | } 255 | 256 | 257 | let backupScale = this.settings.scale; 258 | this.settings.scale = 1; 259 | this.update(); 260 | this.settings.scale = backupScale; 261 | this.resetGlare(); 262 | } 263 | 264 | getValues() { 265 | let x, y; 266 | 267 | if (this.fullPageListening) { 268 | x = this.event.clientX / this.clientWidth; 269 | y = this.event.clientY / this.clientHeight; 270 | } else { 271 | x = (this.event.clientX - this.left) / this.width; 272 | y = (this.event.clientY - this.top) / this.height; 273 | } 274 | 275 | x = Math.min(Math.max(x, 0), 1); 276 | y = Math.min(Math.max(y, 0), 1); 277 | 278 | let tiltX = (this.reverse * (this.settings.max - x * this.settings.max * 2)).toFixed(2); 279 | let tiltY = (this.reverse * (y * this.settings.max * 2 - this.settings.max)).toFixed(2); 280 | let angle = Math.atan2(this.event.clientX - (this.left + this.width / 2), -(this.event.clientY - (this.top + this.height / 2))) * (180 / Math.PI); 281 | 282 | return { 283 | tiltX: tiltX, 284 | tiltY: tiltY, 285 | percentageX: x * 100, 286 | percentageY: y * 100, 287 | angle: angle 288 | }; 289 | } 290 | 291 | updateElementPosition() { 292 | let rect = this.element.getBoundingClientRect(); 293 | 294 | this.width = this.element.offsetWidth; 295 | this.height = this.element.offsetHeight; 296 | this.left = rect.left; 297 | this.top = rect.top; 298 | } 299 | 300 | update() { 301 | let values = this.getValues(); 302 | 303 | this.element.style.transform = "perspective(" + this.settings.perspective + "px) " + 304 | "rotateX(" + (this.settings.axis === "x" ? 0 : values.tiltY) + "deg) " + 305 | "rotateY(" + (this.settings.axis === "y" ? 0 : values.tiltX) + "deg) " + 306 | "scale3d(" + this.settings.scale + ", " + this.settings.scale + ", " + this.settings.scale + ")"; 307 | 308 | if (this.glare) { 309 | this.glareElement.style.transform = `rotate(${values.angle}deg) translate(-50%, -50%)`; 310 | this.glareElement.style.opacity = `${values.percentageY * this.settings["max-glare"] / 100}`; 311 | } 312 | 313 | this.element.dispatchEvent(new CustomEvent("tiltChange", { 314 | "detail": values 315 | })); 316 | 317 | this.updateCall = null; 318 | } 319 | 320 | /** 321 | * Appends the glare element (if glarePrerender equals false) 322 | * and sets the default style 323 | */ 324 | prepareGlare() { 325 | // If option pre-render is enabled we assume all html/css is present for an optimal glare effect. 326 | if (!this.glarePrerender) { 327 | // Create glare element 328 | const jsTiltGlare = document.createElement("div"); 329 | jsTiltGlare.classList.add("js-tilt-glare"); 330 | 331 | const jsTiltGlareInner = document.createElement("div"); 332 | jsTiltGlareInner.classList.add("js-tilt-glare-inner"); 333 | 334 | jsTiltGlare.appendChild(jsTiltGlareInner); 335 | this.element.appendChild(jsTiltGlare); 336 | } 337 | 338 | this.glareElementWrapper = this.element.querySelector(".js-tilt-glare"); 339 | this.glareElement = this.element.querySelector(".js-tilt-glare-inner"); 340 | 341 | if (this.glarePrerender) { 342 | return; 343 | } 344 | 345 | Object.assign(this.glareElementWrapper.style, { 346 | "position": "absolute", 347 | "top": "0", 348 | "left": "0", 349 | "width": "100%", 350 | "height": "100%", 351 | "overflow": "hidden", 352 | "pointer-events": "none" 353 | }); 354 | 355 | Object.assign(this.glareElement.style, { 356 | "position": "absolute", 357 | "top": "50%", 358 | "left": "50%", 359 | "pointer-events": "none", 360 | "background-image": `linear-gradient(0deg, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%)`, 361 | "width": `${this.element.offsetWidth * 2}px`, 362 | "height": `${this.element.offsetWidth * 2}px`, 363 | "transform": "rotate(180deg) translate(-50%, -50%)", 364 | "transform-origin": "0% 0%", 365 | "opacity": "0", 366 | }); 367 | } 368 | 369 | updateGlareSize() { 370 | if (this.glare) { 371 | Object.assign(this.glareElement.style, { 372 | "width": `${this.element.offsetWidth * 2}`, 373 | "height": `${this.element.offsetWidth * 2}`, 374 | }); 375 | } 376 | } 377 | 378 | updateClientSize() { 379 | this.clientWidth = window.innerWidth 380 | || document.documentElement.clientWidth 381 | || document.body.clientWidth; 382 | 383 | this.clientHeight = window.innerHeight 384 | || document.documentElement.clientHeight 385 | || document.body.clientHeight; 386 | } 387 | 388 | onWindowResize() { 389 | this.updateGlareSize(); 390 | this.updateClientSize(); 391 | } 392 | 393 | setTransition() { 394 | clearTimeout(this.transitionTimeout); 395 | this.element.style.transition = this.settings.speed + "ms " + this.settings.easing; 396 | if (this.glare) this.glareElement.style.transition = `opacity ${this.settings.speed}ms ${this.settings.easing}`; 397 | 398 | this.transitionTimeout = setTimeout(() => { 399 | this.element.style.transition = ""; 400 | if (this.glare) { 401 | this.glareElement.style.transition = ""; 402 | } 403 | }, this.settings.speed); 404 | 405 | } 406 | 407 | /** 408 | * Method return patched settings of instance 409 | * @param {boolean} settings.reverse - reverse the tilt direction 410 | * @param {number} settings.max - max tilt rotation (degrees) 411 | * @param {startX} settings.startX - the starting tilt on the X axis, in degrees. Default: 0 412 | * @param {startY} settings.startY - the starting tilt on the Y axis, in degrees. Default: 0 413 | * @param {number} settings.perspective - Transform perspective, the lower the more extreme the tilt gets 414 | * @param {string} settings.easing - Easing on enter/exit 415 | * @param {number} settings.scale - 2 = 200%, 1.5 = 150%, etc.. 416 | * @param {number} settings.speed - Speed of the enter/exit transition 417 | * @param {boolean} settings.transition - Set a transition on enter/exit 418 | * @param {string|null} settings.axis - What axis should be disabled. Can be X or Y 419 | * @param {boolean} settings.glare - What axis should be disabled. Can be X or Y 420 | * @param {number} settings.max-glare - the maximum "glare" opacity (1 = 100%, 0.5 = 50%) 421 | * @param {boolean} settings.glare-prerender - false = VanillaTilt creates the glare elements for you, otherwise 422 | * @param {boolean} settings.full-page-listening - If true, parallax effect will listen to mouse move events on the whole document, not only the selected element 423 | * @param {string|object} settings.mouse-event-element - String selector or link to HTML-element what will be listen mouse events 424 | * @param {boolean} settings.reset - false = If the tilt effect has to be reset on exit 425 | * @param {gyroscope} settings.gyroscope - Enable tilting by deviceorientation events 426 | * @param {gyroscopeSensitivity} settings.gyroscopeSensitivity - Between 0 and 1 - The angle at which max tilt position is reached. 1 = 90deg, 0.5 = 45deg, etc.. 427 | * @param {gyroscopeSamples} settings.gyroscopeSamples - How many gyroscope moves to decide the starting position. 428 | */ 429 | extendSettings(settings) { 430 | let defaultSettings = { 431 | reverse: false, 432 | max: 15, 433 | startX: 0, 434 | startY: 0, 435 | perspective: 1000, 436 | easing: "cubic-bezier(.03,.98,.52,.99)", 437 | scale: 1, 438 | speed: 300, 439 | transition: true, 440 | axis: null, 441 | glare: false, 442 | "max-glare": 1, 443 | "glare-prerender": false, 444 | "full-page-listening": false, 445 | "mouse-event-element": null, 446 | reset: true, 447 | gyroscope: true, 448 | gyroscopeMinAngleX: -45, 449 | gyroscopeMaxAngleX: 45, 450 | gyroscopeMinAngleY: -45, 451 | gyroscopeMaxAngleY: 45, 452 | gyroscopeSamples: 10 453 | }; 454 | 455 | let newSettings = {}; 456 | for (var property in defaultSettings) { 457 | if (property in settings) { 458 | newSettings[property] = settings[property]; 459 | } else if (this.element.hasAttribute("data-tilt-" + property)) { 460 | let attribute = this.element.getAttribute("data-tilt-" + property); 461 | try { 462 | newSettings[property] = JSON.parse(attribute); 463 | } catch (e) { 464 | newSettings[property] = attribute; 465 | } 466 | 467 | } else { 468 | newSettings[property] = defaultSettings[property]; 469 | } 470 | } 471 | 472 | return newSettings; 473 | } 474 | 475 | static init(elements, settings) { 476 | if (elements instanceof Node) { 477 | elements = [elements]; 478 | } 479 | 480 | if (elements instanceof NodeList) { 481 | elements = [].slice.call(elements); 482 | } 483 | 484 | if (!(elements instanceof Array)) { 485 | return; 486 | } 487 | 488 | elements.forEach((element) => { 489 | if (!("vanillaTilt" in element)) { 490 | element.vanillaTilt = new VanillaTilt(element, settings); 491 | } 492 | }); 493 | } 494 | } 495 | 496 | if (typeof document !== "undefined") { 497 | /* expose the class to window */ 498 | window.VanillaTilt = VanillaTilt; 499 | 500 | /** 501 | * Auto load 502 | */ 503 | VanillaTilt.init(document.querySelectorAll("[data-tilt]")); 504 | } 505 | 506 | return VanillaTilt; 507 | 508 | }()); 509 | -------------------------------------------------------------------------------- /Countdown/App.js: -------------------------------------------------------------------------------- 1 | const countdown = () => { 2 | const countDate = new Date("Dec 19, 2021 00:00:00").getTime(); 3 | const now = new Date().getTime(); 4 | const gap = countDate - now; 5 | 6 | // Time as normal units 7 | const second = 1000; 8 | const minute = second * 60; 9 | const hour = minute * 60; 10 | const day = hour * 24; 11 | 12 | // Converting our gap to normal units not ms 13 | const textDay = Math.floor(gap / day); 14 | const textHour = Math.floor((gap % day) / hour); 15 | const textMinute = Math.floor((gap % hour) / minute); 16 | const textSecond = Math.floor((gap % minute) / second); 17 | 18 | // Rendering countdown values into DOM 19 | document.querySelector(".day").innerText = textDay; 20 | document.querySelector(".hour").innerText = textHour; 21 | document.querySelector(".min").innerText = textMinute; 22 | document.querySelector(".sec").innerText = textSecond; 23 | }; 24 | 25 | // calling the function for every second (1000ms = 1s) 26 | setInterval(countdown, 1000); 27 | -------------------------------------------------------------------------------- /Countdown/images/balloon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Countdown/images/party-hat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/Countdown/images/party-hat.png -------------------------------------------------------------------------------- /Countdown/index.html: -------------------------------------------------------------------------------- 1 | | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Birthday Countdown 11 | 12 | 13 |
14 |
15 |

Countdown to my Birthday!

16 |
17 |
18 |

Time

19 |

Day

20 |
21 |
22 |

Time

23 |

Hour

24 |
25 |
26 |

Time

27 |

Minute

28 |
29 |
30 |

Time

31 |

Second

32 |
33 |
34 |
35 | Baloons 36 |

GitHub: Ratheshan03

37 |
38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /Countdown/style.css: -------------------------------------------------------------------------------- 1 | /* General Styles */ 2 | 3 | * { 4 | margin: 0; 5 | padding: 0; 6 | box-sizing: border-box; 7 | } 8 | 9 | body { 10 | font-family: "Lato", sans-serif; 11 | background-color: #f1fcee; 12 | } 13 | 14 | /* Content styles */ 15 | 16 | h2 { 17 | font-size: 4.5rem; 18 | font-weight: bold; 19 | padding: 2rem; 20 | color: #1d3557; 21 | } 22 | 23 | .coming-soon { 24 | min-height: 90vh; 25 | display: flex; 26 | flex-direction: column; 27 | align-items: center; 28 | justify-content: center; 29 | } 30 | 31 | .countdown { 32 | display: flex; 33 | justify-content: space-around; 34 | text-align: center; 35 | } 36 | 37 | .day, 38 | .hour, 39 | .min, 40 | .sec { 41 | font-size: 3rem; 42 | color: #457b9d; 43 | } 44 | 45 | .waiting { 46 | height: 50vh; 47 | margin-top: 20px; 48 | } 49 | 50 | .p-tag { 51 | display: flex; 52 | align-items: center; 53 | margin-top: 20px; 54 | right: 0; 55 | bottom: 0; 56 | } 57 | 58 | .p-tag a { 59 | text-decoration: none; 60 | cursor: pointer; 61 | color: rgb(255, 82, 111); 62 | } 63 | -------------------------------------------------------------------------------- /Dynamic Calendar/dycalendar.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * dyCalendar is a JavaScript library for creating Calendar. 3 | * 4 | * Author: Yusuf Shakeel 5 | * https://github.com/yusufshakeel 6 | * 7 | * GitHub Link: https://github.com/yusufshakeel/dyCalendarJS 8 | * 9 | * MIT license 10 | * Copyright (c) 2016 Yusuf Shakeel 11 | * 12 | * Date: 2014-08-17 sunday 13 | */ 14 | 15 | .dycalendar-container { 16 | display: inline-block; 17 | border : 1px solid #eee; 18 | } 19 | 20 | .dycalendar-container.round-edge { 21 | border-radius: 5%; 22 | -o-border-radius: 5%; 23 | -moz-border-radius: 5%; 24 | -webkit-border-radius: 5%; 25 | } 26 | 27 | 28 | 29 | /*================================== DAY CALENDAR ========================*/ 30 | /* 31 | * day calendar style 32 | *-------------------------------------------------*/ 33 | .dycalendar-day-container { 34 | padding : 10px; 35 | text-align : center; 36 | font-family : Arial; 37 | } 38 | 39 | .dycalendar-day-container div{ 40 | padding : 0; 41 | margin-bottom : 10px; 42 | } 43 | 44 | .dycalendar-day-container .dycalendar-span-day { 45 | font-size : 110%; 46 | } 47 | 48 | .dycalendar-day-container .dycalendar-span-date { 49 | font-size : 250%; 50 | } 51 | 52 | .dycalendar-day-container .dycalendar-span-month-year { 53 | font-size : 90% 54 | } 55 | 56 | /*================================== DAY CALENDAR ENDS HERE ===============*/ 57 | 58 | 59 | 60 | /*================================== MONTH CALENDAR DEFAULT ========================*/ 61 | 62 | /* 63 | * month calendar style 64 | *-------------------------------------------------*/ 65 | .dycalendar-month-container { 66 | padding : 10px; 67 | text-align : center; 68 | font-family : Arial; 69 | } 70 | 71 | .dycalendar-month-container div{ 72 | padding : 0; 73 | margin-bottom : 10px; 74 | } 75 | 76 | .dycalendar-month-container .dycalendar-header { 77 | position : relative; 78 | } 79 | 80 | .dycalendar-month-container .dycalendar-header .dycalendar-prev-next-btn { 81 | position : absolute; 82 | top : 0; 83 | cursor : pointer; 84 | } 85 | 86 | .dycalendar-month-container .dycalendar-header .dycalendar-prev-next-btn.prev-btn { 87 | left : 0; 88 | } 89 | 90 | .dycalendar-month-container .dycalendar-header .dycalendar-prev-next-btn.next-btn { 91 | right : 0; 92 | } 93 | 94 | .dycalendar-month-container .dycalendar-span-month-year { 95 | margin : 5px; 96 | cursor : pointer; 97 | } 98 | 99 | .dycalendar-month-container .dycalendar-body table tr td { 100 | padding : 5px; 101 | } 102 | 103 | .dycalendar-month-container .dycalendar-today-date, 104 | .dycalendar-month-container .dycalendar-target-date { 105 | background-color: #111; 106 | color : #fff; 107 | border-radius: 2px; 108 | } 109 | 110 | /*================================== MONTH CALENDAR ENS HERE ===============*/ 111 | 112 | 113 | 114 | /*================================== DYCALENDAR SKIN =======================*/ 115 | 116 | /* 117 | * calendar skin (default skin) 118 | *-------------------------------------------------*/ 119 | .dycalendar-container.gradient { 120 | background: #fff; 121 | background: linear-gradient(#fff, #d3d3d3); 122 | background: -o-linear-gradient(#fff, #d3d3d3); 123 | background: -moz-linear-gradient(#fff, #d3d3d3); 124 | background: -webkit-linear-gradient(#fff, #d3d3d3); 125 | } 126 | 127 | /* 128 | * calendar skin (skin-black) 129 | *-------------------------------------------------*/ 130 | .dycalendar-container.skin-black { 131 | color : #fff; 132 | background-color: #111; 133 | border : 0; 134 | } 135 | 136 | .dycalendar-container.skin-black.gradient { 137 | background: #111; 138 | background: linear-gradient(#555, #111); 139 | background: -o-linear-gradient(#555, #111); 140 | background: -moz-linear-gradient(#555, #111); 141 | background: -webkit-linear-gradient(#555, #111); 142 | } 143 | 144 | .dycalendar-container.skin-black .dycalendar-today-date, 145 | .dycalendar-container.skin-black .dycalendar-target-date { 146 | background-color: #fff; 147 | color : #111; 148 | border-radius: 2px; 149 | } 150 | 151 | /* 152 | * calendar skin (skin-blue) 153 | *-------------------------------------------------*/ 154 | .dycalendar-container.skin-blue { 155 | color : #fff; 156 | background-color: #3c99d3; 157 | border : 0; 158 | } 159 | 160 | .dycalendar-container.skin-blue.gradient { 161 | background: #3c99d3; 162 | background: linear-gradient(#5ebbf5, #3c99d3); 163 | background: -o-linear-gradient(#5ebbf5, #3c99d3); 164 | background: -moz-linear-gradient(#5ebbf5, #3c99d3); 165 | background: -webkit-linear-gradient(#5ebbf5, #3c99d3); 166 | } 167 | 168 | .dycalendar-container.skin-blue .dycalendar-today-date, 169 | .dycalendar-container.skin-blue .dycalendar-target-date { 170 | background-color: #fff; 171 | color : #3c99d3; 172 | border-radius: 2px; 173 | } 174 | 175 | /* 176 | * calendar skin (skin-green) 177 | *-------------------------------------------------*/ 178 | .dycalendar-container.skin-green { 179 | color : #fff; 180 | background-color: #2bb063; 181 | border : 0; 182 | } 183 | 184 | .dycalendar-container.skin-green.gradient { 185 | background: #2bb063; 186 | background: linear-gradient(#3dd175, #2bb063); 187 | background: -o-linear-gradient(#3dd175, #2bb063); 188 | background: -moz-linear-gradient(#3dd175, #2bb063); 189 | background: -webkit-linear-gradient(#3dd175, #2bb063); 190 | } 191 | 192 | .dycalendar-container.skin-green .dycalendar-today-date, 193 | .dycalendar-container.skin-green .dycalendar-target-date { 194 | background-color: #fff; 195 | color : #2bb063; 196 | border-radius: 2px; 197 | } 198 | 199 | /* 200 | * calendar skin (skin-purple) 201 | *-------------------------------------------------*/ 202 | .dycalendar-container.skin-purple { 203 | color : #fff; 204 | background-color: #975ea4; 205 | border : 0; 206 | } 207 | 208 | .dycalendar-container.skin-purple.gradient { 209 | background: #975ea4; 210 | background: linear-gradient(#ca82d7, #975ea4); 211 | background: -o-linear-gradient(#ca82d7, #975ea4); 212 | background: -moz-linear-gradient(#ca82d7, #975ea4); 213 | background: -webkit-linear-gradient(#ca82d7, #975ea4); 214 | } 215 | 216 | .dycalendar-container.skin-purple .dycalendar-today-date, 217 | .dycalendar-container.skin-purple .dycalendar-target-date { 218 | background-color: #fff; 219 | color : #975ea4; 220 | border-radius: 2px; 221 | } 222 | 223 | /* 224 | * calendar skin (skin-red) 225 | *-------------------------------------------------*/ 226 | .dycalendar-container.skin-red { 227 | color : #fff; 228 | background-color: #e94d40; 229 | border : 0; 230 | } 231 | 232 | .dycalendar-container.skin-red.gradient { 233 | background: #e94d40; 234 | background: linear-gradient(#fb6f62, #e94d40); 235 | background: -o-linear-gradient(#fb6f62, #e94d40); 236 | background: -moz-linear-gradient(#fb6f62, #e94d40); 237 | background: -webkit-linear-gradient(#fb6f62, #e94d40); 238 | } 239 | 240 | .dycalendar-container.skin-red .dycalendar-today-date, 241 | .dycalendar-container.skin-red .dycalendar-target-date { 242 | background-color: #fff; 243 | color : #e94d40; 244 | border-radius: 2px; 245 | } 246 | 247 | /* 248 | * calendar skin (skin-spacegray) 249 | *-------------------------------------------------*/ 250 | .dycalendar-container.skin-spacegray { 251 | color : #fff; 252 | background-color: #343d46; 253 | border : 0; 254 | } 255 | 256 | .dycalendar-container.skin-spacegray.gradient { 257 | background: #343d46; 258 | background: linear-gradient(#454e57, #343d46); 259 | background: -o-linear-gradient(#454e57, #343d46); 260 | background: -moz-linear-gradient(#454e57, #343d46); 261 | background: -webkit-linear-gradient(#454e57, #343d46); 262 | } 263 | 264 | .dycalendar-container.skin-spacegray .dycalendar-today-date, 265 | .dycalendar-container.skin-spacegray .dycalendar-target-date { 266 | background-color: #fff; 267 | color : #343d46; 268 | border-radius: 2px; 269 | } 270 | 271 | /*================================== DYCALENDAR SKIN ENDS HERE =============*/ 272 | 273 | 274 | /*================================== DYCALENDAR SHADOW =====================*/ 275 | /* 276 | * calendar shadow (shadow-default) 277 | *-------------------------------------------------*/ 278 | .dycalendar-container.shadow-default { 279 | -o-box-shadow: 0 4px 4px 0 rgba(50, 50, 50, 0.4); 280 | -moz-box-shadow: 0 4px 4px 0 rgba(50, 50, 50, 0.4); 281 | -webkit-box-shadow: 0 4px 4px 0 rgba(50, 50, 50, 0.4); 282 | box-shadow: 0 4px 4px 0 rgba(50, 50, 50, 0.4); 283 | } 284 | 285 | /* 286 | * calendar shadow (shadow-black) 287 | *-------------------------------------------------*/ 288 | .dycalendar-container.shadow-black { 289 | -o-box-shadow: 0 4px 4px 0 rgba(0, 0, 0, 0.4); 290 | -moz-box-shadow: 0 4px 4px 0 rgba(0, 0, 0, 0.4); 291 | -webkit-box-shadow: 0 4px 4px 0 rgba(0, 0, 0, 0.4); 292 | box-shadow: 0 4px 4px 0 rgba(0, 0, 0, 0.4); 293 | } 294 | 295 | /* 296 | * calendar shadow (shadow-blue) 297 | *-------------------------------------------------*/ 298 | .dycalendar-container.shadow-blue { 299 | -o-box-shadow: 0 4px 4px 0 rgba(60, 153, 211, 0.4); 300 | -moz-box-shadow: 0 4px 4px 0 rgba(60, 153, 211, 0.4); 301 | -webkit-box-shadow: 0 4px 4px 0 rgba(60, 153, 211, 0.4); 302 | box-shadow: 0 4px 4px 0 rgba(60, 153, 211, 0.4); 303 | } 304 | 305 | /* 306 | * calendar shadow (shadow-green) 307 | *-------------------------------------------------*/ 308 | .dycalendar-container.shadow-green { 309 | -o-box-shadow: 0 4px 4px 0 rgba(43, 176, 99, 0.4); 310 | -moz-box-shadow: 0 4px 4px 0 rgba(43, 176, 99, 0.4); 311 | -webkit-box-shadow: 0 4px 4px 0 rgba(43, 176, 99, 0.4); 312 | box-shadow: 0 4px 4px 0 rgba(43, 176, 99, 0.4); 313 | } 314 | 315 | /* 316 | * calendar shadow (shadow-purple) 317 | *-------------------------------------------------*/ 318 | .dycalendar-container.shadow-purple { 319 | -o-box-shadow: 0 4px 4px 0 rgba(151, 94, 164, 0.4); 320 | -moz-box-shadow: 0 4px 4px 0 rgba(151, 94, 164, 0.4); 321 | -webkit-box-shadow: 0 4px 4px 0 rgba(151, 94, 164, 0.4); 322 | box-shadow: 0 4px 4px 0 rgba(151, 94, 164, 0.4); 323 | } 324 | 325 | /* 326 | * calendar shadow (shadow-red) 327 | *-------------------------------------------------*/ 328 | .dycalendar-container.shadow-red { 329 | -o-box-shadow: 0 4px 4px 0 rgba(233, 77, 64, 0.4); 330 | -moz-box-shadow: 0 4px 4px 0 rgba(233, 77, 64, 0.4); 331 | -webkit-box-shadow: 0 4px 4px 0 rgba(233, 77, 64, 0.4); 332 | box-shadow: 0 4px 4px 0 rgba(233, 77, 64, 0.4); 333 | } 334 | 335 | /* 336 | * calendar shadow (shadow-spacegray) 337 | *-------------------------------------------------*/ 338 | .dycalendar-container.shadow-spacegray { 339 | -o-box-shadow: 0 4px 4px 0 rgba(52, 61, 70, 1); 340 | -moz-box-shadow: 0 4px 4px 0 rgba(52, 61, 70, 1); 341 | -webkit-box-shadow: 0 4px 4px 0 rgba(52, 61, 70, 1); 342 | box-shadow: 0 4px 4px 0 rgba(52, 61, 70, 1); 343 | } 344 | 345 | /*================================== DYCALENDAR SHADOW ENDS HERE ===========*/ 346 | -------------------------------------------------------------------------------- /Dynamic Calendar/dycalendar.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * dyCalendar is a JavaScript library for creating Calendar. 3 | * 4 | * Author: Yusuf Shakeel 5 | * https://github.com/yusufshakeel 6 | * 7 | * GitHub Link: https://github.com/yusufshakeel/dyCalendarJS 8 | * 9 | * MIT license 10 | * Copyright (c) 2016 Yusuf Shakeel 11 | * 12 | * Date: 2014-08-17 sunday 13 | */ 14 | /*! dyCalendarJS | (c) 2016 Yusuf Shakeel | https://github.com/yusufshakeel/dyCalendarJS */ 15 | (function (global) { 16 | 17 | "use strict"; 18 | 19 | var 20 | //this will be used by the user. 21 | dycalendar = {}, 22 | 23 | //window document 24 | document = global.document, 25 | 26 | //starting year 27 | START_YEAR = 1900, 28 | 29 | //end year 30 | END_YEAR = 9999, 31 | 32 | //name of the months 33 | monthName = { 34 | full: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], 35 | mmm: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] 36 | }, 37 | 38 | //name of the days 39 | dayName = { 40 | full: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], 41 | d: ['S', 'M', 'T', 'W', 'T', 'F', 'S'], 42 | dd: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'], 43 | ddd: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'] 44 | }; 45 | 46 | /** 47 | * this function will create month table. 48 | * 49 | * @param object data this contains the calendar data 50 | * @param object option this is the settings object 51 | * @return html 52 | */ 53 | function createMonthTable(data, option) { 54 | 55 | var 56 | table, tr, td, 57 | r, c, count; 58 | 59 | table = document.createElement("table"); 60 | tr = document.createElement("tr"); 61 | 62 | //create 1st row for the day letters 63 | for (c = 0; c <= 6; c = c + 1) { 64 | td = document.createElement("td"); 65 | td.innerHTML = "SMTWTFS"[c]; 66 | tr.appendChild(td); 67 | } 68 | table.appendChild(tr); 69 | 70 | //create 2nd row for dates 71 | tr = document.createElement("tr"); 72 | 73 | //blank td 74 | for (c = 0; c <= 6; c = c + 1) { 75 | if (c === data.firstDayIndex) { 76 | break; 77 | } 78 | td = document.createElement("td"); 79 | tr.appendChild(td); 80 | } 81 | 82 | //remaing td of dates for the 2nd row 83 | count = 1; 84 | while (c <= 6) { 85 | td = document.createElement("td"); 86 | td.innerHTML = count; 87 | if (data.today.date === count && data.today.monthIndex === data.monthIndex && option.highlighttoday === true) { 88 | td.setAttribute("class", "dycalendar-today-date"); 89 | } 90 | if (option.date === count && option.month === data.monthIndex && option.highlighttargetdate === true) { 91 | td.setAttribute("class", "dycalendar-target-date"); 92 | } 93 | tr.appendChild(td); 94 | count = count + 1; 95 | c = c + 1; 96 | } 97 | table.appendChild(tr); 98 | 99 | //create remaining rows 100 | for (r = 3; r <= 7; r = r + 1) { 101 | tr = document.createElement("tr"); 102 | for (c = 0; c <= 6; c = c + 1) { 103 | if (count > data.totaldays) { 104 | table.appendChild(tr); 105 | return table; 106 | } 107 | td = document.createElement('td'); 108 | td.innerHTML = count; 109 | if (data.today.date === count && data.today.monthIndex === data.monthIndex && option.highlighttoday === true) { 110 | td.setAttribute("class", "dycalendar-today-date"); 111 | } 112 | if (option.date === count && option.month === data.monthIndex && option.highlighttargetdate === true) { 113 | td.setAttribute("class", "dycalendar-target-date"); 114 | } 115 | count = count + 1; 116 | tr.appendChild(td); 117 | } 118 | table.appendChild(tr); 119 | } 120 | 121 | return table; 122 | } 123 | 124 | /** 125 | * this function will draw Calendar Month Table 126 | * 127 | * @param object data this contains the calendar data 128 | * @param object option this is the settings object 129 | * @return html 130 | */ 131 | function drawCalendarMonthTable(data, option) { 132 | 133 | var 134 | table, 135 | div, container, elem; 136 | 137 | //get table 138 | table = createMonthTable(data, option); 139 | 140 | //calendar container 141 | container = document.createElement("div"); 142 | container.setAttribute("class", "dycalendar-month-container"); 143 | 144 | //-------------------------- Header ------------------ 145 | 146 | //header div 147 | div = document.createElement("div"); 148 | div.setAttribute("class", "dycalendar-header"); 149 | div.setAttribute("data-option", JSON.stringify(option)); 150 | 151 | //prev button 152 | if (option.prevnextbutton === "show") { 153 | elem = document.createElement("span"); 154 | elem.setAttribute("class", "dycalendar-prev-next-btn prev-btn"); 155 | elem.setAttribute("data-date", option.date); 156 | elem.setAttribute("data-month", option.month); 157 | elem.setAttribute("data-year", option.year); 158 | elem.setAttribute("data-btn", "prev"); 159 | elem.innerHTML = "<"; 160 | //add prev button span to header div 161 | div.appendChild(elem); 162 | } 163 | 164 | //month span 165 | elem = document.createElement("span"); 166 | elem.setAttribute("class", "dycalendar-span-month-year"); 167 | if (option.monthformat === "mmm") { 168 | elem.innerHTML = data.monthName + " " + data.year; 169 | } else if (option.monthformat === "full") { 170 | elem.innerHTML = data.monthNameFull + " " + data.year; 171 | } 172 | 173 | //add month span to header div 174 | div.appendChild(elem); 175 | 176 | //next button 177 | if (option.prevnextbutton === "show") { 178 | elem = document.createElement("span"); 179 | elem.setAttribute("class", "dycalendar-prev-next-btn next-btn"); 180 | elem.setAttribute("data-date", option.date); 181 | elem.setAttribute("data-month", option.month); 182 | elem.setAttribute("data-year", option.year); 183 | elem.setAttribute("data-btn", "next"); 184 | elem.innerHTML = ">"; 185 | //add prev button span to header div 186 | div.appendChild(elem); 187 | } 188 | 189 | //add header div to container 190 | container.appendChild(div); 191 | 192 | //-------------------------- Body ------------------ 193 | 194 | //body div 195 | div = document.createElement("div"); 196 | div.setAttribute("class", "dycalendar-body"); 197 | div.appendChild(table); 198 | 199 | //add body div to container div 200 | container.appendChild(div); 201 | 202 | //return container 203 | return container; 204 | } 205 | 206 | /** 207 | * this function will draw Calendar Day 208 | * 209 | * @param object data this contains the calendar data 210 | * @param object option this is the settings object 211 | * @return html 212 | */ 213 | function drawCalendarDay(data, option) { 214 | 215 | var 216 | div, container, elem; 217 | 218 | //calendar container 219 | container = document.createElement("div"); 220 | container.setAttribute("class", "dycalendar-day-container"); 221 | 222 | //-------------------------- Header ------------------ 223 | 224 | //header div 225 | div = document.createElement("div"); 226 | div.setAttribute("class", "dycalendar-header"); 227 | 228 | //day span 229 | elem = document.createElement("span"); 230 | elem.setAttribute("class", "dycalendar-span-day"); 231 | if (option.dayformat === "ddd") { 232 | elem.innerHTML = dayName.ddd[data.targetedDayIndex]; 233 | } else if (option.dayformat === "full") { 234 | elem.innerHTML = dayName.full[data.targetedDayIndex]; 235 | } 236 | 237 | //add day span to footer div 238 | div.appendChild(elem); 239 | 240 | //add header div to container 241 | container.appendChild(div); 242 | 243 | //-------------------------- Body ------------------ 244 | 245 | //body div 246 | div = document.createElement("div"); 247 | div.setAttribute("class", "dycalendar-body"); 248 | 249 | //date span 250 | elem = document.createElement("span"); 251 | elem.setAttribute("class", "dycalendar-span-date"); 252 | elem.innerHTML = data.date; 253 | 254 | //add date span to body div 255 | div.appendChild(elem); 256 | 257 | //add body div to container 258 | container.appendChild(div); 259 | 260 | //-------------------------- Footer ------------------ 261 | 262 | //footer div 263 | div = document.createElement("div"); 264 | div.setAttribute("class", "dycalendar-footer"); 265 | 266 | //month span 267 | elem = document.createElement("span"); 268 | elem.setAttribute("class", "dycalendar-span-month-year"); 269 | if (option.monthformat === "mmm") { 270 | elem.innerHTML = data.monthName + " " + data.year; 271 | } else if (option.monthformat === "full") { 272 | elem.innerHTML = data.monthNameFull + " " + data.year; 273 | } 274 | 275 | //add month span to footer div 276 | div.appendChild(elem); 277 | 278 | //add footer div to container 279 | container.appendChild(div); 280 | 281 | //return container 282 | return container; 283 | } 284 | 285 | /** 286 | * this function will extend source object with defaults object. 287 | * 288 | * @param object source this is the source object 289 | * @param object defaults this is the default object 290 | * @return object 291 | */ 292 | function extendSource(source, defaults) { 293 | var property; 294 | for (property in defaults) { 295 | if (source.hasOwnProperty(property) === false) { 296 | source[property] = defaults[property]; 297 | } 298 | } 299 | return source; 300 | } 301 | 302 | /** 303 | * This function will return calendar detail. 304 | * 305 | * @param integer year 1900-9999 (optional) if not set will consider 306 | * the current year. 307 | * @param integer month 0-11 (optional) 0 = Jan, 1 = Feb, ... 11 = Dec, 308 | * if not set will consider the current month. 309 | * @param integer date 1-31 (optional) 310 | * @return boolean|object if error return false, else calendar detail 311 | */ 312 | function getCalendar(year, month, date) { 313 | 314 | var 315 | dateObj = new Date(), 316 | dateString, 317 | result = {}, 318 | idx; 319 | 320 | if (year < START_YEAR || year > END_YEAR) { 321 | global.console.error("Invalid Year"); 322 | return false; 323 | } 324 | if (month > 11 || month < 0) { 325 | global.console.error("Invalid Month"); 326 | return false; 327 | } 328 | if (date > 31 || date < 1) { 329 | global.console.error("Invalid Date"); 330 | return false; 331 | } 332 | 333 | result.year = year; 334 | result.month = month; 335 | result.date = date; 336 | 337 | //today 338 | result.today = {}; 339 | dateString = dateObj.toString().split(" "); 340 | 341 | idx = dayName.ddd.indexOf(dateString[0]); 342 | result.today.dayIndex = idx; 343 | result.today.dayName = dateString[0]; 344 | result.today.dayFullName = dayName.full[idx]; 345 | 346 | idx = monthName.mmm.indexOf(dateString[1]); 347 | result.today.monthIndex = idx; 348 | result.today.monthName = dateString[1]; 349 | result.today.monthNameFull = monthName.full[idx]; 350 | 351 | result.today.date = dateObj.getDate(); 352 | 353 | result.today.year = dateString[3]; 354 | 355 | //get month-year first day 356 | dateObj.setDate(1); 357 | dateObj.setMonth(month); 358 | dateObj.setFullYear(year); 359 | dateString = dateObj.toString().split(" "); 360 | 361 | idx = dayName.ddd.indexOf(dateString[0]); 362 | result.firstDayIndex = idx; 363 | result.firstDayName = dateString[0]; 364 | result.firstDayFullName = dayName.full[idx]; 365 | 366 | idx = monthName.mmm.indexOf(dateString[1]); 367 | result.monthIndex = idx; 368 | result.monthName = dateString[1]; 369 | result.monthNameFull = monthName.full[idx]; 370 | 371 | //get total days for the month-year 372 | dateObj.setFullYear(year); 373 | dateObj.setMonth(month + 1); 374 | dateObj.setDate(0); 375 | result.totaldays = dateObj.getDate(); 376 | 377 | //get month-year targeted date 378 | dateObj.setFullYear(year); 379 | dateObj.setMonth(month); 380 | dateObj.setDate(date); 381 | dateString = dateObj.toString().split(" "); 382 | 383 | idx = dayName.ddd.indexOf(dateString[0]); 384 | result.targetedDayIndex = idx; 385 | result.targetedDayName = dateString[0]; 386 | result.targetedDayFullName = dayName.full[idx]; 387 | 388 | return result; 389 | 390 | } 391 | 392 | /** 393 | * this function will handle the on click event. 394 | */ 395 | function onClick() { 396 | 397 | document.body.onclick = function (e) { 398 | 399 | //get event object (window.event for IE compatibility) 400 | e = global.event || e; 401 | 402 | var 403 | //get target dom object reference 404 | targetDomObject = e.target || e.srcElement, 405 | 406 | //other variables 407 | date, month, year, btn, option, dateObj; 408 | 409 | //prev-next button click 410 | //extra checks to make sure object exists and contains the class of interest 411 | if ((targetDomObject) && (targetDomObject.classList) && (targetDomObject.classList.contains("dycalendar-prev-next-btn"))) { 412 | date = parseInt(targetDomObject.getAttribute("data-date")); 413 | month = parseInt(targetDomObject.getAttribute("data-month")); 414 | year = parseInt(targetDomObject.getAttribute("data-year")); 415 | btn = targetDomObject.getAttribute("data-btn"); 416 | option = JSON.parse(targetDomObject.parentElement.getAttribute("data-option")); 417 | 418 | if (btn === "prev") { 419 | month = month - 1; 420 | if (month < 0) { 421 | year = year - 1; 422 | month = 11; 423 | } 424 | } 425 | else if (btn === "next") { 426 | month = month + 1; 427 | if (month > 11) { 428 | year = year + 1; 429 | month = 0; 430 | } 431 | } 432 | 433 | option.date = date; 434 | option.month = month; 435 | option.year = year; 436 | 437 | drawCalendar(option); 438 | } 439 | 440 | //month click 441 | //extra checks to make sure object exists and contains the class of interest 442 | if ((targetDomObject) && (targetDomObject.classList) && (targetDomObject.classList.contains("dycalendar-span-month-year"))) { 443 | option = JSON.parse(targetDomObject.parentElement.getAttribute("data-option")); 444 | dateObj = new Date(); 445 | 446 | option.date = dateObj.getDate(); 447 | option.month = dateObj.getMonth(); 448 | option.year = dateObj.getFullYear(); 449 | 450 | drawCalendar(option); 451 | } 452 | }; 453 | } 454 | 455 | //------------------------------ dycalendar.draw() ---------------------- 456 | 457 | /** 458 | * this function will draw the calendar based on user preferences. 459 | * 460 | * option = { 461 | * target : "#id|.class" //(mandatory) for id use #id | for class use .class 462 | * type : "calendar-type" //(optional) values: "day|month" (default "day") 463 | * month : "integer" //(optional) value 0-11, where 0 = January, ... 11 = December (default current month) 464 | * year : "integer" //(optional) example 1990. (default current year) 465 | * date : "integer" //(optional) example 1-31. (default current date) 466 | * monthformat : "full" //(optional) values: "mmm|full" (default "full") 467 | * dayformat : "full" //(optional) values: "ddd|full" (default "full") 468 | * highlighttoday : boolean //(optional) (default false) if true will highlight today's date 469 | * highlighttargetdate : boolean //(optional) (default false) if true will highlight targeted date of the month year 470 | * prevnextbutton : "hide" //(optional) (default "hide") (values: "show|hide") if set to "show" it will show the nav button (prev|next) 471 | * } 472 | * 473 | * @param object option user preferences 474 | * @return boolean true if success, false otherwise 475 | */ 476 | dycalendar.draw = function (option) { 477 | 478 | //check if option is passed or not 479 | if (typeof option === "undefined") { 480 | global.console.error("Option missing"); 481 | return false; 482 | } 483 | 484 | var 485 | self = this, //pointing at dycalendar object 486 | 487 | dateObj = new Date(), 488 | 489 | //default settings 490 | defaults = { 491 | type: "day", 492 | month: dateObj.getMonth(), 493 | year: dateObj.getFullYear(), 494 | date: dateObj.getDate(), 495 | monthformat: "full", 496 | dayformat: "full", 497 | highlighttoday: false, 498 | highlighttargetdate: false, 499 | prevnextbutton: "hide" 500 | }; 501 | 502 | //extend user options with predefined options 503 | option = extendSource(option, defaults); 504 | 505 | drawCalendar(option); 506 | 507 | }; 508 | 509 | //------------------------------ dycalendar.draw() ends here ------------ 510 | 511 | /** 512 | * this function will draw the calendar inside the target container. 513 | */ 514 | function drawCalendar(option) { 515 | 516 | var 517 | //variables for creating calendar 518 | calendar, 519 | calendarHTML, 520 | targetedElementBy = "id", 521 | targetElem, 522 | 523 | //other variables 524 | i, len, elemArr; 525 | 526 | //find target element by 527 | if (option.target[0] === "#") { 528 | targetedElementBy = "id"; 529 | } else if (option.target[0] === ".") { 530 | targetedElementBy = "class"; 531 | } 532 | targetElem = option.target.substring(1); 533 | 534 | //get calendar HTML 535 | switch (option.type) { 536 | case "day": 537 | //get calendar detail 538 | calendar = getCalendar(option.year, option.month, option.date); 539 | //get calendar html 540 | calendarHTML = drawCalendarDay(calendar, option); 541 | break; 542 | 543 | case "month": 544 | //get calendar detail 545 | calendar = getCalendar(option.year, option.month, option.date); 546 | //get calendar html 547 | calendarHTML = drawCalendarMonthTable(calendar, option); 548 | break; 549 | 550 | default: 551 | global.console.error("Invalid type"); 552 | return false; 553 | } 554 | 555 | //draw calendar 556 | if (targetedElementBy === "id") { 557 | 558 | document.getElementById(targetElem).innerHTML = calendarHTML.outerHTML; 559 | 560 | } else if (targetedElementBy === "class") { 561 | 562 | elemArr = document.getElementsByClassName(targetElem); 563 | for (i = 0, len = elemArr.length; i < len; i = i + 1) { 564 | elemArr[i].innerHTML = calendarHTML.outerHTML; 565 | } 566 | 567 | } 568 | } 569 | 570 | //events 571 | onClick(); 572 | 573 | //attach to global window object 574 | global.dycalendar = dycalendar; 575 | 576 | }(typeof window !== "undefined" ? window : this)); 577 | -------------------------------------------------------------------------------- /Dynamic Calendar/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Dynamic Calendar 9 | 10 | 11 | 12 | 13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Dynamic Calendar/script.js: -------------------------------------------------------------------------------- 1 | //from dynamic calendar js 2 | dycalendar.draw({ 3 | target: "#dycalendar", 4 | type: "month", 5 | dayformat: "full", 6 | monthformat: "full", 7 | highlighttargetdate: true, 8 | prevnextbutton: "show", 9 | }); 10 | -------------------------------------------------------------------------------- /Dynamic Calendar/style.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css?family=Poppins:200,300,400,500,600,700,800,900&display=swap"); 2 | 3 | * { 4 | margin: 0; 5 | padding: 0; 6 | box-sizing: border-box; 7 | font-family: "Poppins", sans-serif; 8 | } 9 | 10 | section { 11 | position: relative; 12 | display: flex; 13 | justify-content: center; 14 | align-items: center; 15 | min-height: 100vh; 16 | background: #161623; 17 | overflow: hidden; 18 | } 19 | 20 | section::before { 21 | content: ""; 22 | position: absolute; 23 | width: 400px; 24 | height: 400px; 25 | background: linear-gradient(#ffc107, #e91e63); 26 | border-radius: 50%; 27 | transform: translate(-250px, -120px); 28 | } 29 | 30 | section::after { 31 | content: ""; 32 | position: absolute; 33 | width: 400px; 34 | height: 400px; 35 | background: linear-gradient(#2196f3, #31ff38); 36 | border-radius: 50%; 37 | transform: translate(250px, 150px); 38 | } 39 | 40 | .box { 41 | position: relative; 42 | z-index: 1000; 43 | } 44 | 45 | .container { 46 | position: relative; 47 | width: 400px; 48 | min-height: 400px; 49 | background: rgba(255, 255, 255, 0.1); 50 | border-radius: 10px; 51 | box-shadow: 0 25px 45px rgba(0, 0, 0, 0.1); 52 | border: 1px solid rgba(255, 255, 255, 0.5); 53 | border-right: 1px solid rgba(255, 255, 255, 0.2); 54 | border-bottom: 1px solid rgba(255, 255, 255, 0.2); 55 | backdrop-filter: blur(25px); 56 | display: flex; 57 | justify-content: center; 58 | align-items: center; 59 | } 60 | 61 | #dycalendar { 62 | width: 100%; 63 | padding: 20px; 64 | } 65 | 66 | #dycalendar table { 67 | width: 100%; 68 | margin-top: 40px; 69 | border-spacing: 5px; 70 | } 71 | 72 | #dycalendar table tr:nth-child(1) td { 73 | background: rgb(255, 231, 231); 74 | color: #111; 75 | border-radius: 4px; 76 | font-weight: 600; 77 | } 78 | 79 | #dycalendar table td { 80 | color: #fff; 81 | padding: 10px; 82 | cursor: pointer; 83 | border-radius: 4px; 84 | } 85 | 86 | #dycalendar table td:hover { 87 | background-color: #fff; 88 | color: #111 !important; 89 | } 90 | 91 | .dycalendar-month-container .dycalendar-today-date, 92 | .dycalendar-month-container .dycalendar-target-date { 93 | background-color: #fff; 94 | color: #111 !important; 95 | } 96 | 97 | .dycalendar-month-container 98 | .dycalendar-header 99 | .dycalendar-prev-next-btn.prev-btn { 100 | background: rgb(255, 240, 240); 101 | color: #111; 102 | width: 40px; 103 | height: 35px; 104 | left: 4px; 105 | border-radius: 4px; 106 | display: flex; 107 | justify-content: center; 108 | align-items: center; 109 | font-size: 24px; 110 | } 111 | 112 | .dycalendar-month-container 113 | .dycalendar-header 114 | .dycalendar-prev-next-btn.next-btn { 115 | background: rgb(255, 240, 240); 116 | color: #111; 117 | width: 40px; 118 | height: 35px; 119 | right: 4px; 120 | border-radius: 4px; 121 | display: flex; 122 | justify-content: center; 123 | align-items: center; 124 | font-size: 24px; 125 | } 126 | 127 | .dycalendar-month-container .dycalendar-span-month-year { 128 | color: #fff; 129 | font-size: 1.5rem; 130 | font-weight: 500; 131 | } 132 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Ratheshan Sathiyamoorthy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Music-Player/images/hey.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/Music-Player/images/hey.jpg -------------------------------------------------------------------------------- /Music-Player/images/summer.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/Music-Player/images/summer.jpg -------------------------------------------------------------------------------- /Music-Player/images/ukulele.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/Music-Player/images/ukulele.jpg -------------------------------------------------------------------------------- /Music-Player/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | Music Player 13 | 14 | 15 |

Music Player

16 | 17 |
18 |
19 |

20 |
21 |
22 |
23 |
24 | 25 | 26 | 27 |
28 | music-cover 29 |
30 | 41 |
42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /Music-Player/music/hey.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/Music-Player/music/hey.mp3 -------------------------------------------------------------------------------- /Music-Player/music/summer.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/Music-Player/music/summer.mp3 -------------------------------------------------------------------------------- /Music-Player/music/ukulele.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/Music-Player/music/ukulele.mp3 -------------------------------------------------------------------------------- /Music-Player/script.js: -------------------------------------------------------------------------------- 1 | const musicContainer = document.getElementById("music-container"); 2 | const playBtn = document.getElementById("play"); 3 | const prevBtn = document.getElementById("prev"); 4 | const nextBtn = document.getElementById("next"); 5 | 6 | const audio = document.getElementById("audio"); 7 | const progress = document.getElementById("progress"); 8 | const progressContainer = document.getElementById("progress-container"); 9 | const title = document.getElementById("title"); 10 | const cover = document.getElementById("cover"); 11 | const currTime = document.querySelector("#currTime"); 12 | const durTime = document.querySelector("#durTime"); 13 | 14 | // Song titles 15 | const songs = ["hey", "summer", "ukulele"]; 16 | 17 | // Keep track of song 18 | let songIndex = 2; 19 | 20 | // Initially load song details into DOM 21 | loadSong(songs[songIndex]); 22 | 23 | // Update song details 24 | function loadSong(song) { 25 | title.innerText = song; 26 | audio.src = `music/${song}.mp3`; 27 | cover.src = `images/${song}.jpg`; 28 | } 29 | 30 | // Play song 31 | function playSong() { 32 | musicContainer.classList.add("play"); 33 | playBtn.querySelector("i.fas").classList.remove("fa-play"); 34 | playBtn.querySelector("i.fas").classList.add("fa-pause"); 35 | 36 | audio.play(); 37 | } 38 | 39 | // Pause song 40 | function pauseSong() { 41 | musicContainer.classList.remove("play"); 42 | playBtn.querySelector("i.fas").classList.add("fa-play"); 43 | playBtn.querySelector("i.fas").classList.remove("fa-pause"); 44 | 45 | audio.pause(); 46 | } 47 | 48 | // Previous song 49 | function prevSong() { 50 | songIndex--; 51 | 52 | if (songIndex < 0) { 53 | songIndex = songs.length - 1; 54 | } 55 | 56 | loadSong(songs[songIndex]); 57 | 58 | playSong(); 59 | } 60 | 61 | // Next song 62 | function nextSong() { 63 | songIndex++; 64 | 65 | if (songIndex > songs.length - 1) { 66 | songIndex = 0; 67 | } 68 | 69 | loadSong(songs[songIndex]); 70 | 71 | playSong(); 72 | } 73 | 74 | // Update progress bar 75 | function updateProgress(e) { 76 | const { duration, currentTime } = e.srcElement; 77 | const progressPercent = (currentTime / duration) * 100; 78 | progress.style.width = `${progressPercent}%`; 79 | } 80 | 81 | // Set progress bar 82 | function setProgress(e) { 83 | const width = this.clientWidth; 84 | const clickX = e.offsetX; 85 | const duration = audio.duration; 86 | 87 | audio.currentTime = (clickX / width) * duration; 88 | } 89 | 90 | //get duration & currentTime for Time of song 91 | function DurTime(e) { 92 | const { duration, currentTime } = e.srcElement; 93 | var sec; 94 | var sec_d; 95 | 96 | // define minutes currentTime 97 | let min = currentTime == null ? 0 : Math.floor(currentTime / 60); 98 | min = min < 10 ? "0" + min : min; 99 | 100 | // define seconds currentTime 101 | function get_sec(x) { 102 | if (Math.floor(x) >= 60) { 103 | for (var i = 1; i <= 60; i++) { 104 | if (Math.floor(x) >= 60 * i && Math.floor(x) < 60 * (i + 1)) { 105 | sec = Math.floor(x) - 60 * i; 106 | sec = sec < 10 ? "0" + sec : sec; 107 | } 108 | } 109 | } else { 110 | sec = Math.floor(x); 111 | sec = sec < 10 ? "0" + sec : sec; 112 | } 113 | } 114 | 115 | get_sec(currentTime, sec); 116 | 117 | // change currentTime DOM 118 | currTime.innerHTML = min + ":" + sec; 119 | 120 | // define minutes duration 121 | let min_d = isNaN(duration) === true ? "0" : Math.floor(duration / 60); 122 | min_d = min_d < 10 ? "0" + min_d : min_d; 123 | 124 | function get_sec_d(x) { 125 | if (Math.floor(x) >= 60) { 126 | for (var i = 1; i <= 60; i++) { 127 | if (Math.floor(x) >= 60 * i && Math.floor(x) < 60 * (i + 1)) { 128 | sec_d = Math.floor(x) - 60 * i; 129 | sec_d = sec_d < 10 ? "0" + sec_d : sec_d; 130 | } 131 | } 132 | } else { 133 | sec_d = isNaN(duration) === true ? "0" : Math.floor(x); 134 | sec_d = sec_d < 10 ? "0" + sec_d : sec_d; 135 | } 136 | } 137 | 138 | // define seconds duration 139 | 140 | get_sec_d(duration); 141 | 142 | // change duration DOM 143 | durTime.innerHTML = min_d + ":" + sec_d; 144 | } 145 | 146 | // Event listeners 147 | playBtn.addEventListener("click", () => { 148 | const isPlaying = musicContainer.classList.contains("play"); 149 | 150 | if (isPlaying) { 151 | pauseSong(); 152 | } else { 153 | playSong(); 154 | } 155 | }); 156 | 157 | // Change song 158 | prevBtn.addEventListener("click", prevSong); 159 | nextBtn.addEventListener("click", nextSong); 160 | 161 | // Time/song update 162 | audio.addEventListener("timeupdate", updateProgress); 163 | 164 | // Click on progress bar 165 | progressContainer.addEventListener("click", setProgress); 166 | 167 | // Song ends 168 | audio.addEventListener("ended", nextSong); 169 | 170 | // Time of song 171 | audio.addEventListener("timeupdate", DurTime); 172 | -------------------------------------------------------------------------------- /Music-Player/style.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css?family=Lato&display=swap"); 2 | 3 | * { 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | background-image: linear-gradient( 9 | 0deg, 10 | rgba(247, 247, 247, 1) 23.8%, 11 | rgb(255, 191, 172) 92% 12 | ); 13 | height: 100vh; 14 | display: flex; 15 | flex-direction: column; 16 | align-items: center; 17 | justify-content: center; 18 | font-family: "Lato", sans-serif; 19 | margin: 0; 20 | } 21 | 22 | h1 { 23 | font-size: 38px; 24 | } 25 | 26 | .music-container { 27 | background-color: #fff; 28 | border-radius: 15px; 29 | box-shadow: 0 20px 20px 0 rgba(252, 169, 169, 0.6); 30 | display: flex; 31 | padding: 25px 35px; 32 | position: relative; 33 | margin: 75px 0; 34 | z-index: 10; 35 | } 36 | 37 | .img-container { 38 | position: relative; 39 | width: 110px; 40 | } 41 | 42 | .img-container::after { 43 | content: ""; 44 | background-color: #fff; 45 | border-radius: 50%; 46 | border: 1px solid lightcoral; 47 | position: absolute; 48 | bottom: 100%; 49 | left: 50%; 50 | width: 20px; 51 | height: 20px; 52 | transform: translate(-50%, 50%); 53 | } 54 | 55 | .img-container img { 56 | border-radius: 50%; 57 | object-fit: cover; 58 | height: 110px; 59 | width: inherit; 60 | position: absolute; 61 | bottom: 0; 62 | left: 0; 63 | animation: rotate 3s linear infinite; 64 | 65 | animation-play-state: paused; 66 | } 67 | 68 | .music-container.play .img-container img { 69 | animation-play-state: running; 70 | } 71 | 72 | @keyframes rotate { 73 | from { 74 | transform: rotate(0deg); 75 | } 76 | 77 | to { 78 | transform: rotate(360deg); 79 | } 80 | } 81 | 82 | .navigation { 83 | display: flex; 84 | align-items: center; 85 | justify-content: center; 86 | z-index: 1; 87 | } 88 | 89 | .action-btn { 90 | background-color: #fff; 91 | border: 0; 92 | color: #dfdbdf; 93 | font-size: 20px; 94 | cursor: pointer; 95 | padding: 10px; 96 | margin: 0 20px; 97 | } 98 | 99 | .action-btn.action-btn-big { 100 | color: #cdc2d0; 101 | font-size: 30px; 102 | } 103 | 104 | .action-btn:focus { 105 | outline: 0; 106 | } 107 | 108 | .music-info { 109 | background-color: rgba(255, 255, 255, 0.5); 110 | border-radius: 15px 15px 0 0; 111 | position: absolute; 112 | top: 0; 113 | left: 20px; 114 | width: calc(100% - 40px); 115 | padding: 10px 10px 10px 150px; 116 | opacity: 0; 117 | transform: translateY(0%); 118 | transition: transform 0.3s ease-in, opacity 0.3s ease-in; 119 | z-index: 0; 120 | } 121 | 122 | .music-container.play .music-info { 123 | opacity: 1; 124 | transform: translateY(-100%); 125 | } 126 | 127 | .music-info h4 { 128 | margin: 0; 129 | } 130 | 131 | .progress-container { 132 | background: #fff; 133 | border-radius: 5px; 134 | cursor: pointer; 135 | margin: 10px 0; 136 | height: 4px; 137 | width: 100%; 138 | } 139 | 140 | .progress { 141 | background-color: #fe8daa; 142 | border-radius: 5px; 143 | height: 100%; 144 | width: 0%; 145 | transition: width 0.1s linear; 146 | } 147 | -------------------------------------------------------------------------------- /Parallex-website/images/NordicLandscape.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/Parallex-website/images/NordicLandscape.jpg -------------------------------------------------------------------------------- /Parallex-website/images/aurora.jfif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/Parallex-website/images/aurora.jfif -------------------------------------------------------------------------------- /Parallex-website/images/bg1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/Parallex-website/images/bg1.png -------------------------------------------------------------------------------- /Parallex-website/images/girl1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/Parallex-website/images/girl1.png -------------------------------------------------------------------------------- /Parallex-website/images/lake.jfif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/Parallex-website/images/lake.jfif -------------------------------------------------------------------------------- /Parallex-website/images/lofotons.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/Parallex-website/images/lofotons.jpg -------------------------------------------------------------------------------- /Parallex-website/images/mountainsLake.jfif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/Parallex-website/images/mountainsLake.jfif -------------------------------------------------------------------------------- /Parallex-website/images/rock1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/Parallex-website/images/rock1.png -------------------------------------------------------------------------------- /Parallex-website/images/switzleft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/Parallex-website/images/switzleft.png -------------------------------------------------------------------------------- /Parallex-website/images/switzright.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/Parallex-website/images/switzright.png -------------------------------------------------------------------------------- /Parallex-website/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Parallax Universe 7 | 8 | 9 | 10 | 14 | 15 | 16 | 17 |
18 | 27 | 28 |
29 |

Explore Nature.

30 | 31 | 32 | 33 |
34 | 35 |
36 |
37 |
38 | 39 | 40 |

Mountains of Himmeltindan

41 |

42 | Himmeltindan has the highest elevation of any mountain on the 43 | central Lofoten island of Vestvågøya. One of the highest peaks 44 | in the region and the highest on its island. It provides the best 45 | view of the southeast chain of Lofoten that we saw during our stay. 46 | 47 |

48 |
49 |
50 | 51 | 52 |

Northern Lights at Tromsø

53 |

54 | Tromsø is the largest city in Northern Norway. With a location at nearly 70° north, 55 | and between fjords, mountain peaks, and islands, it is a prime starting point 56 | for your Arctic adventure. The city is situated in the middle of the auroral oval, 57 | the area with the highest probability of seeing the northern lights. 58 | 59 |

60 |
61 |
62 |
63 | 64 |
65 |
66 |
67 | 68 | 69 |

Mountains of Himmeltindan

70 |

71 | Himmeltindan has the highest elevation of any mountain on the 72 | central Lofoten island of Vestvågøya. One of the highest peaks 73 | in the region and the highest on its island. It provides the best 74 | view of the southeast chain of Lofoten that we saw during our stay. 75 | 76 |

77 |
78 |
79 | 80 | 81 |

Northern Lights at Tromsø

82 |

83 | Tromsø is the largest city in Northern Norway. With a location at nearly 70° north, 84 | and between fjords, mountain peaks, and islands, it is a prime starting point 85 | for your Arctic adventure. The city is situated in the middle of the auroral oval, 86 | the area with the highest probability of seeing the northern lights. 87 | 88 |

89 |
90 |
91 |
92 | 93 | 94 | 95 |
96 |
97 |
98 | lake 99 |
100 |

Norway.

101 |
102 |
103 | 104 |
105 |

106 | Lorem, ipsum dolor sit amet consectetur adipisicing elit. Facere neque 107 | consequuntur a nisi, illo quia cupiditate fuga et eos minima 108 | voluptatum cum dolorum quas repellat eaque beatae vitae veritatis 109 | quae. 110 |

111 |
112 |
113 | 114 | 115 |

Mountains of Himmeltindan

116 |

117 | Himmeltindan has the highest elevation of any mountain on the 118 | central Lofoten island of Vestvågøya. One of the highest peaks 119 | in the region and the highest on its island. It provides the best 120 | view of the southeast chain of Lofoten that we saw during our stay. 121 | 122 |

123 |
124 |
125 | 126 | 127 |

Northern Lights at Tromsø

128 |

129 | Tromsø is the largest city in Northern Norway. With a location at nearly 70° north, 130 | and between fjords, mountain peaks, and islands, it is a prime starting point 131 | for your Arctic adventure. The city is situated in the middle of the auroral oval, 132 | the area with the highest probability of seeing the northern lights. 133 | 134 |

135 |
136 |
137 |
138 | 139 |
140 | 141 | 146 | 147 | 148 | 149 | 150 | -------------------------------------------------------------------------------- /Parallex-website/script.js: -------------------------------------------------------------------------------- 1 | let controller = new ScrollMagic.Controller(); 2 | let timeline = new TimelineMax(); 3 | 4 | timeline 5 | .to(".rock", 10, { y: -300 }) 6 | .to(".girl", 20, { y: -200 }, "-=10") 7 | .fromTo(".bg1", { y: -50 }, { y: 0, duration: 10 }, "-=10") 8 | .to(".content", 25, { top: "0%" }, "-=20") 9 | .fromTo(".content-images", { opacity: 0 }, { opacity: 1, duration: 12 }) 10 | .fromTo(".text", { opacity: 0.9 }, { opacity: 0.7, duration: 12 }) 11 | .to(".content-2", 80, { top: "0%" }, "-=10") 12 | .fromTo(".content-images-lake", { opacity: 0.5 }, { opacity: 1, duration: 1 }) 13 | .fromTo(".text-2", { opacity: 0 }, { opacity: 1, duration: 3 }); 14 | 15 | let scene = new ScrollMagic.Scene({ 16 | triggerElement: "section", 17 | duration: "300%", 18 | triggerHook: 0, 19 | }) 20 | .setTween(timeline) 21 | .setPin("section") 22 | .addTo(controller); 23 | -------------------------------------------------------------------------------- /Parallex-website/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | box-sizing: border-box; 5 | font-family: "Poppins", sans-serif; 6 | } 7 | nav { 8 | position: absolute; 9 | width: 100%; 10 | display: flex; 11 | padding: 3rem 10rem; 12 | justify-content: space-between; 13 | color: #1c2227; 14 | } 15 | 16 | .container { 17 | height: 100vh; 18 | } 19 | .container img { 20 | width: 100%; 21 | position: absolute; 22 | height: 110vh; 23 | object-fit: cover; 24 | z-index: -1; 25 | } 26 | 27 | .main-title { 28 | position: absolute; 29 | top: 28%; 30 | left: 50%; 31 | font-size: 6rem; 32 | color: #fff; 33 | text-shadow: 0 20px 20px rgba(0, 0, 0, 0.15); 34 | transform: translate(-50%, -30%); 35 | } 36 | 37 | .content, 38 | .content-2 { 39 | width: 100%; 40 | background: rgb(24, 24, 24); 41 | min-height: 100vh; 42 | z-index: 2; 43 | color: #fff; 44 | position: absolute; 45 | } 46 | .content-images, 47 | .content-images-lake { 48 | display: flex; 49 | justify-content: space-evenly; 50 | align-items: center; 51 | min-height: 100vh; 52 | text-align: center; 53 | } 54 | .content-images-lake { 55 | min-height: 60vh; 56 | } 57 | .image { 58 | object-fit: cover; 59 | width: 35rem; 60 | height: 24rem; 61 | } 62 | .lake { 63 | object-fit: cover; 64 | width: 100%; 65 | } 66 | .centerLake { 67 | position: absolute; 68 | top: 20%; 69 | left: 22%; 70 | font-size: 4rem; 71 | /* text-shadow: 0 0 20px rgba(165, 169, 174,.1); */ 72 | } 73 | .centerLake h3, 74 | .centerLake h1 { 75 | text-shadow: 0.5em 0 1em rgba(165, 169, 174, 0.1); 76 | } 77 | .text, 78 | .text-2 { 79 | padding: 2rem 2rem; 80 | font-size: 1.1rem; 81 | } 82 | 83 | .button { 84 | cursor: pointer; 85 | padding: 12px 20px; 86 | margin: 0 5px; 87 | border-radius: 8px; 88 | background-color: transparent; 89 | } 90 | .button:hover { 91 | background-color: rgba(233, 236, 239, 0.6); 92 | } 93 | .nav-container { 94 | display: flex; 95 | align-items: center; 96 | justify-content: center; 97 | } 98 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## JavaScript Projects for Beginners 🚀 2 | 3 | Sharpen your JavaScript skills by building projects using Pure JavaScript without any frameworks. 4 | All projects are well structured with comments for explainations and it is very easy to understand every bit of code. 5 | 6 | ### Project List: 7 | 8 |
    9 |
  1. 10 |

    3D Card Animation 😃

    11 | 12 |
  2. 13 |
    14 |
  3. 15 |

    Analog Clock 🕙

    16 | 17 |
  4. 18 |
    19 |
  5. 20 |

    BMI Calculator 📲

    21 | 22 |
  6. 23 |
    24 |
  7. 25 |

    Calculator 📱

    26 | 27 |
  8. 28 |
    29 |
  9. 30 |

    Countdown ⏲️

    31 | 32 |
  10. 33 |
    34 |
  11. 35 |

    Dynamic Calendar 📅

    36 | 37 |
  12. 38 |
    39 |
  13. 40 |

    Music Player 🎵

    41 | 42 |
  14. 43 |
    44 |
  15. 45 |

    Parallax Website 🍀

    46 | 47 |
  16. 48 |
    49 |
  17. 50 |

    Temperature Converter 🌤️

    51 | 52 |
  18. 53 |
    54 |
  19. 55 |

    Todo list 📖

    56 | 57 |
  20. 58 |
    59 |
  21. 60 |

    Weather App ⛈️

    61 | 62 |
  22. 63 |
    64 |
  23. 65 |

    Weight Converter 🙇‍♂️

    66 | 67 |
  24. 68 |
    69 |
70 | 71 | #### And Many more to come... ❕ ❗ 72 | 73 | ### If u liked my projects and the code was useful to you, feel free to leave a star (much appreciated 😃), fork it and customize the projects as you like! :) 74 | ### Thankyou. 75 | 76 | 77 | 78 | ## Contributions 79 | Check our contribution guidelines and start open sourcing 80 | [Contibutions-file](CONTRIBUTIONS.md). 81 | 82 | 83 | ⏩ This Repo is Licensed under the [MIT License](LICENSE). 84 | -------------------------------------------------------------------------------- /SpeechToText/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/SpeechToText/demo.png -------------------------------------------------------------------------------- /SpeechToText/script.js: -------------------------------------------------------------------------------- 1 | var speechRecognition = window.webkitSpeechRecognition; 2 | 3 | var recognition = new speechRecognition(); 4 | 5 | var textbox = $("#textbox"); 6 | 7 | var instructions = $("#instructions"); 8 | 9 | var content = ""; 10 | 11 | recognition.continuous = true; 12 | 13 | // recognition is started 14 | 15 | recognition.onstart = function () { 16 | instructions.text("Voice Recognition is On"); 17 | }; 18 | 19 | recognition.onspeechend = function () { 20 | instructions.text("No Activity"); 21 | }; 22 | 23 | recognition.onerror = function () { 24 | instruction.text("Try Again"); 25 | }; 26 | 27 | recognition.onresult = function (event) { 28 | var current = event.resultIndex; 29 | 30 | var transcript = event.results[current][0].transcript; 31 | 32 | content += transcript; 33 | 34 | textbox.val(content); 35 | }; 36 | 37 | $("#start-btn").click(function (event) { 38 | recognition.start(); 39 | }); 40 | 41 | textbox.on("input", function () { 42 | content = $(this).val(); 43 | }); 44 | -------------------------------------------------------------------------------- /SpeechToText/speech.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | speech to text in javascript 8 | 9 | 13 | 14 | 15 | 16 |
17 |

Speech to Text in JavaScript

18 | 19 |
20 | 21 |
22 | 23 |
24 | 25 | 26 |

Press the Start button

27 |
28 |
29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /Temperature-converter/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Temperature converter 9 | 10 | 11 | 12 | 13 |
14 |
15 |

Temperature converter

16 |
17 |
18 | 19 | 20 | 21 |
22 |
23 | 24 | 25 | -------------------------------------------------------------------------------- /Temperature-converter/script.js: -------------------------------------------------------------------------------- 1 | const celcius = document.getElementById("celcius"); 2 | const fahrenheit = document.getElementById("fahrenheit"); 3 | const kelvin = document.getElementById("kelvin"); 4 | 5 | const inputs = document.getElementsByClassName("inputs"); 6 | 7 | for (let i = 0; i < inputs.length; i++) { 8 | let input = inputs[i]; 9 | 10 | input.addEventListener("input", function (e) { 11 | let value = parseFloat(e.target.value); 12 | 13 | switch (e.target.name) { 14 | case "celcius": 15 | fahrenheit.value = value * 1.8 + 32; 16 | kelvin.value = value + 273.15; 17 | break; 18 | case "fahrenheit": 19 | celcius.value = value - 32 / 1.8; 20 | kelvin.value = value - 32 / 1.8 + 273.15; 21 | break; 22 | case "kelvin": 23 | celcius.value = value - 273.15; 24 | fahrenheit.value = (value - 273.15) * 1.8 + 32; 25 | break; 26 | default: 27 | break; 28 | } 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /Temperature-converter/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | font-family: "Poppins", sans-serif; 5 | } 6 | 7 | main { 8 | width: 100%; 9 | height: 100vh; 10 | background-image: linear-gradient( 11 | to bottom, 12 | #ffce00, 13 | #f7a800, 14 | rgb(75, 75, 75) 15 | ); 16 | offset: initial; 17 | } 18 | 19 | header { 20 | display: flex; 21 | justify-content: center; 22 | padding-top: 200px; 23 | } 24 | 25 | h1 { 26 | margin-bottom: 30px; 27 | font-size: 35px; 28 | } 29 | 30 | .inputs { 31 | display: flex; 32 | flex-wrap: wrap; 33 | flex-direction: column; 34 | justify-content: center; 35 | align-items: center; 36 | max-width: 768px; 37 | margin: 0 auto; 38 | } 39 | 40 | .input { 41 | flex: 1 1 40%; 42 | margin: 15px; 43 | min-width: 350px; 44 | appearance: none; 45 | background: none; 46 | background-color: #fff; 47 | border-radius: 8px; 48 | padding: 15px; 49 | border: none; 50 | outline: none; 51 | transition: 0.4s; 52 | } 53 | 54 | .input:focus { 55 | box-shadow: 0px 6px 10px 1px rgba(0, 0, 0, 0.5); 56 | } 57 | -------------------------------------------------------------------------------- /TicTacToe-Maximun/AIFile.js: -------------------------------------------------------------------------------- 1 | var A_Atk = [0,2,4,20,100,105,110,115,120,130]; 2 | var A_Def = [0,1,3,15,55,56,57,58,60,62]; 3 | 4 | function AIMode() 5 | { 6 | if (!InGame) return; 7 | var vmax = -Infinity; 8 | var px = py = -1; 9 | var TBoard = GetBoard(); 10 | for (y = 0; y < size; y++) 11 | { 12 | for (x = 0; x < size; x++) 13 | { 14 | if (TBoard[x+y*size] == -1) 15 | { 16 | TBoard[x+y*size] = 1; 17 | var mark = GetMark(x,y,TBoard); 18 | TBoard[x+y*size] = -1; 19 | if (mark > vmax) 20 | { 21 | px = x;py = y; 22 | vmax = mark; 23 | } 24 | } 25 | } 26 | } 27 | try 28 | { 29 | var sqr = document.getElementsByClassName("square"); 30 | sqr.item(px + py*size).setAttribute("player","1"); 31 | sqr.item(px + py*size).style.backgroundImage = "url('Images/Xpng.png')"; 32 | l_played.push(px+py*size); 33 | } 34 | catch(e) {alert(e.message)} 35 | } 36 | 37 | function GetBoard() 38 | { 39 | var TBoard = []; 40 | var sqr = document.getElementsByClassName("square"); 41 | for (i = 0; i < size*size;i++) 42 | TBoard.push(parseInt(sqr.item(i).getAttribute("player"))); 43 | 44 | return TBoard; 45 | } 46 | 47 | function GetMark(x,y,Tboard) 48 | { 49 | var val = Tboard[x+y*size]; 50 | if (val == -1) return 0; 51 | 52 | var result = A_Atk[GetMarkHor(x,y,Tboard,1)] + A_Atk[GetMarkVer(x,y,Tboard,1)] 53 | + A_Atk[GetMarkCross1(x,y,Tboard,1)] + A_Atk[GetMarkCross2(x,y,Tboard,1)]; 54 | 55 | result += A_Def[GetMarkHor(x,y,Tboard,0)] + A_Def[GetMarkVer(x,y,Tboard,0)] 56 | + A_Def[GetMarkCross1(x,y,Tboard,0)] + A_Def[GetMarkCross2(x,y,Tboard,0)]; 57 | 58 | return result; 59 | } 60 | 61 | function GetMarkHor(x,y,TBoard,player) 62 | { 63 | var count = 0,counto = 0; 64 | for (i = x-1;i > 0;i--) 65 | { 66 | if (TBoard[i+y*size] == player) count++; 67 | else {if (TBoard[i+y*size] != -1) counto++;break;} 68 | } 69 | for (i = x+1;i < size;i++) 70 | { 71 | if (TBoard[i+y*size] == player) count++; 72 | else {if (TBoard[i+y*size] != -1) counto++;break;} 73 | } 74 | if (mode == 1 && counto >= 2) return 0; 75 | if ((x == 0 || x == size-1) && count < 4) counto++; 76 | if (count <= counto) return 0; 77 | else if (count - counto >= 3) return count + counto; 78 | else return count - counto; 79 | } 80 | 81 | function GetMarkVer(x,y,TBoard,player) 82 | { 83 | var count = 0,counto = 0; 84 | for (i = y-1;i > 0;i--) 85 | { 86 | if (TBoard[x+i*size] == player) count++; 87 | else {if (TBoard[x+i*size] != -1) counto++;break;} 88 | } 89 | for (i = y+1;i < size;i++) 90 | { 91 | if (TBoard[x+i*size] == player) count++; 92 | else {if (TBoard[x+i*size] != -1) counto++;break;} 93 | } 94 | if (mode == 1 && counto >= 2) return 0; 95 | if ((y == 0 || y == size-1) && count < 4) counto++; 96 | if (count <= counto) return 0; 97 | else if (count - counto >= 3) return count + counto; 98 | else return count - counto; 99 | } 100 | 101 | function GetMarkCross1(x,y,TBoard,player) 102 | { 103 | var count = 0,counto = 0; 104 | for (i = 1;i < minab(size-x,y+1);i++) 105 | { 106 | if (TBoard[(x+i)+(y-i)*size] == player) count++; 107 | else {if (TBoard[(x+i)+(y-i)*size] != -1) counto++;break;} 108 | } 109 | for (i = 1;i < minab(x+1,size-y);i++) 110 | { 111 | if (TBoard[(x-i)+(y+i)*size] == player) count++; 112 | else {if (TBoard[(x-i)+(y+i)*size] != -1) counto++;break;} 113 | } 114 | if (mode == 1 && counto >= 2) return 0; 115 | if ((x == 0 || x == size-1 || y == 0 || y == size-1) && count < 4) counto++; 116 | if (count <= counto) return 0; 117 | else if (count - counto >= 3) return count + counto; 118 | else return count - counto; 119 | } 120 | 121 | function GetMarkCross2(x,y,TBoard,player) 122 | { 123 | var count = 0,counto = 0; 124 | for (i = 1;i < minab(x+1,y+1);i++) 125 | { 126 | if (TBoard[(x-i)+(y-i)*size] == player) count++; 127 | else {if (TBoard[(x-i)+(y-i)*size] != -1) counto++;break;} 128 | } 129 | for (i = 1;i < minab(size-x,size-y);i++) 130 | { 131 | if (TBoard[(x+i)+(y+i)*size] == player) count++; 132 | else {if (TBoard[(x+i)+(y+i)*size] != -1) counto++;break;} 133 | } 134 | if (mode == 1 && counto >= 2) return 0; 135 | if ((x == 0 || x == size-1 || y == 0 || y == size-1) && count < 4) counto++; 136 | if (count <= counto) return 0; 137 | else if (count - counto >= 3) return count + counto; 138 | else return count - counto; 139 | } -------------------------------------------------------------------------------- /TicTacToe-Maximun/CssFile.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | 3 | #bgr 4 | { 5 | background-image:url('./Images/123.jpg'); 6 | background-repeat:no-repeat; 7 | z-index:-900; 8 | background-size: cover; 9 | } 10 | 11 | #divmain 12 | { 13 | width:500px; 14 | height:500px; 15 | float:left; 16 | margin-left:150px; 17 | margin-top:50px; 18 | overflow:hidden; 19 | } 20 | #divcontrol 21 | { 22 | width:300px; 23 | height:500px; 24 | float:right; 25 | background-color:#FFF; 26 | margin-right:150px; 27 | margin-top:40px; 28 | opacity:0.7; 29 | overflow:hidden; 30 | border-radius:20px; 31 | } 32 | #imgPlayer 33 | { 34 | width:100px; 35 | height:100px; 36 | margin:auto; 37 | margin-top:5px; 38 | background-image:url('./Images/Opng.png'); 39 | background-repeat:round; 40 | background-color:#CCC; 41 | } 42 | 43 | #divcheckbox 44 | { 45 | width:150px; 46 | margin:auto; 47 | margin-top:10px; 48 | } 49 | 50 | #pgrTime 51 | { 52 | margin-left:10px; 53 | margin-top:14px; 54 | width:150px; 55 | height:14px; 56 | background-color:#3F6; 57 | } 58 | 59 | .square 60 | { 61 | width:25px; 62 | height:25px; 63 | font-size:9px; 64 | border-right:#000 2px solid; 65 | border-top:#000 1px solid; 66 | background-color:#FFF; 67 | background-repeat:round; 68 | overflow:hidden; 69 | opacity:0.65; 70 | cursor:pointer; 71 | } 72 | #label1 73 | { 74 | margin-top:10px; 75 | margin-left:20px; 76 | } 77 | #label2 78 | { 79 | margin-top:10px; 80 | margin-left:20px; 81 | float:left; 82 | } 83 | .button 84 | { 85 | width:200px; 86 | height:50px; 87 | margin-left:50px; 88 | margin-top:30px; 89 | font-weight:700; 90 | font-family:"Arial Black", Gadget, sans-serif; 91 | background-color:#99F; 92 | cursor:pointer; 93 | border-radius:15px; 94 | color:#FFF; 95 | } -------------------------------------------------------------------------------- /TicTacToe-Maximun/EventFile.js: -------------------------------------------------------------------------------- 1 | // JavaScript Document 2 | 3 | const size = 15; 4 | const countmax = 5; 5 | var CPlayer = 0; // Current Player (0 is O,1 is X) 6 | var InGame = false; 7 | var l_played = [], 8 | l_win = []; 9 | var mode = 0; // 0: no block; 1: block 10 | var timereturn = false; 11 | var AI = false; 12 | 13 | //New Game 14 | function Loaded() { 15 | CPlayer = 0; // Current Player (0 is O,1 is X) 16 | (l_played = []), (l_win = []); 17 | var imgp = document.getElementById("imgPlayer"); 18 | imgp.style.backgroundImage = "url('Images/Opng.png')"; 19 | 20 | var table = document.getElementById("table"); 21 | var row = document.getElementsByClassName("row"); 22 | var square = document.getElementsByClassName("square"); 23 | 24 | // Create Table 25 | table.innerHTML = ""; 26 | for (y = 0; y < size; y++) { 27 | table.innerHTML += ''; 28 | for (x = 0; x < size; x++) { 29 | var div = 30 | '
'; 31 | row.item(y).innerHTML += '' + div + ""; 32 | square.item(x + y * size).setAttribute("id", (x + y * size).toString()); 33 | square.item(x + y * size).setAttribute("player", "-1"); 34 | } 35 | } 36 | } 37 | 38 | //Play Game 39 | function Click(id) { 40 | if (!InGame) return; 41 | var square = document.getElementsByClassName("square"); 42 | var pos = parseInt(id); 43 | if (square.item(pos).getAttribute("player") != "-1") return; 44 | var path = "url('Images/Opng.png')"; 45 | if (CPlayer == 1) path = "url('Images/Xpng.png')"; 46 | square.item(pos).style.backgroundImage = path; 47 | square.item(pos).setAttribute("player", CPlayer.toString()); 48 | l_played.push(pos); 49 | 50 | var win = WinGame(); 51 | var pwin = CPlayer; 52 | 53 | if (!AI) { 54 | if (CPlayer == 0) CPlayer = 1; 55 | else CPlayer = 0; 56 | 57 | var iplayer = "url('Images/Opng.png')"; 58 | if (CPlayer == 1) iplayer = "url('Images/Xpng.png')"; 59 | var imgp = document.getElementById("imgPlayer"); 60 | imgp.style.backgroundImage = iplayer; 61 | } else { 62 | if (!win) { 63 | AIMode(); 64 | win = WinGame(); 65 | pwin = 1; 66 | } 67 | } 68 | 69 | if (win) { 70 | var mess = 'Player with "X" win'; 71 | if (pwin == 0) mess = 'Player with "O" win'; 72 | alert(mess); 73 | InGame = false; 74 | } else { 75 | var pgr = document.getElementById("pgrTime"); 76 | pgr.value = pgr.getAttribute("max"); 77 | } 78 | } 79 | 80 | // Min Max 81 | function maxab(a, b) { 82 | if (a > b) return a; 83 | else return b; 84 | } 85 | function minab(a, b) { 86 | if (a < b) return a; 87 | else return b; 88 | } 89 | 90 | function MouseOver(id) { 91 | if (!InGame) return; 92 | var square = document.getElementsByClassName("square"); 93 | var pos = parseInt(id); 94 | square.item(pos).style.backgroundColor = "#3F3"; 95 | } 96 | 97 | function MouseOut(id) { 98 | if (!InGame) return; 99 | var square = document.getElementsByClassName("square"); 100 | var pos = parseInt(id); 101 | square.item(pos).style.backgroundColor = "#FFF"; 102 | } 103 | 104 | function WinGame() { 105 | var result = false; 106 | var Board = GetBoard(); 107 | for (x = 0; x < size; x++) { 108 | for (y = 0; y < size; y++) { 109 | if ( 110 | winHor(x, y, Board) || 111 | winVer(x, y, Board) || 112 | winCross1(x, y, Board) || 113 | winCross2(x, y, Board) 114 | ) { 115 | var square = document.getElementsByClassName("square"); 116 | for (i = 0; i < l_win.length; i++) { 117 | square.item(l_win[i]).style.backgroundColor = "#FF0"; 118 | } 119 | result = true; 120 | } 121 | } 122 | } 123 | return result; 124 | } 125 | 126 | // Win Dir 127 | function winHor(x, y, Board) { 128 | l_win = []; 129 | var count = 0, 130 | counto = 0; // count opponent 131 | var player = Board[x + y * size]; 132 | if (player == -1) return false; 133 | 134 | if (x > 0) { 135 | var p = Board[x - 1 + y * size]; 136 | if (p != player && p != -1) counto++; 137 | } 138 | 139 | for (i = x; i < size; i++) { 140 | var p = Board[i + y * size]; 141 | if (p == player && p != -1) { 142 | count++; 143 | l_win.push(i + y * size); 144 | } else { 145 | if (p != -1) counto++; 146 | break; 147 | } 148 | } 149 | if (count >= countmax) { 150 | if (mode == 0) return true; 151 | else { 152 | if (counto >= 2) return false; 153 | else return true; 154 | } 155 | } 156 | return false; 157 | } 158 | 159 | function winVer(x, y, Board) { 160 | l_win = []; 161 | var count = 0, 162 | counto = 0; 163 | var player = Board[x + y * size]; 164 | if (player == -1) return false; 165 | 166 | if (y > 0) { 167 | var p = Board[x + (y - 1) * size]; 168 | if (p != player && p != -1) counto++; 169 | } 170 | 171 | for (i = y; i < size; i++) { 172 | var p = Board[x + i * size]; 173 | if (p == player && p != -1) { 174 | count++; 175 | l_win.push(x + i * size); 176 | } else { 177 | if (p != -1) counto++; 178 | break; 179 | } 180 | } 181 | if (count >= countmax) { 182 | if (mode == 0) return true; 183 | else { 184 | if (counto >= 2) return false; 185 | else return true; 186 | } 187 | } 188 | return false; 189 | } 190 | 191 | function winCross1(x, y, Board) { 192 | l_win = []; 193 | if (x > size - countmax || y < countmax - 1) return false; 194 | var count = 0, 195 | counto = 0; 196 | var player = Board[x + y * size]; 197 | if (player == -1) return false; 198 | 199 | if (y < size - 1 && x > 0) { 200 | var p = Board[x - 1 + (y + 1) * size]; 201 | if (p != player && p != -1) counto++; 202 | } 203 | 204 | for (i = 0; i <= minab(size - x, y); i++) { 205 | var p = Board[x + i + (y - i) * size]; 206 | if (p == player && p != -1) { 207 | count++; 208 | l_win.push(x + i + (y - i) * size); 209 | } else { 210 | if (p != -1) counto++; 211 | break; 212 | } 213 | } 214 | if (count >= countmax) { 215 | if (mode == 0) return true; 216 | else { 217 | if (counto >= 2) return false; 218 | else return true; 219 | } 220 | } 221 | return false; 222 | } 223 | 224 | function winCross2(x, y, Board) { 225 | l_win = []; 226 | if (x > size - countmax || y > size - countmax) return false; 227 | var count = 0, 228 | counto = 0; 229 | var player = Board[x + y * size]; 230 | if (player == -1) return false; 231 | 232 | if (y > 0 && x > 0) { 233 | var p = Board[x - 1 + (y - 1) * size]; 234 | if (p != player && p != -1) counto++; 235 | } 236 | 237 | for (i = 0; i < minab(size - x, size - y); i++) { 238 | var p = Board[x + i + (y + i) * size]; 239 | if (p == player && p != -1) { 240 | count++; 241 | l_win.push(x + i + (y + i) * size); 242 | } else { 243 | if (p != -1) counto++; 244 | break; 245 | } 246 | } 247 | if (count >= countmax) { 248 | if (mode == 0) return true; 249 | else { 250 | if (counto >= 2) return false; 251 | else return true; 252 | } 253 | } 254 | return false; 255 | } 256 | 257 | // Button Event 258 | function PvsP() { 259 | AI = false; 260 | Loaded(); 261 | InGame = true; 262 | var pgr = document.getElementById("pgrTime"); 263 | pgr.value = pgr.getAttribute("max"); 264 | LoadProgress(); 265 | } 266 | 267 | function PvsM() { 268 | AI = true; 269 | Loaded(); 270 | InGame = true; 271 | var pgr = document.getElementById("pgrTime"); 272 | pgr.value = pgr.getAttribute("max"); 273 | LoadProgress(); 274 | } 275 | 276 | function Undo(time) { 277 | if (time < 1) return; 278 | if (l_played.length <= 0 || !InGame) return; 279 | var sqr = document.getElementsByClassName("square"); 280 | sqr.item(l_played[l_played.length - 1]).setAttribute("player", "-1"); 281 | sqr.item(l_played[l_played.length - 1]).style.backgroundImage = ""; 282 | 283 | l_played.pop(); 284 | if (CPlayer == 0) CPlayer = 1; 285 | else CPlayer = 0; 286 | 287 | var iplayer = "url('Images/Opng.png')"; 288 | if (CPlayer == 1) iplayer = "url('Images/Xpng.png')"; 289 | var imgp = document.getElementById("imgPlayer"); 290 | imgp.style.backgroundImage = iplayer; 291 | 292 | var pgr = document.getElementById("pgrTime"); 293 | pgr.value = pgr.getAttribute("max"); 294 | if (AI) Undo(time - 1); 295 | } 296 | 297 | function ChooseMode() { 298 | var chb = document.getElementById("chbmode"); 299 | if (l_played.length > 0) chb.checked = !chb.checked; 300 | if (chb.checked) mode = 1; 301 | else mode = 0; 302 | } 303 | 304 | function TimeReturn() { 305 | var chb = document.getElementById("chbtime"); 306 | if (l_played.length > 0) chb.checked = !chb.checked; 307 | if (chb.checked) timereturn = true; 308 | else timereturn = false; 309 | if (timereturn) LoadProgress(); 310 | } 311 | 312 | function LoadProgress() { 313 | if (!timereturn || !InGame) return; 314 | setTimeout(function () { 315 | var pgr = document.getElementById("pgrTime"); 316 | pgr.value--; 317 | if (pgr.value > 0) LoadProgress(); 318 | else { 319 | var mess = 'Player with "X" win'; 320 | if (CPlayer == 1) mess = 'Player with "O" win'; 321 | alert(mess); 322 | InGame = false; 323 | } 324 | }, 100); 325 | } 326 | -------------------------------------------------------------------------------- /TicTacToe-Maximun/Images/123.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/TicTacToe-Maximun/Images/123.jpg -------------------------------------------------------------------------------- /TicTacToe-Maximun/Images/Opng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/TicTacToe-Maximun/Images/Opng.png -------------------------------------------------------------------------------- /TicTacToe-Maximun/Images/Screenshot 2021-11-05 151902.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/TicTacToe-Maximun/Images/Screenshot 2021-11-05 151902.png -------------------------------------------------------------------------------- /TicTacToe-Maximun/Images/Xpng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/TicTacToe-Maximun/Images/Xpng.png -------------------------------------------------------------------------------- /TicTacToe-Maximun/Images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/TicTacToe-Maximun/Images/favicon.ico -------------------------------------------------------------------------------- /TicTacToe-Maximun/Images/imgtt.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/TicTacToe-Maximun/Images/imgtt.jpg -------------------------------------------------------------------------------- /TicTacToe-Maximun/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Game Caro Onilne 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 |
16 |
17 |
18 |
CURENT PLAYER:
19 |
20 |
21 |
TIME:
22 | 23 | 24 |
25 | 26 | 27 |
28 |
29 | 30 | Block both sides 31 |
32 |
33 | 34 | -------------------------------------------------------------------------------- /Todo List/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Todo App 9 | 10 | 11 | 12 | 13 |
14 |
Todo List
15 |
16 | 17 | 18 |
19 | 20 | 24 |
25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Todo List/script.js: -------------------------------------------------------------------------------- 1 | // getting all required elements 2 | const inputBox = document.querySelector(".inputfield input"); 3 | const addBtn = document.querySelector(".inputfield button"); 4 | const todoList = document.querySelector(".todoList"); 5 | const deleteAllBtn = document.querySelector(".footer button"); 6 | 7 | // onkeyup event 8 | inputBox.onkeyup = () => { 9 | let userEnteredValue = inputBox.value; //getting user entered value 10 | if (userEnteredValue.trim() != 0) { 11 | //if the user value isn't only spaces 12 | addBtn.classList.add("active"); //active the add button 13 | } else { 14 | addBtn.classList.remove("active"); //unactive the add button 15 | } 16 | }; 17 | 18 | showTasks(); //calling showTask function 19 | 20 | addBtn.onclick = () => { 21 | //when user click on plus icon button 22 | let userEnteredValue = inputBox.value; //getting input field value 23 | let getLocalStorageData = localStorage.getItem("New Todo"); //getting localstorage 24 | if (getLocalStorageData == null) { 25 | //if localstorage has no data 26 | listArray = []; //create a blank array 27 | } else { 28 | listArray = JSON.parse(getLocalStorageData); //transforming json string into a js object 29 | } 30 | listArray.push(userEnteredValue); //pushing or adding new value in array 31 | localStorage.setItem("New Todo", JSON.stringify(listArray)); //transforming js object into a json string 32 | showTasks(); //calling showTask function 33 | addBtn.classList.remove("active"); //unactive the add button once the task added 34 | }; 35 | 36 | function showTasks() { 37 | let getLocalStorageData = localStorage.getItem("New Todo"); 38 | if (getLocalStorageData == null) { 39 | listArray = []; 40 | } else { 41 | listArray = JSON.parse(getLocalStorageData); 42 | } 43 | const pendingTasksNumb = document.querySelector(".pendingTasks"); 44 | pendingTasksNumb.textContent = listArray.length; //passing the array length in pendingtask 45 | if (listArray.length > 0) { 46 | //if array length is greater than 0 47 | deleteAllBtn.classList.add("active"); //active the delete button 48 | } else { 49 | deleteAllBtn.classList.remove("active"); //unactive the delete button 50 | } 51 | let newLiTag = ""; 52 | listArray.forEach((element, index) => { 53 | newLiTag += `
  • ${element}
  • `; 54 | }); 55 | todoList.innerHTML = newLiTag; //adding new li tag inside ul tag 56 | inputBox.value = ""; //once task added leave the input field blank 57 | } 58 | 59 | // delete task function 60 | function deleteTask(index) { 61 | let getLocalStorageData = localStorage.getItem("New Todo"); 62 | listArray = JSON.parse(getLocalStorageData); 63 | listArray.splice(index, 1); //delete or remove the li 64 | localStorage.setItem("New Todo", JSON.stringify(listArray)); 65 | showTasks(); //call the showTasks function 66 | } 67 | 68 | // delete all tasks function 69 | deleteAllBtn.onclick = () => { 70 | listArray = []; //empty the array 71 | localStorage.setItem("New Todo", JSON.stringify(listArray)); //set the item in localstorage 72 | showTasks(); //call the showTasks function 73 | }; 74 | -------------------------------------------------------------------------------- /Todo List/style.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Poppins:wght@200;300;400;500;600;700&display=swap"); 2 | * { 3 | margin: 0; 4 | padding: 0; 5 | box-sizing: border-box; 6 | font-family: "Poppins", sans-serif; 7 | } 8 | ::selection { 9 | color: #ffff; 10 | background: linear-gradient(to right, #68e6ea 0%, #02194b 100%); 11 | } 12 | body { 13 | width: 100%; 14 | height: 100vh; 15 | /* overflow: hidden; */ 16 | padding: 10px; 17 | background: linear-gradient(to bottom, #68eacc 0%, #02194b 100%); 18 | } 19 | .Wrapper { 20 | background: #fff; 21 | max-width: 400px; 22 | width: 100%; 23 | margin: 120px auto; 24 | padding: 25px; 25 | border-radius: 5px; 26 | box-shadow: 0px 10px 15px 0px rgba(0, 0, 0, 0.5); 27 | } 28 | .Wrapper header { 29 | font-size: 30px; 30 | font-weight: 600; 31 | } 32 | .Wrapper .inputfield { 33 | margin: 20px 0; 34 | width: 100%; 35 | display: flex; 36 | height: 45px; 37 | } 38 | .inputfield input { 39 | width: 85%; 40 | height: 100%; 41 | outline: none; 42 | border-radius: 3px; 43 | border: 1px solid #ccc; 44 | font-size: 17px; 45 | padding-left: 15px; 46 | transition: all 0.3s ease; 47 | } 48 | .inputfield input:focus { 49 | border-color: #5877ff; 50 | } 51 | .inputfield button { 52 | width: 50px; 53 | height: 100%; 54 | border: none; 55 | color: #fff; 56 | margin-left: 5px; 57 | font-size: 21px; 58 | outline: none; 59 | background: #6063ff; 60 | cursor: pointer; 61 | border-radius: 3px; 62 | opacity: 0.6; 63 | pointer-events: none; 64 | transition: all 0.3s ease; 65 | } 66 | .inputfield button:hover, 67 | .footer button:hover { 68 | background: #2d57b3; 69 | } 70 | .inputfield button.active { 71 | opacity: 1; 72 | pointer-events: auto; 73 | } 74 | .Wrapper .todoList { 75 | max-height: 250px; 76 | overflow-y: auto; 77 | } 78 | .todoList li { 79 | position: relative; 80 | list-style: none; 81 | height: 45px; 82 | line-height: 45px; 83 | margin-bottom: 8px; 84 | background: #f2f2f2; 85 | border-radius: 3px; 86 | padding: 0 15px; 87 | cursor: default; 88 | overflow: hidden; 89 | } 90 | .todoList li .icon { 91 | position: absolute; 92 | right: -45px; 93 | background: #e74c3c; 94 | width: 45px; 95 | text-align: center; 96 | color: #fff; 97 | border-radius: 0 3px 3px 0; 98 | cursor: pointer; 99 | transition: all 0.2s ease; 100 | } 101 | .todoList li:hover .icon { 102 | right: 0px; 103 | } 104 | .Wrapper .footer { 105 | display: flex; 106 | width: 100%; 107 | margin-top: 20px; 108 | align-items: center; 109 | justify-content: space-between; 110 | } 111 | .footer button { 112 | padding: 6px 10px; 113 | border-radius: 3px; 114 | border: none; 115 | outline: none; 116 | color: #fff; 117 | font-weight: 400; 118 | font-size: 16px; 119 | margin-left: 5px; 120 | background: #709cfc; 121 | cursor: pointer; 122 | user-select: none; 123 | opacity: 0.6; 124 | pointer-events: none; 125 | transition: all 0.3s ease; 126 | } 127 | .footer button.active { 128 | opacity: 1; 129 | pointer-events: auto; 130 | } 131 | -------------------------------------------------------------------------------- /Video-Doboianh/Screenshot (301).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/Video-Doboianh/Screenshot (301).png -------------------------------------------------------------------------------- /Video-Doboianh/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Custom video player 8 | 9 | 10 | 11 |
    12 |
    13 |
    14 | 15 | 16 | 17 | 18 |
    19 | 20 | 23 | 24 | 70 |
    71 |
    72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /Video-Doboianh/index.js: -------------------------------------------------------------------------------- 1 | // Select elements here 2 | const video = document.getElementById('video'); 3 | const videoControls = document.getElementById('video-controls'); 4 | const playButton = document.getElementById('play'); 5 | const playbackIcons = document.querySelectorAll('.playback-icons use'); 6 | const timeElapsed = document.getElementById('time-elapsed'); 7 | const duration = document.getElementById('duration'); 8 | const progressBar = document.getElementById('progress-bar'); 9 | const seek = document.getElementById('seek'); 10 | const seekTooltip = document.getElementById('seek-tooltip'); 11 | const volumeButton = document.getElementById('volume-button'); 12 | const volumeIcons = document.querySelectorAll('.volume-button use'); 13 | const volumeMute = document.querySelector('use[href="#volume-mute"]'); 14 | const volumeLow = document.querySelector('use[href="#volume-low"]'); 15 | const volumeHigh = document.querySelector('use[href="#volume-high"]'); 16 | const volume = document.getElementById('volume'); 17 | const playbackAnimation = document.getElementById('playback-animation'); 18 | const fullscreenButton = document.getElementById('fullscreen-button'); 19 | const videoContainer = document.getElementById('video-container'); 20 | const fullscreenIcons = fullscreenButton.querySelectorAll('use'); 21 | 22 | const videoWorks = !!document.createElement('video').canPlayType; 23 | if (videoWorks) { 24 | video.controls = false; 25 | videoControls.classList.remove('hidden'); 26 | } 27 | 28 | // Add functions here 29 | 30 | // togglePlay toggles the playback state of the video. 31 | // If the video playback is paused or ended, the video is played 32 | // otherwise, the video is paused 33 | function togglePlay() { 34 | if (video.paused || video.ended) { 35 | video.play(); 36 | } else { 37 | video.pause(); 38 | } 39 | } 40 | 41 | // updatePlayButton updates the playback icon and tooltip 42 | // depending on the playback state 43 | function updatePlayButton() { 44 | playbackIcons.forEach((icon) => icon.classList.toggle('hidden')); 45 | 46 | if (video.paused) { 47 | playButton.setAttribute('data-title', 'Play (k)'); 48 | } else { 49 | playButton.setAttribute('data-title', 'Pause (k)'); 50 | } 51 | } 52 | 53 | // formatTime takes a time length in seconds and returns the time in 54 | // minutes and seconds 55 | function formatTime(timeInSeconds) { 56 | const result = new Date(timeInSeconds * 1000).toISOString().substr(11, 8); 57 | 58 | return { 59 | minutes: result.substr(3, 2), 60 | seconds: result.substr(6, 2), 61 | }; 62 | } 63 | 64 | // initializeVideo sets the video duration, and maximum value of the 65 | // progressBar 66 | function initializeVideo() { 67 | const videoDuration = Math.round(video.duration); 68 | seek.setAttribute('max', videoDuration); 69 | progressBar.setAttribute('max', videoDuration); 70 | const time = formatTime(videoDuration); 71 | duration.innerText = `${time.minutes}:${time.seconds}`; 72 | duration.setAttribute('datetime', `${time.minutes}m ${time.seconds}s`); 73 | } 74 | 75 | // updateTimeElapsed indicates how far through the video 76 | // the current playback is by updating the timeElapsed element 77 | function updateTimeElapsed() { 78 | const time = formatTime(Math.round(video.currentTime)); 79 | timeElapsed.innerText = `${time.minutes}:${time.seconds}`; 80 | timeElapsed.setAttribute('datetime', `${time.minutes}m ${time.seconds}s`); 81 | } 82 | 83 | // updateProgress indicates how far through the video 84 | // the current playback is by updating the progress bar 85 | function updateProgress() { 86 | seek.value = Math.floor(video.currentTime); 87 | progressBar.value = Math.floor(video.currentTime); 88 | } 89 | 90 | // updateSeekTooltip uses the position of the mouse on the progress bar to 91 | // roughly work out what point in the video the user will skip to if 92 | // the progress bar is clicked at that point 93 | function updateSeekTooltip(event) { 94 | const skipTo = Math.round( 95 | (event.offsetX / event.target.clientWidth) * 96 | parseInt(event.target.getAttribute('max'), 10) 97 | ); 98 | seek.setAttribute('data-seek', skipTo); 99 | const t = formatTime(skipTo); 100 | seekTooltip.textContent = `${t.minutes}:${t.seconds}`; 101 | const rect = video.getBoundingClientRect(); 102 | seekTooltip.style.left = `${event.pageX - rect.left}px`; 103 | } 104 | 105 | // skipAhead jumps to a different point in the video when the progress bar 106 | // is clicked 107 | function skipAhead(event) { 108 | const skipTo = event.target.dataset.seek 109 | ? event.target.dataset.seek 110 | : event.target.value; 111 | video.currentTime = skipTo; 112 | progressBar.value = skipTo; 113 | seek.value = skipTo; 114 | } 115 | 116 | // updateVolume updates the video's volume 117 | // and disables the muted state if active 118 | function updateVolume() { 119 | if (video.muted) { 120 | video.muted = false; 121 | } 122 | 123 | video.volume = volume.value; 124 | } 125 | 126 | // updateVolumeIcon updates the volume icon so that it correctly reflects 127 | // the volume of the video 128 | function updateVolumeIcon() { 129 | volumeIcons.forEach((icon) => { 130 | icon.classList.add('hidden'); 131 | }); 132 | 133 | volumeButton.setAttribute('data-title', 'Mute (m)'); 134 | 135 | if (video.muted || video.volume === 0) { 136 | volumeMute.classList.remove('hidden'); 137 | volumeButton.setAttribute('data-title', 'Unmute (m)'); 138 | } else if (video.volume > 0 && video.volume <= 0.5) { 139 | volumeLow.classList.remove('hidden'); 140 | } else { 141 | volumeHigh.classList.remove('hidden'); 142 | } 143 | } 144 | 145 | // toggleMute mutes or unmutes the video when executed 146 | // When the video is unmuted, the volume is returned to the value 147 | // it was set to before the video was muted 148 | function toggleMute() { 149 | video.muted = !video.muted; 150 | 151 | if (video.muted) { 152 | volume.setAttribute('data-volume', volume.value); 153 | volume.value = 0; 154 | } else { 155 | volume.value = volume.dataset.volume; 156 | } 157 | } 158 | 159 | // animatePlayback displays an animation when 160 | // the video is played or paused 161 | function animatePlayback() { 162 | playbackAnimation.animate( 163 | [ 164 | { 165 | opacity: 1, 166 | transform: 'scale(1)', 167 | }, 168 | { 169 | opacity: 0, 170 | transform: 'scale(1.3)', 171 | }, 172 | ], 173 | { 174 | duration: 500, 175 | } 176 | ); 177 | } 178 | 179 | // toggleFullScreen toggles the full screen state of the video 180 | // If the browser is currently in fullscreen mode, 181 | // then it should exit and vice versa. 182 | function toggleFullScreen() { 183 | if (document.fullscreenElement) { 184 | document.exitFullscreen(); 185 | } else if (document.webkitFullscreenElement) { 186 | // Need this to support Safari 187 | document.webkitExitFullscreen(); 188 | } else if (videoContainer.webkitRequestFullscreen) { 189 | // Need this to support Safari 190 | videoContainer.webkitRequestFullscreen(); 191 | } else { 192 | videoContainer.requestFullscreen(); 193 | } 194 | } 195 | 196 | // updateFullscreenButton changes the icon of the full screen button 197 | // and tooltip to reflect the current full screen state of the video 198 | function updateFullscreenButton() { 199 | fullscreenIcons.forEach((icon) => icon.classList.toggle('hidden')); 200 | 201 | if (document.fullscreenElement) { 202 | fullscreenButton.setAttribute('data-title', 'Exit full screen (f)'); 203 | } else { 204 | fullscreenButton.setAttribute('data-title', 'Full screen (f)'); 205 | } 206 | } 207 | 208 | // togglePip toggles Picture-in-Picture mode on the video 209 | async function togglePip() { 210 | try { 211 | if (video !== document.pictureInPictureElement) { 212 | pipButton.disabled = true; 213 | await video.requestPictureInPicture(); 214 | } else { 215 | await document.exitPictureInPicture(); 216 | } 217 | } catch (error) { 218 | console.error(error); 219 | } finally { 220 | pipButton.disabled = false; 221 | } 222 | } 223 | 224 | // hideControls hides the video controls when not in use 225 | // if the video is paused, the controls must remain visible 226 | function hideControls() { 227 | if (video.paused) { 228 | return; 229 | } 230 | 231 | videoControls.classList.add('hide'); 232 | } 233 | 234 | // showControls displays the video controls 235 | function showControls() { 236 | videoControls.classList.remove('hide'); 237 | } 238 | 239 | // keyboardShortcuts executes the relevant functions for 240 | // each supported shortcut key 241 | function keyboardShortcuts(event) { 242 | const { key } = event; 243 | switch (key) { 244 | case 'k': 245 | togglePlay(); 246 | animatePlayback(); 247 | if (video.paused) { 248 | showControls(); 249 | } else { 250 | setTimeout(() => { 251 | hideControls(); 252 | }, 2000); 253 | } 254 | break; 255 | case 'm': 256 | toggleMute(); 257 | break; 258 | case 'f': 259 | toggleFullScreen(); 260 | break; 261 | } 262 | } 263 | 264 | // Add eventlisteners here 265 | playButton.addEventListener('click', togglePlay); 266 | video.addEventListener('play', updatePlayButton); 267 | video.addEventListener('pause', updatePlayButton); 268 | video.addEventListener('loadedmetadata', initializeVideo); 269 | video.addEventListener('timeupdate', updateTimeElapsed); 270 | video.addEventListener('timeupdate', updateProgress); 271 | video.addEventListener('volumechange', updateVolumeIcon); 272 | video.addEventListener('click', togglePlay); 273 | video.addEventListener('click', animatePlayback); 274 | video.addEventListener('mouseenter', showControls); 275 | video.addEventListener('mouseleave', hideControls); 276 | videoControls.addEventListener('mouseenter', showControls); 277 | videoControls.addEventListener('mouseleave', hideControls); 278 | seek.addEventListener('mousemove', updateSeekTooltip); 279 | seek.addEventListener('input', skipAhead); 280 | volume.addEventListener('input', updateVolume); 281 | volumeButton.addEventListener('click', toggleMute); 282 | fullscreenButton.addEventListener('click', toggleFullScreen); 283 | videoContainer.addEventListener('fullscreenchange', updateFullscreenButton); 284 | 285 | document.addEventListener('DOMContentLoaded', () => { 286 | if (!('pictureInPictureEnabled' in document)) { 287 | pipButton.classList.add('hidden'); 288 | } 289 | }); 290 | document.addEventListener('keyup', keyboardShortcuts); 291 | -------------------------------------------------------------------------------- /Video-Doboianh/poster.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/Video-Doboianh/poster.jpg -------------------------------------------------------------------------------- /Video-Doboianh/style.css: -------------------------------------------------------------------------------- 1 | /* ========================================================================== 2 | #Custom HTML5 Video Player 3 | ========================================================================== */ 4 | 5 | :root { 6 | --youtube-red: #FE0900; 7 | } 8 | 9 | html { 10 | box-sizing: border-box; 11 | font-family: "YouTube Noto",Roboto,Arial,Helvetica,sans-serif; 12 | height: 100%; 13 | } 14 | 15 | *, *::before, *::after { 16 | box-sizing: inherit; 17 | margin: 0; 18 | padding: 0; 19 | } 20 | 21 | body { 22 | height: 100%; 23 | } 24 | 25 | .container { 26 | width: 100%; 27 | height: 100%; 28 | display: flex; 29 | justify-content: center; 30 | align-items: center; 31 | } 32 | 33 | .video-container { 34 | width: 800px; 35 | border-radius: 4px; 36 | margin: 0 auto; 37 | position: relative; 38 | display: flex; 39 | flex-direction: column; 40 | justify-content: center; 41 | } 42 | 43 | video { 44 | width: 100%; 45 | height: 100%; 46 | border-radius: 4px; 47 | } 48 | 49 | .video-controls { 50 | right: 0; 51 | left: 0; 52 | padding: 10px; 53 | position: absolute; 54 | bottom: 0; 55 | transition: all 0.2s ease; 56 | background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.5)); 57 | } 58 | 59 | .video-controls.hide { 60 | opacity: 0; 61 | pointer-events: none; 62 | } 63 | 64 | .video-progress { 65 | position: relative; 66 | height: 8.4px; 67 | margin-bottom: 10px; 68 | } 69 | 70 | progress { 71 | -webkit-appearance: none; 72 | -moz-appearance: none; 73 | appearance: none; 74 | border-radius: 2px; 75 | width: 100%; 76 | height: 8.4px; 77 | pointer-events: none; 78 | position: absolute; 79 | top: 0; 80 | } 81 | 82 | progress::-webkit-progress-bar { 83 | background-color: #474545; 84 | border-radius: 2px; 85 | } 86 | 87 | progress::-webkit-progress-value { 88 | background: var(--youtube-red); 89 | border-radius: 2px; 90 | } 91 | 92 | progress::-moz-progress-bar { 93 | border: 1px solid var(--youtube-red); 94 | background: var(--youtube-red); 95 | } 96 | 97 | .seek { 98 | position: absolute; 99 | top: 0; 100 | width: 100%; 101 | cursor: pointer; 102 | margin: 0; 103 | } 104 | 105 | .seek:hover+.seek-tooltip { 106 | display: block; 107 | } 108 | 109 | .seek-tooltip { 110 | display: none; 111 | position: absolute; 112 | top: -50px; 113 | margin-left: -20px; 114 | font-size: 12px; 115 | padding: 3px; 116 | content: attr(data-title); 117 | font-weight: bold; 118 | color: #fff; 119 | background-color: rgba(0, 0, 0, 0.6); 120 | } 121 | 122 | .bottom-controls { 123 | display: flex; 124 | justify-content: space-between; 125 | align-items: center; 126 | } 127 | 128 | .left-controls { 129 | display: flex; 130 | align-items: center; 131 | color: #fff; 132 | } 133 | 134 | .volume-controls { 135 | display: flex; 136 | align-items: center; 137 | margin-right: 10px; 138 | } 139 | 140 | .volume-controls input { 141 | width: 100px; 142 | opacity: 1; 143 | transition: all 0.4s ease; 144 | } 145 | 146 | .volume-controls:hover input, .volume-controls input:focus { 147 | width: 100px; 148 | opacity: 1; 149 | } 150 | 151 | button { 152 | cursor: pointer; 153 | position: relative; 154 | margin-right: 7px; 155 | font-size: 12px; 156 | padding: 3px; 157 | border: none; 158 | outline: none; 159 | background-color: transparent; 160 | } 161 | 162 | button * { 163 | pointer-events: none; 164 | } 165 | 166 | button::before { 167 | content: attr(data-title); 168 | position: absolute; 169 | display: none; 170 | right: 0; 171 | top: -50px; 172 | background-color: rgba(0, 0, 0, 0.6); 173 | color: #fff; 174 | font-weight: bold; 175 | padding: 4px 6px; 176 | word-break: keep-all; 177 | white-space: pre; 178 | } 179 | 180 | button:hover::before { 181 | display: inline-block; 182 | } 183 | 184 | .fullscreen-button { 185 | margin-right: 0; 186 | } 187 | 188 | .pip-button svg { 189 | width: 26px; 190 | height: 26px; 191 | } 192 | 193 | .playback-animation { 194 | pointer-events: none; 195 | position: absolute; 196 | top: 50%; 197 | left: 50%; 198 | margin-left: -40px; 199 | margin-top: -40px; 200 | width: 80px; 201 | height: 80px; 202 | border-radius: 80px; 203 | background-color: rgba(0, 0, 0, 0.6); 204 | display: flex; 205 | justify-content: center; 206 | align-items: center; 207 | opacity: 0; 208 | } 209 | 210 | input[type=range] { 211 | -webkit-appearance: none; 212 | -moz-appearance: none; 213 | height: 8.4px; 214 | background: transparent; 215 | cursor: pointer; 216 | } 217 | 218 | input[type=range]:focus { 219 | outline: none; 220 | } 221 | 222 | input[type=range]::-webkit-slider-runnable-track { 223 | width: 100%; 224 | cursor: pointer; 225 | border-radius: 1.3px; 226 | -webkit-appearance: none; 227 | transition: all 0.4s ease; 228 | } 229 | 230 | input[type=range]::-webkit-slider-thumb { 231 | height: 16px; 232 | width: 16px; 233 | border-radius: 16px; 234 | background: var(--youtube-red); 235 | cursor: pointer; 236 | -webkit-appearance: none; 237 | margin-left: -1px; 238 | } 239 | 240 | input[type=range]:focus::-webkit-slider-runnable-track { 241 | background: transparent; 242 | } 243 | 244 | input[type=range].volume { 245 | height: 5px; 246 | background-color: #fff; 247 | } 248 | 249 | input[type=range].volume::-webkit-slider-runnable-track { 250 | background-color: transparent; 251 | } 252 | 253 | input[type=range].volume::-webkit-slider-thumb { 254 | margin-left: 0; 255 | height: 14px; 256 | width: 14px; 257 | background: #fff; 258 | } 259 | 260 | input[type=range]::-moz-range-track { 261 | width: 100%; 262 | height: 8.4px; 263 | cursor: pointer; 264 | border: 1px solid transparent; 265 | background: transparent; 266 | border-radius: 1.3px; 267 | } 268 | 269 | input[type=range]::-moz-range-thumb { 270 | height: 14px; 271 | width: 14px; 272 | border-radius: 50px; 273 | border: 1px solid var(--youtube-red); 274 | background: var(--youtube-red); 275 | cursor: pointer; 276 | margin-top: 5px; 277 | } 278 | 279 | input[type=range]:focus::-moz-range-track { 280 | outline: none; 281 | } 282 | 283 | input[type=range].volume::-moz-range-thumb { 284 | border: 1px solid #fff; 285 | background: #fff; 286 | } 287 | 288 | .hidden { 289 | display: none; 290 | } 291 | 292 | svg { 293 | width: 28px; 294 | height: 28px; 295 | fill: #fff; 296 | stroke: #fff; 297 | cursor: pointer; 298 | } 299 | -------------------------------------------------------------------------------- /Video-Doboianh/video.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ratheshan03/JavaScript-Projects-for-Beginners/df7cd8ba410d4b4c07910a2263b43891fcb46a64/Video-Doboianh/video.mp4 -------------------------------------------------------------------------------- /Weather-app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Weather App 9 | 10 | 11 | 12 | 13 | 14 |
    15 | 19 |
    20 |

    Weather in Denver

    21 |

    51°C

    22 |
    23 | 24 |
    Cloudy
    25 |
    26 |
    Humidity: 70%
    27 |
    Wind speed: 7.4 km/h
    28 |
    29 | 30 |
    31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /Weather-app/script.js: -------------------------------------------------------------------------------- 1 | let weather = { 2 | apiKey: "166ab4233db5802fde57d87f62b9ea6e", 3 | fetchWeather: function (city) { 4 | fetch( 5 | "https://api.openweathermap.org/data/2.5/weather?q=" + 6 | city + 7 | "&units=metric&appid=" + 8 | this.apiKey 9 | ) 10 | .then((response) => { 11 | if (!response.ok) { 12 | alert("No weather found."); 13 | throw new Error("No weather found."); 14 | } 15 | return response.json(); 16 | }) 17 | .then((data) => this.displayWeather(data)); 18 | }, 19 | 20 | displayWeather: function (data) { 21 | // Getting the values and setting up on the variables 22 | const { name } = data; 23 | const { icon, description } = data.weather[0]; 24 | const { temp, humidity } = data.main; 25 | const { speed } = data.wind; 26 | 27 | // displaying the data 28 | document.querySelector(".city").innerText = "Weather in " + name; 29 | document.querySelector(".icon").src = 30 | "https://openweathermap.org/img/wn/" + icon + ".png"; 31 | document.querySelector(".description").innerText = description; 32 | document.querySelector(".temp").innerText = temp + "°C"; 33 | document.querySelector(".humidity").innerText = 34 | "Humidity: " + humidity + "%"; 35 | document.querySelector(".wind").innerText = 36 | "Wind speed: " + speed + " km/h"; 37 | 38 | document.querySelector(".weather").classList.remove("loading"); 39 | document.body.style.backgroundImage = 40 | "url('https://source.unsplash.com/1600x900/?" + name + "')"; 41 | }, 42 | search: function () { 43 | this.fetchWeather(document.querySelector(".search-bar").value); 44 | }, 45 | }; 46 | 47 | document.querySelector(".search button").addEventListener("click", function () { 48 | weather.search(); 49 | }); 50 | 51 | document 52 | .querySelector(".search-bar") 53 | .addEventListener("keyup", function (event) { 54 | if (event.key == "Enter") { 55 | weather.search(); 56 | } 57 | }); 58 | 59 | weather.fetchWeather("Kandy"); 60 | -------------------------------------------------------------------------------- /Weather-app/search.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Weather-app/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | display: flex; 3 | align-items: center; 4 | justify-content: center; 5 | height: 100vh; 6 | margin: 0; 7 | font-family: "Poppins", sans-serif; 8 | font-size: 120%; 9 | background: #333; 10 | background-image: url("https://source.unsplash.com/1600x900/?landscape"); 11 | } 12 | 13 | .card { 14 | background: #000000d0; 15 | color: white; 16 | padding: 2em; 17 | border-radius: 30px; 18 | width: 100%; 19 | max-width: 420px; 20 | margin: 1em; 21 | } 22 | 23 | .search { 24 | display: flex; 25 | align-items: center; 26 | justify-content: center; 27 | } 28 | 29 | input.search-bar { 30 | border: none; 31 | outline: none; 32 | padding: 0.4em 1em; 33 | border-radius: 24px; 34 | background: #7c7c7c2b; 35 | color: white; 36 | font-family: inherit; 37 | font-size: 105%; 38 | width: calc(100% - 100px); 39 | } 40 | 41 | button { 42 | margin: 0.5em; 43 | border-radius: 50%; 44 | border: none; 45 | height: 44px; 46 | width: 44px; 47 | background: #7c7c7c2b; 48 | color: white; 49 | cursor: pointer; 50 | transition: 0.2s ease-in-out; 51 | } 52 | 53 | button:hover { 54 | background: #7c7c7c6b; 55 | } 56 | 57 | h1.temp { 58 | margin: 0; 59 | margin-bottom: 0.4em; 60 | } 61 | 62 | .flex { 63 | display: flex; 64 | align-items: center; 65 | } 66 | 67 | .description { 68 | text-transform: capitalize; 69 | margin-left: 8px; 70 | } 71 | 72 | .weather.loading { 73 | visibility: hidden; 74 | max-height: 20px; 75 | position: relative; 76 | } 77 | 78 | .weather.loading::after { 79 | visibility: visible; 80 | content: "Loading..."; 81 | color: whitesmoke; 82 | position: absolute; 83 | top: 0; 84 | left: 20px; 85 | } 86 | -------------------------------------------------------------------------------- /Weight-converter/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | 10 | Weight converter 11 | 12 | 13 | 14 |
    15 |
    16 |
    17 |

    Weight Converter

    18 |
    19 |
    20 | 21 |
    22 |
    23 |
    24 |
    25 |
    26 |
    Grams:
    27 |
    28 |
    29 |
    30 | 31 |
    32 |
    33 |
    Kilograms:
    34 |
    35 |
    36 |
    37 | 38 |
    39 |
    40 |
    Ounces:
    41 |
    42 |
    43 |
    44 |
    45 |
    46 |
    47 |
    48 | 49 | 50 | -------------------------------------------------------------------------------- /Weight-converter/script.js: -------------------------------------------------------------------------------- 1 | document.getElementById("output").style.display = "none"; 2 | 3 | document.getElementById("lbsInput").addEventListener("input", function (e) { 4 | let lbs = e.target.value; 5 | document.getElementById("output").style.display = "block"; 6 | document.getElementById("gramsOutput").innerHTML = lbs / 0.0022046; 7 | document.getElementById("kgOutput").innerHTML = lbs / 2.2046; 8 | document.getElementById("ozOutput").innerHTML = lbs * 16; 9 | }); 10 | -------------------------------------------------------------------------------- /Weight-converter/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin-top: 70px; 3 | background-image: linear-gradient( 4 | 0deg, 5 | rgb(20, 20, 20) 23.8%, 6 | rgb(88, 88, 88) 92% 7 | ); 8 | color: white; 9 | height: 100vh; 10 | } 11 | .card { 12 | color: white; 13 | box-shadow: 0 10px 10px 0 rgba(100, 100, 100, 0.6); 14 | } 15 | 16 | .card-primary { 17 | background: rgba(93, 144, 253, 0.884); 18 | } 19 | 20 | .card-success { 21 | background: rgba(93, 253, 128, 0.884); 22 | } 23 | 24 | .card-danger { 25 | background: rgba(253, 93, 128, 0.884); 26 | } 27 | --------------------------------------------------------------------------------