【问题标题】:How to generate rainbow colored text in Javascript?如何在 Javascript 中生成彩虹色文本?
【发布时间】:2016-08-16 01:36:46
【问题描述】:

我需要一个纯 javascript 中的彩虹函数。

【问题讨论】:

  • 让你的生活更加丰富多彩
  • 没有什么比做一个糟糕的stackoverflow问题更能让你自己回答的了。
  • @RobGudgeon 这是一个问答,当你提问时有一个复选框。
  • 我投票决定将此问题作为离题结束,因为 OP 将其视为博客来发布他们面临的问题的代码。问题不是问题,而是声明说他们有问题并使用答案发布非常过时的代码。
  • @user2816085 此时有 3 上和 6 下,这就是为什么你看到它像 -3。

标签: javascript html colors


【解决方案1】:

解决方案 1:Javascript + HSL

这应该适用于任何浏览器

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;
}
&lt;p class="rainbowText"&gt;This is an awesome text&lt;/p&gt;

解决方案 2:背景剪辑 + 线性渐变

这是一个webkit only答案(Chrome),但应该更有效。

更新 (01/2021):现代浏览器支持此功能。

有关兼容性列表,请查看background-clip: text(包括仅支持-webkit-前缀的那些)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;
}
&lt;span class="rainbowText"&gt;This is an awesome text&lt;/span&gt;

【讨论】:

  • 你是最新的吗?
  • 我添加了另一个解决方案,应该可以在任何浏览器中工作
【解决方案2】:

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>

【讨论】:

    【解决方案3】:

    相当老的问题,但如果有人仍在寻找一个纯 JavaScript 只回答动画彩虹文本(如果你通过我的意大利面条足够努力的话,你可以控制方向和速度),这是我的版本:https://github.com/FeedbackFox/RGB-CSS-script

    工作 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;
    }
    

    【讨论】:

      【解决方案4】:

      我研究了同样的事情并想出了这个:

      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);
      &lt;p&gt;WOO!&lt;p&gt;

      这也可以用作书签,效果很好!

      【讨论】:

        【解决方案5】:
        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;
        }
        

        而且它在更短的时间内做同样的事情。

        【讨论】:

          【解决方案6】:

          这取决于你想要什么样的彩虹文字。有些彩虹款式真的很优雅。

          这里有几个:-

          1. codepen 的一支笔。
          2. Another pen here
          3. animated rainbow text at jsfiddle

          &lt;div class="rainbow-text"&gt;Words and things&lt;/div&gt;

          @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;
          }
          

          【讨论】:

          • 寻找其他例子。不一定所有答案都如你所愿。应该有人们的选择。
          • 不确定 OP 是否想要动画颜色或只是静态彩虹色文本
          • 但您应该使用 hsl 轻松更改色调而不更改饱和度和亮度。例如:codepen.io/VincentCharpentier/pen/vOMpWL
          猜你喜欢
          • 1970-01-01
          • 2018-05-31
          • 2023-03-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-01-18
          • 1970-01-01
          • 2011-03-12
          相关资源
          最近更新 更多