【问题标题】:jQuery fadeTo based on time of dayjQuery fadeTo 基于一天中的时间
【发布时间】:2017-08-19 01:03:52
【问题描述】:

我正在开发一个名为 BitDay 的开源项目,该项目是我不久前在 Reddit 上开始的。

我有 12 个元素作为 CSS 类,每个元素都有自己的背景图片。

现在,我的 jQuery 获取时间,并根据一天中的时间对类名应用扩展,因此每 2 小时背景会改变一次

$(function() {
  $('.clock').hide();
  $('.music').hide();

  //Cache these for performance
  $h1 = $('h1');
  $h3 = $('h3');
  $body = $('body');

  //Sets the font size based on scale
  var setScale = function(elem, scaleFactor) {
    var scaleSource = $body.width(),
      maxScale = 500,
      minScale = 100; //Tweak these values to taste

    var fontSize = scaleSource * scaleFactor; //Multiply the width of the body by the scaling factor:
    if (fontSize > maxScale) fontSize = maxScale;
    if (fontSize < minScale) fontSize = minScale;

    elem.css('font-size', fontSize + '%');
  }

  //Resize fonts
  setScale($h1, .2);
  setScale($h3, .10);

  //Resize font based on windows size
  $(window).resize(function() {
    setScale($h1, .2);
    setScale($h3, .10);
  });

  //Check visited cookie
  var visited = $.cookie("visited")

  if (visited == null) {
    //Fade our title page into the real wallpaper.
    setTimeout(function() {

      //Set the background
      var d = new Date();
      var hour = d.getHours();
      var cssClass = getPicture(hour);

      //Made our waiting div the active div
      $('.bg-tobe').removeClass('bg-tobe').addClass('bg-' + cssClass);

      //Fade out the active and put it in a waiting state
      $('.bg-splash').fadeOut(function() {
        $('.bg-splash').removeClass('bg-splash').addClass('bg-tobe');
      });

      //Fade in the new bg and clock. Fade out the title
      $('.bg-' + cssClass).fadeIn();
      $('.title').fadeOut();

      updateClock();
      $('.clock').fadeIn();
      $('.music').fadeIn();
    }, 0);
  } else {
    //Set the background
    var d = new Date();
    var hour = d.getHours();
    var cssClass = getPicture(hour);

    //Made our waiting div the active div
    $('.bg-tobe').removeClass('bg-tobe').addClass('bg-' + cssClass);
    $('.bg-splash').removeClass('bg-splash').addClass('bg-tobe');

    //Fade in bg and fade out title
    $('.bg-' + cssClass).fadeIn('1000');
    $('.title').fadeOut('slow');

    //Set up clock and music
    updateClock();
    $('.clock').fadeIn('slow');
    $('.music').fadeIn('slow');
  }

  // set cookie
  $.cookie('visited', 'yes', {
    expires: 30,
    path: '/'
  });

  //Start updating the clock
  setInterval('updateClock()', 1000);

});

//Determines the picture to use based on the hour
function getPicture(hour) {
  if (hour >= 23 || hour <= 2)
    return 11;
  else if (hour >= 22)
    return 10;
  else if (hour >= 21)
    return 9;
  else if (hour >= 19)
    return 8;
  else if (hour >= 16)
    return 7;
  else if (hour >= 15)
    return 6;
  else if (hour >= 13)
    return 5;
  else if (hour >= 12)
    return 4;
  else if (hour >= 10)
    return 3;
  else if (hour >= 7)
    return 2;
  else if (hour >= 5)
    return 1;
  else
    return 0;
};

