如何使图像拉伸以填充PhotoSwipe中的可用区域

时间:2015-04-16 15:05:40

标签: javascript css image gallery photoswipe

我希望使用PhotoSwipe来显示我的自适应网站上每篇文章中的所有图片,例如当您点击或点按http://dailymail.co.uk中的内容中图片时获得的图库。主要用途是为用户提供图片的大视图,并允许他们在不离开文章的情况下在移动设备上放大图片。

PhotoSwipe非常适用于此目的。我的JS梳理了文章内容,并根据它找到的图像构建了PhotoSwipe数组。但是有一个问题:我文章中的一些图片很小。这在移动设备上并不算太糟糕,但在桌面设备上,我很容易在一个大的黑色画廊区域中间找到一张小图片。每日邮报通过总是将图像拉伸到适合画廊区域来解决这个问题 - 稍微丑陋的一些照片,但它提供了一个很大的视野。

有什么方法可以选择性地在PhotoSwipe画廊中拉伸小图像以填充更多可用区域?旧版PhotoSwipe曾经有一个imageScaleMethod选项,可以让你将图像调整到屏幕尺寸:我能用最新版本v4.0.7做些什么吗?

这是一个CodePen,它应该说明我在说什么 - 第三张图像是我想要伸展一下的图像。我在这个例子中的幻灯片是:

var items = [
    {
        src: 'http://lorempixel.com/1000/750/cats/',
        w: 1000,
        h: 750,
        title: 'Fairly big cat'
    },
    {
        src: 'http://lorempixel.com/1200/900/cats/',
        w: 1200,
        h: 900,
        title: 'Another quite big cat'
    },
    {
        src: 'http://lorempixel.com/200/320/cats/',
        w: 200,
        h: 320,
        title: 'Small cat'
    }
];

3 个答案:

答案 0 :(得分:3)

起初我以为我可以通过添加一个beforeChange监听器来解决这个问题,该监听器可以放大每个图像以适应显示区域。方便的是,PhotoSwipe中的每个项目都有一个属性fitRatio表示适合显示区域所需的缩放比率。

CodePen的第34行,就在gallery.init();行前{I}}我添加了:

gallery.listen('beforeChange', function () {
    gallery.zoomTo(gallery.currItem.fitRatio, {x: gallery.viewportSize.x / 2, y: gallery.viewportSize.y / 2}, 1);
});

将当前图片缩放到正确的比例以适合图库,以幻灯片的x和y中心为中心,持续时间为1微秒。 (有关zoomTo方法的详细信息,请参阅PhotoSwipe API documentation。)

但是放大会停用桌面上的“点击滑动”操作,我想保留它。

因此,我正在测量浏览器窗口并设置图像宽度和高度以匹配。您必须考虑图像是横向还是纵向,如果用户调整浏览器窗口大小,则需要更新尺寸。

var measureWindow = function () {
    windowW = $window.width();
    windowH = $window.height();
};

measureWindow();

// If image is landscape or square, set width to window width and height to width * ratio
// If image is portrait, set height to window height and width to height / ratio
var getImageDimensions = function (w, h) {
    var ratio = h / w;
    if (w >= h) {
        return {
            width : windowW,
            height: windowW * ratio
        }
    } else {
        return {
            width : windowH / ratio,
            height: windowH
        }
    }
};

然后,当我将每个图像添加到我的数组时,我做

var dimensions = getImageDimensions(width, height),
    o = {
        el : value,
        src: src,
        w  : dimensions.width,
        h  : dimensions.height
    };

其中o是表示图像的对象。

如果用户调整窗口大小,我还会在我的图库中添加一个监听器以再次调用measureWindow。这会更新windowWwindowH

    var debouncedMeasure = _.debounce(measureWindow, 250);

    gallery.listen('beforeResize', function () {
        debouncedMeasure();
    });

严格来说,当我开心时,我应该更新我的图像数组中的尺寸,这样新图像的大小就会正确地适应新的窗口尺寸。

我最终得到了the solution - 您需要查看full preview以查看其工作原理。


修改

为了从PhotoSwipe获得最佳效果,我发现只要它处于活动状态,我就必须在页面的其余部分隐藏内容。当我打开它时,我

html.addClass('photoswipe-active');

gallery.listen('close', function () {
    html.removeClass('photoswipe-active');
});

并设置可见性:当该类存在时隐藏在其他内容上。如果页面中有任何导致重新绘制的内容(如动画gif),则可能会导致PhotoSwipe滑动并捏合缩放手势。隐藏内容可以保持顺畅。

当我尝试在调整大小时测量PhotoSwipe元素时,我也遇到了性能问题 - 测量窗口似乎要好得多。

答案 1 :(得分:0)

我正在使用wordpress插件并添加了以下css。 (然后我将wordpress中的缩略图大小设置为0。)

.photoswipe_gallery_holder {
width: 101%;
margin-left: -5px;
}
.photoswipe_gallery {
width: 100%!important;
margin-top: 20px!important;
margin-bottom: 20px!important;
margin-right: 0px!important;
margin-left: 0px!important;
padding-bottom:0px!important;
}
.photoswipe_gallery figure {
width: 100%!important;
-webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
-moz-box-sizing: border-box;    /* Firefox, other Gecko */
box-sizing: border-box;         /* Opera/IE 8+ */
padding: 5px!important;
}
.photoswipe_gallery figure img {
width: 100%!important;
height: auto!important;
padding: 0px!important;
}
.photoswipe_gallery figure a {
width: 100%!important;
height: auto!important;
}

@media screen and (min-width: 480px) {
.photoswipe_gallery figure {
width: 50%!important;
}
}

@media screen and (min-width: 750px) {
.photoswipe_gallery figure {
width: 25%!important;
}
}

“持有人”div是如此我们可以将事情转移到排队。如果你使用这个,你需要设置overflow:hidden;在父div上。我的父级div在响应式网站上的最宽处是968px。

答案 2 :(得分:0)

如果您查看源代码,则可以看到它在某些时候是/曾经是计划中的功能,因为它的某些部分显示:

// not fully implemented yet
scaleMode: 'fit' // TODO

这确实没有什么帮助,但是我只是说这是一个有趣的细节。

我对这个问题的解决方案是:只需将data-size属性设置为大于大多数常见屏幕尺寸的尺寸。当我从PHP生成标记时,我只需要输入以下内容:

data-size="<?php echo intval($img_x * 1.5); ?>x<?php echo intval($img_y * 1.5); ?>"

所需的实际数量可能会因您的情况而异,但是我已经将所有图像设置为固定大小,并且1.5乘数足以使它们覆盖大多数屏幕。

这不是一个“正确”的解决方案,但是,它对于客户端来说是简单,快速且轻巧的(不需要其他JavaScript魔术)。与上面建议的精心设计的JavaScript繁重解决方案相比,对于简单的项目而言可能是一个好处。

事实上,我正在使用MobileDetect,所以我只是增加了台式机的图像大小,因为我的原始图像适用于手机(和平板电脑)。

data-size="<?php echo intval($img_x * ($mobile_detect->isMobile() ? 1 : 1.5)); ?>x<?php echo intval($img_y * ($mobile_detect->isMobile() ? 1 : 1.5)); ?>"

您需要根据自己的需要规划大小,并且可能需要为每个图像使用不同的乘数,但是我的观点是,可以在图库标记中轻松进行大小操作,而不是尝试覆盖值从JavaScript中删除,或在某些事件后强制缩放PhotoSwipe(我已经尝试过并且工作起来或多或少都可以切换图像,但是例如在打开PhotoSwipe时会引起故障)。