Created
August 1, 2012 15:27
-
-
Save vitalyrotari/3227802 to your computer and use it in GitHub Desktop.
Mobile Gallery
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
((window) -> | |
"use strict" | |
$ = window.Zepto | |
screen = window.screen | |
document = window.document | |
hasOwn = (obj, key) -> | |
obj.hasOwnProperty key | |
Device = | |
UA_MOBILE: (/iphone|ipod|android|blackberry|opera|mini|windows\sce|palm|smartphone|iemobile/i.test(window.navigator.userAgent.toLowerCase())) | |
UA_TABLET: (/ipad|android|android\s3\.0|xoom|sch-i800|playbook|tablet|kindle/i.test(window.navigator.userAgent.toLowerCase())) | |
TYPE_DESKTOP: 0 | |
TYPE_PHONE: 1 | |
TYPE_TABLET: 2 | |
phone: | |
width: | |
min: 240 | |
max: 960 | |
height: | |
min: 320 | |
max: 960 | |
tablet: | |
width: | |
min: 240 | |
max: 960 | |
height: | |
min: 320 | |
max: 960 | |
matchResolutions: (width, height, type) -> | |
(width >= this[type].width.min and width <= this[type].width.max) and (height >= this[type].height.min and height <= this[type].height.max) | |
detect: -> | |
orientation = window.orientation | |
width = undefined | |
height = undefined | |
if orientation isnt `undefined` | |
width = (if (orientation is 0) then screen.width else screen.height) | |
height = (if (orientation is 0) then screen.height else screen.width) | |
if @UA_MOBILE and @matchResolutions(width, height, "phone") | |
return @TYPE_PHONE | |
else | |
return @TYPE_TABLET if @UA_TABLET and @matchResolutions(width, height, "tablet") | |
@TYPE_DESKTOP | |
class Gallery | |
currentPage: 1 | |
constructor: (container) -> | |
@$ = container: $(container) | |
@images = (if (images instanceof Array) then images else []) | |
@init() if @images.length > 0 | |
init: () -> | |
@deviceType = Device.detect() | |
@imagesPerPage = (if (@deviceType is Device.TYPE_PHONE) then 4 else 9) | |
@pagesCount = Math.round(@images.length / @imagesPerPage); | |
@create() | |
$(document).on("swipeLeft", (event) => | |
event.preventDefault() | |
@(nextPage) | |
).on("swipeRight", (event) => | |
event.preventDefault() | |
@prevPage() | |
) | |
@reflow() | |
@preloadImages() | |
create: () -> | |
@$.content = $("<div class=\"content\"></div>") | |
@$.container.append(@$.content) | |
while p < @pagesCount | |
content += "<div class=\"page\">" | |
i = 0 | |
while i < @imagesPerPage | |
image = @images[lastIndex] | |
content += "<figure data-image=\"#{image.src}\">" | |
content += "<figcaption>#{image.caption}</figcaption>" if hasOwn(image, "caption") | |
content += "</figure>" | |
lastIndex++ | |
i++ | |
content += "</div>" | |
p++ | |
@$.content.append(content) | |
destroy: () -> | |
$(document).off("swipeLeft swipeRight") | |
toPage: () -> | |
nextPage = @currentPage + num | |
pagesCount = @$.pages.length | |
if nextPage < 1 | |
nextPage = 1 | |
else | |
nextPage = pagesCount if pagesCount < nextPage | |
if @currentPage isnt nextPage | |
leftPosition = 100 * (nextPage - 1) | |
@currentPage = nextPage | |
@$.content.css(left: "-#{leftPosition}%") | |
@preloadImages() | |
nextPage: () -> | |
@toPage 1 | |
prevPage: () -> | |
@toPage -1 | |
preloadImages: () -> | |
$page = @$.pages.eq(@currentPage - 1) | |
$items = undefined | |
load = () -> | |
$item = $(this) | |
imagePath = $item.data("image") | |
image = document.createElement("img") | |
image.src = imagePath | |
$(image).on("load", () -> | |
$item.css(backgroundImage: "url('#{imagePath}')").addClass("loaded") | |
) | |
if $page.length isnt 0 | |
$page.find("figure").not(".loaded").each (index) -> | |
load.call(this) | |
reflow: () -> | |
@$.pages = @$.content.find(".page") | |
count = @$.pages.length | |
@$.content.css width: (count * 100) + "%" | |
@$.pages.css width: (100 / count) + "%" | |
window.TN = {} unless window.TN instanceof Object | |
TN.Device = Device | |
TN.Gallery = Gallery | |
) @ |
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
(function (window) { | |
"use strict"; | |
var $ = window.Zepto, | |
screen = window.screen, | |
document = window.document, | |
TN = window.TN = window.TN || {}; | |
function hasOwn(obj, key) { | |
return obj.hasOwnProperty(key); | |
} | |
TN.Device = { | |
UA_MOBILE: (/iphone|ipod|android|blackberry|opera|mini|windows\sce|palm|smartphone|iemobile/i.test(window.navigator.userAgent.toLowerCase())), | |
UA_TABLET: (/ipad|android|android\s3\.0|xoom|sch-i800|playbook|tablet|kindle/i.test(window.navigator.userAgent.toLowerCase())), | |
TYPE_DESKTOP: 0, | |
TYPE_PHONE: 1, | |
TYPE_TABLET: 2, | |
phone: { | |
width: {min: 240, max: 960}, | |
height: {min: 320, max: 960} | |
}, | |
tablet: { | |
width: {min: 240, max: 960}, | |
height: {min: 320, max: 960} | |
}, | |
matchResolutions: function (width, height, type) { | |
return ((width >= this[type].width.min && width <= this[type].width.max) && | |
(height >= this[type].height.min && height <= this[type].height.max)); | |
}, | |
detect: function () { | |
var orientation = window.orientation, | |
width, | |
height; | |
if (orientation !== undefined) { | |
width = (orientation === 0) ? screen.width : screen.height; | |
height = (orientation === 0) ? screen.height : screen.width; | |
if (this.UA_MOBILE && this.matchResolutions(width, height, 'phone')) { | |
return this.TYPE_PHONE; | |
} else { | |
if (this.UA_TABLET && this.matchResolutions(width, height, 'tablet')) { | |
return this.TYPE_TABLET; | |
} | |
} | |
} | |
return this.TYPE_DESKTOP; | |
} | |
}; | |
TN.Gallery = function (container, images) { | |
this.$.container = $(container); | |
this.images = (images instanceof Array) ? images : []; | |
if (this.images.length > 0) { | |
this.init(); | |
} | |
}; | |
TN.Gallery.prototype.$ = {}; | |
TN.Gallery.prototype.currentPage = 1; | |
TN.Gallery.prototype.init = function () { | |
var self = this; | |
this.deviceType = TN.Device.detect(); | |
this.imagesPerPage = (this.deviceType === TN.Device.TYPE_PHONE) ? 4 : 9; | |
this.pagesCount = Math.round(this.images.length / this.imagesPerPage); | |
this.create(); | |
$(document) | |
.on('swipeLeft', function (event) { | |
event.preventDefault(); | |
self.nextPage(); | |
}) | |
.on('swipeRight', function (event) { | |
event.preventDefault(); | |
self.prevPage(); | |
}); | |
this.reflow(); | |
this.preloadImages(); | |
}; | |
TN.Gallery.prototype.create = function () { | |
var content = '', | |
lastIndex = 0, | |
image; | |
this.$.content = $('<div class="content"></div>'); | |
$(this.$.container).append(this.$.content); | |
for (var p = 0, i; p < this.pagesCount; p++) { | |
content += '<div class="page">'; | |
for (i=0; i < this.imagesPerPage; i++) { | |
image = this.images[lastIndex]; | |
content += '<figure data-image="' + image.src + '">'; | |
if (hasOwn(image, 'caption')) { | |
content += '<figcaption>' + image.caption + '<\/figcaption>'; | |
} | |
content += '<\/figure>'; | |
lastIndex++; | |
} | |
content += '<\/div>'; | |
} | |
this.$.content.append(content); | |
}; | |
TN.Gallery.prototype.destroy = function () { | |
$(document).off('swipeLeft swipeRight'); | |
}; | |
TN.Gallery.prototype.toPage = function (num) { | |
var nextPage = this.currentPage + num, | |
pagesCount = this.$.pages.length, | |
leftPosition = 0; | |
if (nextPage < 1) { | |
nextPage = 1; | |
} else { | |
if (pagesCount < nextPage) { | |
nextPage = pagesCount; | |
} | |
} | |
if (this.currentPage !== nextPage) { | |
leftPosition = 100 * (nextPage - 1); | |
this.currentPage = nextPage; | |
this.$.content | |
.css({left: String(-leftPosition) + '%'}); | |
this.preloadImages(); | |
} | |
}; | |
TN.Gallery.prototype.nextPage = function () { | |
this.toPage(1); | |
}; | |
TN.Gallery.prototype.prevPage = function () { | |
this.toPage(-1); | |
}; | |
TN.Gallery.prototype.preloadImages = function () { | |
var $page = this.$.pages.eq(this.currentPage - 1), | |
$items, | |
load = function () { | |
var $item = $(this), | |
imagePath = $item.data('image'), | |
image = document.createElement('img'); | |
image.src = imagePath; | |
$(image).on('load', function () { | |
$item | |
.css({backgroundImage: "url('" + imagePath + "')"}) | |
.addClass('loaded'); | |
}); | |
}; | |
if ($page.length !== 0) { | |
$page.find('figure') | |
.not('.loaded') | |
.each(function (index) { | |
load.call(this); | |
}); | |
} | |
}; | |
TN.Gallery.prototype.reflow = function () { | |
this.$.pages = this.$.content.find('.page'); | |
var count = this.$.pages.length; | |
this.$.content.css({width: (count * 100) + '%'}); | |
this.$.pages.css({width: (100 / count) + '%'}); | |
}; | |
}(this)); |
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> | |
<html> | |
<head> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"> | |
<meta name="apple-mobile-web-app-status-bar-style" content="black"> | |
<meta name="apple-mobile-web-app-capable" content="yes"> | |
<link href="css/styles.css" rel="stylesheet"> | |
<script src="http://zeptojs.com/zepto.min.js"></script> | |
<meta charset=utf-8 /> | |
<title>JS Bin</title> | |
</head> | |
<body> | |
<section class="gallery"></section> | |
<script src="js/app.js"></script> | |
<script> | |
(function ($) { | |
"use strict"; | |
var caption = '<h2>Description<\/h2><small>adition text here...<\/small>', | |
imagesLists = [{ | |
"src": 'http://leclick.ru/files/restaurants/photo/5523.jpg', | |
"caption": caption | |
}, { | |
"src": 'http://leclick.ru/files/restaurants/photo/5522.jpg', | |
"caption": caption | |
}, { | |
"src": 'http://leclick.ru/files/restaurants/photo/5521.jpg', | |
"caption": caption | |
}, { | |
"src": 'http://leclick.ru/files/restaurants/photo/5519.jpg', | |
"caption": caption | |
}, { | |
"src": 'http://leclick.ru/files/restaurants/photo/5466.jpg', | |
"caption": caption | |
}, { | |
"src": 'http://leclick.ru/files/restaurants/photo/5517.jpg', | |
"caption": caption | |
}, { | |
"src": 'http://leclick.ru/files/restaurants/photo/5516.jpg', | |
"caption": caption | |
}, { | |
"src": 'http://leclick.ru/files/restaurants/photo/5513.jpg', | |
"caption": caption | |
}, { | |
"src": 'http://leclick.ru/files/restaurants/photo/5526.jpg', | |
"caption": caption | |
}, | |
{ | |
"src": 'http://leclick.ru/files/restaurants/photo/3259.jpg', | |
"caption": caption | |
}, { | |
"src": 'http://leclick.ru/files/restaurants/photo/3258.jpg', | |
"caption": caption | |
}, { | |
"src": 'http://leclick.ru/files/restaurants/photo/3257.jpg', | |
"caption": caption | |
}, { | |
"src": 'http://leclick.ru/files/restaurants/photo/3256.jpg', | |
"caption": caption | |
}, { | |
"src": 'http://leclick.ru/files/restaurants/photo/3255.jpg', | |
"caption": caption | |
}, { | |
"src": 'http://leclick.ru/files/restaurants/photo/5697.jpg', | |
"caption": caption | |
}, { | |
"src": 'http://leclick.ru/files/restaurants/photo/5696.jpg', | |
"caption": caption | |
}, { | |
"src": 'http://leclick.ru/files/restaurants/photo/5695.jpg', | |
"caption": caption | |
}, { | |
"src": 'http://leclick.ru/files/restaurants/photo/5694.jpg', | |
"caption": caption | |
}, | |
]; | |
$(function () { | |
var gallery = new TN.Gallery('.gallery', imagesLists); | |
}); | |
}(Zepto)); | |
</script> | |
</body> | |
</html> |
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
html, body { | |
height: 100%; | |
} | |
body { | |
background: #444; | |
padding: 0; | |
margin: 0; | |
font-family: "Helvetica Neue", Arial; | |
font-size: 13px; | |
line-height: 18px; | |
overflow: hidden; | |
} | |
.gallery { | |
background: red; | |
position: absolute; | |
top: 0; | |
left: 0; | |
button: 0; | |
width: 100%; | |
oveflow: hidden; | |
} | |
.gallery .content { | |
padding: 10px; | |
position: absolute; | |
top: 0; | |
left: 0; | |
height: 100%; | |
-webkit-transition: 0.2s all ease-in; | |
-moz-transition: 0.2s all ease-in; | |
-ms-transition: 0.2s all ease-in; | |
-o-transition: 0.2s all ease-in; | |
transition: 0.2s all ease-in; | |
-webkit-transform: translate3d(0,0,0); | |
-moz-transform: translate3d(0,0,0); | |
-ms-transform: translate3d(0,0,0); | |
-o-transform: translate3d(0,0,0); | |
transform: translate3d(0,0,0); | |
} | |
.gallery .page { | |
float: left; | |
margin: 0; | |
position: relative; | |
} | |
.gallery figure { | |
background-color: black; | |
background-image: url('../img/295.gif'); | |
background-repeat: no-repeat; | |
background-position: 50% 50%; | |
box-shadow: 0 0 8px rgba(0, 0, 0, .6); | |
position: relative; | |
margin: 0 20px 20px 0; | |
width: 320px; | |
height: 198px; | |
float: left; | |
overflow: hidden; | |
-webkit-touch-callout: none; | |
-webkit-user-select: none; | |
-khtml-user-select: none; | |
-moz-user-select: none; | |
-ms-user-select: none; | |
user-select: none; | |
} | |
.gallery figcaption { | |
background-color: rgba(0, 0, 0, .6); | |
color: white; | |
position: absolute; | |
left: -20px; | |
right: 0; | |
bottom: 0; | |
padding: 10px 10px; | |
opacity: 0; | |
-webkit-transition: 0.4s all ease-in .2s; | |
-moz-transition: 0.25s all ease-in; | |
-ms-transition: 0.25s all ease-in; | |
-o-transition: 0.25s all ease-in; | |
transition: 0.4s all ease-in .2s; | |
-webkit-transform: translate3d(0,0,0); | |
-moz-transform: translate3d(0,0,0); | |
-ms-transform: translate3d(0,0,0); | |
-o-transform: translate3d(0,0,0); | |
transform: translate3d(0,0,0); | |
} | |
.gallery figcaption h2 { | |
padding: 0; | |
margin: 0; | |
} | |
.gallery figure.loaded { | |
background-size: 100% auto; | |
} | |
.gallery figure.loaded figcaption { | |
opacity: 1; | |
left: 0; | |
} | |
/* Portrait */ | |
@media screen and (orientation:portrait) { | |
.gallery figure { | |
width: 236px; | |
height: 283px; | |
} | |
.gallery figure.loaded { | |
background-size: 200% auto; | |
} | |
} | |
/* Landscape */ | |
@media screen and (orientation:landscape) { | |
} | |
/* Tablets */ | |
@media screen | |
and (min-width: 768px) | |
and (max-width: 1023px) | |
and (orientation: portrait) { | |
.gallery figure:nth-child(3n) { | |
margin-right: 0; | |
} | |
} | |
@media screen | |
and (min-width: 1024px) | |
and (max-width: 1280px) | |
and (orientation:landscape) { | |
.gallery figure:nth-child(3n) { | |
margin-right: 0; | |
} | |
} | |
/* iPhone Portrait */ | |
@media screen | |
and (max-width: 320px) | |
and (orientation: portrait) { | |
.gallery figure { | |
width: 140px; | |
height: 187px | |
} | |
.gallery figure:nth-of-type(2n) { | |
margin-right: 0; | |
} | |
} | |
/* iPhone Landscape */ | |
@media screen | |
and (min-width: 321px) | |
and (max-width: 480px) | |
and (orientation:landscape) { | |
.gallery figure { | |
width: 220px; | |
height: 140px; | |
} | |
.gallery figure:nth-of-type(2n) { | |
margin-right: 0; | |
} | |
} |
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
@mixin transition(@params) { | |
-webkit-transition: @params; | |
-moz-transition: @params; | |
-ms-transition: @params; | |
-o-transition: @params; | |
transition: @params; | |
} | |
@mixin transform(@params) { | |
-webkit-transform: @params; | |
-moz-transform: @params; | |
-ms-transform: @params; | |
-o-transform: @params; | |
transform: @params; | |
} | |
@mixin user-select (@param: none) { | |
-webkit-touch-callout: @param; | |
-webkit-user-select: @param; | |
-khtml-user-select: @param; | |
-moz-user-select: @param; | |
-ms-user-select: @param; | |
user-select: @param; | |
} | |
html, body { | |
height: 100%; | |
} | |
body { | |
background: #444; | |
padding: 0; | |
margin: 0; | |
font-family: "Helvetica Neue", Arial; | |
font-size: 13px; | |
line-height: 18px; | |
overflow: hidden; | |
} | |
.gallery { | |
background: red; | |
position: absolute; | |
top: 0; | |
left: 0; | |
button: 0; | |
width: 100%; | |
oveflow: hidden; | |
.content { | |
padding: 10px; | |
position: absolute; | |
top: 0; | |
left: 0; | |
height: 100%; | |
@include transition(0.2s all ease-in); | |
@include transform(translate3d(0,0,0)); | |
} | |
.page { | |
float: left; | |
margin: 0; | |
position: relative; | |
} | |
figure { | |
background-color: black; | |
background-image: url('../img/295.gif'); | |
background-repeat: no-repeat; | |
background-position: 50% 50%; | |
box-shadow: 0 0 8px rgba(0, 0, 0, .6); | |
position: relative; | |
margin: 0 20px 20px 0; | |
width: 320px; | |
height: 198px; | |
float: left; | |
overflow: hidden; | |
@include user-select; | |
&.loaded { | |
background-size: 100% auto; | |
figcaption { | |
opacity: 1; | |
left: 0; | |
} | |
} | |
} | |
figcaption { | |
background-color: rgba(0, 0, 0, .6); | |
color: white; | |
position: absolute; | |
left: -20px; | |
right: 0; | |
bottom: 0; | |
padding: 10px 10px; | |
opacity: 0; | |
@include transition(0.4s all ease-in .2s); | |
@include transform(translate3d(0,0,0)); | |
h2 { | |
padding: 0; | |
margin: 0; | |
} | |
} | |
} | |
/* Portrait */ | |
@media screen and (orientation:portrait) { | |
.gallery figure { | |
width: 236px; | |
height: 283px; | |
&.loaded { | |
background-size: 200% auto; | |
} | |
} | |
} | |
/* Landscape */ | |
@media screen and (orientation:landscape) { | |
} | |
/* Tablets */ | |
@media screen | |
and (min-width: 768px) | |
and (max-width: 1023px) | |
and (orientation: portrait) { | |
.gallery figure:nth-child(3n) { | |
margin-right: 0; | |
} | |
} | |
@media screen | |
and (min-width: 1024px) | |
and (max-width: 1280px) | |
and (orientation:landscape) { | |
.gallery figure:nth-child(3n) { | |
margin-right: 0; | |
} | |
} | |
/* iPhone Portrait */ | |
@media screen | |
and (max-width: 320px) | |
and (orientation: portrait) { | |
.gallery figure { | |
width: 140px; | |
height: 187px | |
&:nth-of-type(2n) { | |
margin-right: 0; | |
} | |
} | |
} | |
/* iPhone Landscape */ | |
@media screen | |
and (min-width: 321px) | |
and (max-width: 480px) | |
and (orientation:landscape) { | |
.gallery figure { | |
width: 220px; | |
height: 140px; | |
&:nth-of-type(2n) { | |
margin-right: 0; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment