How to dynamically change text colour based on dynamically changing background colour - javascript

I am setting up a new website and need my text to change colour based on the ever-changing background colours in order to maintain contrast. I have scoured the web for answers that don't involve Sass, but none have worked...
I have tried some JavaScript, but they work only when the background is a fixed colour that you change manually.
My Current File:
https://codepen.io/jonathanlee/pen/wZXvRY
var color = function getRandomColor() {
var letters = '0123456789ABCDEF'.split('');
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
setInterval(function() {
document.getElementById("test").style.backgroundColor = color(); //() to execute the function!
}, 3000);
var ww = function isDarkColor(rgb) {
return Math.round((
parseInt(rgb[0], 10) * 299 +
parseInt(rgb[1], 10) * 587 +
parseInt(rgb[2], 10) * 114) / 1000) <= 140
}
if (ww <= 140) {
document.getElementById("test").style.color = '#fff';
} else {
document.getElementById("test").style.color = '#000';
}
One of the other solutions I've tried, but didn't work: http://jsfiddle.net/QkSva/
function isDark(color) {
var match = /rgb\((\d+).*?(\d+).*?(\d+)\)/.exec(color);
return (match[1] & 255) +
(match[2] & 255) +
(match[3] & 255) <
3 * 256 / 2;
}
$('div').each(function() {
console.log($(this).css("background-color"))
$(this).css("color", isDark($(this).css("background-color")) ? 'white' : 'black');
});
The real-life example is an alternate homepage on the website I'm working on, https://nepmelbourne.com/q. I have got a dynamic background, but there are some colours that don't contrast well against my white text.

One way to do it would be to set opposite color of background color to text as follows,
function invertColor(hex, bw) {
if (hex.indexOf('#') === 0) {
hex = hex.slice(1);
}
// convert 3-digit hex to 6-digits.
if (hex.length === 3) {
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
}
if (hex.length !== 6) {
throw new Error('Invalid HEX color.');
}
var r = parseInt(hex.slice(0, 2), 16),
g = parseInt(hex.slice(2, 4), 16),
b = parseInt(hex.slice(4, 6), 16);
if (bw) {
// http://stackoverflow.com/a/3943023/112731
return (r * 0.299 + g * 0.587 + b * 0.114) > 186 ?
'#000000' :
'#FFFFFF';
}
// invert color components
r = (255 - r).toString(16);
g = (255 - g).toString(16);
b = (255 - b).toString(16);
// pad each with zeros and return
return "#" + padZero(r) + padZero(g) + padZero(b);
}
function padZero(str, len) {
len = len || 2;
var zeros = new Array(len).join('0');
return (zeros + str).slice(-len);
}
var color = function getRandomColor() {
var letters = '0123456789ABCDEF'.split('');
var color = '#';
for (var i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
setInterval(function() {
var bgColor = color();
var textColor = invertColor(bgColor,true);
document.getElementById("test").style.backgroundColor = bgColor; //() to execute the function!
document.getElementById("test").style.color = textColor;
}, 3000);
<div id="test">This is some text</div>
Opposite color code taken from How can I generate the opposite color according to current color?
Added an extra parameter bw to invertColor(), if bw is set to true the text color will be black if background is bright and vice versa.

Related

How to achieve TRANSITION effect with setInterval method in JavaScript?

I've set up a web page which changes the background color of the body after every 2 seconds. What I've been struggling with is how to integrate transition effect into the setInterval method. I want the new colors to appear with a fade effect, just like the transition property does in CSS. How can I achieve this effect for these changing/switching background colors?
Here's my code:
var startButton = document.getElementById("startButton");
var body = document.getElementById("body");
// Click Event Listener
startButton.addEventListener("click", function() {
setInterval(function() {
body.style.backgroundColor = generateRandomColors();
}, 2000);
});
// GENERATE Random Colors
function generateRandomColors() {
var arr = [];
arr.push(pickRandomColor());
return arr;
}
// PICK Random Color
function pickRandomColor() {
// Red
var r = Math.floor(Math.random() * 256);
// Green
var g = Math.floor(Math.random() * 256);
// Blue
var b = Math.floor(Math.random() * 256);
// RGB
var rgb = "rgb(" + r + ", " + g + ", " + b + ")";
return rgb;
}
<html>
<body id="body">
<button id="startButton">Start</button>
</body>
</html>
Set the transition property specifying which property you want to transition and how long it will take.
var startButton = document.getElementById("startButton");
var body = document.getElementById("body");
// Click Event Listener
startButton.addEventListener("click", function() {
setInterval(function() {
body.style.backgroundColor = generateRandomColors();
}, 2000);
});
// GENERATE Random Colors
function generateRandomColors() {
var arr = [];
arr.push(pickRandomColor());
return arr;
}
// PICK Random Color
function pickRandomColor() {
// Red
var r = Math.floor(Math.random() * 256);
// Green
var g = Math.floor(Math.random() * 256);
// Blue
var b = Math.floor(Math.random() * 256);
// RGB
var rgb = "rgb(" + r + ", " + g + ", " + b + ")";
return rgb;
}
body { transition: background-color 2s; }
<html>
<body id="body">
<button id="startButton">Start</button>
</body>
</html>

Looping colors percent to RGB

I want to change colors from number. In here, i use RGB colors and I want to change colors if my change number.
function percentToRGB(mx,mi,md) {
var div = (mx-mi)/2;
var r, g, b;
if (md < div) {
// green to yellow
g = Math.floor(255 * (md / div));
r = 255;
} else {
// yellow to red
g = 255;
r = Math.floor(255 * ((div - md % div) / div));
}
b = 0;
return "rgb(" + r + "," + g + "," + b + ")";
}
function render(mx,mi,i,x) {
var x = 20;
document.getElementById("divX").innerHTML=x;
var res;
if(i === x){
document.getElementById("divX").style.backgroundColor=percentToRGB(mx,mi,x);
}
}
function repeat(fn, times,z,y,x) {
for (var i = 0; i < times; i++) {
fn(z,y,i,x);
}
document.getElementById("divX").style.backgroundColor=res;
}
repeat(render, 100,10,20);
li {
font-size:8px;
height:10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="divX"></div>
Example, i want to change number from 20 to 10 and yellow colors will change colors accordingly number.
But in my code just show one colors (yellow).

js background colour transition

I've got the following piece of code and I'd like the 'rect' element (which is a canvas element) transition the colour from black to white. It doesn't. Please advise:
var background = document.getElementById("rect");
setInterval(function() {
for (i=0;i<255;i++) {
background.style.backgroundColor = 'rgb(' + [i, i, i].join(',') + ')';
}
}, 900);
By changing the colors in a loop, you're effectively doing it all at once. Instead, do one change per interval callback:
var background = document.getElementById("rect");
var i = 0;
var timer = setInterval(function() {
background.style.backgroundColor = 'rgb(' + [i, i, i].join(',') + ')';
if (++i > 255) {
clearInterval(timer);
}
}, 900);
Note that at 900ms per change and 255 changes, that will take a long time to complete, so you may need to adjust the interval.
Here's an example using an interval of 20ms:
var background = document.getElementById("rect");
var i = 0;
var timer = setInterval(function() {
background.style.backgroundColor = 'rgb(' + [i, i, i].join(',') + ')';
if (++i > 255) {
clearInterval(timer);
}
}, 20);
#rect {
height: 4em;
}
<div id="rect"></div>

Trying to randomize div color when mouse enters

I'm trying to have it so that each square is a different color when the user hovers over it once the "randomize" button is clicked. Nothing changes when I chose the randomize function. Here's my code:
function randomSetup(numOfSquares){
var numSquares = numOfSquares;
var squareSide = 500 / numSquares;
var totalSquares = numSquares * numSquares;
for(var rows = 0; rows < totalSquares; rows++){
$('<div class="gridSquare"></div>').appendTo('.container')
}
var colors = randomColor();
$('.container').on('mouseenter', '.gridSquare', function(){
$(this).css('background-color', 'rgb(colors,colors,colors)');
});
$('.gridSquare').width(squareSide);
$('.gridSquare').height(squareSide);
}
function randomColor(){
return Math.random() * (255 - 0) + 1;
}
Fiddle
This is invalid:
'rgb(colors,colors,colors)'
Try this:
$('.container').on('mouseenter', '.gridSquare', function(){
var red = randomColor();
var green = randomColor();
var blue = randomColor();
$(this).css('background-color', 'rgb('+red+','+green+','+blue+')');
});
You also need to round your random number:
function randomColor(){
return Math.round(Math.random() * (255 - 0) + 1);
}
http://jsfiddle.net/oLonz7c0/21/
Here you go: http://jsfiddle.net/oLonz7c0/7/
Trippy.
Regenerate the random colors inside the event handler so each square is a different color.
$('.container').on('mouseenter', '.gridSquare', function(){
var colors = [];
colors[0] = Math.round(randomColor());
colors[1] = Math.round(randomColor());
colors[2] = Math.round(randomColor());
$(this).css('background-color', 'rgb('+colors[0]+','+colors[1]+','+colors[2]+')');
});
You can try some thing like
function randomColor(){
var colors = ["#CCCCCC","#333333","#990099"];
var rand = Math.floor(Math.random()*colors.length);
//return Math.random() * (255 - 0) + 1;
return colors[rand];
}
And
var colors ='';
$('.container').on('mouseenter', '.gridSquare', function(){
colors = randomColor();
$(this).css('background-color',colors );
});
Fiddle : http://jsfiddle.net/oLonz7c0/14/

Move text up with javascript

So I need function like this one, -link- but just to move text up, not left. How to achieve this?
So, this is code that moves text left:
//Text fade
var bgcolor;
var fcolor;
var heading;
//Number of steps to fade
var steps;
var colors;
var color = 0;
var step = 1;
var interval1;
var interval2;
//fade: fader function
// Fade from backcolor to forecolor in specified number of steps
function fade(headingtext,backcolor,forecolor,numsteps) {
if (color == 0) {
steps = numsteps;
heading = "<font color='{COLOR}'>"+headingtext+"</strong></font>";
bgcolor = backcolor;
fcolor = forecolor;
colors = new Array(steps);
getFadeColors(bgcolor,fcolor,colors);
}
// insert fader color into message
var text_out = heading.replace("{COLOR}", colors[color]);
// write the message to the document
document.getElementById("fader").innerHTML = text_out;
// select next fader color
color += step;
if (color >= steps) clearInterval(interval1);
}
//getFadeColors: fills colors, using predefined Array, with color hex strings fading from ColorA to ColorB
//Note: Colors.length equals the number of steps to fade
function getFadeColors(ColorA, ColorB, Colors) {
len = Colors.length;
//Strip '#' from colors if present
if (ColorA.charAt(0)=='#') ColorA = ColorA.substring(1);
if (ColorB.charAt(0)=='#') ColorB = ColorB.substring(1);
//Substract red green and blue components from hex string
var r = HexToInt(ColorA.substring(0,2));
var g = HexToInt(ColorA.substring(2,4));
var b = HexToInt(ColorA.substring(4,6));
var r2 = HexToInt(ColorB.substring(0,2));
var g2 = HexToInt(ColorB.substring(2,4));
var b2 = HexToInt(ColorB.substring(4,6));
// calculate size of step for each color component
var rStep = Math.round((r2 - r) / len);
var gStep = Math.round((g2 - g) / len);
var bStep = Math.round((b2 - b) / len);
// fill Colors array with fader colors
for (i = 0; i < len-1; i++) {
Colors[i] = "#" + IntToHex(r) + IntToHex(g) + IntToHex(b);
r += rStep;
g += gStep;
b += bStep;
}
Colors[len-1] = ColorB; // make sure we finish exactly at ColorB
}
//IntToHex: converts integers between 0 - 255 into a two digit hex string.
function IntToHex(n) {
var result = n.toString(16);
if (result.length==1) result = "0"+result;
return result;
}
//HexToInt: converts two digit hex strings into integer.
function HexToInt(hex) {
return parseInt(hex, 16);
}
var startwidth = 0;
//scroll: Make the text scroll using the marginLeft element of the div container
function scroll(startw) {
if (startwidth == 0) {
startwidth=startw;
}
document.getElementById("fader").style.marginLeft = startwidth + "px";
if (startwidth > 1) {
startwidth -= 1;
} else {
clearInterval(interval2);
}
}
function fadeandscroll(txt,color1,color2,numsteps,fademilli,containerwidth,scrollmilli) {
interval1 = setInterval("fade('"+txt+"','"+color1+"','"+color2+"',"+numsteps+")",fademilli);
interval2 = setInterval("scroll("+containerwidth+")",scrollmilli);
}
Something like this seems to do what you want, but jQuery would have been easier.
Demo: Vertical Marquee Demo
window.document.addEventListener("DOMContentLoaded", function()
{
var elm = window.document.querySelectorAll("#display span")[0], height = elm.parentNode.offsetHeight;
elm.style.position = "relative";
elm.style.top = "0px";
var timer = setInterval(function()
{
var top = Number(elm.style.top.replace(/[^\d\-]/g, ''));
top = top > -height ? top - 1 : height;
elm.style.top = top + "px";
}, 50);
/*
* If you want to stop scrolling, call clearInterval(timer);
*
* Example set to stop when clicked.
*/
elm.addEventListener("click", function()
{
clearInterval(timer);
}, false);
}, false);

Categories