function updateClock() {
  var d = new Date();
  var hours = d.getHours();
  var mins = d.getMinutes();
  var ampm = hours < 12 ? "AM" : "PM";

  //Formatting
  mins = ((mins < 10) ? "0" : "") + mins;
  hours = (hours > 12) ? hours - 12 : hours;
  hours = (hours == 0) ? 12 : hours;
  hours = ((hours < 10) ? "0" : "") + hours;

  var str = hours + ":" + mins + " " + ampm;

  //Set the new time
  var $clock = $('.clock h3');
  var oldStr = $clock.text();
  $clock.text(str);

  //Check if the hour has changed
  var oldHour = getMilitaryHour(oldStr);
  if (oldStr.length == 0) return;
  var currHour = d.getHours();
  if (currHour != oldHour) {

    //Change bgs
    var cssClass = getPicture(currHour);
    var oldClass = getPicture(oldHour);

    if (cssClass != oldClass) {

      //Make our waiting div the active div
      $('.bg-tobe').removeClass('bg-tobe').addClass('bg-' + cssClass);

      //Fade in the new bg
      $('.bg-' + cssClass).fadeIn('5000');

      //Fade out the active and put it in a waiting state
      $('.bg-' + oldClass).fadeOut(function() {
        $('.bg-' + oldClass).removeClass('bg-' + oldClass).addClass('bg-tobe');
      });
    }
  }
};

//Returns the military hour from a string formatted in standard time.
function getMilitaryHour(str) {
  var hour = parseInt(str.substring(0, 2));
  var ampm = str.substring(str.length - 2);

  if (ampm == 'PM' && hour != 12)
    return hour + 12;
  else if (ampm == 'AM' && hour == 12)
    return 0;
  else
    return hour;
}
#container {
    height: 100vh;
    position: relative;
}

.bg {
    width: 100vw;
    height: 100vh;
    position: absolute;
    z-index: 99;
    opacity: 0.7;
}


/* Change the background! */

.bg-0 {
    background-image: url("http://i.imgur.com/qexylYA.png");
    width: 100%;
    height: 100%;
    background-size: cover;
    background-repeat: no-repeat;
    margin: 0;
    padding: 0; }

.bg-1 {
    background-image: url("http://i.imgur.com/cRvIYLJ.png");
    width: 100%;
    height: 100%;
    background-size: cover;
    background-repeat: no-repeat;
    margin: 0;
    padding: 0; }

.bg-2 {
    background-image: url("http://i.imgur.com/UusvZC8.png");
    width: 100%;
    height: 100%;
    background-size: cover;
    background-repeat: no-repeat;
    margin: 0;
    padding: 0; }

.bg-3 {
    background-image: url("http://i.imgur.com/URjIjZS.png");
    width: 100%;
    height: 100%;
    background-size: cover;
    background-repeat: no-repeat;
    margin: 0;
    padding: 0; }

.bg-4 {
    background-image: url("http://i.imgur.com/Fy7kANa.png");
    width: 100%;
    height: 100%;
    background-size: cover;
    background-repeat: no-repeat;
    margin: 0;
    padding: 0; }

.bg-5 {
    background-image: url("http://i.imgur.com/e2lvJ8q.png");
    width: 100%;
    height: 100%;
    background-size: cover;
    background-repeat: no-repeat;
    margin: 0;
    padding: 0; }

.bg-6 {
    background-image: url("http://i.imgur.com/JEslGSe.png");
    width: 100%;
    height: 100%;
    background-size: cover;
    background-repeat: no-repeat;
    margin: 0;
    padding: 0; }

.bg-7 {
    background-image: url("http://i.imgur.com/v2h0qzb.png");
    width: 100%;
    height: 100%;
    background-size: cover;
    background-repeat: no-repeat;
    margin: 0;
    padding: 0; }

.bg-8 {
    background-image: url("http://i.imgur.com/xyfqUsX.png");
    width: 100%;
    height: 100%;
    background-size: cover;
    background-repeat: no-repeat;
    margin: 0;
    padding: 0; }

.bg-9 {
    background-image: url("http://i.imgur.com/XbIlhvL.png");
    width: 100%;
    height: 100%;
    background-size: cover;
    background-repeat: no-repeat;
    margin: 0;
    padding: 0; }

.bg-10 {
    background-image: url("http://i.imgur.com/xDAIc6P.png");
    width: 100%;
    height: 100%;
    background-size: cover;
    background-repeat: no-repeat;
    margin: 0;
    padding: 0; }

.bg-11 {
    background-image: url("http://i.imgur.com/kaCxCBi.png");
    width: 100%;
    height: 100%;
    background-size: cover;
    background-repeat: no-repeat;
    margin: 0;
    padding: 0; }
<div id="container">
    <div class="bg-splash"></div>
    <div class="bg-tobe" style="display: none;"></div>
</div>

但是,我希望图像在 2 小时内逐渐淡入另一个,而不是检查小时并立即更改。

比如说在早上 7 点,bg-1 以 100% 的不透明度应用。从这里,它实时淡入 bg-2。早上 8 点,bg-1 的不透明度为 50%,上午 8:30 的不透明度为 25%,以此类推。与此同时,bg-2 将慢慢变得越来越明显。然后在上午 9 点,bg-1 的不透明度为 0%,bg-2 的不透明度为 100%,接下来的 10 张图像继续如此。它应该会创建一个不错的渐变效果。

不过,这里是关键 - 由于这将成为数千名用户的开始屏幕,我们希望它在任何给定时间记住转换量,因此如果用户在上午 8:30 登录,它将显示不透明度为 25% 的 bg-1,混合到 bg-2 中。

这个真的是我的脑筋急转弯,有人能帮忙吗?

【问题讨论】:

  • 能否请您清理一下JS代码? sn-p 抛出错误。
  • @sdvnksv - 复制到 JS 文件中。包括一些显示时间的功能。在github上弄项目可能更容易?
  • 在下面添加了一个工作示例。希望你喜欢它:-)!
  • 我看到你在我回答问题时更新了你的问题(我花了大约 30 分钟来制作一个工作示例......)。您刚刚添加的“踢球者”未在我的解决方案中实现。但是,我确实希望您能欣赏我投入的时间...
  • @LaurensSwart 可以把你放到演职员表屏幕上吗?此外,如果您确实有更多时间,我将非常感谢您对时间“记住”元素的意见。 :)

标签: jquery html css fadeto


【解决方案1】:

给你!将 2000 毫秒更改为 7200000 以使其在 2 小时内缓慢消失。也放在 Fiddle 上:https://jsfiddle.net/pbfuauzg/3/

我一直在试验setInterval()fadeIn() 持续时间之间的时间差。目前,当fade()setInterval 函数稍短(即500 毫秒)时,我得到了最好的结果。请参阅下面的代码。

我还清理了您的 CSS,因为您不必要地重复了大量代码。请问我现在可以吃饼干吗:D?

请注意:在您的脚本中,每个背景之间的间隔并不正好是 2 小时(例如,您有 15:00 的背景和 16:00 的背景)。为了使其完美运行,您必须将这些时间设置为 2 小时间隔,而不是交替 1 小时和 3 小时间隔!

var timeBetweenBackgrounds = 2000; // in milliseconds - change this to 7200000 for 2 hours

var d = new Date();
var hour = d.getHours();
var bgNumber = getPicture(hour);

$(document).ready(function() {

  $('#backgroundOne').addClass('bg-' + bgNumber);

  setBackground();
  window.setInterval(setBackground, timeBetweenBackgrounds);

});

var activeBackground = bgNumber;
var activeDiv = 1;

function setBackground() {

  if (activeDiv == 1) {

    if (activeBackground < 11) {
      var nextBackground = activeBackground + 1;
    }
    if (activeBackground == 11) {
      var nextBackground = 0;
    }
    console.log('Current background = ' + activeBackground + '. Next background = ' + nextBackground + '. Fading out container One. Fading in container Two.');
    $('#backgroundTwo').attr('class', 'bg').addClass('bg-' + nextBackground).fadeIn(timeBetweenBackgrounds);
    $('#backgroundOne').fadeOut((timeBetweenBackgrounds-500), function() {
      activeBackground = nextBackground;
      activeDiv = 2;
    });

  }
  if (activeDiv == 2) {

    if (activeBackground < 11) {
      var nextBackground = activeBackground + 1;
    }
    if (activeBackground == 11) {
      var nextBackground = 0;
    }
    console.log('Current background = ' + activeBackground + '. Next background = ' + nextBackground + '. Fading out container Two. Fading in container One.');
    $('#backgroundOne').attr('class', 'bg').addClass('bg-' + nextBackground).fadeIn(timeBetweenBackgrounds);
    $('#backgroundTwo').fadeOut((timeBetweenBackgrounds-500), function() {
      activeBackground = nextBackground;
      activeDiv = 1;
    });

  }

}


//Determines the picture to use based on the hour
function getPicture(hour) {
  if (hour >= 23 || hour <= 2)
    return 11;
  else if (hour >= 22)
    return 10;
  else if (hour >= 21)
    return 9;
  else if (hour >= 19)
    return 8;
  else if (hour >= 16)
    return 7;
  else if (hour >= 15)
    return 6;
  else if (hour >= 13)
    return 5;
  else if (hour >= 12)
    return 4;
  else if (hour >= 10)
    return 3;
  else if (hour >= 7)
    return 2;
  else if (hour >= 5)
    return 1;
  else
    return 0;
};
body {
  overflow: hidden;
}

.bg {
  width: 100vw;
  height: 100vh;
  position: absolute;
  background-size: cover;
  background-repeat: no-repeat;
  z-index: 99;
  opacity: 0.7;
}

.bg-0 {
  background-image: url("http://i.imgur.com/qexylYA.png");
}

.bg-1 {
  background-image: url("http://i.imgur.com/cRvIYLJ.png");
}

.bg-2 {
  background-image: url("http://i.imgur.com/UusvZC8.png");
}

.bg-3 {
  background-image: url("http://i.imgur.com/URjIjZS.png");
}

.bg-4 {
  background-image: url("http://i.imgur.com/Fy7kANa.png");
}

.bg-5 {
  background-image: url("http://i.imgur.com/e2lvJ8q.png");
}

.bg-6 {
  background-image: url("http://i.imgur.com/JEslGSe.png");
}

.bg-7 {
  background-image: url("http://i.imgur.com/v2h0qzb.png");
}

.bg-8 {
  background-image: url("http://i.imgur.com/xyfqUsX.png");
}

.bg-9 {
  background-image: url("http://i.imgur.com/XbIlhvL.png");
}

.bg-10 {
  background-image: url("http://i.imgur.com/xDAIc6P.png");
}

.bg-11 {
  background-image: url("http://i.imgur.com/kaCxCBi.png");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="bg" id="backgroundOne">

</div>
<div class="bg" id="backgroundTwo" style="display: none;">

</div>

【讨论】:

  • 你先生,应该得到很多饼干!太感谢了! ??? 一件事 - 这会“记住”(使用更好的词)基于一天中的时间的过渡持续时间吗?如果有人在上午 8 点登录,它会在 50% 的转换之间开始,还是从 0 开始?理想情况下,我们希望一切都同步,不管两个太阳是否正在显示,因为这一切都在改变!否则我们可能会在中午 12 点看到日落:P
【解决方案2】:

我决定添加一个新答案来保留上面的答案,因为它的工作方式有点不同,下面的答案相当复杂。

我已经实现了您的“踢球者”功能请求,以便如果我们处于两个背景之间(我在下面的 cmets 中将其称为“时间块”),则褪色会在中途开始。请在下面查看我的代码。

请注意:正如我在之前的回答中所说,我必须将后台时间更改为 2 小时的确切时间间隔(请参阅 javascript 代码的底部)。背景可能不再完美地反映现实生活中的日落/黎明。有些背景可以持续长达 4 小时,而另一些只能持续 1 小时,这需要更多的编码,所以我希望你能忍受这个:-)。

我已将计时器设置为 7200000 毫秒(2 小时),因此您必须检查控制台日志(以及背景图像上的 Inspect Element)以查看它是否实际工作。我添加了一个控制台日志,向您展示它启动的背景图像和不透明度。例如,现在已经快下午 3 点了,它会从几乎完全淡入的背景 7 开始:

CURRENT TIME IS: 14:59. STARTING BACKGROUNDS ARE: bg-6 (opacity 0.01, fading OUT); bg-7 (opacity 0.99, fading IN).

3 分钟后,它将开始淡出 bg-7(因为我们处于新的时间块中)并开始淡入下一个背景,即 bg-8:

CURRENT TIME IS: 15:02. STARTING BACKGROUNDS ARE: bg-7 (opacity 0.98, fading OUT); bg-8 (opacity 0.02, fading IN).

