基于一天中的时间 Lerp 背景颜色

Lerp background colour based on time of day

我一直在开发一个显示时间并使用 p5.js 制作太阳和月亮动画以在背景中旋转的小型 Web 项目。我遇到的问题是实现从一种背景(天空)颜色到另一种颜色的逐渐过渡。

function setColours(){
 var pallete = [color(0),color(232, 131, 72),color(88,52,133),color(45, 221, 227)]
 var cMin = slider.value();
 hr = cMin / 60;
 //lerpAmt = map(mn,0,1440,0,1);
 console.log(hr);

 if(hr <= 4 || hr >= 20) { 
   background(pallete[0])//black
 } 

 else if(hr >5 && hr <= 6){
   background(232, 131, 72)//orange
 } 

 else if(hr >18 && hr <=19){
   background(232, 131, 72)
 }

 else if(hr >4 && hr <= 5){
   background(88,52,133) //purple    
 } 

 else if(hr > 19 && hr <= 20){
   background(88,52,133)       
 }

 else if(hr >= 7|| hr <18){
   background(45, 221, 227) //blue
 }
}

以上是设置页面天空颜色的函数。循环的起始(0)位置在顶部并逆时针旋转。

黑色 -> 紫色 -> 橙色 -> 蓝色 -> 橙色 -> 紫色 -> 黑色

最初,我开始通过对每小时过去的分钟数进行归一化来对颜色进行渐变,这导致天空颜色每小时在黑色和紫色之间过渡,并且一旦过了晚上 8 点(20:00),背景将继续渐变到紫色,即使午夜是黑色的。这让我怀疑获取时间的逻辑是否有任何好处。

  1. 有没有更好的方法来检查当前是否在两个小时之间?
  2. 我怎样才能得到到下一段(天空颜色)的分钟数?

要让 canvas 循环黑色 -> 紫色 -> 橙色 -> 蓝色 -> 橙色 -> 紫色 -> 黑色 if else 案例可以简化.我们还可以通过创建作为调色板索引的颜色常量来使代码更易于阅读。

要获得下一次颜色变化之前的分钟数,我们只需从下一个小时边界减去我们所在的当前小时,然后乘以 60。

function setup() {
  createCanvas(1120, 630);
  frameRate(60);
}
var mn = 0;
function draw() {
if (mn > 1439)
  mn = 0;
  mn++;
  setColours();
}

function setColours(){
  var black = 0;
  var orange = 1;
  var purple = 2;
  var blue = 3;
  var pallete = [color(0),color(232, 131, 72),color(88,52,133),color(45, 221, 227)];
 // let hr = mn/60.0; // will also work instead of map
  let hr = map(mn,0,1440,0,23);
  if (hr < 4){
    background(pallete[black]);
    console.log("Minutes until color change " + ((4 - hr)*60)); 
  } else if (hr < 6){
    background(pallete[purple]);
    console.log("Minutes until color change " + ((6 - hr)*60)); 
  } else if (hr < 8){
    background(pallete[orange]);
    console.log("Minutes until color change " + ((8 - hr)*60)); 
  } else if (hr < 16){
    background(pallete[blue]);
    console.log("Minutes until color change " + ((16 - hr)*60)); 
  } else if (hr < 18){
    background(pallete[orange]);
    console.log("Minutes until color change " + ((18 - hr)*60)); 
  } else if (hr < 20){
    background(pallete[purple]);
    console.log("Minutes until color change " + ((20 - hr)*60)); 
  } else {
     background(pallete[black]);
     // here we subtract our hour from 28 to account for the 4 hours at the beginning
     console.log("Minutes until color change " + ((28- hr)*60)); 
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.8.0/p5.min.js"></script>

您也可以使用 lerpColor() 函数,这将帮助您在颜色之间进行平滑过渡。由于 lerpColor 将从一种定义的颜色变为另一种,我将更改时间间隔的边界以表示对应颜色为 "purest" 的一天中的时间(午夜是 "blackest", 中午是 "bluest", 等等)

我冒昧地重写了您的一些代码以制作一个您可以检查的片段。在其中,您可以使用滑块控制一天中的时间并查看颜色变化。

const slider = document.getElementById('slider')
const label = document.getElementById('sliderValue')
slider.oninput = handleChange

function handleChange(event){
  cMin = event.target.value
  sliderValue.innerText = parseInt(cMin/60)+"h / "+cMin + "m"
  
  setColours()
}

const black = [0, 0, 0]
const purple = [88, 52, 133]
const orange = [232, 131, 72]
const blue = [45, 221, 227]

let cMin
let hr
let currentColor

function setup(){
  createCanvas(300, 50)
  background(black)
}

function setColours(){
 
 hr = cMin / 60;
 
 if(hr >= 0 && hr <= 4.5){
   currentColor = lerpSkyColor(black, purple, 0, 4.5)
 }
 
 if(hr > 4.5 && hr <= 5.5){
   currentColor = lerpSkyColor(purple, orange, 4.5, 5.5)
 }
 
 if(hr > 5.5 && hr <= 12){
   currentColor = lerpSkyColor(orange, blue, 5.5, 12)
 }
 
 if(hr > 12 && hr <= 18.5){
   currentColor = lerpSkyColor(blue, orange, 12, 18.5)
 }
 
 if(hr > 18.5 && hr <= 19.5){
   currentColor = lerpSkyColor(orange, purple, 18.5, 19.5)
 }
 
 if(hr > 19.5 && hr <= 24){
   currentColor = lerpSkyColor(purple, black, 19.5, 24)
 }
 
 background(currentColor)
}

function lerpSkyColor(from, to, startTime, endTime){
  const lerpAmt = map(hr, startTime, endTime, 0, 1)
  return lerpColor(color(from), color(to), lerpAmt)
}
#slider{
  width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.10.2/p5.min.js"></script>

<h2 id="sliderValue">0h / 0m</h2>
<input id="slider" type="range" min="0" max="1440" value="1"/>

您还可以调整 setColours 方法的 if/else 部分的时间间隔,以更好地反映真实的颜色变化并在一段时间内保持颜色不变(也许在 17H 而不是 12h 开始从蓝色变为橙色)

if(hr > 12 && hr <=17){
  currentColor = blue
}
if(hr > 17 && hr <= 18.5){
  currentColor = lerpSkyColor(blue, orange, 17, 18.5)
}