implement image/video lightbox for Marketplace app detail page (bug 737337)
This commit is contained in:
Родитель
de15f5ef8d
Коммит
a1e5bf70cd
|
@ -364,32 +364,6 @@ h1.addon,
|
|||
}
|
||||
}
|
||||
|
||||
.previews, #lightbox {
|
||||
.control {
|
||||
display: block;
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 5%;
|
||||
text-decoration: none;
|
||||
font-size: 48px;
|
||||
font-family: @serif-stack;
|
||||
text-align: center;
|
||||
line-height: 200px;
|
||||
top: 0;
|
||||
z-index: 30;
|
||||
.transition(.3s color);
|
||||
&.next {
|
||||
right: 0;
|
||||
}
|
||||
&.prev {
|
||||
left: 0;
|
||||
}
|
||||
&.disabled {
|
||||
color: #ccc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.metadata {
|
||||
li {
|
||||
line-height: 1.4em;
|
||||
|
|
|
@ -82,12 +82,12 @@
|
|||
height: 64px;
|
||||
line-height: 53px;
|
||||
span {
|
||||
display: inline-block;
|
||||
display: block;
|
||||
line-height: 20px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
img {
|
||||
img, video {
|
||||
-moz-transition: .3s opacity ease;
|
||||
-webkit-transition: .3s opacity ease;
|
||||
opacity: 0;
|
||||
|
@ -101,4 +101,33 @@
|
|||
display: block;
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
video {
|
||||
max-height: 80%;
|
||||
}
|
||||
}
|
||||
|
||||
.previews, #lightbox {
|
||||
.control {
|
||||
display: block;
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 5%;
|
||||
text-decoration: none;
|
||||
font-size: 48px;
|
||||
font-family: Georgia, serif;
|
||||
text-align: center;
|
||||
line-height: 200px;
|
||||
top: 0;
|
||||
z-index: 30;
|
||||
.transition(.3s color);
|
||||
&.next {
|
||||
right: 0;
|
||||
}
|
||||
&.prev {
|
||||
left: 0;
|
||||
}
|
||||
&.disabled {
|
||||
color: #ccc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
@import 'lib';
|
||||
|
||||
#lightbox {
|
||||
.controls {
|
||||
height: 80px;
|
||||
}
|
||||
.caption {
|
||||
span {
|
||||
line-height: 20px;
|
||||
margin: 0 auto;
|
||||
height: 60px;
|
||||
overflow: hidden;
|
||||
width: 90%;
|
||||
}
|
||||
}
|
||||
.close {
|
||||
.border-radius(4px);
|
||||
background-image: url(../../img/impala/banner-close.png);
|
||||
cursor: pointer;
|
||||
height: 25px;
|
||||
text-indent: -9999px;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
top: 1em;
|
||||
right: 1em;
|
||||
width: 25px;
|
||||
&:hover {
|
||||
background-color: #c40000;
|
||||
background-position: -25px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.previews, #lightbox {
|
||||
.control {
|
||||
font-size: 48px;
|
||||
line-height: 50px;
|
||||
width: 64px;
|
||||
}
|
||||
}
|
|
@ -13,7 +13,8 @@
|
|||
href.substr(0,7) === 'mailto:' ||
|
||||
href.substr(0,1) === '#' ||
|
||||
href.indexOf('/developers/') !== -1 ||
|
||||
href.indexOf('/statistics/') !== -1) {
|
||||
href.indexOf('/statistics/') !== -1 ||
|
||||
href.indexOf('?modified=') !== -1) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
(function() {
|
||||
var $document = $(document),
|
||||
$lightbox = $('#lightbox'),
|
||||
$content = $lightbox.find('.content'),
|
||||
$caption = $lightbox.find('.caption span'),
|
||||
$previews = $('.previews'),
|
||||
current, $strip,
|
||||
lbImage = template('<img id="preview{0}" src="{1}">'),
|
||||
lbVideo = template('<video id="preview{0}" src="{1}" controls></video>');
|
||||
if (!$lightbox.length) return;
|
||||
function showLightbox() {
|
||||
$lightbox.show();
|
||||
showImage(this);
|
||||
$(window).bind('keydown.lightboxDismiss', function(e) {
|
||||
switch (e.which) {
|
||||
case z.keys.ESCAPE:
|
||||
hideLightbox();
|
||||
break;
|
||||
case z.keys.LEFT:
|
||||
showPrev();
|
||||
break;
|
||||
case z.keys.RIGHT:
|
||||
showNext();
|
||||
break;
|
||||
}
|
||||
});
|
||||
//I want to ensure the lightbox is painted before fading it in.
|
||||
setTimeout(function() {
|
||||
$lightbox.addClass('show');
|
||||
},0);
|
||||
}
|
||||
function hideLightbox() {
|
||||
$lightbox.removeClass('show');
|
||||
// We can't trust transitionend to fire in all cases.
|
||||
setTimeout(function() {
|
||||
$lightbox.hide();
|
||||
}, 500);
|
||||
$(window).unbind('keydown.lightboxDismiss');
|
||||
}
|
||||
function cookieCutter(values) {
|
||||
if (values[1].indexOf('.webm') > 0) {
|
||||
return lbVideo(values);
|
||||
} else {
|
||||
return lbImage(values);
|
||||
}
|
||||
}
|
||||
function showImage(a) {
|
||||
var $a = $(a),
|
||||
$oldimg = $lightbox.find('img, video');
|
||||
current = $a.parent().index();
|
||||
$strip = $a.closest('ul').find('li');
|
||||
$previews.find('.panel').removeClass('active')
|
||||
.eq(current).addClass('active');
|
||||
var $img = $('#preview'+current);
|
||||
if ($img.length) {
|
||||
$oldimg.css('opacity', 0);
|
||||
$img.css('opacity', 1);
|
||||
} else {
|
||||
$img = $(cookieCutter([current, $a.attr('href')]));
|
||||
$content.append($img);
|
||||
$img.load(function(e) {
|
||||
$oldimg.css('opacity', 0);
|
||||
$img.css('opacity', 1);
|
||||
for (var i=0; i<$strip.length; i++) {
|
||||
if (i != current) {
|
||||
var $p = $strip.eq(i).find('a');
|
||||
$content.append(cookieCutter([i, $p.attr('href')]));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
$caption.removeAttr('style oldtext');
|
||||
$caption.text($a.attr('title'));
|
||||
$caption.truncate({dir: 'v'});
|
||||
$lightbox.find('.control').removeClass('disabled');
|
||||
if (current < 1) {
|
||||
$lightbox.find('.control.prev').addClass('disabled');
|
||||
}
|
||||
if (current == $strip.length-1){
|
||||
$lightbox.find('.control.next').addClass('disabled');
|
||||
}
|
||||
}
|
||||
function showNext() {
|
||||
if (current < $strip.length-1) {
|
||||
showImage($strip.eq(current+1).find('a'));
|
||||
if (!this.window) {
|
||||
$(this).blur();
|
||||
}
|
||||
}
|
||||
}
|
||||
function showPrev() {
|
||||
if (current > 0) {
|
||||
showImage($strip.eq(current-1).find('a'));
|
||||
if (!this.window) {
|
||||
$(this).blur();
|
||||
}
|
||||
}
|
||||
}
|
||||
$('#lightbox .next').click(_pd(showNext));
|
||||
$('#lightbox .prev').click(_pd(showPrev));
|
||||
$('.previews ul a').click(_pd(showLightbox));
|
||||
$('#lightbox').click(_pd(function(e) {
|
||||
if ($(e.target).is('.close, #lightbox')) {
|
||||
hideLightbox();
|
||||
}
|
||||
}));
|
||||
})();
|
|
@ -69,24 +69,26 @@ z.page.on('fragmentloaded', function() {
|
|||
// $('.slider').each(slider);
|
||||
});
|
||||
|
||||
$('.slider').each(function() {
|
||||
var $this = $(this),
|
||||
$ul = $this.find('ul'),
|
||||
$a = $ul.find('a');
|
||||
$this.hover(function(e) {
|
||||
$ul.addClass('moving-left');
|
||||
// e.clientX > ($this.width() / 2)
|
||||
if ($('body.home').length) {
|
||||
$('.slider').each(function() {
|
||||
var $this = $(this),
|
||||
$ul = $this.find('ul'),
|
||||
$a = $ul.find('a');
|
||||
$this.hover(function(e) {
|
||||
$ul.addClass('moving-left');
|
||||
// e.clientX > ($this.width() / 2)
|
||||
});
|
||||
$this.mouseout(function() {
|
||||
$a.removeClass('frozen');
|
||||
$ul.addClass('done');
|
||||
});
|
||||
$a.hover(_.throttle(function(e) {
|
||||
$(this).addClass('frozen');
|
||||
$ul.addClass('done');
|
||||
}, 250));
|
||||
$a.mouseout(_.throttle(function(e) {
|
||||
$(this).removeClass('frozen');
|
||||
$ul.removeClass('done');
|
||||
}, 250));
|
||||
});
|
||||
$this.mouseout(function() {
|
||||
$a.removeClass('frozen');
|
||||
$ul.addClass('done');
|
||||
});
|
||||
$a.hover(_.throttle(function(e) {
|
||||
$(this).addClass('frozen');
|
||||
$ul.addClass('done');
|
||||
}, 250));
|
||||
$a.mouseout(_.throttle(function(e) {
|
||||
$(this).removeClass('frozen');
|
||||
$ul.removeClass('done');
|
||||
}, 250));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -76,9 +76,8 @@ $.fn.lineclamp = function(lines) {
|
|||
if (lh.substr(-2) == 'px') {
|
||||
lh = parseFloat(lh.replace('px', ''));
|
||||
$this.css({'max-height': Math.ceil(lh) * lines,
|
||||
'overflow': 'hidden',
|
||||
'text-overflow': 'ellipsis'})
|
||||
.truncate({dir: 'v'});
|
||||
'overflow': 'hidden',
|
||||
'text-overflow': 'ellipsis'});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
@ -91,6 +91,8 @@ CSS = {
|
|||
'css/mkt/login.less',
|
||||
'css/mkt/purchase.less',
|
||||
'css/devreg/l10n.less',
|
||||
'css/impala/lightbox.less',
|
||||
'css/mkt/lightbox.less',
|
||||
),
|
||||
'mkt/in-app-payments': (
|
||||
'css/mkt/reset.less',
|
||||
|
@ -227,6 +229,7 @@ JS = {
|
|||
'js/mkt/apps.js',
|
||||
'js/zamboni/outgoing_links.js',
|
||||
'js/common/upload-image.js',
|
||||
'js/mkt/lightbox.js',
|
||||
|
||||
# Search suggestions.
|
||||
'js/impala/ajaxcache.js',
|
||||
|
|
|
@ -99,7 +99,7 @@
|
|||
{% endif %}
|
||||
</section>
|
||||
|
||||
{% if product.all_previews|length %}
|
||||
{% if product.all_previews %}
|
||||
<section class="previews slider full">
|
||||
<ul class="content">
|
||||
{%- for preview in product.all_previews -%}
|
||||
|
@ -112,6 +112,18 @@
|
|||
{%- endfor -%}
|
||||
</ul>
|
||||
</section>
|
||||
<div id="lightbox">
|
||||
<section>
|
||||
<div class="content">
|
||||
<a class="close" href="#">{{ _('Close') }}</a>
|
||||
</div>
|
||||
<div class="controls">
|
||||
<a href="#" class="control next">»</a>
|
||||
<a href="#" class="control prev">«</a>
|
||||
<div class="caption"><span></span></div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<section class="support c">
|
||||
|
|
Загрузка…
Ссылка в новой задаче