Skip to content

Commit e8db940

Browse files
authored
Merge pull request #31 from nemtsov/feature/slide_caption
Refactor and add cross-fade animations
2 parents 491d5d0 + 0ce519d commit e8db940

File tree

11 files changed

+128
-80
lines changed

11 files changed

+128
-80
lines changed

Diff for: examples/simple/index.html

+27-31
Original file line numberDiff line numberDiff line change
@@ -8,42 +8,38 @@
88
</head>
99
<body>
1010
<div class="project">
11-
<div class="project-slide" data-picture='{
12-
"img": { "src": "http://placehold.it/250x150" },
13-
"sources": [{
14-
"srcset": "http://placehold.it/550x450",
15-
"media_query": "(min-width: 1px)"
16-
}]
17-
}'>
18-
<img alt="first" width="350" height="150"
19-
src="http://placehold.it/350x150" />
11+
<div class="project-slide">
12+
<script type="text/html" class="js-lightbox-slide-content">
13+
<picture>
14+
<source srcset="http://placehold.it/700x300" media="(min-width: 1px)">
15+
<img src="http://placehold.it/250x150">
16+
</picture>
17+
</script>
18+
<img alt="first" width="350" height="150" src="http://placehold.it/350x150">
2019
</div>
2120

22-
<div class="project-slide" data-picture='{
23-
"img": { "src": "http://placehold.it/250x160" },
24-
"sources": [{
25-
"srcset": "http://placehold.it/550x460",
26-
"media_query": "(min-width: 1px)"
27-
}]
28-
}'>
29-
<img alt="second" width="350" height="160"
30-
src="http://placehold.it/350x160" />
31-
</div>
21+
<img class="project-slide" alt="second"
22+
width="350" height="160"
23+
src="http://placehold.it/350x160"
24+
data-src="http://placehold.it/700x320" />
3225

33-
<div class="project-slide" data-picture='{
34-
"img": { "src": "http://placehold.it/250x170" },
35-
"sources": [{
36-
"srcset": "http://placehold.it/550x470",
37-
"media_query": "(min-width: 1px)"
38-
}]
39-
}'>
40-
<img alt="third" width="350" height="170"
41-
src="http://placehold.it/350x170" />
26+
<div class="project-slide">
27+
<script type="text/html" class="js-lightbox-slide-content">
28+
<picture>
29+
<source srcset="http://placehold.it/700x340" media="(min-width: 1px)">
30+
<img src="http://placehold.it/260x170">
31+
</picture>
32+
</script>
33+
<img alt="third" width="350" height="170" src="http://placehold.it/350x170" />
4234
</div>
4335

44-
<script type="text/template" class="project-slide" data-contains-slide-content="true">
45-
<iframe width="560" height="315" src="https://www.youtube.com/embed/oHg5SJYRHA0" frameborder="0" allowfullscreen></iframe>
46-
</script>
36+
<div class="project-slide">
37+
<script type="text/html" class="js-lightbox-slide-content">
38+
<iframe width="560" height="315"
39+
src="https://www.youtube.com/embed/oHg5SJYRHA0"
40+
frameborder="0" allowfullscreen></iframe>
41+
</script>
42+
</div>
4743
</div>
4844
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
4945
<script src="/bundle.js"></script>

Diff for: package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "lightbox",
3-
"version": "4.2.0",
3+
"version": "5.0.0",
44
"description": "Image lightbox",
55
"main": "src",
66
"scripts": {

Diff for: sass/lightbox.scss

+29-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@ $button-padding: 40px;
66
#{$property}: calc(#{$params}) #{$important};
77
}
88

9+
html.lightbox-enabled {
10+
11+
&,
12+
body {
13+
overflow: hidden;
14+
}
15+
16+
} // html.lightbox-enabled
17+
918
.lightbox-link {
1019
cursor: pointer;
1120
}
@@ -17,6 +26,26 @@ $button-padding: 40px;
1726
user-select: none;
1827
}
1928

29+
.lightbox-content {
30+
31+
align-items: center;
32+
display: flex;
33+
height: 100vh;
34+
justify-content: center;
35+
left: 0;
36+
opacity: 1;
37+
position: fixed;
38+
top: 0;
39+
transition: .2s;
40+
width: 100vw;
41+
42+
&.hidden {
43+
opacity: 0;
44+
}
45+
46+
} // .lightbox-content
47+
48+
2049
#lightbox-blocking {
2150
bottom: 0;
2251
left: 0;
@@ -32,7 +61,6 @@ $button-padding: 40px;
3261
height: 100%;
3362
left: 0;
3463
position: fixed;
35-
text-align: center;
3664
top: 0;
3765
width: 100%;
3866
z-index: 1001;

Diff for: src/ChromeView.js

+18-19
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import 'style!../sass/lightbox.scss';
12
import $ from 'jquery';
23
import idleTimer from 'idle-timer';
34
import tinycolor from 'tinycolor2';
@@ -7,6 +8,8 @@ const ESCAPE_KEYCODE = 27;
78
const LEFT_ARROW_KEYCODE = 37;
89
const RIGHT_ARROW_KEYCODE = 39;
910
const EXTRAS_HIDDEN_CLASS = 'extras-hidden';
11+
const CONTENT_CLASS = 'lightbox-content';
12+
const ENABLED_CLASS = 'lightbox-enabled';
1013
const HIDDEN_CLASS = 'hidden';
1114

1215
export default class ChromeView {
@@ -54,6 +57,8 @@ export default class ChromeView {
5457
}
5558
});
5659

60+
$('html').addClass(ENABLED_CLASS);
61+
5762
this._$view
5863
.find('.js-blocking')
5964
.css({
@@ -73,7 +78,15 @@ export default class ChromeView {
7378

7479
renderSlide(slide) {
7580
this._maybeHidePrevNext(slide);
76-
this._$contents.html(this._getSlideContent(slide));
81+
82+
const $next = $(`<div class="${CONTENT_CLASS} ${HIDDEN_CLASS}">`);
83+
$next.html(this._getSlideContent(slide));
84+
85+
this._$contents.find(`.${HIDDEN_CLASS}`).remove();
86+
this._$contents.append($next);
87+
88+
this._$contents.find(`.${CONTENT_CLASS}:lt(1)`).addClass(HIDDEN_CLASS);
89+
setTimeout(() => $next.removeClass(HIDDEN_CLASS), 0);
7790
}
7891

7992
destroy() {
@@ -83,6 +96,8 @@ export default class ChromeView {
8396
.add(this._$context)
8497
.off('.lightbox');
8598

99+
$('html').removeClass(ENABLED_CLASS);
100+
86101
if (this._idleTimer) {
87102
this._idleTimer.destroy();
88103
}
@@ -106,24 +121,8 @@ export default class ChromeView {
106121
}
107122

108123
_getSlideContent(slide) {
109-
const picture = slide.$node.data('picture');
110-
const src = slide.$node.data('src');
111-
let $content;
112-
if (picture) {
113-
$content = $('<picture />');
114-
picture.sources.forEach(({ srcset, media_query: media }) => {
115-
$('<source />', { srcset, media }).appendTo($content);
116-
});
117-
const { src, alt } = picture.img;
118-
$('<img />', { src, alt }).appendTo($content);
119-
}
120-
else if (slide.$node.data('containsSlideContent')) {
121-
$content = slide.$node.html();
122-
}
123-
else {
124-
$content = $('<img />', { src: src });
125-
}
126-
return $content;
124+
const { src } = slide;
125+
return src ? $('<img />', { src }) : slide.content;
127126
}
128127

129128
_maybeHidePrevNext(activeSlide) {

Diff for: src/Controller.js

+21-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import $ from 'jquery';
22

3+
const SLIDE_ID_ATTR = 'lightbox-slide-id';
4+
35
export default class Controller {
46
constructor($context, props) {
57
this._props = props;
@@ -53,15 +55,21 @@ export default class Controller {
5355
destroy() {
5456
this.close();
5557
this._$eventNode.off();
56-
this._$links.removeClass('lightbox-link').off('click');
58+
this._$links
59+
.removeClass('lightbox-link')
60+
.removeData(SLIDE_ID_ATTR)
61+
.off('click');
5762
}
5863

5964
_bind() {
6065
const self = this;
61-
this._$links.addClass('lightbox-link').click(function(e) {
62-
e.stopPropagation();
63-
self.open(self.slides.filter(slide => slide.$node.is(this))[0].id);
64-
});
66+
this._$links.addClass('lightbox-link')
67+
.each((id, el) => $(el).data(SLIDE_ID_ATTR, id))
68+
.click(function(e) {
69+
e.stopPropagation();
70+
self.open(self.slides.filter(
71+
slide => slide.id === $(this).data(SLIDE_ID_ATTR))[0].id);
72+
});
6573
}
6674

6775
_trigger(eventName, params) {
@@ -71,9 +79,13 @@ export default class Controller {
7179
_createSlides($links) {
7280
return $links
7381
.toArray()
74-
.map((node, i) => ({
75-
id: i,
76-
$node: $(node)
77-
}));
82+
.map((node, i) => {
83+
const $node = $(node);
84+
return {
85+
id: i,
86+
src: $node.data('src'),
87+
content: $node.find(this._props.slideContentSelector).html()
88+
};
89+
});
7890
}
7991
}

Diff for: src/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export default {
77
init(props) {
88
props = Object.assign({
99
context: document.body,
10+
slideContentSelector: '.js-lightbox-slide-content',
1011
slideSelector: '.js-lightbox',
1112
bgColor: '#fff',
1213
opacity: '0.94',

Diff for: src/templates.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ export const lightbox = `
3737
${prevControl}
3838
${nextControl}
3939
${closeControl}
40-
<div class="lightbox-contents js-contents"></div>
40+
<div class="lightbox-contents js-contents">
41+
<div class="lightbox-content"></div>
42+
</div>
4143
</div>
4244
</div>
4345
</div>

Diff for: test/fixtures/css/disable_animations.css

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
* {
2+
/*CSS transitions*/
3+
-o-transition-property: none !important;
4+
-moz-transition-property: none !important;
5+
-ms-transition-property: none !important;
6+
-webkit-transition-property: none !important;
7+
transition-property: none !important;
8+
9+
/*CSS transforms*/
10+
-o-transform: none !important;
11+
-moz-transform: none !important;
12+
-ms-transform: none !important;
13+
-webkit-transform: none !important;
14+
transform: none !important;
15+
16+
/*CSS animations*/
17+
-webkit-animation: none !important;
18+
-moz-animation: none !important;
19+
-o-animation: none !important;
20+
-ms-animation: none !important;
21+
animation: none !important;
22+
}

Diff for: test/karma.conf.js

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ module.exports = function(config) {
99
'jasmine'
1010
],
1111
files: [
12+
'test/fixtures/css/disable_animations.css',
1213
require.resolve('es6-shim'),
1314
'node_modules/jquery/dist/jquery.js',
1415
'node_modules/jasmine-jquery/lib/jasmine-jquery.js',

Diff for: test/specs/ChromeView.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ describe('ChromeView', function() {
7070
expectNextToBeShown();
7171
});
7272

73-
it('should render the html contents of a slide that has a data-contains-slide-contents="true" attr', function() {
74-
this.set({}, [{ id: 0, $node: $('<div data-contains-slide-content="true"><button /></div>') }]);
73+
it('should render the html contents of a slide', function() {
74+
this.set({}, [{ id: 0, content: $('<div><button /></div>') }]);
7575
this.listeners.open(this.controller.slides[0]);
7676
expect($(CHROME_WRAP_CLASS)).toContainElement('button');
7777
});

Diff for: test/specs/index.js

+3-16
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ describe('lightbox', function() {
3838

3939
it('should render the blocking div when clicked on the lightbox node', function() {
4040
lightbox.init();
41-
expect($(BLOCKING_CLASS)).not.toBeVisible();
41+
expect($(BLOCKING_CLASS)).not.toBeInDOM();
4242
$(LIGHTBOX_CLASS).first().click();
4343
expect($(BLOCKING_CLASS)).toBeVisible();
4444
});
@@ -52,12 +52,12 @@ describe('lightbox', function() {
5252

5353
expect($next).toBeVisible();
5454
expect($(img(1))).toBeVisible();
55-
expect($(img(2))).not.toBeVisible();
55+
expect($(img(2))).not.toBeInDOM();
5656

5757
$next.click();
5858

5959
tempWait(() => {
60-
expect($(img(1))).not.toBeVisible();
60+
expect($(img(1)).parent().css('opacity')).toBe('0');
6161
expect($(img(2))).toBeVisible();
6262
done();
6363
});
@@ -74,17 +74,4 @@ describe('lightbox', function() {
7474
}, 15);
7575
});
7676
});
77-
78-
it('should support data-picture in the lightbox image', function(done) {
79-
affix(`.picture-lightbox[data-picture="${JSON.stringify({
80-
sources: [{ srcset: imagePath(1), media_query: '(min-width: 1px)' }],
81-
img: { src: imagePath(1) }
82-
}).replace(/"/g, '&quot;')}"] img[style="width:50px;height:50px"]`);
83-
lightbox.init({ slideSelector: '.picture-lightbox' });
84-
$('.picture-lightbox').first().click();
85-
tempWait(() => {
86-
expect($('img[src$="1.png"]')).toBeVisible();
87-
done();
88-
});
89-
});
9077
});

0 commit comments

Comments
 (0)