From d1d28536beaf364b358e933973160c01bafb382a Mon Sep 17 00:00:00 2001 From: nexoscreator Date: Fri, 18 Oct 2024 09:00:26 +0530 Subject: [PATCH] Day:003 and 004 added --- README.md | 2 + projects/day-003-lazy-load-images/README.md | 82 ++++++++++++++++ projects/day-003-lazy-load-images/index.html | 28 ++++++ projects/day-003-lazy-load-images/main.js | 21 ++++ projects/day-003-lazy-load-images/style.css | 23 +++++ .../day-004-lightbox-image-gallery/README.md | 61 ++++++++++++ .../day-004-lightbox-image-gallery/index.html | 36 +++++++ .../day-004-lightbox-image-gallery/main.js | 61 ++++++++++++ .../day-004-lightbox-image-gallery/style.css | 95 +++++++++++++++++++ script.js | 2 + 10 files changed, 411 insertions(+) create mode 100644 projects/day-003-lazy-load-images/README.md create mode 100644 projects/day-003-lazy-load-images/index.html create mode 100644 projects/day-003-lazy-load-images/main.js create mode 100644 projects/day-003-lazy-load-images/style.css create mode 100644 projects/day-004-lightbox-image-gallery/README.md create mode 100644 projects/day-004-lightbox-image-gallery/index.html create mode 100644 projects/day-004-lightbox-image-gallery/main.js create mode 100644 projects/day-004-lightbox-image-gallery/style.css diff --git a/README.md b/README.md index 5208e57..6fe2f4a 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,8 @@ Welcome to my **365 Days of Web Development** challenge! In this repository, I'm |-----|--------------|-------------|-----------| | 001 | [Syntax Code Box](./projects/day-001-syntax-code-box) | How to Create a Syntax Code Box | [Demo](https://example.com) | | 002 | [Toast Notification](./projects/day-002-toast-notification) | Creating a Toast Notification | [Demo](https://example.com) | +| 003 | [Lazy load images](./projects/day-003-lazy-load-images) | Creating a Toast Notification | [Demo](https://example.com) | +| 004 | [Lightbox Images Gallery](./projects/day-004-lightbox-image-gallery) | Creating a Toast Notification | [Demo](https://example.com) | | ... | ... | ... | ... | diff --git a/projects/day-003-lazy-load-images/README.md b/projects/day-003-lazy-load-images/README.md new file mode 100644 index 0000000..8836d6a --- /dev/null +++ b/projects/day-003-lazy-load-images/README.md @@ -0,0 +1,82 @@ +# Day 003: Lazy Load Images + +## Project Description + +This project demonstrates the implementation of lazy loading for images on a web page. Lazy loading is a technique that defers the loading of non-critical resources (in this case, images) until they are needed. This approach can significantly improve page load times and reduce bandwidth usage, especially for pages with many images or on slower network connections. + +## Technologies Used + +- HTML5 +- CSS3 +- JavaScript (Vanilla JS) +- Intersection Observer API + +## Features + +- Lazy loading of images as they enter the viewport +- Placeholder images or low-resolution previews while full images load +- Smooth transition effect when images load +- Responsive design to showcase lazy loading across different screen sizes +- Performance metrics display to show the benefits of lazy loading + +## Challenges Faced + +1. Implementing lazy loading without relying on external libraries +2. Ensuring compatibility across different browsers +3. Creating an effective placeholder strategy while images load +4. Balancing between performance gains and user experience + +## Lessons Learned + +- How to use the Intersection Observer API for efficient lazy loading +- Techniques for creating and styling placeholder images +- The importance of performance optimization in web development +- How to measure and display performance metrics in real-time + +## Future Improvements + +- Implement progressive image loading (blur-up technique) +- Add support for lazy loading background images in CSS +- Create a reusable lazy loading component or module +- Implement error handling for failed image loads +- Add option to preload critical images for faster initial display + +## Live Demo + +[View Live Demo](https://nexoscreator.github.io/365-Days-of-Web-Development/projects/day-003-lazy-load-images/) + +## Screenshots + +![Lazy Load Images Screenshot](https://github.com/nexoscreator/365-Days-of-Web-Development/raw/main/projects/day-003-lazy-load-images/screenshot.png) + +## How to Use + +1. Clone the repository +2. Navigate to the `projects/day-003-lazy-load-images` directory +3. Open `index.html` in your web browser +4. Scroll down the page to see images lazy load as they enter the viewport + +## Code Snippet + +Here's a key part of the lazy loading implementation: + +```javascript +const images = document.querySelectorAll('[data-src]'); + +const imgOptions = { + threshold: 0, + rootMargin: "0px 0px 300px 0px" +}; + +const imgObserver = new IntersectionObserver((entries, imgObserver) => { + entries.forEach(entry => { + if (!entry.isIntersecting) return; + + const img = entry.target; + img.src = img.dataset.src; + img.classList.add('loaded'); + imgObserver.unobserve(img); + }); +}, imgOptions); + +images.forEach(img => imgObserver.observe(img)); \ No newline at end of file diff --git a/projects/day-003-lazy-load-images/index.html b/projects/day-003-lazy-load-images/index.html new file mode 100644 index 0000000..038d719 --- /dev/null +++ b/projects/day-003-lazy-load-images/index.html @@ -0,0 +1,28 @@ + + + + + + + Day 003: Lazy Load Images + + + + +
+ Lazy loaded image 1 + Lazy loaded image 2 + Lazy loaded image 3 + Lazy loaded image 4 + Lazy loaded image 5 + Lazy loaded image 6 + Lazy loaded image 7 + Lazy loaded image 8 + Lazy loaded image 9 + Lazy loaded image 10 +
+ + + + + \ No newline at end of file diff --git a/projects/day-003-lazy-load-images/main.js b/projects/day-003-lazy-load-images/main.js new file mode 100644 index 0000000..82c62e5 --- /dev/null +++ b/projects/day-003-lazy-load-images/main.js @@ -0,0 +1,21 @@ +document.addEventListener('DOMContentLoaded', function() { + const images = document.querySelectorAll('.lazy-image'); + + const imgOptions = { + threshold: 0, + rootMargin: "0px 0px 300px 0px" + }; + + const imgObserver = new IntersectionObserver((entries, imgObserver) => { + entries.forEach(entry => { + if (!entry.isIntersecting) return; + + const img = entry.target; + img.src = img.dataset.src; + img.classList.add('loaded'); + imgObserver.unobserve(img); + }); + }, imgOptions); + + images.forEach(img => imgObserver.observe(img)); +}); \ No newline at end of file diff --git a/projects/day-003-lazy-load-images/style.css b/projects/day-003-lazy-load-images/style.css new file mode 100644 index 0000000..0995764 --- /dev/null +++ b/projects/day-003-lazy-load-images/style.css @@ -0,0 +1,23 @@ +.image-container { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: 1rem; +} + +.lazy-image { + width: 100%; + height: 300px; + object-fit: cover; + background-color: #ddd; + transition: opacity 0.3s ease-in-out; +} + +.lazy-image.loaded { + opacity: 1; +} + +@media (max-width: 600px) { + .image-container { + grid-template-columns: 1fr; + } +} \ No newline at end of file diff --git a/projects/day-004-lightbox-image-gallery/README.md b/projects/day-004-lightbox-image-gallery/README.md new file mode 100644 index 0000000..e01b89f --- /dev/null +++ b/projects/day-004-lightbox-image-gallery/README.md @@ -0,0 +1,61 @@ +# Day 004: Lightbox Image Gallery + +## Project Description + +This project implements a responsive lightbox image gallery. Users can click on thumbnail images to view them in a larger, overlay lightbox. The lightbox includes navigation controls to move between images, as well as a close button to exit the lightbox view. + +## Technologies Used + +- HTML5 +- CSS3 +- JavaScript (Vanilla JS) + +## Features + +- Responsive grid layout for thumbnail images +- Smooth transition effects when opening and closing the lightbox +- Navigation controls (previous and next buttons) in the lightbox +- Close button to exit the lightbox view +- Keyboard navigation support (arrow keys and Esc key) +- Automatic image sizing to fit the viewport + +## Challenges Faced + +1. Implementing smooth transitions between images in the lightbox +2. Ensuring responsive design for both the thumbnail grid and the lightbox view +3. Handling various image aspect ratios while maintaining a consistent layout +4. Implementing keyboard navigation in addition to click events + +## Lessons Learned + +- Advanced CSS transitions and transforms for creating smooth visual effects +- Techniques for creating an overlay effect with CSS and JavaScript +- Handling keyboard events for improved accessibility and user experience +- Managing image loading and error states in JavaScript + +## Future Improvements + +- Add touch swipe support for mobile devices +- Implement image lazy loading for better performance with large galleries +- Add zoom functionality for detailed image viewing +- Create a slideshow mode with autoplay feature +- Implement caption support for images + +## Live Demo + +[View Live Demo](https://nexoscreator.github.io/365-Days-of-Web-Development/projects/day-004-lightbox-image-gallery/) + +## Screenshots + +![Lightbox Image Gallery Screenshot](https://github.com/nexoscreator/365-Days-of-Web-Development/raw/main/projects/day-004-lightbox-image-gallery/screenshot.png) + +## How to Use + +1. Clone the repository +2. Navigate to the `projects/day-004-lightbox-image-gallery` directory +3. Open `index.html` in your web browser +4. Click on any thumbnail to open the lightbox view +5. Use the navigation arrows or keyboard arrow keys to move between images +6. Click the close button or press the Esc key to exit the lightbox + +This project serves as an excellent starting point for implementing a lightbox image gallery in your web applications. Feel free to customize and expand upon it to suit your specific needs! \ No newline at end of file diff --git a/projects/day-004-lightbox-image-gallery/index.html b/projects/day-004-lightbox-image-gallery/index.html new file mode 100644 index 0000000..2998bce --- /dev/null +++ b/projects/day-004-lightbox-image-gallery/index.html @@ -0,0 +1,36 @@ + + + + + + + Day 004: Lightbox Image Gallery + + + + + + + + + + + + \ No newline at end of file diff --git a/projects/day-004-lightbox-image-gallery/main.js b/projects/day-004-lightbox-image-gallery/main.js new file mode 100644 index 0000000..c442352 --- /dev/null +++ b/projects/day-004-lightbox-image-gallery/main.js @@ -0,0 +1,61 @@ +document.addEventListener('DOMContentLoaded', function() { + const gallery = document.querySelector('.gallery'); + const lightbox = document.getElementById('lightbox'); + const lightboxImg = document.getElementById('lightbox-img'); + const caption = document.getElementById('caption'); + const close = document.querySelector('.close'); + const prev = document.querySelector('.prev'); + const next = document.querySelector('.next'); + let currentIndex = 0; + const images = document.querySelectorAll('.gallery-img'); + + function openLightbox(index) { + lightbox.style.display = 'block'; + lightboxImg.src = images[index].src.replace('300/200', '1200/800'); + caption.textContent = images[index].alt; + currentIndex = index; + } + + function closeLightbox() { + lightbox.style.display = 'none'; + } + + function showPrev() { + currentIndex = (currentIndex - 1 + images.length) % images.length; + openLightbox(currentIndex); + } + + function showNext() { + currentIndex = (currentIndex + 1) % images.length; + openLightbox(currentIndex); + } + + gallery.addEventListener('click', function(e) { + if (e.target.classList.contains('gallery-img')) { + const index = Array.from(images).indexOf(e.target); + openLightbox(index); + } + }); + + close.addEventListener('click', closeLightbox); + prev.addEventListener('click', showPrev); + next.addEventListener('click', showNext); + + document.addEventListener('keydown', function(e) { + if (lightbox.style.display === 'block') { + if (e.key === 'ArrowLeft') { + showPrev(); + } else if (e.key === 'ArrowRight') { + showNext(); + } else if (e.key === 'Escape') { + closeLightbox(); + } + } + }); + + lightbox.addEventListener('click', function(e) { + if (e.target === lightbox) { + closeLightbox(); + } + }); +}); \ No newline at end of file diff --git a/projects/day-004-lightbox-image-gallery/style.css b/projects/day-004-lightbox-image-gallery/style.css new file mode 100644 index 0000000..d096647 --- /dev/null +++ b/projects/day-004-lightbox-image-gallery/style.css @@ -0,0 +1,95 @@ +.gallery { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + gap: 1rem; +} + +.gallery-img { + width: 100%; + height: 200px; + object-fit: cover; + cursor: pointer; + transition: transform 0.3s ease; +} + +.gallery-img:hover { + transform: scale(1.05); +} + +.lightbox { + display: none; + position: fixed; + z-index: 999; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.9); + transition: opacity 0.3s ease; +} + +.lightbox-content { + display: block; + max-width: 90%; + max-height: 80%; + margin: auto; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + border: 2px solid #fff; +} + +.caption { + text-align: center; + color: #fff; + padding: 10px; + position: absolute; + bottom: 0; + left: 0; + right: 0; + background-color: rgba(0, 0, 0, 0.6); +} + +.close { + color: #fff; + position: absolute; + top: 10px; + right: 25px; + font-size: 35px; + font-weight: bold; + cursor: pointer; +} + +.prev, +.next { + cursor: pointer; + position: absolute; + top: 50%; + width: auto; + padding: 16px; + margin-top: -50px; + color: white; + font-weight: bold; + font-size: 20px; + transition: 0.6s ease; + border-radius: 0 3px 3px 0; + user-select: none; + -webkit-user-select: none; +} + +.next { + right: 0; + border-radius: 3px 0 0 3px; +} + +.prev:hover, +.next:hover { + background-color: rgba(0, 0, 0, 0.8); +} + +@media (max-width: 600px) { + .gallery { + grid-template-columns: 1fr; + } +} \ No newline at end of file diff --git a/script.js b/script.js index f2ab60e..6e37903 100644 --- a/script.js +++ b/script.js @@ -3,6 +3,8 @@ document.addEventListener('DOMContentLoaded', function() { const projects = [ { id: 1, title: "Syntax Code Box", description: "A mobile-friendly navigation bar", link: "./projects/day-001-syntax-code-box/index.html" }, { id: 2, title: "Toast Notification", description: "A simple to-do list application", link: "./projects/day-002-toast-notification/index.html" }, + { id: 3, title: "Lazy Load Images", description: "Lazy loading of images as they enter the viewport", link: "./projects/day-003-lazy-load-images" }, + { id: 4, title: "Lightbox Images", description: "a responsive lightbox image gallery.", link: "./projects/day-004-lightbox-image-gallery" }, // Add more projects here as you complete them ];