diff --git a/animation/03-dropdown-menu/README.md b/animation/03-dropdown-menu/README.md new file mode 100644 index 0000000..0d12b6a --- /dev/null +++ b/animation/03-dropdown-menu/README.md @@ -0,0 +1,18 @@ +# Dropdown Menu + +We've set up a dropdown menu in this exercise. Load up the page, you can see a single menu title, with a dropdown menu that will open upon clicking on the title. + +Your task is to add animation to the dropdown menu so that it will have an effect of expanding. Check out the desired outcome below, and notice the _bounce_ illusion when the dropdown expands close to its final end state. + +### Hints +- You need to specify a _transform-origin_ property to make the dropdown menu start transforming from the top +- You need to add an intermediate step to the keyframe at rule to implement the _bounce_ illusion. + +## Desired Outcome + +![outcome](./desired-outcome.gif) + +### Self Check + +- The dropdown menu expands after you click on the menu title +- There's a _bounce_ illusion towards the end of the animation \ No newline at end of file diff --git a/animation/03-dropdown-menu/desired-outcome.gif b/animation/03-dropdown-menu/desired-outcome.gif new file mode 100644 index 0000000..282e7a4 Binary files /dev/null and b/animation/03-dropdown-menu/desired-outcome.gif differ diff --git a/animation/03-dropdown-menu/index.html b/animation/03-dropdown-menu/index.html new file mode 100644 index 0000000..c08e141 --- /dev/null +++ b/animation/03-dropdown-menu/index.html @@ -0,0 +1,23 @@ + + + + + + + Dropdown Menu + + + + + + + diff --git a/animation/03-dropdown-menu/script.js b/animation/03-dropdown-menu/script.js new file mode 100644 index 0000000..a6aea30 --- /dev/null +++ b/animation/03-dropdown-menu/script.js @@ -0,0 +1,15 @@ +const dropdownContainer = document.querySelector(".dropdown-container"); +const menuTitle = document.querySelector(".menu-title"); +const dropdownMenu = document.querySelector(".dropdown-menu"); + +menuTitle.addEventListener("click", (e) => { + if (e.target === e.currentTarget) { + dropdownMenu.classList.toggle("visible"); + } +}) + +window.addEventListener("click", (e) => { + if (!dropdownContainer.contains(e.target)) { + dropdownMenu.classList.remove("visible") + } +}) \ No newline at end of file diff --git a/animation/03-dropdown-menu/solution/solution.css b/animation/03-dropdown-menu/solution/solution.css new file mode 100644 index 0000000..5c12c21 --- /dev/null +++ b/animation/03-dropdown-menu/solution/solution.css @@ -0,0 +1,52 @@ +.dropdown-container { + max-width: 250px; + margin: 40px auto; + text-align: center; + line-height: 50px; + font-size: 15px; + color: rgb(247, 247, 247); + cursor: pointer; +} + +.menu-title { + background-color: rgb(163, 162, 162); +} + +.dropdown-menu { + list-style: none; + padding: 0; + margin: 0; + background-color: rgb(99, 97, 97); + + display: none; +} + +ul.dropdown-menu li:hover { + background: rgb(47, 46, 46); +} + +.visible { + display: block; +} + +/* SOLUTION */ + +.visible { + animation: expand 500ms ease-in-out; + transform-origin: top; +} + +@keyframes expand { + 0% { + transform: scaleY(0); + } + + 70% { + transform: scaleY(1.1); + } + + 100% { + transform: scaleY(1); + } +} + diff --git a/animation/03-dropdown-menu/solution/solution.html b/animation/03-dropdown-menu/solution/solution.html new file mode 100644 index 0000000..4827777 --- /dev/null +++ b/animation/03-dropdown-menu/solution/solution.html @@ -0,0 +1,23 @@ + + + + + + + Dropdown Menu + + + + + + + diff --git a/animation/03-dropdown-menu/solution/solution.js b/animation/03-dropdown-menu/solution/solution.js new file mode 100644 index 0000000..a6aea30 --- /dev/null +++ b/animation/03-dropdown-menu/solution/solution.js @@ -0,0 +1,15 @@ +const dropdownContainer = document.querySelector(".dropdown-container"); +const menuTitle = document.querySelector(".menu-title"); +const dropdownMenu = document.querySelector(".dropdown-menu"); + +menuTitle.addEventListener("click", (e) => { + if (e.target === e.currentTarget) { + dropdownMenu.classList.toggle("visible"); + } +}) + +window.addEventListener("click", (e) => { + if (!dropdownContainer.contains(e.target)) { + dropdownMenu.classList.remove("visible") + } +}) \ No newline at end of file diff --git a/animation/03-dropdown-menu/style.css b/animation/03-dropdown-menu/style.css new file mode 100644 index 0000000..9f47d77 --- /dev/null +++ b/animation/03-dropdown-menu/style.css @@ -0,0 +1,32 @@ +.dropdown-container { + max-width: 250px; + margin: 40px auto; + text-align: center; + line-height: 50px; + font-size: 15px; + color: rgb(247, 247, 247); + cursor: pointer; +} + +.menu-title { + background-color: rgb(163, 162, 162); +} + +.dropdown-menu { + list-style: none; + padding: 0; + margin: 0; + background-color: rgb(99, 97, 97); + + display: none; +} + +ul.dropdown-menu li:hover { + background: rgb(47, 46, 46); +} + +.visible { + display: block; +} + +