jekyll-theme-ricky 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/assets/img/a.jpg ADDED
Binary file
Binary file
data/assets/img/b.jpg ADDED
Binary file
data/assets/img/c.jpg ADDED
Binary file
data/assets/img/d.jpg ADDED
Binary file
data/assets/img/e.jpg ADDED
Binary file
data/assets/img/f.jpg ADDED
Binary file
Binary file
@@ -0,0 +1,277 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Card.
5
+ */
6
+ var Card = (function (window) {
7
+
8
+ /**
9
+ * Enum of CSS selectors.
10
+ */
11
+ var SELECTORS = {
12
+ container: '.card__container',
13
+ content: '.card__content',
14
+ clip: '.clip'
15
+ };
16
+
17
+ /**
18
+ * Enum of CSS classes.
19
+ */
20
+ var CLASSES = {
21
+ containerClosed: 'card__container--closed',
22
+ bodyHidden: 'body--hidden'
23
+ };
24
+
25
+ /**
26
+ * Card.
27
+ */
28
+ var Card = function (id, el) {
29
+
30
+ this.id = id;
31
+
32
+ this._el = el;
33
+
34
+ // Get elements.
35
+ this._container = $(this._el).find(SELECTORS.container)[0];
36
+ this._clip = $(this._el).find(SELECTORS.clip)[0];
37
+ this._content = $(this._el).find(SELECTORS.content)[0];
38
+
39
+ this.isOpen = false;
40
+
41
+ this._TL = null;
42
+ };
43
+
44
+ /**
45
+ * Open card.
46
+ * @param {Function} callback The callback `onCardMove`.
47
+ */
48
+ Card.prototype.openCard = function (callback) {
49
+
50
+ this._TL = new TimelineLite;
51
+
52
+ var slideContentDown = this._slideContentDown();
53
+ var clipImageIn = this._clipImageIn();
54
+ var floatContainer = this._floatContainer(callback);
55
+ var clipImageOut = this._clipImageOut();
56
+ var slideContentUp = this._slideContentUp();
57
+
58
+ // Compose sequence and use duration to overlap tweens.
59
+ this._TL.add(slideContentDown);
60
+ this._TL.add(clipImageIn, 0);
61
+ this._TL.add(floatContainer, '-=' + clipImageIn.duration() * 0.6);
62
+ // this._TL.add(clipImageOut, '-=' + floatContainer.duration() * 0.3);
63
+ this._TL.add(slideContentUp/*, '-=' + clipImageOut.duration() * 0.6*/);
64
+
65
+ this.isOpen = true;
66
+
67
+ return this._TL;
68
+ };
69
+
70
+ /**
71
+ * Slide content down.
72
+ * @private
73
+ */
74
+ Card.prototype._slideContentDown = function () {
75
+
76
+ var tween = TweenLite.to(this._content, 0.8, {
77
+ y: window.innerHeight,
78
+ ease: Expo.easeInOut
79
+ });
80
+
81
+ return tween;
82
+ };
83
+
84
+ /**
85
+ * Clip image in.
86
+ * @private
87
+ */
88
+ Card.prototype._clipImageIn = function () {
89
+
90
+ // Polygon.
91
+ var TL = new TimelineLite;
92
+
93
+ var start = [
94
+ [0, 1200],
95
+ [0, 0],
96
+ [1920, 0],
97
+ [1920, 1200]
98
+ ];
99
+
100
+ var end = [
101
+ [916, 430],
102
+ [1125, 643],
103
+ [960, 607],
104
+ [793, 570]
105
+ ];
106
+
107
+ var points = [];
108
+
109
+ // Create a tween for each point.
110
+ start.forEach(function (point, i) {
111
+
112
+ var tween = TweenLite.to(point, 1.5, end[i]);
113
+
114
+ end[i].onUpdate = function () {
115
+
116
+ points.push(point.join());
117
+
118
+ // Every 4 point update clip-path.
119
+ if (points.length === end.length) {
120
+ $(this._clip).attr('points', points.join(' '));
121
+ // Reset.
122
+ points = [];
123
+ }
124
+
125
+ }.bind(this);
126
+
127
+ tween.vars.ease = Expo.easeInOut;
128
+
129
+ // Add at position 0.
130
+ TL.add(tween, 0);
131
+
132
+ }, this);
133
+
134
+ return TL;
135
+ };
136
+
137
+ /**
138
+ * Float card to final position.
139
+ * @param {Function} callback The callback `onCardMove`.
140
+ * @private
141
+ */
142
+ Card.prototype._floatContainer = function (callback) {
143
+
144
+ $(document.body).addClass(CLASSES.bodyHidden);
145
+
146
+ var TL = new TimelineLite;
147
+
148
+ var rect = this._container.getBoundingClientRect();
149
+ var windowW = window.innerWidth;
150
+
151
+ var track = {
152
+ width: 0,
153
+ x: rect.left + (rect.width / 2),
154
+ y: rect.top + (rect.height / 2)
155
+ };
156
+
157
+ TL.set(this._container, {
158
+ width: rect.width,
159
+ height: rect.height,
160
+ x: rect.left,
161
+ y: rect.top,
162
+ position: 'fixed',
163
+ overflow: 'hidden'
164
+ });
165
+
166
+ TL.to([this._container, track], 2, {
167
+ width: windowW,
168
+ height: '100%',
169
+ x: windowW / 2,
170
+ y: 0,
171
+ xPercent: -50,
172
+ ease: Expo.easeInOut,
173
+ clearProps: 'all',
174
+ className: '-=' + CLASSES.containerClosed,
175
+ onUpdate: callback.bind(this, track),
176
+ // Fix IE: if the image is set to fixed when CLASSES.containerClosed
177
+ // is removed IE doesn't follow the tween, fix by setting
178
+ // the image position to fixed when tween is completed.
179
+ onComplete: function () {
180
+ $(this._container).addClass('card__container--fix-image');
181
+ }.bind(this)
182
+ });
183
+
184
+ return TL;
185
+ };
186
+
187
+ /**
188
+ * Clip image out.
189
+ * @private
190
+ */
191
+ Card.prototype._clipImageOut = function () {
192
+
193
+ var tween = this._clipImageIn();
194
+
195
+ tween.reverse();
196
+
197
+ return tween;
198
+ };
199
+
200
+ /**
201
+ * Slide content up.
202
+ * @private
203
+ */
204
+ Card.prototype._slideContentUp = function () {
205
+
206
+ var tween = TweenLite.to(this._content, 1, {
207
+ y: 0,
208
+ clearProps: 'all',
209
+ ease: Expo.easeInOut
210
+ });
211
+
212
+ return tween;
213
+ };
214
+
215
+ /**
216
+ * Close card.
217
+ */
218
+ Card.prototype.closeCard = function () {
219
+
220
+ TweenLite.to(this._container, 0.4, {
221
+ scrollTo: {
222
+ y: 0
223
+ },
224
+ onComplete: function () {
225
+ $(this._container).css('overflow', 'hidden');
226
+ }.bind(this),
227
+ ease: Power2.easeOut
228
+ });
229
+
230
+ this._TL.eventCallback('onReverseComplete', function () {
231
+
232
+ TweenLite.set([this._container, this._content], {
233
+ clearProps: 'all'
234
+ });
235
+
236
+ $(document.body).removeClass(CLASSES.bodyHidden);
237
+
238
+ this.isOpen = false;
239
+
240
+ }.bind(this));
241
+
242
+ return this._TL.reverse();
243
+ };
244
+
245
+ /**
246
+ * Hide card, called for all cards except the selected one.
247
+ */
248
+ Card.prototype.hideCard = function () {
249
+
250
+ var tween = TweenLite.to(this._el, 0.4, {
251
+ scale: 0.8,
252
+ autoAlpha: 0,
253
+ transformOrigin: 'center bottom',
254
+ ease: Expo.easeInOut
255
+ });
256
+
257
+ return tween;
258
+ };
259
+
260
+ /**
261
+ * Show card, called for all cards except the selected one.
262
+ */
263
+ Card.prototype.showCard = function () {
264
+
265
+ var tween = TweenLite.to(this._el, 0.5, {
266
+ scale: 1,
267
+ autoAlpha: 1,
268
+ clearProps: 'all',
269
+ ease: Expo.easeInOut
270
+ });
271
+
272
+ return tween;
273
+ };
274
+
275
+ return Card;
276
+
277
+ })(window);
@@ -0,0 +1,309 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Demo.
5
+ */
6
+ var demo = (function (window) {
7
+
8
+ /**
9
+ * Enum of CSS selectors.
10
+ */
11
+ var SELECTORS = {
12
+ pattern: '.pattern',
13
+ card: '.card',
14
+ cardImage: '.card__image',
15
+ cardClose: '.card__btn-close'
16
+ };
17
+
18
+ /**
19
+ * Enum of CSS classes.
20
+ */
21
+ var CLASSES = {
22
+ patternHidden: 'pattern--hidden',
23
+ polygon: 'polygon',
24
+ polygonHidden: 'polygon--hidden'
25
+ };
26
+
27
+ var ATTRIBUTES = {
28
+ index: 'data-index',
29
+ id: 'data-id'
30
+ };
31
+
32
+ /**
33
+ * Map of svg paths and points.
34
+ */
35
+ var polygonMap = {
36
+ paths: null,
37
+ points: null
38
+ };
39
+
40
+ /**
41
+ * Container of Card instances.
42
+ */
43
+ var layout = {};
44
+
45
+ /**
46
+ * Initialise demo.
47
+ */
48
+ var init = function () {
49
+
50
+ // For options see: https://github.com/qrohlf/Trianglify
51
+ var pattern = Trianglify({
52
+ width: window.innerWidth,
53
+ height: window.innerHeight,
54
+ cell_size: 90,
55
+ variance: 1,
56
+ stroke_width: 1,
57
+ x_colors: 'random',
58
+ y_colors: 'random'
59
+ }).svg(); // Render as SVG.
60
+
61
+ _mapPolygons(pattern);
62
+
63
+ _bindCards();
64
+
65
+ _bindHashChange();
66
+
67
+ _triggerOpenCard('', _getHashFromURL(location.href));
68
+ };
69
+
70
+ /**
71
+ * Store path elements, map coordinates and sizes.
72
+ * @param {Element} pattern The SVG Element generated with Trianglify.
73
+ * @private
74
+ */
75
+ var _mapPolygons = function (pattern) {
76
+
77
+ // Append SVG to pattern container.
78
+ $(SELECTORS.pattern).append(pattern);
79
+
80
+ // Convert nodelist to array,
81
+ // Used `.childNodes` because IE doesn't support `.children` on SVG.
82
+ polygonMap.paths = [].slice.call(pattern.childNodes);
83
+
84
+ polygonMap.points = [];
85
+
86
+ polygonMap.paths.forEach(function (polygon) {
87
+
88
+ // Hide polygons by adding CSS classes to each svg path (used attrs because of IE).
89
+ $(polygon).attr('class', CLASSES.polygon);
90
+
91
+ var rect = polygon.getBoundingClientRect();
92
+
93
+ var point = {
94
+ x: rect.left + rect.width / 2,
95
+ y: rect.top + rect.height / 2
96
+ };
97
+
98
+ polygonMap.points.push(point);
99
+ });
100
+
101
+ // All polygons are hidden now, display the pattern container.
102
+ $(SELECTORS.pattern).removeClass(CLASSES.patternHidden);
103
+ };
104
+
105
+ /**
106
+ * Bind Card elements.
107
+ * @private
108
+ */
109
+ var _bindCards = function () {
110
+
111
+ var elements = $(SELECTORS.card);
112
+
113
+ $.each(elements, function (card, i) {
114
+
115
+ var instance = new Card(i, card);
116
+
117
+ layout[i] = {
118
+ card: instance
119
+ };
120
+
121
+ var $card = $(card);
122
+ $card.attr(ATTRIBUTES.index, i + '');
123
+
124
+ var cardImage = $card.find(SELECTORS.cardImage);
125
+ var cardClose = $card.find(SELECTORS.cardClose);
126
+
127
+ $(cardImage).on('click', function () {
128
+ location.hash = $card.attr(ATTRIBUTES.id);
129
+ });
130
+ $(cardClose).on('click', function () {
131
+ location.hash = '';
132
+ });
133
+ });
134
+ };
135
+
136
+ /**
137
+ * Create a sequence for the open or close animation and play.
138
+ * @param {boolean} isOpenClick Flag to detect when it's a click to open.
139
+ * @param {number} id The id of the clicked card.
140
+ * @private
141
+ *
142
+ */
143
+ var _playSequence = function (isOpenClick, id) {
144
+
145
+ var card = layout[id].card;
146
+
147
+ // Prevent when card already open and user click on image.
148
+ if (card.isOpen && isOpenClick) {
149
+ return;
150
+ }
151
+
152
+ // Create timeline for the whole sequence.
153
+ var sequence = new TimelineLite({paused: true});
154
+
155
+ var tweenOtherCards = _showHideOtherCards(id);
156
+
157
+ if (!card.isOpen) {
158
+ // Open sequence.
159
+
160
+ _setPatternBgImg($(this).find(SELECTORS.cardImage).find('image'));
161
+
162
+ sequence.add(tweenOtherCards);
163
+ sequence.add(card.openCard(_onCardMove), 0);
164
+
165
+ } else {
166
+ // Close sequence.
167
+
168
+ var closeCard = card.closeCard();
169
+ var position = closeCard.duration() * 0.8; // 80% of close card tween.
170
+
171
+ sequence.add(closeCard);
172
+ sequence.add(tweenOtherCards, position);
173
+ }
174
+
175
+ sequence.play();
176
+ };
177
+
178
+ /**
179
+ * Show/Hide all other cards.
180
+ * @param {number} id The id of the clcked card to be avoided.
181
+ * @private
182
+ */
183
+ var _showHideOtherCards = function (id) {
184
+
185
+ var TL = new TimelineLite;
186
+
187
+ var selectedCard = layout[id].card;
188
+
189
+ for (var i in layout) {
190
+
191
+ if (layout.hasOwnProperty(i)) {
192
+ var card = layout[i].card;
193
+
194
+ // When called with `openCard`.
195
+ if (card.id !== id && !selectedCard.isOpen) {
196
+ TL.add(card.hideCard(), 0);
197
+ }
198
+
199
+ // When called with `closeCard`.
200
+ if (card.id !== id && selectedCard.isOpen) {
201
+ TL.add(card.showCard(), 0);
202
+ }
203
+ }
204
+ }
205
+
206
+ return TL;
207
+ };
208
+
209
+ /**
210
+ * Add card image to pattern background.
211
+ * @param {Element} image The clicked SVG Image Element.
212
+ * @private
213
+ */
214
+ var _setPatternBgImg = function (image) {
215
+
216
+ var imagePath = $(image).attr('xlink:href');
217
+
218
+ $(SELECTORS.pattern).css('background-image', 'url(' + imagePath + ')');
219
+ };
220
+
221
+ /**
222
+ * Callback to be executed on Tween update, whatever a polygon
223
+ * falls into a circular area defined by the card width the path's
224
+ * CSS class will change accordingly.
225
+ * @param {Object} track The card sizes and position during the floating.
226
+ * @private
227
+ */
228
+ var _onCardMove = function (track) {
229
+
230
+ var radius = track.width / 2;
231
+
232
+ var center = {
233
+ x: track.x,
234
+ y: track.y
235
+ };
236
+
237
+ polygonMap.points.forEach(function (point, i) {
238
+
239
+ if (_detectPointInCircle(point, radius, center)) {
240
+ $(polygonMap.paths[i]).attr('class', CLASSES.polygon + ' ' + CLASSES.polygonHidden);
241
+ } else {
242
+ $(polygonMap.paths[i]).attr('class', CLASSES.polygon);
243
+ }
244
+ });
245
+ };
246
+
247
+ /**
248
+ * Detect if a point is inside a circle area.
249
+ * @private
250
+ */
251
+ var _detectPointInCircle = function (point, radius, center) {
252
+
253
+ var xp = point.x;
254
+ var yp = point.y;
255
+
256
+ var xc = center.x;
257
+ var yc = center.y;
258
+
259
+ var d = radius * radius;
260
+
261
+ return Math.pow(xp - xc, 2) + Math.pow(yp - yc, 2) <= d;
262
+ };
263
+
264
+ /**
265
+ * initialize page view according to hash
266
+ * @private
267
+ */
268
+ var _triggerOpenCard = function (fromId, toId) {
269
+ var getIndex = function (card) {
270
+ var index = $(card).attr(ATTRIBUTES.index);
271
+ return parseInt(index, 10);
272
+ };
273
+ if (fromId) {
274
+ var fromBlogCard = $('[' + ATTRIBUTES.id + '="' + fromId + '"]')[0];
275
+ if (fromBlogCard) {
276
+ _playSequence.call(fromBlogCard, false, getIndex(fromBlogCard));
277
+ }
278
+ }
279
+ if (toId) {
280
+ var toBlogCard = $('[' + ATTRIBUTES.id + '="' + toId + '"]')[0];
281
+ if (toBlogCard) {
282
+ _playSequence.call(toBlogCard, true, getIndex(toBlogCard));
283
+ }
284
+ }
285
+ };
286
+
287
+ var _getHashFromURL = function (url) {
288
+ var a = document.createElement('a');
289
+ a.href = url;
290
+ return a.hash.slice(1);
291
+ };
292
+
293
+ var _bindHashChange = function () {
294
+ window.addEventListener('hashchange', function (e) {
295
+ var newHash = _getHashFromURL(e.newURL);
296
+ var oldHash = _getHashFromURL(e.oldURL);
297
+ _triggerOpenCard(oldHash, newHash);
298
+ });
299
+ };
300
+
301
+ // Expose methods.
302
+ return {
303
+ init: init
304
+ };
305
+
306
+ })(window);
307
+
308
+ // Kickstart Demo.
309
+ window.onload = demo.init;