Welcome back! If you've been following along, we've already solved challenges of Days 1 to 6 in our journey. Now, buckle up as we dive headfirst into the next leg of this adventure Days 7 to 12. Let's start.
Day 7: Xmas Present wishlist
Task
- Add items to wishlist array.
- Iterate over the wishlist array.
- Display your wishlist on the page.
- Style the wishlist with CSS.
Stretch Goals
- Provide a way to add / remove wishlist items.
- Make each array an object with item's name, description, and a link to where it can be purchased
const wishlist = [
{
name: "Books",
description: "I love to read so need more books!",
link: "https://www.amazon.in/"
},
{
name: "Headphone",
description: "Nirvanaa 751 ANC Wireless Headphone",
link: "https://www.boat-lifestyle.com/products/nirvana-751-anc-headphone"
}
];
function renderList(list){
let listEl = ""
list.map((list, index) =>{
listEl += `
<div class='wishlist-box'>
<div>
<h2><a href='${list.link}' target='_blank'>${list.name}</a></h2>
<p>${list.description}</p>
</div>
<div class="delete" onclick="deleteWish(${index})">❌</div>
</div>
`
})
wishlistEl.innerHTML = listEl
}
renderList(wishlist)
addWishBtn.addEventListener('click', function(){
if(!wishNameInput.value || !wishDescriptionInput.value || !wishLinkInput.value) return
const newWish = {
name: wishNameInput.value,
description: wishDescriptionInput.value,
link: wishLinkInput.value
}
wishlist.push(newWish)
renderList(wishlist)
wishNameInput.value = wishDescriptionInput.value = wishLinkInput.value = ""
})
function deleteWish(index){
wishlist.splice(index, 1)
renderList(wishlist)
}
- First, created an array of objects called
wishlist
and rendered this object using themap()
method on the UI. - For the
Add Wish
button, first checked if there is a value in the inputs. If not, the process is terminated. If there is a value, added all the values to a new object and pushed this object to thewishlist
array. Finally, cleared all the inputs. - Lastly, for
deleteWish
, get the index of the item we wished to delete. Based on that index, use the splice method to remove that item from the array and update the UI.
Check my scrim here.
Day 8: Animated Progress Bar
HTML
<div class="progress-bar">
<div class="progress-status"></div>
</div>
CSS
.progress-bar,
.progress-status {
height: 30px;
background: var(--progressbar-bg);
border-radius: 50px;
width: 100%;
}
.progress-bar {
position: relative;
}
.progress-status {
position: absolute;
top: 0;
animation: progress 5s infinite;
animation-timing-function: linear;
animation-fill-mode: forwards;
}
@keyframes progress {
0% {
width: 0%;
background-color: var(--start);
}
50% {
width: 50%;
background-color: var(--middle);
}
100% {
width: 100%;
background-color: var(--finish);
}
}
- First, positioned the
progress-status
div on theprogress-bar
usingposition:absolute
. - For the
progress-status
, applied animation: progress 5s infinite; to call the keyframe "progress" infinitely. - In the keyframe, defined animations starting at 0%, reaching 50%, and finishing at 100%.
- To ensure smooth operation, used
animation-timing-function: linear
. Without this, the progress bar starts correctly but then slows down at 50% and restarts again after that.
Check my scrim here.
Day 9: AI Christmas E-card
Task
- When a user hits submit, dialogModal should be hidden.
- Use the inputted text to generate an image for the e-card using an AI model.
- Render the image to imageContainer.
formSubmit.addEventListener('submit', function(e){
e.preventDefault()
dialogModal.close();
image.style.display = "none"
loadingText.style.display = "block"
if(!userInput.value) return
query({"inputs": userInput.value}).then(async(response) => {
const src = await blobToBase64(response)
loadingText.style.display = "none"
image.src = src
image.style.display = "block"
});
})
async function query(data) {
const response = await fetch(
"https://api-inference.huggingface.co/models/stabilityai/stable-diffusion-xl-base-1.0",
{
headers: { Authorization: `Bearer ${process.env.HUGGING_FACE_API_KEY}` },
method: "POST",
body: JSON.stringify(data),
}
);
const result = await response.blob();
return result;
}
function blobToBase64(blob) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = function () {
const base64String = reader.result;
resolve(base64String);
};
reader.onerror = function (error) {
reject(error);
};
reader.readAsDataURL(blob);
});
}
- I used huggingface for this challenge. You can find the documentation here.
- When the form is submitted we use the given description as input to call the function that will return a blob of image. This blob is then converted to Base64 using the
blobToBase64
function. - The function uses the
FileReader
object, which is part of the web platform's File API, to read the contents of the Blob. - It sets up an onload event handler, which will be triggered when the reading operation is successfully completed.
- Inside the onload handler, it converts the read content to a Base64-encoded string and resolves the Promise with that string.
- If there is an error during the reading operation, the onerror event handler is triggered, and the Promise is rejected with the error.
- Finally, we append this image to UI.
Check my scrim here.
Day 10: Rockin' Around
Task
- Add code to make the youtube player play the new YouTube song
const player = document.getElementById("player")
function playSong(id) {
const youtubeSrc = `https://www.youtube.com/embed/${id}?autoplay=1`
player.src = youtubeSrc
}
- The code creates a URL for a YouTube video using a template literal. It takes a video ID and constructs a YouTube video URL with the format.
- At the end, assigned this URL to the player's src.
Check my scrim here.
Day 11: Flag Challenge
Task
- Create Switzerland Flag in CSS
HTML
<div class="flag flag-swiss">
<div class="cross cross1"></div>
<div class="cross cross2"></div>
</div>
CSS
.flag{
width: 300px;
height: 300px;
background: var(--red);
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-template-rows: repeat(5, 1fr);
}
.cross{
background: var(--white);
}
.cross1{
grid-row: 2/5;
grid-column: 3/4;
}
.cross2{
grid-row: 3/4;
grid-column: 2/5;
}
- I used
grid
` for this challenge, defining the height and width of the div and setting its display property to grid.
- The grid is defined with 5 rows and 5 columns, each set to
1fr
- Based on the image above, I have positioned
.cross1
,.cross2
accordingly usinggrid-row
andgrid-column
.
Check my scrim here.
Day 12: Santa's Gift Sorter
Task
- Help santa by sorting the gifts array into alphabetical order and reverse alphabetical order.
const xmasGifts = ['guitar 🎸', 'skates ⛸️', 'bear 🧸', 'magnet 🧲', 'laptop 💻', 'games console 🎮', 'jewellery 💍', 'kite 🪁'];
const sortedAZ = [...xmasGifts].sort();
console.log('A-Z: ', sortedAZ);
const sortedZA = [...xmasGifts].sort().reverse();
console.log('Z-A: ', sortedZA);
- For sorting into alphabetical order, we have used
sort()
method - For sorting in reverse alphabetical order, we have first used sort() and then used
reverse()
.
Check my scrim here.
Would love to hear your thoughts. Stay tuned for the next iteration of this series.
Top comments (0)