Last active
April 27, 2019 09:10
-
-
Save nfreear/4b786f19551759a8c8dd1ac8c22a1fac to your computer and use it in GitHub Desktop.
Snake layout (static)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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