【问题标题】:Preview and zoom image like Firefox像 Firefox 一样预览和缩放图像
【发布时间】:2018-07-05 05:27:03
【问题描述】:

当您在 Firefox 中打开图像时,它具有以下特征:

  • 在浏览器中居中显示。
  • 将包含高度/宽度(不超过浏览器尺寸)。
  • 调整大小不会超过其最大大小。
  • 如果小于浏览器窗口,则根本不调整大小。
  • 保持纵横比。
  • 有一个缩放工具,可以将图像调整到最大尺寸并允许它超过浏览器尺寸。

我将如何使用 CSS/JS 复制它?我使用 CSS 尝试了几种不同的方法,但我假设它需要 JS,但我找不到任何示例。

我使用 contains 取得的最佳效果:

height: 100%;
width: 100%;
background-url: {location of image}
background-position: center center;
background-repeat: no-repeat;
background-size: contain;

但这只会对较大的图像产生很好的效果,因为它会拉伸较小的图像以匹配浏览器的高度或宽度,因此我希望小于浏览器的图像只是居中并保留它们的最大高度/宽度。

【问题讨论】:

  • 在 Firefox 中,图像被渲染为一个 img 元素。你需要把它作为背景还是一个img元素也可以?

标签: javascript jquery css image


【解决方案1】:

jsBin demo

(免责声明:仅限现代浏览器:(IE9+))

您只需要:

<div id="parent">
  <img src="image.jpg">
</div>

CSS:

html,
body{
  margin:0;
  height:100%;
  background:url(http://i.imgur.com/aSqDLP0.png);
}

body{ /* or use a wrapper element instead */
  display: table;
  width: 100%;
  text-align: center;
}
#parent{
  display: table-cell;
  vertical-align: middle;
}
#parent img{
  vertical-align: middle;
  max-height: 100vh;
  max-width: 100vw;
  box-shadow: 0 4px 15px #111;
}

以上对于居中和调整大小的东西已经足够了。
如果您还想像 Firefox 一样做:

  • 放大光标悬停 - 如果图像被浏览器调整大小(小)
  • 将窗口滚动到点击的坐标 - 如果图片很小
  • 缩小光标 - 如果图像被放大(点击) - 显示-

比一点 jQuery 可能会派上用场:

var $parent = $("#parent"),
    isParentSmaller = false,
    zoom = false,
    parW, parH,
    imgW, imgH;

$parent.find("img").on("mouseenter click", function( e ){

  imgW = this.naturalWidth;
  imgH = this.naturalHeight;
  parW = $parent.width();
  parH = $parent.height();
  isParentSmaller = parW-1 < imgW || parH-1 < imgH;

  $(this).css({
    cursor: isParentSmaller ? (zoom?"zoom-out":"zoom-in") : "auto"
  });

  if(e.type=="click" && isParentSmaller){
    zoom = !zoom;       // Toggle zoom boolean  
    $(this).css({       // Apply cursor styles
      maxWidth  : zoom ? "none" : "100vw",
      maxHeight : zoom ? "none" : "100vh",
      cursor    : zoom ? "zoom-out":"zoom-in"
    });
    // Scroll window where we want to zoom:
    window.scrollTo(((imgW/parW)-1)*e.clientX, ((imgH/parH)-1)*e.clientY);
  }

});

谦虚点,上面的表现甚至比 Firefox 更好,因为如果你调整窗口大小,Firefox 会失去放大镜光标:)

【讨论】:

  • 这正是我想要的,完美的工作。
【解决方案2】:

注意:我重写了我的答案,因为我之前的解决方案在 Firefox 中不起作用(哦,具有讽刺意味)。它还在其他浏览器中引起了奇怪的行为。原因是 flexbox 将图像垂直和水平居中。

让我们一步一步来。

为了在设置最大尺寸的同时保持图像的纵横比,可以通过以下方式实现:

