Use My Code!
7/14/26
Here are some snippets of code that you can use on your site, with or without a linkback.
Collage / Table Scatter
Created for my Sewing Items page.
Reload the page! They are scattered differently every time. The way this works is the script gives each image an appropriate radius and a random velocity and tilt. Then, it runs a short physics simulation for them to collide with eachother.
HTML:
<div id="collage">
<a href="https://blamensir.neocities.org/"><img src="images/buttons/blamensir-bottles.png"></a>
<a href="https://oopsiedoodle.com/"><img src="images/buttons/OopsieDoodleButton.png"></a>
<a href="https://ribo.zone/"><img src="images/buttons/ribozone.png"></a>
<a href="https://vibes.fish/"><img src="images/buttons/vibesbtn2.gif"></a>
<img src="images/pins-blue.gif">
<img src="images/pins-green.gif">
<img src="images/pins-red.gif">
<!-- Replace these with any number of your images -->
</div>
CSS:
#collage {
width: 100%;
/* Make this height whatever you would like it to be */
height: 100px;
position: relative;
}
#collage img {
position: absolute;
}
#collage img:hover {
border-style: solid;
border-color: brown;
}
JavaScript:
<script type="module">
// Author: Loops from loops4.neocities.org
import * as d3 from "https://cdn.jsdelivr.net/npm/d3@7/+esm";
// Get all images from collage
window.onload = (event) => {
const collage = document.getElementById("collage");
let collageWidth = collage.scrollWidth;
let collageHeight = collage.scrollHeight;
let imgs = collage.getElementsByTagName("img"); // is type HTMLCollection
// Get image elements in nodes ready for d3 collision simulation
let imgNodes = [];
for(let i = 0; i < imgs.length; i++) {
let img = imgs[i];
imgNodes[i] = {
element: img,
x: Math.random()*collageWidth,
y: Math.random()*collageHeight,
vx: Math.random() - 0.5,
vy: Math.random() - 0.5,
radius: ((img.width + img.height) / 4),
rotation: Math.random()*30 -15
};
};
// Create simulation
const simulation = d3.forceSimulation(imgNodes)
.force("collide", d3.forceCollide().radius(d => d.radius + 1).iterations(2))
.force("bounds", alpha => {
imgNodes.forEach(img => {
const minX = img.element.width / 2;
const maxX = collageWidth - img.element.width / 2;
const minY = img.element.height / 2;
const maxY = collageHeight - img.element.height / 2;
if (img.x < minX) {
img.x = minX;
img.vx *= -1;
} else if (img.x > maxX) {
img.x = maxX;
img.vx *= -1;
}
if (img.y < minY) {
img.y = minY;
img.vy *= -1;
} else if (img.y > maxY) {
img.y = maxY;
img.vy *= -1;
}
});
})
.stop();
// Run the simulation
for (let i = 0; i < 250; i++) {
simulation.tick();
}
// Place the image elements
for (let i = 0; i < imgNodes.length; i++) {
console.log(imgNodes[i].rotation);
imgNodes[i].element.style.top = imgNodes[i].y - imgNodes[i].element.height / 2 + "px";
imgNodes[i].element.style.left = imgNodes[i].x - imgNodes[i].element.width / 2 + "px";
imgNodes[i].element.style.rotate = imgNodes[i].rotation + "deg";
}
};
</script>
If you prefer, you can reload your page until you get a scatter you like, then inspect the page and copy/paste the image tags and get rid of the script.



