Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found
Not Found

Submitted

Galleria Slideshow Site with React

Hayd 270

@haydee75

Desktop design screenshot for the Galleria slideshow site coding challenge

This is a solution for...

  • HTML
  • CSS
  • JS
3intermediate
View challenge

Design comparison


SolutionDesign

Solution retrospective


Hi! :) That challenge was interesting and challenging! Does anyone know a good way to avoid using masonry and have the same behaviour ? The documentation I found on internet wasnt that great

Community feedback

Rafal 1,395

@grizhlieCodes

Posted

Just posting a portion of the code separately, portion because I think I removed some CSS and some fine-tuning to the below JS, don't ask me why... The idea was for this code to run when the page was mounted in the browser (I was using Svelte) and position the images in the grid by telling each image how many rows it should span. Then grid-auto-flow: dense; would take care of the rest, because css-grid is magic.

	const updateGrid = (gridItems) => {
		gridItems.forEach((item) => {
			const image = item.querySelector('img');
			const rowHeight = 20; //js
			const gap = 20; // js
                        // height of element before any manipulation
			const itemHeight = image.naturalHeight; 
			const rowSpan = Math.ceil((itemHeight + gap) / (rowHeight + gap));
			item.style.gridRowEnd = 'span ' + rowSpan;
			const articleHeight = (rowHeight + gap) * (rowSpan - 1);
			item.style.height = articleHeight + 'px';
		});
	};

	let mounted = false;
	onMount(() => {
		mounted = true;
		const items = document.querySelectorAll('.art-piece');
		// updateGrid(items);
	});

Auto-flow was set to dense of course and all that good stuff that grid offers. Also learned about the existence of naturalHeight in javascript, pretty useful stuff.

Marked as helpful

0
Rafal 1,395

@grizhlieCodes

Posted

Solution looks great 😁!

As for avoiding using masonry, I was pondering the same. I jumped on this one and I think I finished it first but after a little trial and error I realised it would take a ton of time to get an algorithm in place. I ended up folding and applying 4 columns. And I dislike using libraries for this sort of stuff as I end up learning less so for now I'm avoiding them.

The concept however is simple. Application of it gets slightly complicated around step 4 (succeeding step 4 was the closest I got to) and rather complicated around step 5.

  1. You make the container into CSS grid.
  2. You set the columns as you see fit, assuming some repeat and auto-fit.
  3. The rows is where the 'magic' starts to take place. You set them to something like grid-auto-rows: 20px.
  4. Then we get into Javascript. We basically want to get the height of each image and apply grid-row: span x. The math behind this means that we need to include how many rows the image spans + count in the gap-heights. It gets rather messy from this point on.
  5. Because now we need to write an algorithm that best tries to create a grid that has columns as similar in height as possible. The most efficient way I think would be to order the images by height. Tallest images would be fitted as the first image in each column. Then you keep on applying some sort of logic that seems to work. I suck at math so I can't even imagine it, i'd need to trial-and-error.

But that is the basic gist. I got until step 4. So it was fully functioning but I couldn't get the images to line-up. Something would always be sticking out. By using my own JS i got a design that is more or less the same as yours, 1 image was just sticking out on the bottom. Overall it worked but wasn't finished so I scrapped it for now 😅.

Marked as helpful

0
P
Bastien 810

@BastD29

Posted

Hi @haydee75, nice project! I am having a hard time trying to upgrade with react router v6, and in App.js I replaced : <Routes> <Route exact path="/galleria">

        <Gallery datas={data} clickEvent={handleSlideShow} />
        
      </Route>
      <Route path="/galleria/:urlPath">
        
        <Paint datas={data} />
        
      </Route>
</Routes>

by :

<Routes> <Route path="galleria" element={<Gallery datas={data} clickEvent={handleSlideShow} />} /> <Route path="/galleria/:urlPath" element={<Paint datas={data} />} /> </Routes>

Unfortunately is does not work when clicking prev or next button as the urlPath comes being added to the previous one, and render a blank page..

0
P
Patrick 14,325

@palgramming

Posted

I do not know your answer to the masonry question but I will say what you have created so far looks really nice 🌟🌟🌟🌟🌟 Congrats in attempting to do this bigger challenge

0

Please log in to post a comment

Log in with GitHub
Discord logo

Join our Discord community

Join thousands of Frontend Mentor community members taking the challenges, sharing resources, helping each other, and chatting about all things front-end!

Join our Discord