Skip to content

Instantly share code, notes, and snippets.

@gamecubate
Created July 28, 2023 14:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gamecubate/9a11dc457eba83ccec77c94a610853e9 to your computer and use it in GitHub Desktop.
Save gamecubate/9a11dc457eba83ccec77c94a610853e9 to your computer and use it in GitHub Desktop.
packary test
<header>
<h1>&nbsp;</h1>
</header>
<main></main>
<footer>
<h1>FOOTER</h1>
</footer>
const N_SECTION_ITEMS_MIN = 7;
const N_SECTION_ITEMS_MAX = 14;
const PHONEMS = [" ", "AC", "TU", "A", "LI", "TÉS", "AR", "GENT", "MON", "DE", "VA", "CAN", "CES", "SAN", "TÉ", "EN", "QUÊ", "TES", " "];
const COLORS_1 = ["#5a7495", "#599095", "#729559", "#958059", "#955958"];
const COLORS = ["#e52003", "#e5ad00", "#1ee503", "#04b1e5", "#9701e5"];
function init() {
console.clear();
loadSection();
initOnScrollSectionLoader();
const ad_slot = d3.select("section").selectAll(".item").filter((n, idx) => idx == 1);
growItemAfter(ad_slot, 2000);
}
function initOnScrollSectionLoader() {
const opts = {
root: null,
rootMargin: "0px",
threshold: 1.0,
};
const observer = new IntersectionObserver(handleIntersect, opts);
const target = document.querySelector("footer");
observer.observe(target);
}
function handleIntersect(entries, observer) {
entries.forEach((e) => {
if (e.isIntersecting && Math.floor(e.intersectionRatio) === 1) {
loadSection(rnd_title());
}
});
}
function growItemAfter(sel, ms) {
setTimeout(() => {
sel
.classed("h1", false)
.classed("h2", true)
.datum().layout();
}, ms);
}
function loadSection(title) {
const section = d3.select("main").append("section");
if (title) section.append("h1").text(title);
const grid = section.append("div").attr("class", "grid");
const n_items = N_SECTION_ITEMS_MIN + Math.floor(Math.random() * (N_SECTION_ITEMS_MAX - N_SECTION_ITEMS_MIN + 1));
_.range(n_items).forEach((n, idx) => {
const w = idx == 1 ? "w1" : "w" + (rnd(2) + 1);
const h = idx == 1 ? "h1" : "h" + (rnd(2) + 1);
const col = idx == 1 ? "blue" : rnd_el(COLORS);
const text = idx == 1 ? "PUB" : "ARTICLE";
grid.call(add_item, w, h, col, text);
});
var p = new Packery(grid.node(), {
itemSelector: ".item",
percentPosition: true,
initLayout: false
});
grid
.selectAll(".item")
.datum(p);
p.on('fitComplete', function(item) { console.log(`Packery fit complete for ${item}`); });
p.on('layoutComplete', function(laidOutItems) { console.log(`layout : ${laidOutItems.length} items`); });
p.layout();
}
function add_item(sel, w, h, col, text) {
sel
.append("div")
.attr("class", () => `item ${w} ${h}`)
.style("background-color", col)
.on("click", function(e) {
let item = d3.select(this);
resize_item(item);
})
.append("span").attr("class", "text").text(text);
}
function resize_item(sel) {
const w = sel.classed("w1") ? "w2" : "w1";
const h = sel.classed("h1") ? "h2" : "h1";
sel
.classed("w1", false)
.classed("w2", false)
.classed("h1", false)
.classed("h2", false)
.classed(`${w} ${h}`, true)
//.datum().fit(sel.node())
.datum().layout();
}
function resize_item_height(sel) {
const h = sel.classed("h1") ? "h2" : "h1";
sel
.classed("h1", false)
.classed("h2", false)
.classed(`${h}`, true)
//.datum().fit(sel.node())
.datum().layout();
}
// Utils
function rnd(ceil) {
return Math.floor(Math.random() * ceil);
}
function rnd_el(els) {
return els[rnd(els.length)];
}
function rnd_els(all_els, n) {
return _.range(n).map(() => rnd_el(all_els));
}
// Helpers
function rnd_title() {
return rnd_els(PHONEMS, (3 + rnd(5))).join("");
}
init();
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.8.5/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.13.6/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/packery/2.1.2/packery.pkgd.min.js"></script>
body {
background-color: #000;
font-family: sans-serif;
margin: 0;
}
header {
background-color: #e42303;
color: white;
margin: 0;
padding: 1rem;
}
main {
margin: 0;
min-height: 1000px;
position: relative;
width: 100%;
}
section:first-child {
margin-top: 3rem;
}
section {
margin-bottom: 5rem;
padding: 1rem;
position: relative;
}
h1 {
color: #fff;
font-size: 2rem;
margin: 0;
padding: 0;
}
section h1 {
background-color: #e42303;
color: #fff;
display: inline-block;
font-size: 3rem;
margin: 0 0 10px 8px;
padding: 0.5rem 1rem;
}
.item {
background-color: #FFF;
margin: 10px;
position: relative;
width: 10px;
}
.item.w1 {
width: 100px;
width: 15%;
}
.item.w2 {
width: 220px;
width: calc(30% + 20px);
}
.item.h1 {
height: 100px;
}
.item.h2 {
height: 220px;
}
.item .text {
background-color: #000;
color: #FFF;
display: inline-block;
font-weight: 800;
margin: 5px;
padding: 5px;
}
footer {
background-color: black;
color: white;
margin: 0;
min-height: 150px;
padding: 1rem;
}
.dn {
display: none;
outline: 5px solid yellow;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment