DEV Community

Aishwarya Mali
Aishwarya Mali

Posted on

#JavaScriptmas 2023 Day 13 to 18

Welcome back! If you've been following along, we've already solved challenges of Days 1 to 12 in our journey. Now, buckle up as we dive into the next leg of this adventure Days 13 to 18. Let's start.

Day 13: Christmas Dinner Picker

Task

  • Write the code to help a user choose the perfect Christmas dinner idea based on the number of people attending.
  • Include a checkbox for the user to specify the meal should be vegetarian-friendly.
  • Dinner suggestions (or choose your own!): Vegetarian: Winter Squash Risotto 4 people or less: Ham 5+ people: Turkey
const numOfGuests = document.getElementById('guests')
const btnCalculate = document.getElementById('btn')
const isVegetarian = document.getElementById('vegetarian-input')

const dinnerOption = document.getElementById('food')

btnCalculate.addEventListener('click', function(){
    const guests = +numOfGuests.value
    if(isVegetarian.checked){
        dinnerOption.textContent = 'Winter Squash Risotto'
    } else{
        dinnerOption.textContent = guests <= 4 ? 'Ham' : 'Turkey'
    }
    numOfGuests.value = ''
})
Enter fullscreen mode Exit fullscreen mode
  • When the 'Calculate' button is first pressed, we retrieve the number of guests. Adding + is a trick to convert string to a number.
  • If the 'Vegetarian?' checkbox is checked, the dinner option appended to the UI is 'Winter Squash Risotto'.
  • Otherwise, we check if the number of guests is less than or equal to 4.
  • If it is, 'Ham' is chosen; otherwise, 'Turkey' is chosen and then appended to the UI.

Check my scrim here.

Day 14: Lonely elf

Task

  • Write a function to duplicate the elf when the button is clicked.
  • Limit the number of elves to 6 per row.
  • Make sure that the elves stay in the elf hangout zone, no matter how many there are.
  • Limit the total number of elves to 100.
let elfCount = 2

btn.addEventListener("click", duplicateElf)

function duplicateElf(){
    if(elfCount === 2) elfHeader.innerText = 'Elves'
    if(elfCount <= 100){
        elf.textContent += '🧝'
        elfCount += 1
    }else{
        const enoughElves = document.getElementById('more-elfs')
        enoughElves.style.display = "block"
    }
}
Enter fullscreen mode Exit fullscreen mode
  • When the 'Duplicate elf' button is pressed, we first change the title to 'Elves'.
  • Next, we check if elfCount is less than or equal to 100.
  • If it is, we append one more elf to the UI and increase the count of elfCount.
  • Otherwise, we append 'No more elves can be added' to UI.

Check my scrim here.

Day 15: Archery Target

Task

  • Create CSS only archery target

HTML

<div class="rings">
 <div class="ring ring-1">
  <div class="ring ring-2">
   <div class="ring ring-3">
    <div class="ring bullseye"></div>
   </div>
  </div>
 </div>
</div>
Enter fullscreen mode Exit fullscreen mode

CSS

.rings{
    position: relative;
}

.ring{
    border-radius: 50%;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%)
}

.ring-1{
    width: 300px;
    height: 300px;
    background: var(--black);
}

.ring-2{
    width: 220px;
    height: 220px;
    background: var(--blue);
}

.ring-3{
   width: 140px;
   height: 140px;
   background: var(--red); 
}

.bullseye{
   width: 60px;
   height: 60px;
   background: var(--yellow); 
}
Enter fullscreen mode Exit fullscreen mode
  • The main .rings div is set to position: relative; so that the other rings can overlay it.
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%)
Enter fullscreen mode Exit fullscreen mode
  • The above CSS is to ensure the circles are always centered.
  • Subsequently, for each ring, we decrease the width and height by 80px, ensuring the circle remains perfectly sized, and apply the background color.

Check my scrim here.

Day 16: Naughty list, nice list

Task

  • Write the JavaScript to sort the people in sorteesArr into the naughty and nice lists, according to whether they have been good or not. Then display the names in the relevant place in the DOM.
  • Add the option to add new names to the sorteesArr.
btn.addEventListener("click", function(){
    for(let i=0; i<sorteesArr.length; i++){
        sort(sorteesArr[i])
    }
})

addPerson.addEventListener('click', function(){
    const newPerson = {
        name: newName.value,
        hasBeenGood: isGood.checked
    }
    sorteesArr.push(newPerson)
    sort(newPerson)
    newName.value = ''
    isGood.checked = false
})

function sort(person){
    if(person.hasBeenGood){
        nice += `<li>${person.name}</li>`
    }else{
        naughty += `<li>${person.name}</li>`
    }
    niceList.innerHTML = nice
    naughtyList.innerHTML = naughty
}
Enter fullscreen mode Exit fullscreen mode
  • First, we call the sort() function for the length of the sorteesArr.
  • Within the function, we check if the person 'has been good?'.
  • If yes, we create a string of <li> elements and add it to the niceList. Otherwise, we add it to the naughtyList.
  • When 'Add person' is pressed, we create a newPerson object and push it to sorteesArr, followed by a call to the sort() function.

Check my scrim here.

Day 17: Word Carousel

Task

  • Create a CSS only Word Carousel.
  • Match styles and display 4 things you love.

HTML

<div class="container">
 <h1>I love</h1>
<div>
Enter fullscreen mode Exit fullscreen mode

CSS

body{
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100vh;
}

h1::after {
  content: "";
  animation: carousel 5s steps(1) infinite;
  background: var(--bg-word);
  color: #fff;
  margin-left: 2px;
  padding: 8px 10px;
  border-radius: 4px;
}

@keyframes carousel {
  0% {
    content: "reading";
  }
  45% {
    content: "Scrimba";
  }
  65% {
    content: "coding";
  }
  85% {
      content: "music";
  }
}
Enter fullscreen mode Exit fullscreen mode
  • We first center the <h1> tag by applying styles to <body>.
  • For the carousel part, we apply styles to the ::after selector.
animation: carousel 5s steps(1) infinite;
Enter fullscreen mode Exit fullscreen mode
  • The animation is named 'carousel' with a duration of 5s.
  • The steps() function is set to 1, which means the animation will move in discrete steps rather than smoothly transitioning.
  • The infinite value is used to make the animation repeat indefinitely.
  • Keyframes are added to specify the content to be displayed at different percentages.

Check my scrim here.

Day 18: AI Alt Text Generator

Task

  • Use AI to generate alt text for the image provided by generateImage().
  • Pass the alt text to renderImage() as a parameter.
async function generateAltText(blob, imageUrl) {
    const altText = await hf.imageToText({
        data: blob,
        model: "nlpconnect/vit-gpt2-image-captioning",
    })
    renderImage(imageUrl, altText.generated_text) 
}
Enter fullscreen mode Exit fullscreen mode
  • I used huggingface for this challenge. You can find the documentation here.
  • hf.imageToText is a function from the Hugging Face library for generating text from a provided image.
  • The data passed to it is in the form of a blob, and the model parameter represents the specific model used for image-to-text generation.
  • In summary, this code requests a model from Hugging Face to generate alt text for an image based on the provided blob. The resulting alt text is then passed to the renderImage() function.

Check my scrim here.

Would love to hear your thoughts on this. Can't believe it has been 18 days already. Stay tuned for the last iteration of this series.

Top comments (0)