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>
Related
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.
Hi i made a stopwatch in javascript and every time it updates, it deletes, and then after a second appears again and deletes. So every second it appears and disappears, making it blink. How can i make it appear until the next second updates, making a smooth transition.
Here is my code:
function GameTimer() {
var gameTimeMinutes = 0;
var gameTimeSeconds = 0;
var gameTime = "";
this.addTime = function() {
gameTimeSeconds += 1;
if (gameTimeSeconds < 10) {
gameTime = gameTimeMinutes + " : 0" + gameTimeSeconds;
} else {
gameTime = gameTimeMinutes + " : " + gameTimeSeconds;
}
if (gameTimeSeconds == 60) {
gameTimeSeconds = 0;
gameTimeMinutes++;
}
};
this.draw = function() {
graph.clearRect(0, 0, canvas.width, canvas.height);
var fontSize = 25;
graph.lineWidth = playerConfig.textBorderSize;
graph.fillStyle = playerConfig.textColor;
graph.strokeStyle = playerConfig.textBorder;
graph.miterLimit = 1;
graph.lineJoin = 'round';
graph.textAlign = 'right';
graph.textBaseline = 'middle';
graph.font = 'bold ' + fontSize + 'px sans-serif';
graph.strokeText(gameTime, 100, 30);
graph.fillText(gameTime, 100, 30);
};
this.update = function() {
this.addTime();
this.draw();
}.bind(this);
this.update();
}
var playerConfig = {textBorderSize: "1px", textColor: "black", textBorder: "solid"};
var canvas = document.getElementById("timer");
var graph = canvas.getContext("2d");
var gameTimer = new GameTimer();
setInterval(gameTimer.update, 1000);
<canvas id="timer" width="200" height="100"></canvas>
So just to clarify, i tried changing the interval time to ten seconds, and every ten seconds it appears and disappears, meaning that it is gone for the next ten seconds until it appears and disappears again. It doesn't stay there until the next update.
Thanks!
I believe that the flashing could be a result of setInterval not synchronizing with the screen's refresh rate. If so, requestAnimationFrame may be able to solve this.
This does use unnecessary system resources, but may solve your problem regardless.
Try this:
this.timeUntilUpdate = Date.now();
this.update = function(){
if(Date.now() - this.timeUntilUpdate > 1000){
this.addTime();
this.draw();
}
requestAnimationFrame(this.update);
}
And then at the end replace setInterval(gameTimer.update, 1000); with requestAnimationFrame(GameTimer.update) or possibly just GameTimer.update();
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>
I was trying to create an animation where it loads when the page loads.
Initially it creates object with white background.
Every 1 second, it shifts the object to right by 10px, at mean while change the object color by adding 10 to its RGB value.
I've create this jsFiddle, but it doesn't work (border is to distinguish the object)
Any inputs will be largely appreciated.
function RGB2HTML(red, green, blue)
{
var decColor =0x1000000* blue + 0x100 * green + 0x10000 *red ;
return '#'+decColor.toString(16).substr(1);
}
window.onload = function(){
var currentColor='white';
var red = 0;
var green = 0;
var blue =0;
setInterval(function(){
$('.object').style.top += 10px;
$('.object').style.left += 10px;
$('.object').style.background-color = RGB2HTML(red+10; green+10; blue+10)
}, 1000);
};
Here is the jsfiddle:
http://jsfiddle.net/jykG8/70/
Here you go: http://jsfiddle.net/jykG8/77/
We can set variables for the initial top and left values, so that we may pass them into jQuery's .css() and increment from there. The same principal applies with the color transformation.
window.onload = function(){
var currentColor='white';
var red = 0;
var green = 0;
var blue = 0;
var top = 0;
var left = 0;
setInterval(function(){
$('.object').css('top', top += 10);
$('.object').css('left', left += 10);
$('.object').css('background-color', 'rgb('+(red+=10)+','+(green+=10)+','+(blue+=10)+')');
}, 1000);
};
Further, since we're dealing with one selector, we can combine the CSS properties into one call:
$('.object').css({
'top' : top += 10,
'left' : left += 10,
'background-color' : 'rgb('+(red+=10)+','+(green+=10)+','+(blue+=10)+')'
});
Example: http://jsfiddle.net/jykG8/80/
Try this:
window.onload = function(){
var red = 0;
var green = 0;
var blue =0;
setInterval(function(){
var t = parseInt($('.object').css('top')) + 10;
var l = parseInt($('.object').css('left')) + 10;
red += 10;
green += 10;
blue += 10;
$('.object').css({top: t}).css({left: l}).css({'background-color': '#' + red.toString(16) + green.toString(16) + blue.toString(16)});
}, 1000);
};
http://jsfiddle.net/jykG8/79/
http://jsfiddle.net/vdU9X/
function RGB2HTML(red, green, blue)
{
var decColor = blue + 256 * green + 65536 * red;
return '#' + decColor.toString(16);
}
window.onload = function(){
var currentColor='white';
var red = 255;
var green = 255;
var blue =255;
var left = 0;
var top = 0;
setInterval(function(){
top += 10;
left += 10;
red -= 10;
green -= 10;
blue -= 10;
$('.object').css ({
'top' : top,
'left' : left,
'background-color': RGB2HTML(red, green, blue)
});
}, 1000);
};
I'm not 100% sure about the RGB2HTML function. I may have the blue & red reversed. But, if you want to go from white to black you need to start at 256 and go down. There should be some logic added to account for negative being invalid.
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);