.img {
  display: block; // could also be inline-block or other block-like types
  max-height: 100%;
  max-width: 100%;
  height: auto;
  width: auto;
}

现在,从技术上讲,使用 flexbox 使元素垂直和水平居中只需 3 行代码。如上所述,这在某些浏览器中缩放图像时会导致奇怪的行为。相反,我们使用text-align: center 将图像沿 x 轴居中,并使用一种称为“幽灵元素”的方法将图像沿 y 轴居中。您可以在this article from CSS Tricks 中了解更多信息。总之,我们有这个使元素居中:

.parent {
  text-align: center;
  white-space: nowrap;
}

.parent:before {
  content: '';
  display: inline-block;
  height: 100%;
  vertical-align: middle;
  margin-right: -0.25em;
}

.centered-child {
  display: inline-block;
  vertical-align: middle;
}

最后,我们结合了缩放和居中。我假设 HTML 在正文中仅存在一个 &lt;img class="img" ...&gt;

html {
  width: 100%;
  height: 100%;
}

body {
  margin: 0;
  width: 100%;
  height: 100%;
  background-color: #333;
  text-align: center;
}

body:before {
  content: '';
  width: 0;
  height: 100%;
  display: inline-block;
  vertical-align: middle;
  white-space: nowrap;
  margin-left: -0.25em;
}

.img {
  display: inline-block;
  vertical-align: middle;
  max-height: 100%;
  max-width: 100%;
  width: auto;
  height: auto;
}

现在我们实现缩放

为了缩放图像,我们需要 JavaScript。让我们使用 jQuery。

在 JavaScript 中更改 css 属性不好,所以我们准备了两个额外的类。

.img.is-zoomable {
  cursor: zoom-in;
}

.img.is-zoomed {
  cursor: zoom-out;
  max-height: none;
  max-width: none;
}

点击时,JavaScript 将切换 is-zoomed 类,而在 mouseenter 时,我们决定是否可以缩放图像。如果可以缩放,我们添加类is-zoomable

$('.img').on('click', function() {
    $(this).toggleClass('is-zoomed');
});
$('.img').on('mouseenter', function() {
    var origWidth = this.naturalWidth;
    var origHeight = this.naturalHeight;
    var currWidth = $(this).width();
    var currHeight = $(this).height();
    if (origWidth !== currWidth || origHeight !== currHeight) {
        $(this).addClass('is-zoomable');
    }
});

等等,我们完成了。有关工作示例,请参阅my codepen

【讨论】:

  • @TimoM 你的例子有问题jsbin.com/dehalo/2/edit?html,css,js,output - 点击图片看看它发生了。我错过了什么吗?
  • 返回 undefined 的变量 $(this).clientWidth 是什么?另外我建议您快速查看stackoverflow.com/questions/833699/…
  • @RokoC.Buljan 在微小的 jsbin iframe 中似乎有问题。它适用于具有每个视口大小的每个浏览器。这是MDN about clientWidth。我喜欢使用它而不是 naturalWidth(和 -height),因为它与 HTMLImageElement 无关。由于图片的box-model在其他浏览器中不会有差异,所以使用它是没有问题的。
  • @RokoC.Buljan 如果它也应该在 iframe 中工作,只需在缩放时将 Ghost 元素的 content 设置为 none。但我不会为这种极端情况添加不必要且令人困惑的代码。
  • @TimoM 你应该console.log 而不是你的变量origWidth 因为它返回undefined!即使从 jsBin 下载,您的演示也会损坏,因此它与 jsBin 框架无关,而是与您的代码(Chrome 浏览器)有关,因为即使在 jsFiddle 中也存在相同的缩放错误。 (还有一个小问题是即使我们无法使用缩放操作也会出现放大镜......)有什么想法吗?
猜你喜欢
  • 1970-01-01
  • 2014-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-22
  • 1970-01-01
  • 2017-02-01
相关资源
最近更新 更多