如何使我的CSS过渡更平滑/在不同的浏览器上工作?

4

我正在尝试创建一个页面,当你点击按钮时可以更改背景图片。代码笔:http://codepen.io/meek/pen/EPLZpW

body {
  background: url('https://s3.eu-central-1.amazonaws.com/meek-img/1.jpg') no-repeat center center fixed;
  background-size: cover;
  -webkit-transition: background .5s ease-in-out;
  -moz-transition: background .5s ease-in-out;
  -o-transition: background .5s ease-in-out;
  transition: background .5s ease-in-out;
}

我当前的做法存在两个主要问题:
  1. 在Mozilla Firefox中根本无法工作。
  2. 动画效果不流畅。它会瞬间切换到一个空白背景,然后再运行动画。有没有办法避免这种情况,或者由于加载时间而不可避免?如果有其他方法来实现这个功能而避免这个问题该怎么做?起初,我想使用jQuery进行动画处理,但被告知这并不是最佳选择。

“background”是一个很大、通用的属性。你希望它能做什么?是指“background-position”吗?“background-image”?你希望图片淡入吗?就是这样吗? - random_user_name
背景图像属性在CSS3中不可动画化 - 您应该预加载您的图像,以免出现空白。 - Jaromanda X
@JaromandaX 预加载图像可以解决奇怪的动画问题。接下来我将对图像不透明度进行动画处理,而不是背景。谢谢! - mlamp
2个回答

3

对完整属性background进行转换可能会产生一些奇怪的影响,特别是当图像涉及到时。直接在背景图像上进行这些转换对您的浏览器要求很高。并且,如您所述,在不同的浏览器中表现不一致。

更好的做法是在具有该背景属性的元素(如div)上进行opacity的转换或动画。这样,浏览器就不必担心转换图片,只需要关注转换div,这将导致浏览器任务更加简单。如果要更改网页的背景,则只需添加具有该背景图像的div。

我已根据您的代码包含了一个片段来演示一般想法。您还会注意到,仅在请求图像作为背景图像时预加载图像。这样,用户只下载他要看到的图像。我的演示使用jQuery,但可以很容易地使用vanilla JS集成。

function preload_img (src, callback) {
  var img = new Image();

  img.onload = function() {
    if( callback && typeof callback === 'function' ) {
      callback( img );
    }
  };
  
  img.src = src;
}

var imgs = [
  "https://s3.eu-central-1.amazonaws.com/meek-img/1.jpg",
  "https://s3.eu-central-1.amazonaws.com/meek-img/2.jpg",
  "https://s3.eu-central-1.amazonaws.com/meek-img/3.jpg", 
  "https://s3.eu-central-1.amazonaws.com/meek-img/4.jpg", 
  "https://s3.eu-central-1.amazonaws.com/meek-img/5.jpg", 
  "https://s3.eu-central-1.amazonaws.com/meek-img/6.jpg", 
  "https://s3.eu-central-1.amazonaws.com/meek-img/7.jpg", 
  "https://s3.eu-central-1.amazonaws.com/meek-img/8.jpg", 
  "https://s3.eu-central-1.amazonaws.com/meek-img/9.jpg" 
];

function change_bg() {
  var random_index = Math.floor(Math.random() * imgs.length);
  preload_img( imgs[random_index], function( img ) {
    $('<div>')
      .addClass('bg-image')
      .css('background-image', 'url(' + img.src + ')')
      .appendTo('body')
    ;
  } );
}

$( 'button' ).click( function() {
  change_bg();
} );

change_bg();
@keyframes fadein
{
  from { opacity: 0; }
  to { opacity: 1; }
}

.bg-image
{
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  animation: fadein 1s;
  background-size: cover;
}

.mimi
{
  z-index: 1;
  bottom: 0;
  height: 100px;
  left: 0;
  margin: auto;
  position: absolute;
  top: 0;
  right: 0;
  width: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<body>
  <div class="mimi">
    <button class="btn btn-default btn-lg">click me</button>
  </div>
</body>


非常感谢您提供如此详尽的答案! - mlamp
谢谢你帮我省去了写示例的时间 :P - seahorsepip

2

我建议在当前图片上方加载新图片,并将透明度转换为1。然后,您可以删除下面的图片。

另外,请确保在开始过渡之前完全加载图像。

使用append()添加新图像,当新图像加载完成后,您可以向其添加一个带有透明度1的类。


你能更具体地说明一下我如何使用append()吗?我对jQuery不太熟悉,但据我所知,append()会向元素添加HTML,而我使用的背景图片是CSS参数。 - mlamp
您可以使用append在元素中添加HTML,并在图像CSS之前添加样式标签。如果需要,明天我可以制作一个演示。 - seahorsepip

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接