我很高兴看到最终产品,如果您想将我的名字添加到演职员表中,我将非常感激!祝你好运!

哦,这是新的小提琴:https://jsfiddle.net/LaurensSwart/2go9g5n5/1/

var timeBetweenBackgrounds = 7200000; // in milliseconds - change this to 7200000 for 2 hour between every image

var d = new Date();
var hour = d.getHours();
var minutes = d.getMinutes();
var bgNumber = getPicture(hour);

$(document).ready(function() {

  // Determine starting background images:

  if (bgNumber < 11) {
    var bgNumberNext = bgNumber + 1;
  }
  if (bgNumber == 11) {
    var bgNumberNext = 0;
  }
  
  $('#backgroundOne').addClass('bg-' + bgNumber);
  $('#backgroundTwo').addClass('bg-' + bgNumberNext);
  
  // Get time overshoot (i.e. how far (in percentage) are we in a certain time-block):
  // Every block is 2 hours, so 1 hour into a block would be 50% (0.50)
  // Every minute would be 1/120th of a block (minutes / 60 * 0.50)
  
  var timeovershoot= 0;
  
  // Add 50% to the current block if we're in the second hour of a block (see hour definition on the bottom and adjust this if necessary):
  
  if (hour == 0 || hour == 22 || hour == 20 || hour == 18 || hour == 16 || hour == 14 || hour == 12 || hour == 10 || hour == 8 || hour == 6 || hour == 4 || hour == 2){
    timeovershoot= timeovershoot + 0.5;
  }
  
  // Calculate minute overshoot and add this to the time overshoot:
  
  minuteovershoot= (minutes/60)*0.5;
  timeovershoot= timeovershoot + minuteovershoot;
  
  // Calculate time remaining till this block ends (to determine how long to continue fading for):
  
  percentageOfBlockDone= timeovershoot;
  percentageOfBlockRemaining= 1-percentageOfBlockDone;
  secondsInBlockRemaining= timeBetweenBackgrounds * percentageOfBlockRemaining;
  
  console.log('CURRENT TIME IS: ' + hour + ':' + minutes + '. STARTING BACKGROUNDS ARE: bg-' + bgNumber + ' (opacity ' + percentageOfBlockRemaining.toFixed(2) + ', fading OUT); bg-' + bgNumberNext + ' (opacity ' + percentageOfBlockDone.toFixed(2) + ', fading IN).')
  
  // Set opacity values adjusted to percentage of current block that has elapsed:
  // We're fading div ONE out, so this will have an opacity of the percentage still remaining in this block,
  // and we're fading div TWO in, so this will have an opacity of percentage done in this block.
  
  $('#backgroundOne').css('opacity',percentageOfBlockRemaining);
  $('#backgroundTwo').css('opacity',percentageOfBlockDone);

  // Adjust fade timers and start fading:
  
  $('#backgroundOne').fadeTo(secondsInBlockRemaining, 0);
  $('#backgroundTwo').fadeTo(secondsInBlockRemaining, 1, function(){
  
  	// Once we're done finishing fading the time block that we started in, continue like normal:
  
  	 window.setInterval(setBackground, timeBetweenBackgrounds);
     
  });

});

var activeBackground = bgNumber;
var activeDiv = 1;

function setBackground() {

  if (activeDiv == 1) {

    if (activeBackground < 11) {
      var nextBackground = activeBackground + 1;
    }
    if (activeBackground == 11) {
      var nextBackground = 0;
    }
    console.log('Current background = ' + activeBackground + '. Next background = ' + nextBackground + '. Fading out container One. Fading in container Two.');
    $('#backgroundTwo').attr('class', 'bg').addClass('bg-' + nextBackground).fadeIn(timeBetweenBackgrounds);
    $('#backgroundOne').fadeOut((timeBetweenBackgrounds - 500), function() {
      activeBackground = nextBackground;
      activeDiv = 2;
    });

  }
  if (activeDiv == 2) {

    if (activeBackground < 11) {
      var nextBackground = activeBackground + 1;
    }
    if (activeBackground == 11) {
      var nextBackground = 0;
    }
    console.log('Current background = ' + activeBackground + '. Next background = ' + nextBackground + '. Fading out container Two. Fading in container One.');
    $('#backgroundOne').attr('class', 'bg').addClass('bg-' + nextBackground).fadeIn(timeBetweenBackgrounds);
    $('#backgroundTwo').fadeOut((timeBetweenBackgrounds - 500), function() {
      activeBackground = nextBackground;
      activeDiv = 1;
    });

  }

}


//Determines the picture to use based on the hour
function getPicture(hour) {
  if (hour >= 23 || hour <= 1)
    return 11;
  else if (hour >= 21)
    return 10;
  else if (hour >= 19)
    return 9;
  else if (hour >= 17)
    return 8;
  else if (hour >= 15)
    return 7;
  else if (hour >= 13)
    return 6;
  else if (hour >= 11)
    return 5;
  else if (hour >= 9)
    return 4;
  else if (hour >= 7)
    return 3;
  else if (hour >= 5)
    return 2;
  else if (hour >= 3)
    return 1;
  else
    return 0;
};
body {
  overflow: hidden;
}

.bg {
  width: 100vw;
  height: 100vh;
  position: absolute;
  background-size: cover;
  background-repeat: no-repeat;
  z-index: 99;
  opacity: 0.7;
  margin: 0;
  padding: 0;
}

.bg-0 {
  background-image: url("http://i.imgur.com/qexylYA.png");
}

.bg-1 {
  background-image: url("http://i.imgur.com/cRvIYLJ.png");
}

.bg-2 {
  background-image: url("http://i.imgur.com/UusvZC8.png");
}

.bg-3 {
  background-image: url("http://i.imgur.com/URjIjZS.png");
}

.bg-4 {
  background-image: url("http://i.imgur.com/Fy7kANa.png");
}

.bg-5 {
  background-image: url("http://i.imgur.com/e2lvJ8q.png");
}

.bg-6 {
  background-image: url("http://i.imgur.com/JEslGSe.png");
}

.bg-7 {
  background-image: url("http://i.imgur.com/v2h0qzb.png");
}

.bg-8 {
  background-image: url("http://i.imgur.com/xyfqUsX.png");
}

.bg-9 {
  background-image: url("http://i.imgur.com/XbIlhvL.png");
}

.bg-10 {
  background-image: url("http://i.imgur.com/xDAIc6P.png");
}

.bg-11 {
  background-image: url("http://i.imgur.com/kaCxCBi.png");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="bg" id="backgroundOne">

</div>
<div class="bg" id="backgroundTwo">

</div>

【讨论】:

  • 我无话可说。你太棒了!非常感谢您抽出时间来帮助解决这个问题。它工作得很好! 2 小时的增量正是我正在使用的,因为之前我们希望日落持续更长时间,因为它很漂亮 :) 但是现在由于逐渐褪色,人们会在一段时间内看到日落的变化。这将是美丽的。我不知道该怎么感谢你才足够!您可以访问bitday.me 获取当前版本,当新版本准备好时,它将在此处替换 :) 我已经将您添加到贡献者列表中! ?
  • 酷!看起来很棒!很高兴我能成为很棒的事情的一部分!如果可以的话,请选择第二个答案,如果可以的话,请+1 :)(不确定您需要等待多久的 stackrep)。哦,如果您需要更多帮助,请告诉我,我很乐意在需要的地方提供帮助!
  • 在我有 15rep 之前我不能 :( 但是一旦我这样做了,我就会 +1!页面加载的分钟过冲似乎使当前背景透明,但下面没有可见的背景,所以我将超调设置为 0.01,它似乎解决了。我不断更改计算机上的时间以测试它,以及页面重新加载,这似乎是迄今为止最好的解决方案。好消息是我可能今晚之前准备好一个 alpha 版本 :) 如果我这样做了,我会在这里发布开发链接。
  • 酷!你现在应该有 15 个 :-)(呵呵)
  • 分钟过冲应该使两个背景(当前和下一个)更加透明(最大 0.49),具体取决于我们在时间块中的位置。 IE。如果我们在一个时间块中为 1:59 小时,则该小时将增加 0.50,而 59 分钟将增加 59/60 * 0.50 = 0.49 不透明度,使整体不透明度为 0.99
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多