Skip to content

Instantly share code, notes, and snippets.

@nfreear
Last active April 27, 2019 09:10
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 nfreear/4b786f19551759a8c8dd1ac8c22a1fac to your computer and use it in GitHub Desktop.
Save nfreear/4b786f19551759a8c8dd1ac8c22a1fac to your computer and use it in GitHub Desktop.
Snake layout (static)
<!doctype html> <title> *Snake - static </title>
<link rel=stylesheet href="https://unpkg.com/bootstrap@4.3.1/dist/css/bootstrap.min.css" />
<style>
.snake-layout > * > div { background: darkgreen; color: white; font-size: 2rem; height: 234px; width: 416px; }
.d-flex > * { transition: all 5s ease-in-out; -X-flex-grow: 3; }
</style>
<style>
/* Bootstrap only goes up to 'order-12' ! */
.order-13 { order: 13; }
.order-14 { order: 14; }
/* ... */
</style>
<div class="container-fluid">
<h1> Snake - static </h1>
.
<ul class="snake-layout d-flex flex-wrap justify-content-between list-unstyled">
<li class="p-2"> 30 </li>
<li class="p-2"> 29 </li>
<li class="p-2"> 28 </li>
<li class="p-2"> 27 </li>
<li class="p-2 w-100"> 26 </li>
<li class="p-2"> 25 </li>
<li class="p-2"> 24 </li>
<li class="p-2"> 23 </li>
<li class="p-2"> 22 </li>
<li class="p-2"> 21 </li>
<li class="p-2"> 20 </li>
<li class="p-2"> 19 </li>
<li class="p-2"> 18 </li>
<li class="p-2"> 17 </li>
<li class="p-2"> 16 </li>
<li class="p-2"> 15 </li>
<li class="p-2"> 14 </li>
<li class="p-2"> 13 </li>
<li class="p-2"> 12 </li>
<li class="p-2"> 11 </li>
<li class="p-2"> 10 </li>
<li class="p-2"> 9 </li>
<li class="p-2"> 8 </li>
<li class="p-2"> 7 </li>
<li class="p-2"> 6 </li>
<li class="p-2"> 5 </li>
<li class="p-2"> 4 </li>
<li class="p-2"> 3 </li>
<li class="p-2"> 2 </li>
<li class="p-2"> 1 </li>
</ul>
</div>
<script>
const WIDTH = 416; // pixels.
const MARGIN = 0; // 5; // pixels.
const CONTAINER = document.querySelector('.snake-layout');
const ELEMS = CONTAINER.querySelectorAll(':scope > *'); // Direct children ('.flex-item');
const ITEMS = Array.from(ELEMS);
// Reverse order !
const REVERSE_LOOKUP = {
cols_4: { 6:9, 7:8, 8:7, 9:6, 16:19, 17:18, 18:17, 19:16, 26:29, 27:28, 28:27, 29:26 }, // Rhythm: 10; 1-based !
cols_3: { 5:7, 6:6, 7:5, 13:15, 14:14, 15:13, 21:23, 22:22, 23:21, 29:31, 30:30, 31:29 }, // Rhythm: 8;
cols_2: { 4:5, 5:4, 10:11, 11:10, 16:17, 17:16, 22:23, 23:22, 28:29, 29:28, 34:35, 35:34 }, // Rhythm: 6;
};
// Bootstrap's justify-content-start / end !
const JC_LOOKUP = {
cols_4: { 5:0, 10:1, 15:0, 20:1, 25:0, 30:1 },
cols_3: { 4:0, 8:1, 12:0, 16:1, 20:0, 24:1, 28:0, 32:1, },
cols_2: { 3:0, 6:1, 9:0, 12:1, 15:0, 18:1, 21:0, 24:1, 27:0, 30:1, },
};
const onResizeSnakeLayout = evt => {
const perRow = parseInt( (CONTAINER.offsetWidth - MARGIN) / WIDTH ); // Margins ?
console.warn(evt, CONTAINER.offsetWidth / WIDTH, perRow); // Your resize function here
// Reset: remove Bootstrap styles.
ITEMS.forEach(el => {
// el.classList.remove('p-2')
el.classList.remove('w-100')
el.classList.remove('justify-content-start')
el.classList.remove('justify-content-end')
el.classList.remove('d-flex')
el.className = el.className.replace(/\border-\d+/, '');
});
// Filter 'single' items (num-8, num-3)
const SINGLES = ITEMS.filter((el, idx) => (idx + 1) % (perRow + 1) === 0 )
console.warn('filtered:', SINGLES); //, REVERSE);
if (perRow > 1) {
SINGLES.forEach(el => {
el.classList.add('w-100')
el.classList.add('d-flex')
})
// Set the 'order-N' class!
ITEMS.forEach((el, idx) => {
if (REVERSE_LOOKUP[ 'cols_' + perRow ][ idx + 1 ]) {
el.style.order = parseInt(REVERSE_LOOKUP[ 'cols_' + perRow ][ idx + 1 ]);
} else {
el.style.order = idx + 1;
// el.classList.add('order-' + (idx + 1))
}
if (typeof JC_LOOKUP[ 'cols_' + perRow ][ idx + 1 ] === 'number') {
let jc = JC_LOOKUP[ 'cols_' + perRow ][ idx + 1 ];
el.classList.add('justify-content-' + (jc === 1 ? 'start': 'end'));
}
})
}
};
// Initialize items.
ITEMS.forEach((el, idx) => {
const NUM = el.innerText;
el.classList.add('num-' + NUM)
// el.setAttribute('data-order', NUM)
el.innerHTML = '<div class="d-flex justify-content-center align-items-center">' + NUM + '</div>';
// el.title = 'Item ' + NUM;
});
</script>
<script>
// Throttling :~ https://developer.mozilla.org/en-US/docs/Web/API/Document/defaultView/resize_event#Examples
const onResizeThrottled = (listenerFunc, delay) => {
delay = delay || 100; // Milliseconds.
let resizeTaskId = null;
window.addEventListener('resize', evt => {
if (resizeTaskId !== null) {
window.clearTimeout(resizeTaskId);
}
resizeTaskId = window.setTimeout(() => {
resizeTaskId = null;
listenerFunc(evt);
}, delay);
});
window.dispatchEvent(new Event('resize'));
};
onResizeThrottled(onResizeSnakeLayout);
</script>
<pre class="container">
© Nick Freear, 26-April-2019. With Richard Greenwood | https://gist.github.com/nfreear/4b786f19551759a8c8dd1ac8c22a1fac
* https://css-tricks.com/snippets/css/a-guide-to-flexbox/
* https://codepen.io/team/css-tricks/pen/EKEYob
* https://getbootstrap.com/docs/4.0/utilities/flex/
* https://developer.mozilla.org/en-US/docs/Web/API/Document/defaultView/resize_event#Examples
</pre>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment