This HTML and Javascript combined are supposed to form bars that are the height of the numbers entered in the prompt, relative to each other. The bars are not appearing when the numbers are entered. What do I need to fix in my code in order to make the bars appear?
"use strict";
window.onload=function()
{
var userValue;
var i;
var j;
var k;
var error;
var correct;
j = 0;
k = 0;
error = new Array(j);
correct = new Array(k);
userValue = window.prompt("Insert values separated by comma, whitespace, or both.");
userValue = packArray(trimElements(toArray(userValue, " ,")));
for(i = 0; i < userValue.length; i++)
{
if(isNumeric(userValue[i]) === false)
{
error[j] = userValue[i];
j = j + 1;
}
else
{
correct[k] = userValue[i];
k = k + 1;
}
}
if(error.length > 0)
{
window.alert("Error: " + error);
}
else
{
createGraph(userValue, document.getElementById("positiveQuadrant"));
}
};
function toArray(data, delimiters)
{
var locArray;
var result;
var i;
var dataArray;
var start;
locArray = findPositions(data, delimiters);
result = "";
i = 0;
if(data === null)
{
data = "";
}
else
{
result = result + data;
}
if(delimiters === null)
{
delimiters = "";
}
else
{
result = result + delimiters;
}
if(delimiters.length === 0)
{
delimiters = delimiters + " \t\r\n\f";
}
dataArray = new Array(locArray.length + 1);
start = 0;
while(i < dataArray.length)
{
dataArray[i] = data.substring(start, locArray[i]);
start = locArray[i] + 1;
i = i + 1;
}
return dataArray;
}
function findPositions(someString, lookForThis)
{
var i;
var result;
var count;
result = new Array(count);
i = 0;
count = 0;
while(i < someString.length)
{
if(lookForThis.indexOf(someString.charAt(i)) >= 0)
{
result[count] = someString.indexOf(lookForThis.charAt(i), (i + 1) - 1);
count = count + 1;
}
i = i + 1;
}
return result;
}
function trimElements(array)
{
var i;
var trimArray;
trimArray = new Array(array.length);
i = 0;
while(i < array.length)
{
trimArray[i] = trim(array[i]);
i = i + 1;
}
return trimArray;
}
function packArray(array)
{
var i;
var count;
var packedArray;
i = 0;
count = 0;
packedArray = new Array(count);
while(i < array.length)
{
if(array[i] !== null && array[i] !== "")
{
packedArray[count] = array[i];
count = count + 1;
}
i = i + 1;
}
return packedArray;
}
function convertToNumber(array)
{
var i;
var result;
i = 0;
result = "";
while(i < array.length)
{
if(isNumeric(array[i]) === true)
{
array[i] = Number(array[i]);
}
else
{
result = result + " " + array[i];
}
i = i + 1;
}
return trim(result);
}
function trim(data)
{
var start;
var whitespace;
var end;
var result;
if(typeof data==="string")
{
whitespace=" \n\r\t\f";
start=0;
}
else
{
result=data;
}
while((start<data.length)&&(whitespace.indexOf(data.charAt(start))))
{
start=start+1;
};
end=data.length-1;
while((end>=0)&&(whitespace.indexOf(data.charAt(end))))
{
end=end-1;
};
if(end<start)
{
result="";
}
else
{
result=data.substring(1+start,end);
}
return result;
};
function createHTMLElement(elementType, id, classInfo, content)
{
if(elementType===null)
{
elementType="";
};
trim(elementType);
if(id===null)
{
id="";
}
trim(id);
if(id.length>0)
{
id=" "+"id="+'"'+id+'"'+" ";
};
if(classInfo===null)
{
classInfo="";
}
trim(classInfo);
if(classInfo.length>0)
{
classInfo=" "+ "class="+'"'+classInfo+'"';
}
if(content===null)
{
content="";
};
trim(content);
return '<' +elementType +
id + classInfo +
'>' + content +
'</' + elementType + '>';
};
function isNumeric(data)
{
return isNaN(data);
};
function getRandomInteger(upperLimit)
{
return Math.floor(Math.random()*(upperLimit+1));
};
function getRandomRGB()
{
var blue;
var green;
var red;
red=getRandomInteger(255);
blue=getRandomInteger(255);
green=getRandomInteger(255);
return"rgb("+red+","+green+","+blue+")";
};
function createScaledArray(array, scaleFactor)
{
var i;
var scaledArray;
scaledArray = new Array(array.length);
for(i = 0; i < array.length; i++)
{
scaledArray[i] = (array[i] / scaleFactor);
}
return scaledArray;
}
function createGraph(array, quadReference)
{
var i;
var loc;
var scaleFactor;
var scaleArray;
var html;
var element;
var elementTop;
if(array.length > 0)
{
loc = 0;
for(i = 0; i < array.length; i++)
{
if(Number(array[i]) > Number(array[loc]))
{
loc = i;
}
}
scaleFactor = Math.abs(array[loc]);
scaleArray = createScaledArray(array, scaleFactor);
html = "";
for(i = 0; i < scaleArray.length; i++)
{
html = html + createHTMLElement("div", "columnContainer", "columnContainer", createHTMLElement("div", "coloredArea" + i, "coloredArea", createHTMLElement("div", "dataValue", "dataValue", array[i])));
}
quadReference.innerHTML = html;
for(i = 0; i < scaleArray.length; i++)
{
element = document.getElementById("coloredArea" + i);
elementTop = (100 - (scaleArray[i] * 100));
if(elementTop > 100)
{
elementTop = elementTop + (scaleArray[i] * 100);
}
element.style.top = elementTop + "%";
element.style.height = Math.abs(scaleArray[i] * 100) + "%";
element.style.backgroundColor = getRandomRGB();
}
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<title> Graphing </title>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
<script src="Graphing.js" type="text/javascript"></script>
<style type="text/css">
{
border : 0;
margin : 0;
padding : 0;
}
body
{
font-family : "Times New Roman", serif;
font-size : 12pt;
}
.positiveQuadrant
{
height:12em;
width:2em;
border-right:solid black 3px;
}
.negativeQuadrant
{
position:relative;
height:2em;
width:22em;
border-top:solid black 3px;
bottom:2em;
}
.columnContainer
{
position: relative;
float: left;
height: 10em;
width: 1.5em;
margin: 1px;
}
.coloredArea
{
position: relative;
background-color: red;
}
.dataValue
{
font-size: 12pt;
text-align: center;
position: relative;
top: -16px;
}
</style>
</head>
<body>
<div class ="positiveQuadrant" id="positiveQuadrant"></div>
<div class = "negativeQuadrant" id ="negativeQuadrant"></div>
</body>
</html>
Related
I've been trying to make a little neural network. It plays a copy of the No-Wifi Google dinosaure game. It is not the most efficient (and probably has a tons of leaks), but it works after a hundred generations more or less. But I've notived something: the best elements of the previous generations do not copy to the next or don't act as before, shown by how the best before always jumped and then the next generation doesn't jump at all. Where is the problem? Btw it is a large code but I don't know how to attach files, can you comment on how?
HTML file:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" name="viewport" content="width=device-width,initial-scale=1">
<title>Dino</title>
<script type="text/javascript" src="genetic.js" defer></script>
<script type="text/javascript" src="dino.js" defer></script>
<script type="text/javascript" src="population_dino.js" defer></script>
<link rel="stylesheet" href="dino.css">
</head>
<body>
<div id="score">Score: 0</div>
<div id="line"></div>
<div id="test"></div>
</body>
</html>
genetic.js:
function sigmoid(t) {
return 1/(1+Math.pow(Math.E, -t));
}
function weightedRand(spec) {
var i, j, table=[];
for (i in spec) {
for (j=0; j<spec[i]*10; j++) {
table.push(i);
}
}
//console.log(table,spec)
return table[Math.floor(Math.random() * table.length)];
}
function randomfromminustoone(){
return Math.random()*2-1;
}
class Connection {
constructor(weight) {
if (weight==null){
this.weight=randomfromminustoone();
} else{
this.weight = weight;
}
}
get_weight() {
return this.weight;
}
set_weight(weight) {
return this.weight = weight;
}
}
class Neuron {
constructor(numOuputs = 0, neuronIndex, weights = []) {
this.outputWeights = [];
this.outputVal = null;
this.neuronIndex = neuronIndex;
for (let c = 0; c < numOuputs; c++) {
var weight = weights[c] || null;
this.outputWeights.push(new Connection(weight));
}
}
setOutputVal(outputVal) {
this.outputVal = outputVal;
}
getOutputVal(inputs,inputWeights) {
this.outputVal=0;
for (var i = inputs.length - 1; i >= 0; i--) {
this.outputVal+=inputs[i]*inputWeights[i];
}
this.outputVal=sigmoid(this.outputVal);
return this.outputVal;
}
getNeuronIndex() {
return this.neuronIndex;
}
getOuputWeight(i){
return this.outputWeights[i].get_weight();
}
updateInputWeights(prevLayer) {
for (let n = 0; n < prevLayer.length-1; n++) {
let neuron = prevLayer[n];
// neuron.outputWeights[this.neuronIndex].weight += ;
}
}
}
class Net {
constructor(topology = [],model=false) {
if (model){
this.layers=model.layers;
//console.log("flag");
} else {
this.topology = topology;
// number of layers
this.numLayers = topology.length;
this.layers = [];
for (let layerNum = 0; layerNum < this.numLayers; layerNum++) {
var layer = [];
var numOuputs = topology[layerNum + 1] ? topology[layerNum + 1] : 0;
for (let neuronNum = 0; neuronNum < topology[layerNum]; neuronNum++) {
let neuron = new Neuron(numOuputs, neuronNum);
layer.push(neuron);
}
this.layers.push(layer);
}
}
}
/*
getResults() {
this.resultVals = [];
var lastLayer = this.layers[this.layers.length-1];
for (let n = 0; n < lastLayer.length-1; n++) {
this.resultVals.push(lastLayer[n].getOutputVal());
}
return this.resultVals;
}*/
feedLayer(inputs,layerNum){
let layer=this.layers[layerNum];
let outputs=[];
for (let i = 0; i < layer.length; i++) {
let neuron = layer[i];
let neuronWeights=[];
for (let a = 0; a < this.layers[layerNum-1].length; a++) {
neuronWeights.push(this.layers[layerNum-1][a].getOuputWeight(i));
}
outputs.push(neuron.getOutputVal(inputs,neuronWeights));
}
return outputs;
}
feedAll(inputs){
let prevOutputs=inputs;
for (let i = 1; i < this.layers.length; i++) {
prevOutputs=this.feedLayer(prevOutputs,i);
}
return prevOutputs;
}
};
class Population{
constructor (PopNumber,topology,bestResults=[]){
if (bestResults.length>1){
this.population=[];
for (var i = 0; i < bestResults.length; i++) {
this.population.push(bestResults[i][1]);
console.log(bestResults[i][1].feedAll([0.05,0]))
}
for (var i = 0; i < PopNumber-bestResults.length; i++) {
let addNet= this.choose(bestResults);
/*if (randomfromminustoone()>0.5){
addNet=this.mix_elements(addNet,this.choose(bestResults));
}*/
addNet=this.mutate_values(addNet);
this.population.push(addNet);
}
} else {
this.population=[];
for (var i = 0; i < PopNumber; i++) {
let addNet= new Net(topology);
this.population.push(addNet);
}
}
}
choose(results){
let dic={};
for (var i = 0; i < results.length; i++) {
dic[i]=results[i][0];
}
return results[weightedRand(dic)][1];
}
mix_elements(elem1,elem2){
var output= new Net();
output.topology = elem2.topology;
output.numLayers = elem2.numLayers;
output.layers = elem2.layers;
for (var i = 0; i < elem1.layers.length; i++) {
for (var a = 0; a < elem1.layers[i].length; a++) {
if (randomfromminustoone()>0.5){
output.layers[i][a]=elem1.layers[i][a];
}
}
}
return output;
}
mutate_values(model){
if (model==null){
return [];
}
var output= new Net();
output.topology = model.topology;
output.numLayers = model.numLayers;
output.layers = model.layers;
for (var layer = 0; layer < output.layers.length; layer++) {
for (var neuron = 0; neuron < output.layers[layer].length; neuron++) {
for (var i = 0; i < output.layers[layer][neuron].outputWeights.length; i++) {
if (randomfromminustoone()>0.75){
output.layers[layer][neuron].outputWeights[i].weight =output.layers[layer][neuron].outputWeights[i].get_weight()+randomfromminustoone()/5;
}
}
}
}
return output;
}
};
dino.js:
function getRndInteger(min, max) {
return Math.floor(Math.random() * (max - min + 1) ) + min;
};
function Dino(brain,pop){
this.cooldown=0;
this.score=0;
this.alive=true;
this.y=300;
this.before_jump=this.y;
this.inertia=0;
this.population=pop;
this.div = document.createElement('div');
this.div.className="Dino";
this.div.main=this;
this.div.style.top=this.y+"px";
document.body.appendChild(this.div);
this.brain = brain;
};
Dino.prototype.jump = function(dino){
if (dino.y==dino.before_jump){
//dino.y=dino.before_jump;
dino.inertia=3;
dino.jumpInterval=setInterval( jump => {
dino.y-=dino.inertia
dino.div.style.top=dino.y+"px";
dino.inertia -= 0.05;
if (dino.y>dino.before_jump){
dino.inertia=0;
clearInterval(dino.jumpInterval);
dino.y=dino.before_jump;}
});
}
};
Dino.prototype.down = function(dino){
if (dino.y<dino.before_jump && dino.inertia>-5){
dino.inertia-=1.5;
}
};
Dino.prototype.lost =function(dino){
dino.alive=false;
dino.div.remove();
dino.score=dino.population.score;
dino.population.still_alive-=1;
dino.population.records.push(dino.brain);
delete dino;
};
Dino.prototype.check_collision = function(dino) {
cactuses=document.getElementsByClassName("cactus");
for (var i = cactuses.length - 1; i >= 0; i--) {
if (cactuses[i].main.x<=280 && dino.y>=280 && dino.alive){
dino.lost(dino);
}
};
};
Dino.prototype.smart = function(dino){
var cactuses=Array.from(document.getElementsByClassName("cactus"));
cactuses.sort(function(cactus){
return cactus.main.x;
});
if (cactuses.length>0){
var distance_nearest_cactus=(cactuses[0].main.x-240)/660;
} else{
var distance_nearest_cactus=1;
};
let results = dino.brain.feedAll([distance_nearest_cactus,(300-dino.y)/100*(-dino.inertia/3)]);
let high_score=results.indexOf(Math.max.apply(Math,results))
if (high_score==0){
dino.jump(dino);
} else if (high_score==1){
dino.down(dino);
};
};
function Dot(height){
this.y=height
this.x=900
//-- cree le DIV
this.div = document.createElement('div');
this.div.className = 'dot';
this.div.style.top=this.y+"px";
this.div.style.left=this.x+"px";
this.div.main=this;
document.body.appendChild(this.div);
};
Dot.prototype.delete =function(leave_div)
{
if (leave_div == false){
this.div.remove();
}
delete this;
};
function CreateDot(){
new Dot(getRndInteger(346,350));
};
function Cactus(){
this.x=900
this.div = document.createElement('div');
this.div.style.left=this.x+"px";
this.div.className="cactus";
this.div.main=this;
document.body.appendChild(this.div);
};
Cactus.prototype.delete =function(leave_div)
{
if (leave_div == false){
this.div.remove();}
delete this;
}
function CreateCactus(){
new Cactus();
}
function move_object(object){
object.main.x -= 1;
object.main.div.style.left = object.main.x+'px';
if (object.main.x<230)
{
object.main.delete(false);
}
};
population_dino.js:
class Dino_population{
constructor(nbPopulation,id,prevPop=[]){
this.population=[];
this.id=id;
document.getElementById("test").innerHTML=this.id;
this.brains=new Population(nbPopulation,[2,5,5,3],prevPop);
for (var i = 0; i < nbPopulation; i++) {
this.population.push(new Dino(this.brains.population[i],this));
}
this.number=nbPopulation;
this.still_alive=nbPopulation;
this.score=0;
this.speed=4.5;
var self= this;
this.move_interval=setInterval(function(){self.move_all(self)},self.speed);
this.last_cactus=1000;
this.records=[];
}
move_all(self){
if (getRndInteger(0,60)<10){
CreateDot();
}
self.last_cactus-=getRndInteger(1,10);
if (self.last_cactus<10){
self.last_cactus=getRndInteger(500,5000);
CreateCactus();
}
var cactuses=document.getElementsByClassName("cactus");
for (var i = cactuses.length - 1; i >= 0; i--) {
move_object(cactuses[i]);
};
var dots=document.getElementsByClassName("dot");
for (var v = dots.length - 1; v >= 0; v--) {
move_object(dots[v]);
}
self.score+=1;
document.getElementById("score").innerHTML = "Score: "+Math.floor(self.score/10).toString();
for (var i = self.population.length - 1; i >= 0; i--) {
let dino=self.population[i];
dino.cooldown-=1;
if (dino.cooldown<=0){
dino.cooldown=10;
dino.smart(dino);
}
dino.check_collision(dino);
}
if (self.still_alive==0){
clearInterval(self.move_interval);
var cactuses=document.getElementsByClassName("cactus");
while (cactuses.length>0){
delete cactuses[0].main;
cactuses[0].remove();
};
var dots=document.getElementsByClassName("dot");
while (dots.length>0){
delete dots[0].main;
dots[0].remove();
};
self.new_pop(self);
}
}
new_pop(old){
let old_bests= old.records.slice(Math.max(old.records.length - 10, 0));
let old_best_weighted=[]
for(let i=0;i<old_bests.length;i++){
console.log([old_bests[i].feedAll([0.05,0])])
old_best_weighted.push([10-i,old_bests[i]]);
}
let old_nb=old.number;
let old_id=old.id;
globalThis.pop= new Dino_population(old_nb,old_id+1,old_best_weighted);
}
}
var pop=new Dino_population(200,1);
dino.css:
.Dino{
background-image: url("Dinausaure.png");
background-repeat: no-repeat;
background-size: contain;
width: 60px;
height: 45px;
left: 240px;
position: absolute;
z-index: 3;
}
#ground{
width: 1000px;
height: 200px;
top:270px;
left: 240px;
position: absolute;
}
#line{
width: 670px;
height: 0px;
top:345px;
left:230px;
border-top: 2px solid black;
position: absolute;
z-index: 1;
}
.dot{
border-top: 2px solid black;
width: 2px;
position: absolute;
z-index: 1;
}
.cactus{
background-image: url("cactus.png");
background-repeat: no-repeat;
background-size: contain;
width: 60px;
height: 40px;
top:310px;
position: absolute;
z-index: 0;
}
#score{
top:180px;
left:230px;
position: absolute;
}
Here are the images:
Do no doubht in telling me any optimisation, mistake or bug. I am new at neural networks and do not have much experience with Js.
Any question ask me on comments.
How can I get the chat to scroll to bottom when new content is sent into the chat? I'm trying to add something like this:
$('#what do I have to put here?').animate({scrollTop: $('#and here?').prop("scrollHeight")}, 200);
but I can't make it work (I have no idea where in the code to place it).
Thanks!
This is an important part of the code... Maybe I have to add it here (but I don't know how or where):
<script type="text/javascript">
var _answerBot = new answerBot();
function keypressInput(sender, event) {
if (event.which == 13) {
document.getElementById('subcontent').innerHTML += _answerBot.processInput(sender.value);
sender.value = '';
}
}
</script>
This is a separate scripts.js file:
var answerBot = function () {
var _this = this;
_this.processInput = function (text) {
updateUrl(text);
var _result = "<p class='answerbot-input'>" + text + "</p>";
text = text.replace(new RegExp("[ ]{2,}", "g"), " ");
var _words = text.toLowerCase().split(" ");
var _answers = [];
var _title = "";
if (_words.length === 0 || _words.toString() === '') { //if the input is empty
_answers = _this.specialContext.emptyInput;
_title = _this.specialContext.emptyInput;
} else {
var _possibleAnswers = findMatches(_words);
if (_possibleAnswers.length === 0) { //if no answer found
_answers = _this.specialContext.wrongInput;
_title = _this.specialContext.wrongInput;
}
if (_possibleAnswers.length == 1) { //context recognized
_answers = _this.answers[_possibleAnswers[0]].values;
_title = _this.answers[_possibleAnswers[0]].description;
}
if (_possibleAnswers.length > 1) {
_result += formatText(_this.specialContext.rephrase, _this.specialContext.rephrase);
for (var i = 0; i < _possibleAnswers.length; i++) {
_result += formatText(_this.answers[_possibleAnswers[i]].description, _this.answers[_possibleAnswers[i]].description);
}
}
}
if (_answers.length > 0) {
var _rand = Math.floor((Math.random() - 0.001) * _answers.length);
_result += formatText(_answers[_rand], _title);
}
return _result;
};
function formatText(text, title) {
return "<p class=\'answerbot-ai\' title=\'" + title + "\'>" + text + "</p>";
}
function findMatches(words) {
var foundKeywords = [];
var _possibleAnswers = [];
for (var i = 0; i < _this.keywords.length; i++) {
foundKeywords[i] = 0;
for (var j = 0; j < words.length; j++) {
if (_this.keywords[i].keys.indexOf(words[j]) >= 0) {
foundKeywords[i]++;
if (foundKeywords[i] == _this.keywords[i].keys.length) {
return [_this.keywords[i].value];
}
}
}
if (foundKeywords[i] * 2 > _this.keywords[i].keys.length) {
_possibleAnswers.push(_this.keywords[i].value);
}
}
return _possibleAnswers.filter(function (elem, pos) {
return _possibleAnswers.indexOf(elem) == pos;
});
}
function updateUrl(text){
history.pushState(null, null, "#question=" + encodeURIComponent(text));
if(typeof ga === "function")//google analytics
ga('send', 'event', 'question', text);
}
};
function AddMessage() {
var $message = $("<p>").text("message");
var $messages = $("#messages");
$messages.append($message);
$messages.animate({
scrollTop: $messages.prop("scrollHeight")
});
}
#messages {
border: 1px solid #000;
height: 100px;
overflow: auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="chat">
<div id="messages"></div>
<button onClick="AddMessage()">Add Message</button>
</div>
I need a rainbow function in plain javascript.
Solution 1: Javascript + HSL
this should be working in any browser
window.addEventListener("load", function() {
var elements = document.getElementsByClassName("rainbowText");
for (let i = 0; i < elements.length; i++) {
generateRainbowText(elements[i]);
}
});
function generateRainbowText(element) {
var text = element.innerText;
element.innerHTML = "";
for (let i = 0; i < text.length; i++) {
let charElem = document.createElement("span");
charElem.style.color = "hsl(" + (360 * i / text.length) + ",80%,50%)";
charElem.innerHTML = text[i];
element.appendChild(charElem);
}
}
p {
font-size: 2em;
font-weight: 500;
}
<p class="rainbowText">This is an awesome text</p>
Solution 2: background-clip + linear-gradient
This is a webkit only answer (Chrome) but should be more efficient.
Update (01/2021): This is supported by modern browsers.
For compatibility list, check background-clip: text (including those with only -webkit- prefix support) here (MDN)
let nb_stops = 10; // 10 color stops should be enough
let dir = "left"; // left, right, top, bottom
function SetupRainbow() {
var rainbowStr = GetRainbowString(nb_stops, 80, 50);
var oppositeDir = (dir==="left"?"right":(dir==="right"?"left":(dir==="top"?"bottom":"top")));
var css = '.rainbowText {\
background-clip: text;\
color: transparent;\
-webkit-background-clip: text;\
-webkit-text-fill-color: transparent;\
background-image: -webkit-linear-gradient(' + dir + ',' + rainbowStr + '); \
background-image: linear-gradient(to ' + oppositeDir + ',' + rainbowStr + ') \
}'
var style = document.createElement("style");
style.type = 'text/css';
if (style.styleSheet) {
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
document.head.appendChild(style);
}
// function that generate the rainbow string
function GetRainbowString(nbStops, saturation, luminosity) {
let gap = 360 / nbStops,
colors = [];
for (let i = 0; i < nbStops; i++) {
colors.push("hsl(" + (i * gap) + "," + saturation + "%," + luminosity + "%)");
}
return colors.join();
}
window.addEventListener("load", function() {
SetupRainbow();
});
span {
font-size: 2em;
font-weight: 500;
}
<span class="rainbowText">This is an awesome text</span>
It depends on what kind of rainbow text do you want. Some rainbow styles are really elegant.
Here are few :-
A pen from codepen.
Another pen here.
animated rainbow text at jsfiddle.
<div class="rainbow-text">Words and things</div>
#keyframes rainbow-text {
0% {
color: #e87d7d;
}
2% {
color: #e88a7d;
}
4% {
color: #e8977d;
}
6% {
color: #e8a47d;
}
8% {
color: #e8b07d;
}
10% {
color: #e8bd7d;
}
12% {
color: #e8ca7d;
}
14% {
color: #e8d77d;
}
16% {
color: #e8e47d;
}
18% {
color: #dfe87d;
}
20% {
color: #d3e87d;
}
22% {
color: #c6e87d;
}
24% {
color: #b9e87d;
}
26% {
color: #ace87d;
}
28% {
color: #9fe87d;
}
30% {
color: #92e87d;
}
32% {
color: #86e87d;
}
34% {
color: #7de881;
}
36% {
color: #7de88e;
}
38% {
color: #7de89b;
}
40% {
color: #7de8a8;
}
42% {
color: #7de8b5;
}
44% {
color: #7de8c1;
}
46% {
color: #7de8ce;
}
48% {
color: #7de8db;
}
50% {
color: #7de8e8;
}
52% {
color: #7ddbe8;
}
54% {
color: #7dcee8;
}
56% {
color: #7dc1e8;
}
58% {
color: #7db5e8;
}
60% {
color: #7da8e8;
}
62% {
color: #7d9be8;
}
64% {
color: #7d8ee8;
}
66% {
color: #7d81e8;
}
68% {
color: #867de8;
}
70% {
color: #927de8;
}
72% {
color: #9f7de8;
}
74% {
color: #ac7de8;
}
76% {
color: #b97de8;
}
78% {
color: #c67de8;
}
80% {
color: #d37de8;
}
82% {
color: #df7de8;
}
84% {
color: #e87de4;
}
86% {
color: #e87dd7;
}
88% {
color: #e87dca;
}
90% {
color: #e87dbd;
}
92% {
color: #e87db0;
}
94% {
color: #e87da4;
}
96% {
color: #e87d97;
}
98% {
color: #e87d8a;
}
100% {
color: #e87d7d;
}
}
.rainbow-text {
animation: rainbow-text 1s infinite;
}
I researched the same thing and came up with this:
var css = 'body {animation-name:test; animation-duration:4s; animation-iteration-count:infinite; } #keyframes test{ 0%{color:#ff0000} 20%{color:#00ff00} 40%{color:#ffff00} 60%{color:#0000ff} 80%{color:#00ffff} 100%{color:#ff0000}', head = document.head || document.getElementsByTagName('head')[0], style = document.createElement('style'); style.type = 'text/css'; if (style.styleSheet){ style.styleSheet.cssText = css; } else { style.appendChild(document.createTextNode(css)); } head.appendChild(style);
<p>WOO!<p>
This also works as a bookmarklet, with great results!
const colors = ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet'];
var temp=document.getElementsByTagName('span');
for(let i=0;i<colors.length;i++){
temp[i].style.color=colors[i];
}
<!DOCTYPE html>
<head>
<title>Rainbow</title>
<script src="node_modules/babel-polyfill/dist/polyfill.js" type="text/javascript"> </script>
<script src="https://unpkg.com/#babel/standalone/babel.min.js"></script>
</head>
<body>
<h1>
<span>R</span>
<span>A</span>
<span>I</span>
<span>N</span>
<span>B</span>
<span>O</span>
<span>W</span>
</h1>
</body>
</html>
function rainbow(str) {
var multiplier = 5;
var result = "";
for (var i = 0; i < str.length; i++) {
result += "<font style='color: hsl(" + i * multiplier % 360 + ", 100%, 70%)'>";
result += str.substr(i, 1);
result += "</font>";
}
return result;
}
And it does the same in less time.
Pretty old question, but if anyone's still looking for a plain javascript ONLY answer to animated rainbow text (of which you can control direction and speed if you look hard enough through my spaghetti), here's my version: https://github.com/FeedbackFox/RGB-CSS-script
Working JSfiddle: https://jsfiddle.net/FeedbackFox/68ekobav/1/
//Script made by FeedbackFox. Please refrain from distributing this outside of github, but feel free to use it in whatever you want, whether commercial or non-commercial.
//https://github.com/FeedbackFox/RGB-CSS-script
(function(){
let textspeed = 1;
let backgroundspeed = 0.1;
let hoverspeed = 10;
let hoverbackgroundspeed = -1;
let classestoberainbowed = document.getElementsByClassName('foxrainbow');
let backgroundtoberainbowed = document.getElementsByClassName('foxrainbowbg');
let spanstoberainbowed = spanArrayContents(classestoberainbowed);
textcolorchange(spanstoberainbowed, textspeed);
//Actually do the rainbow effect. Backgrounds only.
let backgroundcounter = 0;
setInterval(() => {
for(let i = 0; i < backgroundtoberainbowed.length; i++) {
backgroundtoberainbowed[i].style.backgroundColor = 'hsl(' + (backgroundcounter + Math.floor(i * 1)) + ', 100%, 70%';
}
backgroundcounter = backgroundcounter + backgroundspeed;
}, 15);
//Turn the rainbow effect on only when the mouse is over the element. Use foxrainbowhover to use.
let rainbowhover = document.getElementsByClassName('foxrainbowhover');
let invertedhover = document.getElementsByClassName('foxrainbowhoverinv');
let rainbowelements = [];
let rainbowinvelements = [];
let hoverinterval = [];
let hoverinvinterval = [];
let hovercounters = [];
let invcounters = [];
let originalcolors = [];
let originalinvcolors = [];
for(let i = 0; i < rainbowhover.length; i++) {
rainbowelements[i] = spanElementContents(rainbowhover[i]);
}
for(let i = 0; i < invertedhover.length; i++) {
rainbowinvelements[i] = spanElementContents(invertedhover[i]);
}
//Set up the wavey effect with counters.
for(let id = 0; id < rainbowelements.length; id++) {
hovercounters[id] = [];
for(let i = 0; i < rainbowelements[id].length; i++) {
hovercounters[id].push(i);
}
}
for(let id = 0; id < rainbowinvelements.length; id++) {
invcounters[id] = [];
for(let i = 0; i < rainbowinvelements[id].length; i++) {
invcounters[id].push(i);
}
}
//Save the original color to easily return to it later.
for(let i = 0; i < rainbowhover.length; i++) {
originalcolors[i] = rainbowhover[i].style.color;
}
// Add event listeners for every item classed foxrainbowhover. If it has a data tag called foxrainbowhover with an id inside it instead uses that to start the hover effect.
for(let id = 0; id < rainbowhover.length; id++) {
//Checks if the passed along id exists or not. If it doesn't, execute regularly. If it does, execute with hover on a different element.
if(rainbowhover[id].dataset.foxrainbowhover) {
let hoverelement = document.getElementById(rainbowhover[id].dataset.foxrainbowhover);
hoverelement.addEventListener("mouseenter", function startanimation() {
hoverinterval[id] = setInterval(() => {
for(let i = 0; i < rainbowelements[id].length; i++) {
rainbowelements[id][i].style.color = 'hsl(' + (hovercounters[id][i] + Math.floor(i * hoverspeed)) + ', 100%, 70%';
hovercounters[id][i]++;
}
}, 7);
}, false);
hoverelement.addEventListener("mouseleave", function stopanimation() {
console.log("gay1");
clearInterval(hoverinterval[id]);
for(let i = 0; i < rainbowelements[id].length; i++) {
rainbowelements[id][i].style.color = originalcolors[id];
}
}, false);
}
else {
rainbowhover[id].addEventListener("mouseenter", function startanimation() {
hoverinterval[id] = setInterval(() => {
for(let i = 0; i < rainbowelements[id].length; i++) {
rainbowelements[id][i].style.color = 'hsl(' + (hovercounters[id][i] + Math.floor(i * hoverspeed)) + ', 100%, 70%';
hovercounters[id][i]++;
}
}, 7);
}, false);
rainbowhover[id].addEventListener("mouseleave", function stopanimation() {
clearInterval(hoverinterval[id]);
for(let i = 0; i < rainbowelements[id].length; i++) {
console.log("gay1");
rainbowelements[id][i].style.color = originalcolors[id];
}
}, false);
}
}
//Same code as before. Will make it way DRY-er later, but for now, this'll have to do.
for(let i = 0; i < invertedhover.length; i++) {
originalinvcolors[i] = invertedhover[i].style.color;
}
let startinterval = [];
// Add event listeners for every item classed foxrainbowhoverinv.
for(let id = 0; id < invertedhover.length; id++) {
startinterval[id] = setInterval(() => {
for(let i = 0; i < rainbowinvelements[id].length; i++) {
rainbowinvelements[id][i].style.color = 'hsl(' + (invcounters[id][i] + Math.floor(i * hoverspeed)) + ', 100%, 70%';
invcounters[id][i]++;
}
}, 7);
//Checks if the passed along id exists or not. If it doesn't, execute regularly. If it does, execute with hover on a different element.
if(invertedhover[id].dataset.foxrainbowhover) {
let hoverelement = document.getElementById(invertedhover[id].dataset.foxrainbowhover);
hoverelement.addEventListener("mouseenter", function stopanimation() {
clearInterval(startinterval[id]);
clearInterval(hoverinvinterval[id]);
for(let i = 0; i < rainbowinvelements[id].length; i++) {
rainbowinvelements[id][i].style.color = originalinvcolors[id];
}
}, false);
hoverelement.addEventListener("mouseleave", function startanimation() {
hoverinvinterval[id] = setInterval(() => {
for(let i = 0; i < rainbowinvelements[id].length; i++) {
rainbowinvelements[id][i].style.color = 'hsl(' + (invcounters[id][i] + Math.floor(i * hoverspeed)) + ', 100%, 70%';
invcounters[id][i]++;
}
}, 7);
}, false);
}
else {
invertedhover[id].addEventListener("mouseenter", function stopanimation() {
clearInterval(startinterval[id]);
clearInterval(hoverinterval[id]);
for(let i = 0; i < rainbowinvelements[id].length; i++) {
rainbowinvelements[id][i].style.color = originalinvcolors[id];
}
}, false);
invertedhover[id].addEventListener("mouseleave", function startanimation() {
hoverinterval[id] = setInterval(() => {
for(let i = 0; i < rainbowinvelements[id].length; i++) {
rainbowinvelements[id][i].style.color = 'hsl(' + (invcounters[id][i] + Math.floor(i * hoverspeed)) + ', 100%, 70%';
invcounters[id][i]++;
}
}, 7);
}, false);
}
}
//Hover but for backgrounds.
let rainbowhoverbg = document.getElementsByClassName('foxrainbowhoverbg');
let hoverbginterval = [];
let hoverbgcounter = 0;
let originalbgcolors = [];
//Save the original color to easily return to it later, but for backgrounds.
for(let i = 0; i < rainbowhoverbg.length; i++) {
originalbgcolors[i] = rainbowhoverbg[i].style.backgroundColor;
}
for(let id = 0; id < rainbowhoverbg.length; id++) {
rainbowhoverbg[id].addEventListener("mouseenter", function startbganimation() {
hoverbginterval[id] = setInterval(() => {
rainbowhoverbg[id].style.backgroundColor = 'hsl(' + (hoverbgcounter + Math.floor(id * hoverbackgroundspeed)) + ', 100%, 70%';
hoverbgcounter++;
}, 15);
}, false);
rainbowhoverbg[id].addEventListener("mouseleave", function stopbganimation() {
clearInterval(hoverbginterval[id]);
rainbowhoverbg[id].style.backgroundColor = originalbgcolors[id];
}, false);
}
})()
//Actually do the rainbow effect. Text only.
function textcolorchange(rainbowarray, rainbowspeed) {
let counterarray = [];
for(let i = 0; i < rainbowarray.length; i++) {
counterarray[i] = 0 + i;
}
setInterval(() => {
for(let i = 0; i < rainbowarray.length; i++) {
rainbowarray[i].style.color = 'hsl(' + (counterarray[i] + Math.floor(i * rainbowspeed)) + ', 100%, 70%';
if(counterarray[i] == 360)
{
counterarray[i] = 0;
}
else {
counterarray[i]++;
}
}
}, 7);
}
//Prepare text for having its color changed by splicing it up into individual bits
//and taking it out of the HTMLcollection.
function spanArrayContents(classes) {
let spans = [];
let chars = [];
for(let i = 0; i < classes.length; i++) {
chars.push(classes[i].innerText.split(""));
classes[i].innerHTML = chars[i].map(function(char) {
return '<span>' + char + "</span>";
}).join('');
}
for(let i = 0; i < classes.length; i++) {
let temphtmlcollection = [].slice.call(classes[i].children)
for(let j = 0; j < temphtmlcollection.length; j++) {
spans.push(temphtmlcollection[j]);
}
}
return spans;
}
//Same as above except for single elements instead of an array of elements.
//Helps split them up and give them an ID before they're taken to the slaughterhouse.
function spanElementContents(element) {
let spans = [];
let chars = [];
chars.push(element.innerText.split(""));
for(let i = 0; i < chars.length; i++){
element.innerHTML = chars[i].map(function(char) {
return '<span>' + char + "</span>";
}).join('');
}
let temphtmlcollection = [].slice.call(element.children)
for(let j = 0; j < temphtmlcollection.length; j++) {
spans.push(temphtmlcollection[j]);
}
return spans;
}
When I hit my calculate button, the new lists with values pulled from the arrays are visible, but the second array is missing a value.The missing value is not always the same value. For example if I put in 1,2,3,4,5,6, it's not always the same number missing, it's probably the last value in the array, but I can't figure out where I went wrong. Here's the code:
$(document).ready(function() {
function copyarray(arraytocopy) {
var theCopy = []; // An new empty array
for (var i = 0, len = arraytocopy.length; i < len; i++) {
theCopy[i] = arraytocopy[i];
}
return theCopy;
}
function sortarray(arraytosort) {
arraytosort.sort(
function(a, b) {
return Math.round(Math.random());
}
);
return arraytosort;
}
function checkarrays(newarray, oldarray) {
var swappositions = [];
for (var i = 0; i < newarray.length; i++) {
if (newarray[i] == oldarray[i]) {
//alert(oldarray[i] + ' is the SAME!');
swappositions.push(newarray[i]);
}
}
var countsame = 0;
swappositions.reverse();
for (var i = 0; i < newarray.length; i++) {
if (newarray[i] == oldarray[i]) {
///alert(oldarray[i] + ' is the SAME!');
newarray[i] = swappositions[countsame];
countsame = countsame + 1;
}
}
for (var i = 0; i < newarray.length; i++) {
if (newarray[i] == oldarray[i]) {
//alert(oldarray[i] + ' is the SAME!');
//swappositions.push(newarray[i]);
var elementbefore = newarray[i - 1];
newarray[i - 1] = newarray[i];
newarray[i] = elementbefore;
}
}
///alert('test');
///alert('new array: ' + newarray);
///alert('old array: ' + oldarray);
//alert(swappositions.toString());
//alert($.inArray( swappositions[0], newarray ));
return true;
}
Array.prototype.randomize2 = function() {
var oldarray = copyarray(this);
sortarray(this);
var notthesame = checkarrays(this, oldarray);
if (notthesame = false) {
//alert('sort again');
sortarray(this);
notthesame = checkarrays(this, oldarray);
}
//alert('new: '+this);
//alert('old: '+oldarray);
//alert('not the same!');
return this;
};
function makelist(myarray) {
var list = '<ol>';
var listitem = '';
for (var i = 0; i < myarray.length; i++) {
if (/\S/.test(myarray[i])) {
listitem = '<li>' + $.trim(myarray[i]) + '</li>';
list += listitem;
}
}
list += '</ol>';
//alert(list.toString());
return list.toString();
}
function combinelists(ordered, random) {
var list = '<ol>';
var listitem = '';
for (var i = 0; i < ordered.length; i++) {
if (/\S/.test(ordered[i])) {
if ($.trim(random[i]) == $.trim(ordered[i])) {
listitem = '<li class="same"><span class="yourname">' + $.trim(ordered[i]) + '</span> is matched with<span class="peersname">' + $.trim(random[i]) + '</span></li>';
list += listitem;
} else {
listitem = '<li><span class="yourname">' + $.trim(ordered[i]) + '</span> is matched with <span class="peersname">' + $.trim(random[i]) + '</span></li>';
list += listitem;
}
}
}
list += '</ol>';
//alert(list.toString());
return list.toString();
}
$('#ranGen').click(function() {
//function randomize(){
var lines = $('#names').val().split(/\n/);
var texts = [];
for (var i = 0; i < lines.length; i++) {
// only push this line if it contains a non whitespace character.
if (/\S/.test(lines[i])) {
texts.push($.trim(lines[i]));
}
}
var orderedlist = makelist(lines);
//$( "#list" ).html(orderedlist);
var linescopy = $.extend(true, [], lines);
var randomarray = linescopy.randomize2();
//alert(randomarray);
var randomlist = makelist(randomarray);
//$( "#randomlist" ).html(randomlist);
var combinedlists = combinelists(lines, randomarray);
$("#combined").html(combinedlists);
});
});
textarea {
height: 100px;
width: 400px;
}
input {
display: block;
}
.list {
display: inline-block;
}
.same {
color: orange;
}
.yourname {
color: blue;
}
.peersname {
color: brown;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<h1>Get a random match </h1>
<p>Insert all your names into the textarea below. Each name should be on a new line. Hit the button to generate your matches.</p>
<form>
<textarea id="names" placeholder="Enter list of names here. Each name should be on a new line."></textarea>
<input type="button" id="ranGen" value="Go" onClick="JavaScript:randomize()" />
</form>
<div id="list" class="list"></div>
<div id="randomlist" class="list"></div>
<div id="combined" class="list"></div>
Filtering out "empty" lines should fix the issue
var lines = $('#names').val().split(/\n/).filter(function (val) {
return val.trim() != '';
});
<html>
<body>
<script type="text/javascript">
start();
function start() {
var val = "0,1";
var n = 5;
var chars = ['a', 'b', 'c', 'd', 'e'];
gVars = chars.slice(0, n);
for (var i = 0; i < gVars.length; i++)
document.write(gVars[i] + "<br />");
var termsStr = val.split(',');
for (var i = 0; i < termsStr.length; i++)
document.write(termsStr[i] + "<br />");
var gOrigTerms = [];
var maxterm = Math.pow(2, termsStr.length) - 1;
document.write("maxterm: " + maxterm + "<br />");
for (var i = 0; i < termsStr.length; i++) {
gOrigTerms[i] = parseInt(termsStr[i]);
document.write(gOrigTerms[i] + "<br />");
if (gOrigTerms[i] > maxterm) document.write("Invalid term in term list." + "<br />");
}
gFormula = new Formula(gVars, gOrigTerms);
document.write(gFormula);
gFormula.toString();
gFormula.reduceToPrimeImplicants(); //here the breakpoint is inserted
}
function Formula(vars, terms)
{
this.vars = vars;
this.termList = [];
for (var i = 0; i < terms.length; i++) {
this.termList[i] = new Term(Dec2Bin(terms[i], vars.length));
document.write("this.termList" + this.termList[i] + "<br />");
}
this.orginalTermList = [];
document.write("this.orginalTermList" + this.orginalTermList + "<br />");
}
function Dec2Bin(dec, size) {
var bits = [];
for (var bit = 0; bit < size; bit++)
{
bits[bit] = 0;
}
var i = 0;
while (dec > 0)
{
if (dec % 2 == 0)
{
bits[i] = 0;
} else
{
bits[i] = 1;
}
i++;
dec = (dec / 2) | 0;
// Or with zero casts result to int (who knows why...)
}
bits.reverse();
return bits;
}
function Term(varVals)
{
this.varVals = varVals;
document.write("this.varVals: " + this.varVals);
}
function reduceToPrimeImplicants() //there is some problem with this function
{
this.originalTermList = this.termList.slice(0);
var numVars = this.termList[0].getNumVars();
var table = [];
for (var dontKnows = 0; dontKnows <= numVars; dontKnows++) {
table[dontKnows] = [];
for (var ones = 0; ones <= numVars; ones++) {
table[dontKnows][ones] = [];
}
table[dontKnows][numVars + 1] = [];
}
table[numVars + 1] = [];
table[numVars + 1][numVars + 1] = [];
for (var i = 0; i < this.termList.length; i++) {
var dontCares = this.termList[i].countValues(DontCare);
var ones = this.termList[i].countValues(1);
var len = table[dontCares][ones].length;
table[dontCares][ones][len] = this.termList[i];
}
for (var dontKnows = 0; dontKnows <= numVars - 1; dontKnows++) {
for (var ones = 0; ones <= numVars - 1; ones++) {
var left = table[dontKnows][ones];
var right = table[dontKnows][ones + 1];
var out = table[dontKnows + 1][ones];
for (var leftIdx = 0; leftIdx < left.length; leftIdx++) {
for (var rightIdx = 0; rightIdx < right.length; rightIdx++) {
var combined = left[leftIdx].combine(right[rightIdx]);
if (combined != null) {
if (out.indexOf(combined) < 0) {
var len = out.length;
out[len] = combined;
}
if (this.termList.indexOf(left[leftIdx]) >= 0) {
this.termList.splice(this.termList.indexOf(left[leftIdx]), 1);
}
if (this.termList.indexOf(right[rightIdx]) >= 0) {
this.termList.splice(this.termList.indexOf(right[rightIdx]), 1);
}
if (this.termList.indexOf(combined) < 0) {
var len = this.termList.length;
this.termList[len] = combined;
}
}
}
}
}
}
}
function getNumVars()
{
return this.varVals.length;
}
function countValues(value)
{
result = 0;
for (var i = 0; i < this.varVals.length; i++) {
if (this.varVals[i] == value) {
result++;
}
}
return result;
}
function combine(term)
{
var diffVarNum = -1; // The position where they differ
for (var i = 0; i < this.varVals.length; i++) {
{
if (this.varVals[i] != term.varVals[i])
if (diffVarNum == -1) {
diffVarNum = i;
} else { // They're different in at least two places return null; }
}
}
if (diffVarNum == -1)
{
// They're identical return null;
}
resultVars = this.varVals.slice(0);
resultVars[diffVarNum] = DontCare;
return new Term(resultVars);
}
</script>
</body>
</html>
In the above code, that is not complete, but which implements quine Mccluskey algorithm. There is a problem while it is debugged.
If a breakpoint is inserted at gFormula.reducetoPrimeImplicants(); the debugger does not go into that function. This is the last function called in the code until now. But, it does go to start(), which is the first function.
There is some problem in reducetoPrimeImplicants(); function because it also gives ERROR in internet explorer.
I am not able to figure out the error. If I remove reducetoPrimeImplicants(); function from the code the works fine.
Please, can somebody tell me why the debugger does not enter reducetoPrimeImplicants();.
I am using the Firebug debugger.
Thanks in advance.
The last function in your page combine() is missing a closing brace.
If you don't mind, a suggestion: Please use http://jsbeautifier.org/ or some similar tool to indent your code better.
Your For loop has two starting braces.
for (var i = 0; i < this.varVals.length; i++) {
{
So remove one. This should solve your problem.