Skip to content

Instantly share code, notes, and snippets.

@grahamjenson
Last active July 22, 2016 01:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save grahamjenson/8309901 to your computer and use it in GitHub Desktop.
Save grahamjenson/8309901 to your computer and use it in GitHub Desktop.
Snake List Widget

I recently wanted to implement a visualisation of a stream of incoming events. For the visualisation I wanted a list where the latest event is added to the beginning and the other events move down the list in a snake like pattern (to minimise the amount of movement). This is an example click on the squares to see my implementation in action. I used jQuery promises (which I recently blogged about here), metro css and coffeescript to implement this visualisation.

<html>
<meta charset="utf-8">
<body>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/metro/3.0.15/css/metro-colors.css">
<style>
/* tile width 130 260 390 520 650 780 910 1040*/
@media screen and (min-width: 260) {
#list {
width: 260px;
}
#list :nth-child(4n+1), #list :nth-child(4n+2){
float: left;
}
#list :nth-child(4n+3), #list :nth-child(4n+4) {
float: right;
}
}
@media screen and (min-width: 390px) {
#list {
width: 390px;
}
#list :nth-child(6n+1), #list :nth-child(6n+2), #list :nth-child(6n+3){
float: left;
}
#list :nth-child(6n+4), #list :nth-child(6n+5), #list :nth-child(6n+6) {
float: right;
}
}
@media screen and (min-width: 520px) {
#list {
width: 520px;
}
#list :nth-child(8n+1), #list :nth-child(8n+2), #list :nth-child(8n+3), #list :nth-child(8n+4){
float: left;
}
#list :nth-child(8n+5), #list :nth-child(8n+6), #list :nth-child(8n+7), #list :nth-child(8n+8) {
float: right;
}
}
@media screen and (min-width: 650px) {
#list {
width: 650px;
}
#list :nth-child(10n+1), #list :nth-child(10n+2), #list :nth-child(10n+3), #list :nth-child(10n+4), #list :nth-child(10n+5){
float: left;
}
#list :nth-child(10n+6), #list :nth-child(10n+7), #list :nth-child(10n+8), #list :nth-child(10n+9), #list :nth-child(10n+10) {
float: right;
}
}
</style>
<script src='https://code.jquery.com/jquery-2.0.3.js'></script>
<script src='https://code.jquery.com/ui/1.10.3/jquery-ui.js'></script>
<script src="https://coffeescript.org/extras/coffee-script.js"></script>
<div class='metro' id='list'>
<div class='tile' style='opacity: 0;'></div>
</div>
<script type="text/coffeescript">
select_random = (items) ->
items[Math.floor(Math.random()*items.length)]
colors = ["bg-black","bg-lime","bg-green","bg-emerald","bg-teal","bg-cyan","bg-cobalt","bg-indigo","bg-violet","bg-pink","bg-magenta","bg-crimson","bg-red","bg-orange","bg-amber","bg-yellow","bg-brown","bg-olive","bg-steel","bg-mauve","bg-taupe","bg-gray","bg-dark","bg-darker","bg-darkBrown","bg-darkCrimson","bg-darkMagenta","bg-darkIndigo","bg-darkCyan","bg-darkCobalt","bg-darkTeal","bg-darkEmerald","bg-darkGreen","bg-darkOrange","bg-darkRed","bg-darkPink","bg-darkViolet","bg-darkBlue","bg-lightBlue","bg-lightTeal","bg-lightOlive","bg-lightOrange","bg-lightPink","bg-lightRed","bg-lightGreen"]
icons = ["icon-home","icon-newspaper","icon-pencil","icon-droplet","icon-pictures","icon-camera","icon-music","icon-film","icon-camera-2","icon-spades","icon-clubs","icon-diamonds","icon-broadcast","icon-mic","icon-book","icon-file","icon-new","icon-copy","icon-folder","icon-folder-2","icon-tag","icon-cart","icon-basket","icon-calculate","icon-support","icon-phone","icon-mail","icon-location","icon-compass","icon-history","icon-clock","icon-bell","icon-calendar","icon-printer","icon-mouse","icon-screen","icon-laptop","icon-mobile","icon-cabinet","icon-drawer","icon-drawer-2","icon-box","icon-box-add","icon-box-remove","icon-download","icon-upload","icon-database","icon-flip","icon-flip-2","icon-undo","icon-redo","icon-forward","icon-reply","icon-reply-2","icon-comments","icon-comments-2","icon-comments-3","icon-comments-4","icon-comments-5","icon-user","icon-user-2","icon-user-3","icon-busy","icon-loading","icon-loading-2","icon-search","icon-zoom-in","icon-zoom-out","icon-key","icon-key-2","icon-locked","icon-unlocked","icon-wrench","icon-equalizer","icon-cog","icon-pie","icon-bars","icon-stats-up","icon-gift","icon-trophy","icon-diamond","icon-coffee","icon-rocket","icon-meter-slow","icon-meter-medium","icon-meter-fast","icon-dashboard","icon-fire","icon-lab","icon-remove","icon-briefcase","icon-briefcase-2","icon-cars","icon-bus","icon-cube","icon-cube-2","icon-puzzle","icon-glasses","icon-glasses-2","icon-accessibility","icon-accessibility-2","icon-target","icon-target-2","icon-lightning","icon-power","icon-power-2","icon-clipboard","icon-clipboard-2","icon-playlist","icon-grid-view","icon-tree-view","icon-cloud","icon-cloud-2","icon-download-2","icon-upload-2","icon-upload-3","icon-link","icon-link-2","icon-flag","icon-flag-2","icon-attachment","icon-eye","icon-bookmark","icon-bookmark-2","icon-star","icon-star-2","icon-star-3","icon-heart","icon-heart-2","icon-thumbs-up","icon-thumbs-down","icon-plus","icon-minus","icon-help","icon-help-2","icon-blocked","icon-cancel","icon-cancel-2","icon-checkmark","icon-minus-2","icon-plus-2","icon-enter","icon-exit","icon-loop","icon-arrow-up-left","icon-arrow-up","icon-arrow-up-right","icon-arrow-right","icon-arrow-down-right","icon-arrow-down","icon-arrow-down-left","icon-arrow-left","icon-arrow-up-2","icon-arrow-right-2","icon-arrow-down-2","icon-arrow-left-2","icon-arrow-up-3","icon-arrow-right-3","icon-arrow-down-3","icon-arrow-left-3","icon-menu","icon-enter-2","icon-backspace","icon-backspace-2","icon-tab","icon-tab-2","icon-checkbox","icon-checkbox-unchecked","icon-checkbox-partial","icon-radio-checked","icon-radio-unchecked","icon-font","icon-paragraph-left","icon-paragraph-center","icon-paragraph-right","icon-paragraph-justify","icon-left-to-right","icon-right-to-left","icon-share","icon-new-tab","icon-new-tab-2","icon-embed","icon-code","icon-bluetooth","icon-share-2","icon-share-3","icon-mail-2","icon-google","icon-google-plus","icon-google-drive","icon-facebook","icon-instagram","icon-twitter","icon-feed","icon-youtube","icon-vimeo","icon-flickr","icon-picassa","icon-dribbble","icon-deviantart","icon-github","icon-github-2","icon-github-3","icon-github-4","icon-github-5","icon-github-6","icon-git","icon-wordpress","icon-joomla","icon-blogger","icon-tumblr","icon-yahoo","icon-amazon","icon-tux","icon-apple","icon-finder","icon-android","icon-windows","icon-soundcloud","icon-skype","icon-reddit","icon-linkedin","icon-lastfm","icon-delicious","icon-stumbleupon","icon-pinterest","icon-xing","icon-flattr","icon-foursquare","icon-paypal","icon-yelp","icon-libreoffice","icon-file-pdf","icon-file-openoffice","icon-file-word","icon-file-excel","icon-file-powerpoint","icon-file-zip","icon-file-xml","icon-file-css","icon-html5","icon-html5-2","icon-css3","icon-chrome","icon-firefox","icon-IE","icon-opera","icon-safari","icon-IcoMoon","icon-sunrise","icon-sun","icon-moon","icon-sun-2","icon-windy","icon-wind","icon-snowflake","icon-cloudy","icon-cloud-3","icon-weather","icon-weather-2","icon-weather-3","icon-lines","icon-cloud-4","icon-lightning-2","icon-lightning-3","icon-rainy","icon-rainy-2","icon-windy-2","icon-windy-3","icon-snowy","icon-snowy-2","icon-snowy-3","icon-weather-4","icon-cloudy-2","icon-cloud-5","icon-lightning-4","icon-sun-3","icon-moon-2","icon-cloudy-3","icon-cloud-6","icon-cloud-7","icon-lightning-5","icon-rainy-3","icon-rainy-4","icon-windy-4","icon-windy-5","icon-snowy-4","icon-snowy-5","icon-weather-5","icon-cloudy-4","icon-lightning-6","icon-thermometer","icon-compass-2","icon-none","icon-Celsius","icon-Fahrenheit","icon-forrst","icon-headphones","icon-bug","icon-cart-2","icon-earth","icon-battery","icon-list","icon-grid","icon-alarm","icon-location-2","icon-pointer","icon-diary","icon-eye-2","icon-console","icon-location-3","icon-move","icon-monitor","icon-mobile-2","icon-switch","icon-star-4","icon-address-book","icon-shit","icon-cone","icon-credit-card","icon-type","icon-volume","icon-volume-2","icon-locked-2","icon-warning","icon-info","icon-filter","icon-bookmark-3","icon-bookmark-4","icon-stats","icon-compass-3","icon-keyboard","icon-award-fill","icon-award-stroke","icon-beaker-alt","icon-beaker","icon-move-vertical","icon-move-horizontal","icon-steering-wheel","icon-volume-3","icon-volume-mute","icon-play","icon-pause","icon-stop","icon-eject","icon-first","icon-last","icon-play-alt","icon-battery-empty","icon-battery-half","icon-battery-full","icon-battery-charging","icon-left-quote","icon-right-quote","icon-left-quote-alt","icon-right-quote-alt","icon-smiley","icon-umbrella","icon-info-2","icon-chart-alt","icon-floppy","icon-at","icon-hash","icon-pilcrow","icon-fullscreen-alt","icon-fullscreen-exit-alt","icon-layers-alt","icon-layers","icon-rainbow","icon-air","icon-spin","icon-auction","icon-dollar","icon-dollar-2","icon-coins","icon-file-2","icon-file-3","icon-file-4","icon-files","icon-phone-2","icon-tablet","icon-monitor-2","icon-window","icon-tv","icon-camera-3","icon-image","icon-open","icon-sale","icon-direction","icon-medal","icon-medal-2","icon-satellite","icon-discout","icon-barcode","icon-ticket","icon-shipping","icon-globe","icon-anchor","icon-pop-out","icon-pop-in","icon-resize","icon-battery-2","icon-battery-3","icon-battery-4","icon-battery-5","icon-tools","icon-alarm-2","icon-alarm-cancel","icon-alarm-clock","icon-chronometer","icon-ruler","icon-lamp","icon-lamp-2","icon-scissors","icon-volume-4","icon-volume-5","icon-volume-6","icon-zip","icon-zip-2","icon-play-2","icon-pause-2","icon-record","icon-stop-2","icon-next","icon-previous","icon-first-2","icon-last-2","icon-arrow-left-4","icon-arrow-down-4","icon-arrow-up-4","icon-arrow-right-4","icon-arrow-right-4","icon-arrow-left-5","icon-arrow-down-5","icon-arrow-up-5","icon-arrow-right-5","icon-cc","icon-cc-by","icon-cc-nc","icon-cc-nc-eu","icon-cc-nc-jp","icon-cc-sa","icon-cc-nd","icon-cc-pd","icon-cc-zero","icon-cc-share","icon-cc-share-2","icon-cycle","icon-stop-3","icon-stats-2","icon-stats-3"]
draw_item = (name) ->
$("<div>
<div class='tile-content icon'>
<i class='#{select_random(icons)}'></i>
</div>
<div class='brand bg-black'>
<span class='label fg-white'>#{name}</span>
</div>
</div>").addClass('tile').addClass(select_random(colors)).prependTo('#list')
window.add_list_item = ->
promises = []
$('#list .tile').each (i,obj) ->
return if $(obj).next().length == 0
promises.push $(obj).position({
my: 'center'
at: 'center'
of: $(obj).next()
using: ((css,calc) ->
$(obj).animate(css, 1000);)
})
$.when(promises...).then( ->
$('#list .tile').css('position',"").css('top','').css('left','')
draw_item($('#list .tile').length ).css('opacity',0).animate({opacity: 1},500)
)
for i in [1..9]
draw_item(i)
window.current_promise = $.when()
$('#list').on('click', ->
window.current_promise = window.current_promise.then(-> add_list_item())
)
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment