From 6b09be7cf7555f599a0c9996e69fcd5f55eb46a4 Mon Sep 17 00:00:00 2001 From: Anton Zhevak Date: Sat, 16 Nov 2013 10:09:27 +0600 Subject: [PATCH 01/13] First release --- css/main.css | 254 +++++++++++++++++++++++++++++++ index.html | 23 +++ js/app.js | 22 +++ js/collections/picture.js | 24 +++ js/helpers/helper.js | 18 +++ js/main.js | 28 ++++ js/models/picture.js | 25 +++ js/router.js | 45 ++++++ js/templates/picture/detail.html | 33 ++++ js/templates/picture/item.html | 8 + js/templates/picture/list.html | 2 + js/views/picture/detail.js | 64 ++++++++ js/views/picture/item.js | 69 +++++++++ js/views/picture/list.js | 33 ++++ 14 files changed, 648 insertions(+) create mode 100644 css/main.css create mode 100644 index.html create mode 100644 js/app.js create mode 100644 js/collections/picture.js create mode 100644 js/helpers/helper.js create mode 100644 js/main.js create mode 100644 js/models/picture.js create mode 100644 js/router.js create mode 100644 js/templates/picture/detail.html create mode 100644 js/templates/picture/item.html create mode 100644 js/templates/picture/list.html create mode 100644 js/views/picture/detail.js create mode 100644 js/views/picture/item.js create mode 100644 js/views/picture/list.js diff --git a/css/main.css b/css/main.css new file mode 100644 index 0000000..90e8b56 --- /dev/null +++ b/css/main.css @@ -0,0 +1,254 @@ +body +{ + margin: 0 40px; + + font: 14px/normal sans-serif; +} + + +.tabs +{ + margin: 10px 0 20px; + padding: 0; + + list-style: none; +} + +.tabs__tab +{ + display: inline; + + margin: 0 15px 0 0; +} + + +.pictures__title +{ + margin: 0 0 20px; + + font-size: 40px; + font-weight: 400; +} + +.pictures__title:first-letter +{ + color: red; +} + +.pictures__items +{ + margin: -10px -10px 80px; + padding: 0; + + list-style: none; + + text-align: justify; + + font: 0/0 a; +} + +.pictures__items:after +{ + display: inline-block; + + width: 100%; + height: 0; + + content: ""; +} + + +.picture +{ + position: relative; + + display: inline-block; + + margin: 10px; + + vertical-align: top; +} + +.picture__link +{ + position: relative; + z-index: 1; + + display: block; + overflow: hidden; + + height: 100px; + + cursor: pointer; +} + +.picture__preview +{ + display: block; +} + +.picture__info +{ + position: absolute; + top: -10px; + left: -10px; + + display: none; + + width: 100%; + padding: 120px 10px 10px 10px; + + text-align: left; + + color: #fff; + background: #2b2b2b; + box-shadow: 0 2px 9px rgba(0,0,0, .6); + + font: 12px/16px sans-serif; +} + +.picture__title +{ + overflow: hidden; + + margin: 0 0 5px; + + text-overflow: ellipsis; +} + +.picture_active_yes, +.picture_hovered_yes +{ + position: relative; + z-index: 100; +} + +.picture_active_yes .picture__info, +.picture_hovered_yes .picture__info +{ + display: block; +} + + +.preview +{ + position: relative; + + display: none; + overflow: hidden; + + background: #2b2b2b; + + font: 14px/normal sans-serif; +} + +.preview__close +{ + position: absolute; + top: 10px; + right: 10px; + + overflow: hidden; + + height: 28px; + + cursor: pointer; + + color: #888; + + font-size: 48px; + font-weight: 700; + line-height: 28px; +} + +.preview__close:hover +{ + color: #ddd; +} + +.preview__slider +{ + margin: 10px 330px 10px 10px; + + text-align: center; +} + +.preview__info +{ + position: absolute; + top: 50px; + right: 10px; + + width: 300px; + + text-align: left; + + color: #eee; +} + +.preview__props +{ + margin: 0; + padding: 0; + + list-style: none; +} + +.preview__prop +{ + margin: 0 0 10px; +} + +.preview__title +{ + margin: 0 0 15px; + + color: #fff; +} + +.preview__author +{ + color: #24a323; +} + +.preview__author:hover +{ + color: red; +} + +.preview__slider +{ + position: relative; +} + +.preview__next, +.preview__prev +{ + position: absolute; + top: 50%; + + margin: -30px 0 0; + + color: #666; + + font-size: 60px; + line-height: 1; +} + +.preview__next:hover, +.preview__prev:hover +{ + cursor: pointer; + + color: #ddd; +} + +.preview__next +{ + right: 0; +} + +.preview__prev +{ + left: 0; +} diff --git a/index.html b/index.html new file mode 100644 index 0000000..8b63815 --- /dev/null +++ b/index.html @@ -0,0 +1,23 @@ + + + + + Домашнее задание №6 + + + + + +
+ + diff --git a/js/app.js b/js/app.js new file mode 100644 index 0000000..c86856d --- /dev/null +++ b/js/app.js @@ -0,0 +1,22 @@ +define([ + 'jquery', + 'underscore', + 'backbone', + 'router' +], function($, _, Backbone, Router) { + + return function() { + + this.router = new Router; + + this.vent = _.extend({}, Backbone.Events); + + var self = this; + $('a[href]').on('click', function(event) { + event.preventDefault(); + self.router.navigate($(this).attr('href'), { trigger : true }); + }); + + }; + +}); diff --git a/js/collections/picture.js b/js/collections/picture.js new file mode 100644 index 0000000..c8b60e6 --- /dev/null +++ b/js/collections/picture.js @@ -0,0 +1,24 @@ +define([ + 'jquery', + 'underscore', + 'backbone', + 'models/picture' +], function($, _, Backbone, Picture) { + + return Backbone.Collection.extend({ + + model : Picture, + + url : 'http://api-fotki.yandex.ru/api/{{type}}/?format=json', + + initialize : function(options) { + this.url = this.url.replace('{{type}}', options.type); + }, + + parse : function(response) { + return response.entries; + } + + }); + +}); diff --git a/js/helpers/helper.js b/js/helpers/helper.js new file mode 100644 index 0000000..b3f4934 --- /dev/null +++ b/js/helpers/helper.js @@ -0,0 +1,18 @@ +define(function() { + + return { + + leadZero : function(num) { + return num < 10 ? '0' + num : num; + }, + + formatDate : function(date) { + date = new Date(date); + return date.getDate() + ' ' + + ('января,февраля,марта,апреля,мая,июня,июля,августа,сентября,октября,ноября,декабря'.split(',')[date.getMonth()]) + ' ' + + date.getFullYear() + ' в ' + this.leadZero(date.getHours()) + ':' + this.leadZero(date.getMinutes()); + } + + } + +}); \ No newline at end of file diff --git a/js/main.js b/js/main.js new file mode 100644 index 0000000..6b89bc0 --- /dev/null +++ b/js/main.js @@ -0,0 +1,28 @@ +requirejs.config({ + paths : { + underscore : '//yandex.st/underscore/1.5.2/underscore-min', + backbone : '//yandex.st/backbone/1.1.0/backbone-min', + jquery : '//yandex.st/jquery/1.10.2/jquery.min', + text : '//cdnjs.cloudflare.com/ajax/libs/require-text/2.0.10/text.min' + }, + shim : { + underscore : { + exports : '_' + }, + backbone : { + deps : ['jquery', 'underscore'], + exports : 'Backbone' + } + } +}); + +require([ + 'backbone', + 'app' +], function(Backbone, App) { + + window.app = new App; + + Backbone.history.start(); + +}); diff --git a/js/models/picture.js b/js/models/picture.js new file mode 100644 index 0000000..9a3c469 --- /dev/null +++ b/js/models/picture.js @@ -0,0 +1,25 @@ +define([ + 'jquery', + 'underscore', + 'backbone', + 'helpers/helper' +], function($, _, Backbone, Helper) { + + return Backbone.Model.extend({ + + parse : function(response, options) { + return { + id : response.id, + title : _.escape(response.title), + author : { + name : response.author, + url : 'http://fotki.yandex.ru/users/' + response.author + '/photos/' + }, + pubDate : Helper.formatDate(response.published), + img : response.img + }; + }, + + }); + +}); diff --git a/js/router.js b/js/router.js new file mode 100644 index 0000000..7698e9d --- /dev/null +++ b/js/router.js @@ -0,0 +1,45 @@ +define([ + 'jquery', + 'underscore', + 'backbone' +], function($, _, Backbone) { + + return Backbone.Router.extend({ + + routes : { + '*type' : 'index' + }, + + index : function(type) { + var types = { + 'top' : 'Популярные фотографии', + 'recent' : 'Новые интересные фотографии', + 'podhistory' : 'Фото дня' + }; + + if (type === null || types[type] === undefined) { + type = 'top'; + } + + require([ + 'collections/picture', + 'views/picture/list' + ], function(PictureCollection, PictureListView) { + var results = new PictureCollection({ + type : type + }); + results.fetch({ + dataType: 'jsonp', + success : function(collection) { + var list = new PictureListView({ + collection : collection, + title : types[type] + }); + } + }); + }); + }, + + }); + +}); diff --git a/js/templates/picture/detail.html b/js/templates/picture/detail.html new file mode 100644 index 0000000..5f09e75 --- /dev/null +++ b/js/templates/picture/detail.html @@ -0,0 +1,33 @@ +
+ + + <%= title %> +
+
+

<%= title %>

+ +
+× diff --git a/js/templates/picture/item.html b/js/templates/picture/item.html new file mode 100644 index 0000000..9789675 --- /dev/null +++ b/js/templates/picture/item.html @@ -0,0 +1,8 @@ + + <%= title %> + +
+

<%= title %>

+
<%= author.name %>
+
<%= pubDate %>
+
diff --git a/js/templates/picture/list.html b/js/templates/picture/list.html new file mode 100644 index 0000000..445c1e8 --- /dev/null +++ b/js/templates/picture/list.html @@ -0,0 +1,2 @@ +

<%= title %>

+ diff --git a/js/views/picture/detail.js b/js/views/picture/detail.js new file mode 100644 index 0000000..84dd469 --- /dev/null +++ b/js/views/picture/detail.js @@ -0,0 +1,64 @@ +define([ + 'jquery', + 'underscore', + 'backbone', + 'text!templates/picture/detail.html' +], function($, _, Backbone, tpl) { + + return Backbone.View.extend({ + + tagName : 'li', + + className : 'preview', + + template : _.template(tpl), + + initialize: function(options) { + window.app.vent.on('preview:open', this.closePreview, this); + window.app.vent.trigger('preview:open'); + this.render(options.addBefore); + }, + + events : { + 'click .preview__close' : 'closePreview', + 'change .preview__sizes' : 'otherImageSize' + }, + + render : function(element) { + var $el = this.$el; + $el.html(this.template(this.model.toJSON())); + + // Вставляем превью перед началом строки + $(element).before($el); + + // Разворачиваем превью и прокручиваем + $el.slideDown('fast', function() { + $(document.body).animate({ scrollTop: $el.offset().top - 10 }, 'fast'); + }); + + return this; + }, + + closePreview : function() { + // Генерируем событие + window.app.vent.trigger('preview:close'); + + // Сворачиваем и удаляем превью + var self = this; + this.$el.slideUp('fast', function() { + self.remove(); + }); + }, + + otherImageSize : function(event) { + // Получаем данные о выбранном размере + var size = $(event.target).val(), + img = this.model.get('img')[size]; + + // Открываем в новой вкладке + window.open(img.href, '_blank'); + } + + }); + +}); diff --git a/js/views/picture/item.js b/js/views/picture/item.js new file mode 100644 index 0000000..6767dde --- /dev/null +++ b/js/views/picture/item.js @@ -0,0 +1,69 @@ +define([ + 'jquery', + 'underscore', + 'backbone', + 'views/picture/detail', + 'text!templates/picture/item.html' +], function($, _, Backbone, PictureDetailView, tpl) { + + return Backbone.View.extend({ + + tagName : 'li', + + className : 'picture', + + template : _.template(tpl), + + initialize: function() { + // При закрытии превью убираем обводку + window.app.vent.on('preview:close', function() { + this.$el.removeClass('picture_active_yes'); + }, this); + + this.render(); + }, + + events : { + 'click .picture__link' : 'showLargerPicture', + 'mouseout .picture__preview' : 'showPictureInfo', + 'mouseover .picture__preview' : 'showPictureInfo', + }, + + render : function() { + this.$el.html(this.template(this.model.toJSON())); + return this; + }, + + showLargerPicture : function() { + var $el = this.$el, + $prevEl; + + // Ищем начало строки для вставки превью + while (true) { + $prevEl = $el.prev(); + if ($prevEl.length > 0) { + if ($prevEl.position().left > $el.position().left) { + break; + } else { + $el = $prevEl; + } + } else { + break; + } + } + + var view = new PictureDetailView({ + model : this.model, + addBefore : $el + }); + + this.$el.addClass('picture_active_yes'); + }, + + showPictureInfo : function(event) { + this.$el.toggleClass('picture_hovered_yes'); + } + + }); + +}); diff --git a/js/views/picture/list.js b/js/views/picture/list.js new file mode 100644 index 0000000..5af7330 --- /dev/null +++ b/js/views/picture/list.js @@ -0,0 +1,33 @@ +define([ + 'jquery', + 'underscore', + 'backbone', + 'views/picture/item', + 'text!templates/picture/list.html' +], function($, _, Backbone, PictureItemView, tpl) { + + return Backbone.View.extend({ + + className : 'pictures', + + template : _.template(tpl), + + initialize: function(options) { + this.render(options.title); + }, + + render : function(title) { + this.$el.html(this.template({ title : title })); + this.collection.each(this.addOne, this); + $('#content').html(this.el); + return this; + }, + + addOne : function(picture) { + var view = new PictureItemView({ model : picture }); + this.$('.pictures__items').append('\n').append(view.render().el); + }, + + }); + +}); From 2d358d69bf5f22129a4fefdfd98c88ac9f1fc7f2 Mon Sep 17 00:00:00 2001 From: Anton Zhevak Date: Sat, 16 Nov 2013 10:22:45 +0600 Subject: [PATCH 02/13] =?UTF-8?q?=D0=9A=D0=BE=D1=81=D0=BC=D0=B5=D1=82?= =?UTF-8?q?=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0=B8=D0=B5=20=D0=B8=D0=B7=D0=BC?= =?UTF-8?q?=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- css/main.css | 2 +- js/app.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/css/main.css b/css/main.css index 90e8b56..4571955 100644 --- a/css/main.css +++ b/css/main.css @@ -96,7 +96,7 @@ body display: none; width: 100%; - padding: 120px 10px 10px 10px; + padding: 120px 10px 10px; text-align: left; diff --git a/js/app.js b/js/app.js index c86856d..3422132 100644 --- a/js/app.js +++ b/js/app.js @@ -13,8 +13,8 @@ define([ var self = this; $('a[href]').on('click', function(event) { - event.preventDefault(); self.router.navigate($(this).attr('href'), { trigger : true }); + return false; }); }; From 7f71513746ff48b9d00e1d8dde17f019a03f135b Mon Sep 17 00:00:00 2001 From: Anton Zhevak Date: Sat, 16 Nov 2013 20:20:48 +0600 Subject: [PATCH 03/13] =?UTF-8?q?=D0=9A=D0=BE=D1=81=D0=BC=D0=B5=D1=82?= =?UTF-8?q?=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0=B8=D0=B5=20=D0=B8=D0=B7=D0=BC?= =?UTF-8?q?=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- css/main.css | 20 ++++++++++++++++++-- js/router.js | 8 +++----- js/templates/picture/detail.html | 2 +- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/css/main.css b/css/main.css index 4571955..68ebb24 100644 --- a/css/main.css +++ b/css/main.css @@ -37,7 +37,7 @@ body .pictures__items { - margin: -10px -10px 80px; + margin: -10px -10px 100px; padding: 0; list-style: none; @@ -134,9 +134,11 @@ body { position: relative; - display: none; + display: inline-block; overflow: hidden; + width: 100%; + background: #2b2b2b; font: 14px/normal sans-serif; @@ -199,6 +201,18 @@ body margin: 0 0 10px; } +.preview__new-window +{ + display: inline-block; + + width: 16px; + height: 16px; + + vertical-align: text-top; + + background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABbmlDQ1BpY2MAAHjalZC/SwJhHMYftUjSMqqhoeEGaQiFsKWxbBBCRMwgq+XuvNPgTo+7k4jGhlYHl4qWLPoPaov+gSAIqqWWmhsKIgi5nvMEJWroe7z3/fC87/P+eAB/VpN1q28G0Cu2mUslhdXCmjDwiBBGMIwgRkXZMhay2TT+rI87+Nx+G3f3wv8qVFQsGfAFyXOyYdrkeXJmyzZcrpPH5bJYJJ+QYyYvSL5xdcnjF5dLHn+6bOZzi4A/TBZKPSz1sFw2dXKMHNW1mty5j/uSsFJZWWafbA8LOaSQhAAJNWxCg404e4WZ/e5LtH0ZVOmR+TewDZOOEsr0xqjWuKvCrlJX+GlcwXKz/5mppc4mvBPCS0D/s+O8TwMDh0Brz3G+jh2n1QQCD8BVo+uvNhjnK/V6V4seAZFd4Pyyq0mnwAUznngyRFNsSwEOv6oCb2fAUAEYY9aD615enXk074H8DpC+BvYPgCmuj2x8A9UQaDp7qyzEAAAACXBIWXMAAAsSAAALEgHS3X78AAAAHHpUWHRhdXRob3IAAHjac8wryc9TiMpILUvMBgAc2ASK5VXOBwAAAVJJREFUOMutU01Lw0AQTdq6Fj/ILY03D6Jg9ZBzejDaY0CKRugv9JD+C8kPCISSgEjIRTxIE3tITGjjm9LoUpJG0IHHDJmZl5l9u4LwRxObCoqiuIXbq0k/tpoIBoPBSxRFOcIU+OCwskYC27Y9wzD8NE1ZVb6DEclfA72K/CvwFMdxq9vt5lUE5QTUnPGJ6XQ6VxQlzLLsXJKkk3V+F5McwLOqFZgoim6Jfr/vhmG4zxg7Re6TmieTSazruoczafOnTBivIXC4AO4Ag7xlWTeyLCuO4/Q0TbuczWb3q/VrCFiSJCP4UdlMay6XyyvgAfEOcEa1lSpghcVwOHymUTF2ZJqmi+I3fD8C2ohzwF+pUHN5Fij0VFVdBEHwTs11Mne23MAcJD6RbbsnPAHJNN4g2azPeAm/ZSTNNxM1xta1P+dFf8Gox4gPf/kA5+gJhP+yL2Tiz6Ca0DikAAAAAElFTkSuQmCC'); +} + .preview__title { margin: 0 0 15px; @@ -227,6 +241,8 @@ body position: absolute; top: 50%; + display: none; + margin: -30px 0 0; color: #666; diff --git a/js/router.js b/js/router.js index 7698e9d..fc8a1b7 100644 --- a/js/router.js +++ b/js/router.js @@ -7,7 +7,7 @@ define([ return Backbone.Router.extend({ routes : { - '*type' : 'index' + '*type' : 'index' }, index : function(type) { @@ -17,9 +17,7 @@ define([ 'podhistory' : 'Фото дня' }; - if (type === null || types[type] === undefined) { - type = 'top'; - } + types[type] === undefined && (type = 'top'); require([ 'collections/picture', @@ -29,7 +27,7 @@ define([ type : type }); results.fetch({ - dataType: 'jsonp', + dataType : 'jsonp', success : function(collection) { var list = new PictureListView({ collection : collection, diff --git a/js/templates/picture/detail.html b/js/templates/picture/detail.html index 5f09e75..0d7039d 100644 --- a/js/templates/picture/detail.html +++ b/js/templates/picture/detail.html @@ -14,7 +14,7 @@

<%= title %>

<% if (img) { %>
  • - Открыть в разрешении + Открыть в разрешении <% for (var size in img) { %>
  • <% if (img) { %>
  • - Открыть в разрешении + Открыть в разрешении
    +
  • <% } %> diff --git a/js/views/picture/detail.js b/js/views/picture/detail.js index 84dd469..1a3e0c9 100644 --- a/js/views/picture/detail.js +++ b/js/views/picture/detail.js @@ -2,8 +2,9 @@ define([ 'jquery', 'underscore', 'backbone', + 'app', 'text!templates/picture/detail.html' -], function($, _, Backbone, tpl) { +], function($, _, Backbone, App, tpl) { return Backbone.View.extend({ @@ -14,19 +15,18 @@ define([ template : _.template(tpl), initialize: function(options) { - window.app.vent.on('preview:open', this.closePreview, this); - window.app.vent.trigger('preview:open'); + App.vent.on('picture:select', this.close, this); this.render(options.addBefore); }, events : { - 'click .preview__close' : 'closePreview', + 'click .preview__close' : 'close', 'change .preview__sizes' : 'otherImageSize' }, render : function(element) { var $el = this.$el; - $el.html(this.template(this.model.toJSON())); + $el.html(this.template(this.model.toJSON())).css('display', 'none'); // Вставляем превью перед началом строки $(element).before($el); @@ -39,9 +39,8 @@ define([ return this; }, - closePreview : function() { - // Генерируем событие - window.app.vent.trigger('preview:close'); + close : function() { + this.model.trigger('preview:close'); // Сворачиваем и удаляем превью var self = this; diff --git a/js/views/picture/item.js b/js/views/picture/item.js index 6767dde..8d52872 100644 --- a/js/views/picture/item.js +++ b/js/views/picture/item.js @@ -2,9 +2,10 @@ define([ 'jquery', 'underscore', 'backbone', + 'app', 'views/picture/detail', 'text!templates/picture/item.html' -], function($, _, Backbone, PictureDetailView, tpl) { +], function($, _, Backbone, App, PictureDetailView, tpl) { return Backbone.View.extend({ @@ -15,18 +16,16 @@ define([ template : _.template(tpl), initialize: function() { - // При закрытии превью убираем обводку - window.app.vent.on('preview:close', function() { - this.$el.removeClass('picture_active_yes'); - }, this); - + App.vent.on('picture:select', this.disactivate, this); + this.model.on('picture:select', this.showPreview, this); + this.model.on('preview:close', this.disactivate, this); this.render(); }, events : { - 'click .picture__link' : 'showLargerPicture', - 'mouseout .picture__preview' : 'showPictureInfo', - 'mouseover .picture__preview' : 'showPictureInfo', + 'mouseout .picture__preview' : 'hover', + 'mouseover .picture__preview' : 'hover', + 'click .picture__link' : 'selectPicture' }, render : function() { @@ -34,7 +33,15 @@ define([ return this; }, - showLargerPicture : function() { + selectPicture : function() { + if (this.$el.hasClass('picture_active_yes')) { + return; + } + App.vent.trigger('picture:select'); + this.model.trigger('picture:select', this); + }, + + showPreview : function() { var $el = this.$el, $prevEl; @@ -52,16 +59,27 @@ define([ } } - var view = new PictureDetailView({ + new PictureDetailView({ model : this.model, addBefore : $el }); + this.activate(); + }, + + activate : function() { this.$el.addClass('picture_active_yes'); + return this; }, - showPictureInfo : function(event) { + disactivate : function() { + this.$el.removeClass('picture_active_yes'); + return this; + }, + + hover : function() { this.$el.toggleClass('picture_hovered_yes'); + return this; } }); From 26002d3c3f3675959a2dcc38f88a3008a225b33c Mon Sep 17 00:00:00 2001 From: Anton Zhevak Date: Sun, 17 Nov 2013 06:28:44 +0600 Subject: [PATCH 06/13] =?UTF-8?q?=D0=A1=D0=BA=D1=80=D1=8B=D1=82=D0=B8?= =?UTF-8?q?=D0=B5=20=D0=BF=D1=80=D0=B5=D0=B2=D1=8C=D1=8E=20=D0=BF=D0=BE=20?= =?UTF-8?q?ESC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- js/views/picture/detail.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/js/views/picture/detail.js b/js/views/picture/detail.js index 1a3e0c9..f70f0c5 100644 --- a/js/views/picture/detail.js +++ b/js/views/picture/detail.js @@ -15,7 +15,9 @@ define([ template : _.template(tpl), initialize: function(options) { + _.bindAll(this, 'keyPress'); App.vent.on('picture:select', this.close, this); + $(document).on('keydown', this.keyPress); this.render(options.addBefore); }, @@ -42,6 +44,9 @@ define([ close : function() { this.model.trigger('preview:close'); + // Удаляем обработчик + $(document).off('keydown', this.keyPress); + // Сворачиваем и удаляем превью var self = this; this.$el.slideUp('fast', function() { @@ -49,6 +54,12 @@ define([ }); }, + keyPress : function(e) { + if (e.which === 27) { + this.close(); + } + }, + otherImageSize : function(event) { // Получаем данные о выбранном размере var size = $(event.target).val(), From f5d43d6a20f52a3bb081647668203cf396ba94f2 Mon Sep 17 00:00:00 2001 From: Anton Zhevak Date: Sun, 17 Nov 2013 07:17:37 +0600 Subject: [PATCH 07/13] =?UTF-8?q?=D0=9D=D0=B0=D0=B2=D0=B8=D0=B3=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D1=8F=20=D0=B4=D0=B0=D0=BB=D0=B5=D0=B5/=D0=BD?= =?UTF-8?q?=D0=B0=D0=B7=D0=B0=D0=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- css/main.css | 2 -- js/models/picture.js | 16 ++++++++++++++++ js/templates/picture/detail.html | 4 ++-- js/views/picture/detail.js | 32 ++++++++++++++++++++++++++++++-- 4 files changed, 48 insertions(+), 6 deletions(-) diff --git a/css/main.css b/css/main.css index ba24966..f8643e8 100644 --- a/css/main.css +++ b/css/main.css @@ -252,8 +252,6 @@ body position: absolute; top: 50%; - display: none; - margin: -30px 0 0; color: #666; diff --git a/js/models/picture.js b/js/models/picture.js index e82dbf0..5d2ced4 100644 --- a/js/models/picture.js +++ b/js/models/picture.js @@ -8,6 +8,10 @@ define([ return Backbone.Model.extend({ + initialize: function(attributes, options) { + this.collection = options.collection; + }, + parse : function(response, options) { return { id : response.id, @@ -21,6 +25,18 @@ define([ }; }, + index : function() { + return this.collection.indexOf(this); + }, + + next : function() { + return this.collection.at(this.index() + 1) || null; + }, + + prev : function() { + return this.collection.at(this.index() - 1) || null; + }, + }); }); diff --git a/js/templates/picture/detail.html b/js/templates/picture/detail.html index 6369093..e8ceb81 100644 --- a/js/templates/picture/detail.html +++ b/js/templates/picture/detail.html @@ -1,6 +1,6 @@
    - - + + <%= title %>
    diff --git a/js/views/picture/detail.js b/js/views/picture/detail.js index f70f0c5..839bf8e 100644 --- a/js/views/picture/detail.js +++ b/js/views/picture/detail.js @@ -18,11 +18,15 @@ define([ _.bindAll(this, 'keyPress'); App.vent.on('picture:select', this.close, this); $(document).on('keydown', this.keyPress); + this.on('picture:prev', this.showPrev, this); + this.on('picture:next', this.showNext, this); this.render(options.addBefore); }, events : { 'click .preview__close' : 'close', + 'click .preview__next' : 'showNext', + 'click .preview__prev' : 'showPrev', 'change .preview__sizes' : 'otherImageSize' }, @@ -55,11 +59,35 @@ define([ }, keyPress : function(e) { - if (e.which === 27) { - this.close(); + switch(e.which) { + case 27: // esc + this.close(); + break; + case 37: // left + this.trigger('picture:prev'); + break; + case 39: // right + this.trigger('picture:next'); + break; } }, + showNext : function() { + var model = this.model.next(); + if (model === null) + return; + App.vent.trigger('picture:select'); + model.trigger('picture:select', this); + }, + + showPrev : function() { + var model = this.model.prev(); + if (model === null) + return; + App.vent.trigger('picture:select'); + model.trigger('picture:select', this); + }, + otherImageSize : function(event) { // Получаем данные о выбранном размере var size = $(event.target).val(), From d1fdd36f7bef46b21bfa801fcd2bccd58312fc3b Mon Sep 17 00:00:00 2001 From: Anton Zhevak Date: Sun, 17 Nov 2013 07:49:16 +0600 Subject: [PATCH 08/13] =?UTF-8?q?=D0=90=D0=BD=D0=B8=D0=BC=D0=B0=D1=86?= =?UTF-8?q?=D0=B8=D1=8F=20=D0=BD=D0=B0=20=D0=B2=D1=80=D0=B5=D0=BC=D1=8F=20?= =?UTF-8?q?=D0=B7=D0=B0=D0=B3=D1=80=D1=83=D0=B7=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- css/main.css | 107 +++++++++++++++++++++++++++++++++++++++++++++++++-- index.html | 8 +++- js/router.js | 1 + 3 files changed, 112 insertions(+), 4 deletions(-) diff --git a/css/main.css b/css/main.css index f8643e8..fc56424 100644 --- a/css/main.css +++ b/css/main.css @@ -1,14 +1,35 @@ +html, body { - margin: 0 40px; + height: 100%; +} + +body +{ + margin: 0; font: 14px/normal sans-serif; } +#content +{ + height: 100%; + margin: 50px 40px -50px; + + text-align: center; +} + + .tabs { - margin: 10px 0 20px; + position: absolute; + top: 15px; + left: 0; + + display: none; + + margin: 0 40px; padding: 0; list-style: none; @@ -26,6 +47,8 @@ body { margin: 0 0 20px; + text-align: left; + font-size: 40px; font-weight: 400; } @@ -37,7 +60,7 @@ body .pictures__items { - margin: -10px -10px 100px; + margin: -10px -10px 0; padding: 0; list-style: none; @@ -277,3 +300,81 @@ body { left: 0; } + + +.loader-helper +{ + display: inline-block; + + height: 100%; + + content: ""; + vertical-align: middle; +} + + +.loader +{ + display: inline-block; + + margin: -100px 0 0; + + vertical-align: middle; +} + +.loader__circle +{ + display: block; + + width: 100px; + height: 100px; + margin: 20px auto; + + -webkit-animation: spin 1s linear infinite; + -moz-animation: spin 1s linear infinite; + -ms-animation: spin 1s linear infinite; + -o-animation: spin 1s linear infinite; + animation: spin 1s linear infinite; + + border: 20px solid #aaa; + border-right-color: transparent; + border-radius: 50%; + box-shadow: 0 0 25px 2px #eee; +} + +.loader__text +{ + text-align: center; + + color: #333; +} + +@-webkit-keyframes spin +{ + from { -webkit-transform: rotate(0deg); } + to { -webkit-transform: rotate(360deg); } +} + +@-moz-keyframes spin +{ + from { -moz-transform: rotate(0deg); } + to { -moz-transform: rotate(360deg); } +} + +@-ms-keyframes spin +{ + from { -ms-transform: rotate(0deg); } + to { -ms-transform: rotate(360deg); } +} + +@-o-keyframes spin +{ + from { -o-transform: rotate(0deg); } + to { -o-transform: rotate(360deg); } +} + +@keyframes spin +{ + from { transform: rotate(0deg); } + to { transform: rotate(360deg); } +} diff --git a/index.html b/index.html index 8b63815..41553ea 100644 --- a/index.html +++ b/index.html @@ -18,6 +18,12 @@ Фото дня -
    +
    +
    +
    +
    +
    Подождите, идёт загрузка...
    +
    +
    diff --git a/js/router.js b/js/router.js index 5e8f385..2de2439 100644 --- a/js/router.js +++ b/js/router.js @@ -33,6 +33,7 @@ define([ collection.fetch({ dataType : 'jsonp', success : function(collection) { + $('.tabs').show(); new PictureListView({ collection : collection, title : types[type] From 11506e36489cd1cf99d152bad8f740e7792f49a3 Mon Sep 17 00:00:00 2001 From: Anton Zhevak Date: Sun, 17 Nov 2013 17:09:51 +0600 Subject: [PATCH 09/13] =?UTF-8?q?=D0=9A=D0=BE=D1=81=D0=BC=D0=B5=D1=82?= =?UTF-8?q?=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0=B8=D0=B5=20=D0=B8=D0=B7=D0=BC?= =?UTF-8?q?=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=B2=20CSS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- css/main.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/css/main.css b/css/main.css index fc56424..b6b7f92 100644 --- a/css/main.css +++ b/css/main.css @@ -198,7 +198,7 @@ body .preview__slider { - margin: 10px 330px 10px 10px; + margin: 10px 330px 10px; text-align: center; } @@ -244,7 +244,7 @@ body vertical-align: text-top; - background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABbmlDQ1BpY2MAAHjalZC/SwJhHMYftUjSMqqhoeEGaQiFsKWxbBBCRMwgq+XuvNPgTo+7k4jGhlYHl4qWLPoPaov+gSAIqqWWmhsKIgi5nvMEJWroe7z3/fC87/P+eAB/VpN1q28G0Cu2mUslhdXCmjDwiBBGMIwgRkXZMhay2TT+rI87+Nx+G3f3wv8qVFQsGfAFyXOyYdrkeXJmyzZcrpPH5bJYJJ+QYyYvSL5xdcnjF5dLHn+6bOZzi4A/TBZKPSz1sFw2dXKMHNW1mty5j/uSsFJZWWafbA8LOaSQhAAJNWxCg404e4WZ/e5LtH0ZVOmR+TewDZOOEsr0xqjWuKvCrlJX+GlcwXKz/5mppc4mvBPCS0D/s+O8TwMDh0Brz3G+jh2n1QQCD8BVo+uvNhjnK/V6V4seAZFd4Pyyq0mnwAUznngyRFNsSwEOv6oCb2fAUAEYY9aD615enXk074H8DpC+BvYPgCmuj2x8A9UQaDp7qyzEAAAACXBIWXMAAAsSAAALEgHS3X78AAAAHHpUWHRhdXRob3IAAHjac8wryc9TiMpILUvMBgAc2ASK5VXOBwAAAVJJREFUOMutU01Lw0AQTdq6Fj/ILY03D6Jg9ZBzejDaY0CKRugv9JD+C8kPCISSgEjIRTxIE3tITGjjm9LoUpJG0IHHDJmZl5l9u4LwRxObCoqiuIXbq0k/tpoIBoPBSxRFOcIU+OCwskYC27Y9wzD8NE1ZVb6DEclfA72K/CvwFMdxq9vt5lUE5QTUnPGJ6XQ6VxQlzLLsXJKkk3V+F5McwLOqFZgoim6Jfr/vhmG4zxg7Re6TmieTSazruoczafOnTBivIXC4AO4Ag7xlWTeyLCuO4/Q0TbuczWb3q/VrCFiSJCP4UdlMay6XyyvgAfEOcEa1lSpghcVwOHymUTF2ZJqmi+I3fD8C2ohzwF+pUHN5Fij0VFVdBEHwTs11Mne23MAcJD6RbbsnPAHJNN4g2azPeAm/ZSTNNxM1xta1P+dFf8Gox4gPf/kA5+gJhP+yL2Tiz6Ca0DikAAAAAElFTkSuQmCC'); + background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABbmlDQ1BpY2MAAHjalZC/SwJhHMYftUjSMqqhoeEGaQiFsKWxbBBCRMwgq+XuvNPgTo+7k4jGhlYHl4qWLPoPaov+gSAIqqWWmhsKIgi5nvMEJWroe7z3/fC87/P+eAB/VpN1q28G0Cu2mUslhdXCmjDwiBBGMIwgRkXZMhay2TT+rI87+Nx+G3f3wv8qVFQsGfAFyXOyYdrkeXJmyzZcrpPH5bJYJJ+QYyYvSL5xdcnjF5dLHn+6bOZzi4A/TBZKPSz1sFw2dXKMHNW1mty5j/uSsFJZWWafbA8LOaSQhAAJNWxCg404e4WZ/e5LtH0ZVOmR+TewDZOOEsr0xqjWuKvCrlJX+GlcwXKz/5mppc4mvBPCS0D/s+O8TwMDh0Brz3G+jh2n1QQCD8BVo+uvNhjnK/V6V4seAZFd4Pyyq0mnwAUznngyRFNsSwEOv6oCb2fAUAEYY9aD615enXk074H8DpC+BvYPgCmuj2x8A9UQaDp7qyzEAAAACXBIWXMAAAsSAAALEgHS3X78AAAAHHpUWHRhdXRob3IAAHjac8wryc9TiMpILUvMBgAc2ASK5VXOBwAAAVJJREFUOMutU01Lw0AQTdq6Fj/ILY03D6Jg9ZBzejDaY0CKRugv9JD+C8kPCISSgEjIRTxIE3tITGjjm9LoUpJG0IHHDJmZl5l9u4LwRxObCoqiuIXbq0k/tpoIBoPBSxRFOcIU+OCwskYC27Y9wzD8NE1ZVb6DEclfA72K/CvwFMdxq9vt5lUE5QTUnPGJ6XQ6VxQlzLLsXJKkk3V+F5McwLOqFZgoim6Jfr/vhmG4zxg7Re6TmieTSazruoczafOnTBivIXC4AO4Ag7xlWTeyLCuO4/Q0TbuczWb3q/VrCFiSJCP4UdlMay6XyyvgAfEOcEa1lSpghcVwOHymUTF2ZJqmi+I3fD8C2ohzwF+pUHN5Fij0VFVdBEHwTs11Mne23MAcJD6RbbsnPAHJNN4g2azPeAm/ZSTNNxM1xta1P+dFf8Gox4gPf/kA5+gJhP+yL2Tiz6Ca0DikAAAAAElFTkSuQmCC); } .preview__title From 241440886ba8613493dff9d9661fe374823f82cf Mon Sep 17 00:00:00 2001 From: Anton Zhevak Date: Sun, 17 Nov 2013 17:27:05 +0600 Subject: [PATCH 10/13] small css fix --- css/main.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/css/main.css b/css/main.css index b6b7f92..55d7357 100644 --- a/css/main.css +++ b/css/main.css @@ -198,7 +198,7 @@ body .preview__slider { - margin: 10px 330px 10px; + margin: 10px 330px 10px 10px; text-align: center; } From a83b56cd1678e6b633d6420b64cfdb987363ff10 Mon Sep 17 00:00:00 2001 From: Anton Zhevak Date: Sun, 17 Nov 2013 19:05:57 +0600 Subject: [PATCH 11/13] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B7=D0=B0=D0=BC=D0=B5=D1=87?= =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- css/main.css | 2 +- js/main.js | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/css/main.css b/css/main.css index 55d7357..1026fd7 100644 --- a/css/main.css +++ b/css/main.css @@ -8,7 +8,7 @@ body { margin: 0; - font: 14px/normal sans-serif; + font: 14px/1.2 sans-serif; } diff --git a/js/main.js b/js/main.js index 0d901b0..57bb42b 100644 --- a/js/main.js +++ b/js/main.js @@ -17,9 +17,8 @@ requirejs.config({ }); require([ - 'backbone', 'app' -], function(Backbone, App) { +], function(App) { App.initialize(); From e6ce43c46558861e5a9429d6b92bd2c5ee01621b Mon Sep 17 00:00:00 2001 From: Anton Zhevak Date: Mon, 18 Nov 2013 06:58:57 +0600 Subject: [PATCH 12/13] =?UTF-8?q?=D0=9A=D0=BE=D1=81=D0=BC=D0=B5=D1=82?= =?UTF-8?q?=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0=B8=D0=B5=20=D0=B8=D0=B7=D0=BC?= =?UTF-8?q?=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- css/main.css | 6 +++--- index.html | 14 +++++++------- js/app.js | 2 +- js/collections/picture.js | 2 +- js/helpers/helper.js | 25 +++++++++++++++++++++---- js/models/picture.js | 2 +- js/router.js | 4 ++-- js/views/picture/list.js | 2 +- 8 files changed, 37 insertions(+), 20 deletions(-) diff --git a/css/main.css b/css/main.css index 1026fd7..19f7cc8 100644 --- a/css/main.css +++ b/css/main.css @@ -21,7 +21,7 @@ body } -.tabs +.menu { position: absolute; top: 15px; @@ -35,7 +35,7 @@ body list-style: none; } -.tabs__tab +.menu__item { display: inline; @@ -169,7 +169,7 @@ body background: #2b2b2b; - font: 14px/normal sans-serif; + font: 14px/1.2 sans-serif; } .preview__close diff --git a/index.html b/index.html index 41553ea..ba5781a 100644 --- a/index.html +++ b/index.html @@ -7,15 +7,15 @@ -
      -
    • - Популярные фотографии +
      diff --git a/js/app.js b/js/app.js index 53bc5ac..bc4f1ad 100644 --- a/js/app.js +++ b/js/app.js @@ -8,7 +8,7 @@ define([ return { initialize : function() { - this.router = new Router; + this.router = new Router(); this.vent = _.extend({}, Backbone.Events); var self = this; diff --git a/js/collections/picture.js b/js/collections/picture.js index 95dcda5..c8b60e6 100644 --- a/js/collections/picture.js +++ b/js/collections/picture.js @@ -17,7 +17,7 @@ define([ parse : function(response) { return response.entries; - }, + } }); diff --git a/js/helpers/helper.js b/js/helpers/helper.js index b3f4934..ab5040d 100644 --- a/js/helpers/helper.js +++ b/js/helpers/helper.js @@ -1,5 +1,20 @@ define(function() { + var months = [ + 'января', + 'февраля', + 'марта', + 'апреля', + 'мая', + 'июня', + 'июля', + 'августа', + 'сентября', + 'октября', + 'ноября', + 'декабря' + ]; + return { leadZero : function(num) { @@ -9,10 +24,12 @@ define(function() { formatDate : function(date) { date = new Date(date); return date.getDate() + ' ' + - ('января,февраля,марта,апреля,мая,июня,июля,августа,сентября,октября,ноября,декабря'.split(',')[date.getMonth()]) + ' ' + - date.getFullYear() + ' в ' + this.leadZero(date.getHours()) + ':' + this.leadZero(date.getMinutes()); + months[date.getMonth()] + ' ' + + date.getFullYear() + ' в ' + + this.leadZero(date.getHours()) + ':' + + this.leadZero(date.getMinutes()); } - } + }; -}); \ No newline at end of file +}); diff --git a/js/models/picture.js b/js/models/picture.js index 5d2ced4..ba95c76 100644 --- a/js/models/picture.js +++ b/js/models/picture.js @@ -35,7 +35,7 @@ define([ prev : function() { return this.collection.at(this.index() - 1) || null; - }, + } }); diff --git a/js/router.js b/js/router.js index 2de2439..19bac10 100644 --- a/js/router.js +++ b/js/router.js @@ -33,7 +33,7 @@ define([ collection.fetch({ dataType : 'jsonp', success : function(collection) { - $('.tabs').show(); + $('.menu').show(); new PictureListView({ collection : collection, title : types[type] @@ -41,7 +41,7 @@ define([ } }); }); - }, + } }); diff --git a/js/views/picture/list.js b/js/views/picture/list.js index 5af7330..37643a5 100644 --- a/js/views/picture/list.js +++ b/js/views/picture/list.js @@ -26,7 +26,7 @@ define([ addOne : function(picture) { var view = new PictureItemView({ model : picture }); this.$('.pictures__items').append('\n').append(view.render().el); - }, + } }); From f2258546229097d144445e5b9c765bcbe079a289 Mon Sep 17 00:00:00 2001 From: Anton Zhevak Date: Tue, 26 Nov 2013 07:34:39 +0600 Subject: [PATCH 13/13] =?UTF-8?q?fix:=20=D1=80=D0=B0=D0=B7=D0=B1=D1=83?= =?UTF-8?q?=D1=85=D0=B0=D0=BD=D0=B8=D0=B5=20App.vent.=5Fevents?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- js/views/picture/detail.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/js/views/picture/detail.js b/js/views/picture/detail.js index 839bf8e..93ad3fa 100644 --- a/js/views/picture/detail.js +++ b/js/views/picture/detail.js @@ -48,8 +48,9 @@ define([ close : function() { this.model.trigger('preview:close'); - // Удаляем обработчик + // Удаляем обработчики $(document).off('keydown', this.keyPress); + App.vent.off('picture:select', this.close); // Сворачиваем и удаляем превью var self = this;