// Vanilla solution let format = require('util').format; const COLORS = [ { stop: 0, rgb: [35, 198, 161] }, { stop: 6, rgb: [245, 235, 73] }, { stop: 48, rgb: [245, 51, 0] }, ]; function getRGBColor (hours) { // ordering of max and min IS IMPORTANT as we're mutating the colors array with reverse let colors = COLORS.slice(0), min = colors.reduce((min, color) => color.stop <= hours ? color : min), max = colors.reverse().reduce((max, color) => color.stop >= hours ? color : max), normalizationFactor; // control for out of bounds, use the same value twice in such an event max = max || min; min = min || max; // calculate the normalization factor, should always be between 0 - 1 normalizationFactor = (hours - min.stop) / (max.stop - min.stop); // at this point we don't care about the stops anymore, just the rgb and factor // calculate and return one RGB array return min.rgb.map((c, i) => { let rgb1 = min.rgb[i], rgb2 = max.rgb[i], normalizedDiff = (rgb2 - rgb1) * normalizationFactor, return Math.round(rgb1 + normalizedDiff); }); } // Timer logic // Pretty shitty but just playing around function simulateTime () { const NOW = Date.now(); const eventDate = NOW + (1000 * 60 * 60 * 24 * 2); // 2 days from now let currentTime = NOW; let interval = setInterval(() => { if (currentTime < eventDate) { let duration = eventDate - currentTime, hours = Math.ceil(duration / 1000 / 60 / 60), color = getRGBColor(hours); console.log(`${format(color)} ${new Date(currentTime).toString()} ${hours} hours before the event`); currentTime += 1000 * 60 * 60 * 2; // increment by 2 hours } else if (currentTime >= eventDate + 3000) { clearInterval(interval); } }, 1000); } simulateTime();