javascript 彩虹色文字的循环动画

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19165364/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 14:37:48  来源:igfitidea点击:

Cycling animation of rainbow-coloured text

javascriptjquerycsscss-animations

提问by Todd

CYCLING COLORS ON HOVER With JavaScript/jQuery

使用 JavaScript/jQuery 在悬停时循环颜色

I'm trying to take a block of text, color each letter according to calculated position between HSL 0deg and 360deg, and on hover animate the colors to the right. I know this is weird, but bear with me. What I want is animated rainbow text on hover.

我正在尝试获取一段文本,根据 HSL 0deg 和 360deg 之间的计算位置为每个字母着色,并在悬停时为右侧的颜色设置动画。我知道这很奇怪,但请耐心等待。我想要的是悬停时的动画彩虹文字。

I've covered the logic of making all of this happen once, but can't get hover cycling behavior to work.

我已经介绍了使所有这些发生一次的逻辑,但无法使悬停循环行为起作用。

here is a link to the codepen.io:http://cdpn.io/txmlf

这是 codepen.io 的链接:http ://cdpn.io/txmlf

I've tried using JavaScript mouse events and jQuery's .hover(). My initial thought was to set an interval on mouse enter and clear it on exit.

我试过使用 JavaScript 鼠标事件和 jQuery 的 .hover()。我最初的想法是在鼠标进入时设置一个间隔并在退出时清除它。

I'd truly appreciate any help on this obviously very important project.

我真的很感激对这个显然非常重要的项目的任何帮助。

回答by Ben Hymanson

You might wanna think about how this'll affect UX, but what about this: http://jsfiddle.net/7Xuep/6/

您可能想考虑这将如何影响 UX,但是呢:http: //jsfiddle.net/7Xuep/6/

Ok, so rotating through all the colours of the rainbow is easy enough using CSS-animations. The issue is then linking them up to all your span tags such that the animation starts in the right place. (i.e. you need the green letter to start it's animation from the colour green etc.) To do this, we can use animation-delay:

好的,所以使用 CSS 动画很容易在彩虹的所有颜色中旋转。然后问题是将它们链接到所有 span 标签,以便动画在正确的位置开始。(即你需要绿色字母从绿色等开始它的动画。)为此,我们可以使用animation-delay

https://developer.mozilla.org/en-US/docs/Web/CSS/animation-delay

https://developer.mozilla.org/en-US/docs/Web/CSS/animation-delay

which we can use to start the rainbow animation at the appropriate colour for each letter. By using a lineartiming function, it's simple to determine at what time the animation will arrive at each colour. Therefore, it's just a matter of attaching the right animation-delayvalue to each <span>element. I do that by just taking your already generated HTML and adding in the CSS rules to each element's styleattribute:

我们可以使用它为每个字母以适当的颜色开始彩虹动画。通过使用linear计时函数,可以很容易地确定动画到达每种颜色的时间。因此,这只是将正确的animation-delay值附加到每个<span>元素的问题。我只是通过使用您已经生成的 HTML 并将 CSS 规则添加到每个元素的style属性来做到这一点:

var animTime = 6, // time for the animation in seconds
    hueChange = 3, // the hue change from one span element to the next
    prefixes = ["", "-webkit-", "-moz-", "-o-"],
    numPrefixes = prefixes.length;

$('.unicorn').find('span').each(function (i) {
    for (var j = 0; j < numPrefixes; j++) {
        $(this).css(prefixes[j] + 'animation-delay', (animTime * ((i * hueChange) % 360) / 360) - animTime + 's');
    }
});

but you could do this at the same time as you're generating all your spanelements. Then it's just a case of setting up the animation using CSS:

但是您可以在生成所有span元素的同时执行此操作。那么这只是使用 CSS 设置动画的一个案例:

.unicorn:hover span {

    animation: colorRotate 6s linear 0s infinite;

}

@keyframes colorRotate {
    from {
        color: rgb(255, 0, 0);
    }
    16.6% {
        color: rgb(255, 0, 255);
    }
    33.3% {
        color: rgb(0, 0, 255);
    }
    50% {
        color: rgb(0, 255, 255);
    }
    66.6% {
        color: rgb(0, 255, 0);
    }
    83.3% {
        color: rgb(255, 255, 0);
    }
    to {
        color: rgb(255, 0, 0);
    }
}

All this gets us to here: http://jsfiddle.net/P6WVg/7/

所有这些都让我们来到这里:http: //jsfiddle.net/P6WVg/7/

Now, if you don't want the colours to reset once someone is no longer hovering over .unicornthen you can use animation-play-state:

现在,如果您不希望在有人不再悬停时重置颜色,.unicorn那么您可以使用animation-play-state

https://developer.mozilla.org/en-US/docs/Web/CSS/animation-play-state

https://developer.mozilla.org/en-US/docs/Web/CSS/animation-play-state

However, I was finding that Chrome has an issue with combining an initial value of -webkit-animation-play-state:paused;and a negative value of -webkit-animation-delaysuch that it just displayed the first frame (i.e. color: rgb(255,0,0);in this case). Therefore I had to use an event listener to add a class containing the animation CSS on the first hover, and this leads us to:

但是,我发现 Chrome 在组合初始值-webkit-animation-play-state:paused;和负值时存在问题-webkit-animation-delay,因此它只显示第一帧(即color: rgb(255,0,0);在这种情况下)。因此,我必须使用事件侦听器在第一次悬停时添加一个包含动画 CSS 的类,这导致我们:

http://jsfiddle.net/7Xuep/6/

http://jsfiddle.net/7Xuep/6/

(that bug in chrome can be tracked here: https://code.google.com/p/chromium/issues/detail?id=269340)

(可以在此处跟踪 chrome 中的错误:https: //code.google.com/p/chromium/issues/detail?id=269340

回答by Roko C. Buljan

Why not keep it simple, (with only your HTML) this is all you need:

为什么不保持简单,(只有你的 HTML)这就是你所需要的:

Live demo

现场演示

var step = 4, // colorChage step, use negative value to change direction
    ms   = 10,  // loop every
    $uni = $('.unicorn'),
    txt  = $uni.text(),
    len  = txt.length,
    lev  = 360/len,
    newCont = "",
    itv;
alert(lev+' '+len);

for(var i=0; i<len; i++)newCont += "<span style='color:hsla("+ i*lev +", 100%, 50%, 1)'>"+ txt.charAt(i) +"</span>";

$uni.html(newCont); // Replace with new content
var $ch = $uni.find('span'); // character

function stop(){ clearInterval(itv); }
function anim(){
  itv = setInterval(function(){
    $ch.each(function(){
      var h = +$(this).attr('style').split(',')[0].split('(')[1]-step % 360;
      $(this).attr({style:"color:hsla("+ h +", 100%, 50%, 1)"});
    });
  }, ms); 
}

$uni.hover(anim,stop);

Tested in FF, Chrome, Opera

在 FF、Chrome、Opera 中测试