Random thumbnail positions on hover of randomly positioned text

I would like that when a user hovers different words, that a random arrangement of thumbnails fades-in.

Some caveats:

  • thumbs should stay fairly close to the corresponding text.
  • thumbs can overlap, but not fully.
  • both the text and the thumb positions should be random on every page refresh
  • text and thumbs shouldn’t fall outside the screen.
  • should be scalable (i.e… I will have max. 10 texts and max. 10 thumbs for every text. the thumbs could spread concentrically if need be)

See the image for an example of what I mean:

And here’s a fiddle of what I have so far: Edit fiddle - JSFiddle - Code Playground

This is a fun one! Also, welcome back @4a0g1kfa54 :slight_smile:

Will the thumbnails need to be in a grid formation, or can they be in a random-ish arbitrary arrangement? Will the thumbnails all be the same size?

Hi @kirupa ! Yes they should be in a random-ish arbitrary arrangement and the thumbnails are all the same size. :slight_smile:

Sorry - things got a bit too busy today for me to look into this. I am hoping to find some time tomorrow morning to fiddle with this :grinning:

no worries @kirupa - i’m interesting to hear your thoughts on this :slight_smile:

so I came across Jason Knight’s random thumb position snippet over at https://forums.htmlhelp.com/ - a non-jquery effort!

All i need now is for multiples of these grey bounding boxes, to also randomly position on a screen.

HTML

<div class="buttonThumbs">
  <button type="button">text</button>
  <img src="https://placeimg.com/100/100/animals" alt="describe this, alt is not optional">
  <img src="https://placeimg.com/100/100/people" alt="describe this, alt is not optional">
  <img src="https://placeimg.com/100/100/tech" alt="describe this, alt is not optional">
  <img src="https://placeimg.com/100/100/nature" alt="describe this, alt is not optional">
<!-- .buttonThumbs --></div>

CSS

html, body {
  height:100%;
}

body {
  display:flex;
  align-items:center;
  justify-content:center;
}

.buttonThumbs {
  position:relative;
  width:30em;
  height:20em;
  max-width:100%;
  max-height:100%;
  margin:auto; /* force scrollbars if too small */
  background:#EEE;
}

.buttonThumbs > * {
  position:absolute;
}

.buttonThumbs button {
  top:50%;
  left:50%;
  border:0;
  background:transparent;
  transform:translate(-50%, -50%);
}

.buttonThumbs img {
  width:100px;
  height:100px;
  opacity:0;
  transition:opacity 1s;
}

.buttonThumbs button:focus ~ img,
.buttonThumbs button:hover ~ img {
  opacity:1;
}

.buttonThumbs img:nth-of-type(1) {
  top:25%;
  left:25%;
}

.buttonThumbs img:nth-of-type(2) {
  top:25%;
  left:75%;
}

.buttonThumbs img:nth-of-type(3) {
  top:75%;
  left:25%;
}

.buttonThumbs img:nth-of-type(4) {
  top:75%;
  left:75%;
}

JS

{ // scope isolating block

	const
		origins = [
			{ x : 0, y : 0 },
			{ x : 0, y : 1 },
			{ x : 1, y : 1 },
			{ x : 1, y : 0 },
		],
		buttonImgEvent = (e) => {
			let img = e.currentTarget.nextElementSibling;
			if (img) {
				let
					originIndex = Math.floor(origins.length * Math.random());
				const
					wrapper = e.currentTarget.closest(".buttonThumbs"),
					halfWidth = wrapper.clientWidth / 2,
					halfHeight = wrapper.clientHeight / 2;
				do {
					img.style.left = (
						Math.random() * (halfWidth - img.clientWidth) + 
						origins[originIndex].x * halfWidth
					) + "px";
					img.style.top = (
						Math.random() * (halfHeight - img.clientHeight) +
						origins[originIndex].y * halfHeight
					) + "px";
					originIndex = (originIndex + 1) % origins.length;
				} while (img = img.nextElementSibling);
			}
		};

	for (const button of document.querySelectorAll(".buttonThumbs button")) {
		button.addEventListener("mouseover", buttonImgEvent);
		button.addEventListener("focus", buttonImgEvent);
	}


} // end scope isolation

Here is his codepen: https://codepen.io/jason-knight/pen/ZEjKvVd

So sorry for not having time for this. Life and work gets in the way sometimes :grinning: