Looping colors percent to RGB - javascript

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).

Related

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

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.

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>

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>

updating HTML information through a Raphael.JS element

I'm trying to update the information of a series or circles that get created through a click event using Raphael.js along with some HTML tags. When they get created, the html generated keeps the information of the circle with the position of its X, Y and its radius, which can be dynamically changed when I move the circle around or change its size, this JSFiddle shows it more clearly:
http://jsfiddle.net/mauricioSanchez/L4mAL/
I have my event listeners
canvasHandler.mouseup(function (e) {
var mouseX = e.offsetX;
var mouseY = e.offsetY;
if (circlePickerSelector) {
makeCircle(mouseX, mouseY);
circlePickerSelector = false;
}
});
circlePicker.click(function () {
circlePickerSelector = !circlePickerSelector;
});
This is the main function that gets called in the first eventListener. Which creates the circle and the HTML elements for that
function makeCircle(mouseX, mouseY) {
//We call it before our circles are dragged so that their array is waiting to store the information
// addingArrays(circleCounter);
var radius;
var fill;
var circle = canvas.circle(mouseX, mouseY, 50).attr({
fill: "hsb(.8, 1, 1)",
stroke: "none",
opacity: .5,
});
// console.log(circles);
// We add an ID and a class to the circle
var ourCircle = $("circle").last();
ourCircle.attr("class", circleCounter);
// And then finally push it to our array of circles
circles.push(circle);
var handlerPos = [mouseX + 35, mouseY + 35];
var s = canvas.circle(handlerPos[0], handlerPos[1], 10).attr({
fill: "hsb(.8, .5, .5)",
stroke: "none",
opacity: .5
});
//We add an id and a class to our little circle.
s.node.id = sizerCounter;
var sizerClass = $('circle').last();
sizerClass.attr("class", "main-circle sizer");
var newSizerClass = $(".sizer");
// console.log(s);
s.hide();
//We now assign a handler for each little circle added and a main circle in order to hide them
var circleClass = $("." + String(circleCounter));
var sizerID = $("#" + String(sizerCounter));
circleClass.mouseenter(function () {
sizerID.toggle();
});
circleClass.mouseleave(function () {
sizerID.hide();
});
sizerID.mouseenter(function () {
$(this).toggle();
});
sizerID.mouseleave(function () {
$(this).hide();
});
// console.log(circleClass);
//We add some resizing and dragging properties
var start = function () {
//storing original coordinates
this.ox = this.attr("cx");
this.oy = this.attr("cy");
this.sizer.ox = this.sizer.attr("cx");
this.sizer.oy = this.sizer.attr("cy")
this.attr({
opacity: 1
});
this.sizer.attr({
opacity: 1
});
}, move = function (dx, dy) {
// move will be called with dx and dy
this.attr({
cx: this.ox + dx,
cy: this.oy + dy
});
this.sizer.attr({
cx: this.sizer.ox + dx,
cy: this.sizer.oy + dy
});
//This is the key function to change
updateModel(this.attrs.cx, this.attrs.cy, this.node.className.baseVal, this.attrs.r);
}, up = function () {
// restoring state
this.attr({
opacity: .5
});
this.sizer.attr({
opacity: .5
});
}, rstart = function () {
// storing original coordinates
this.ox = this.attr("cx");
this.oy = this.attr("cy");
this.big.or = this.big.attr("r");
}, rmove = function (dx, dy) {
// move will be called with dx and dy
this.attr({
cx: this.ox + dy,
cy: this.oy + dy
});
this.big.attr({
r: this.big.or + (dy < 0 ? -1 : 1) * Math.sqrt(2 * dy * dy)
});
updateModel(this.attrs.cx, this.attrs.cy, this.node.className.baseVal, this.attrs.r);
};
circle.drag(move, start, up);
circle.sizer = s;
s.drag(rmove, rstart);
s.big = circle;
//Here we create
var myCodeList = $(".code-list");
var htmlString = "<li class='" + circleCounter + "'> <span class='circle-color'> var color = <div class='circle-color-input' contentEditable autocorrect='off'> type a color</div> ; </span> <br> <span class='circle-radius'> This is a test </span> <br> <span class='circle'> This is a test </span> </li>";
myCodeList.append(htmlString);
updateList();
circleCounter++;
sizerCounter++;
}
Finally this two functions allow the html and the position of the circle to be updated:
function updateModel(x, y, _class, r) {
var len = circles.length;
for (var i = 0; i < len; i++) {
if (circles[i].node.className.baseVal == _class) {
circles[i].attrs.cx = x;
circles[i].attrs.cy = y;
circles[i].attrs.r = r;
}
}
updateList();
}
function updateList() {
//To change that one I have put a class or an id
var listItems = $('.code-list').find('li.' + circleCounter);
// console.log(listItems);
var len = circles.length;
for (var i = 0; i < circles.length; i++) {
//We create one reference. This makes looking for one element more effective. Unless we need to search for a particular element
var currentItem = circles[i];
var updateStringRadius = "var radius = " + parseInt(currentItem.attrs.r) + ";";
var updateStringCircle = "circle (" + currentItem.attrs.cx + " ," + currentItem.attrs.cy + ", radius)";
//This is the div Item for the particular div of each element
var divItem = $(listItems[i]);
var radiusItem = divItem.find("span.circle-radius");
var circleItem = divItem.find("span.circle");
// console.log(currentItem.attrs.cx);
radiusItem.text(updateStringRadius);
console.log($('.circle-radius').html());
circleItem.text(updateStringCircle);
// divItem.text(updateString);
// console.log(divItem);
}
}
If you take a look at the JSfiddle and create three circles for example. it will only update the information of the first one after a circle is created, but now when moved or when resized doesn't change.
I figured it out. So the problem was in this function:
function updateList() {
//To change that one I have put a class or an id
var listItems = $('.code-list').find('li.' + circleCounter);
// console.log(listItems);
var len = circles.length;
for (var i = 0; i < circles.length; i++) {
//We create one reference. This makes looking for one element more effective. Unless we need to search for a particular element
var currentItem = circles[i];
var updateStringRadius = "var radius = " + parseInt(currentItem.attrs.r) + ";";
var updateStringCircle = "circle (" + currentItem.attrs.cx + " ," + currentItem.attrs.cy + ", radius)";
//This is the div Item for the particular div of each element
var divItem = $(listItems[i]);
var radiusItem = divItem.find("span.circle-radius");
var circleItem = divItem.find("span.circle");
// console.log(currentItem.attrs.cx);
radiusItem.text(updateStringRadius);
console.log($('.circle-radius').html());
circleItem.text(updateStringCircle);
// divItem.text(updateString);
// console.log(divItem);
}
}
I changed the way I was initiating the handler and finding its children for this:
function updateList(){
var len = circles.length;
for (var i = 0; i < circles.length; i++) {
var currentItem = circles[i];
var updateStringRadius = "var radius = " + parseInt(currentItem.attrs.r) + ";";
var updateStringCircle = "circle (" + currentItem.attrs.cx + " ," + currentItem.attrs.cy + ", radius)";
var divItem = $('.code-list').find('li.circle-' + (i+1))
var radiusItem = divItem.find("span.circle-radius");
var circleItem = divItem.find("span.circle");
radiusItem.text(updateStringRadius);
circleItem.text(updateStringCircle);
}
I wasn't iterating through the elements properly. I was also recommended that for best practices to change my class from class="1" to class="circle-1".
Here is the JSfiddle

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