彩虹色文本的循环动画

11

使用JavaScript/jQuery在鼠标悬停时循环变换颜色

我想要对一段文本进行操作,根据HSL的0度到360度之间的计算位置为每个字母上色,并在鼠标悬停时将颜色向右动画。虽然这很奇怪,但请耐心听我解释。我的目的是在鼠标悬停时显示动态彩虹文本。

我已经完成了这一切的逻辑操作,但无法实现循环变换的行为。

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

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

如果您能帮助我完成这个非常重要的项目,我将不胜感激。


1
显然非常重要的项目 +1 - Oneezy
1
你没看到Kickstarter的众筹活动吗? :) - Todd
2个回答

17

你可能需要考虑这将如何影响用户体验,但是关于这个问题,可以考虑以下链接:http://jsfiddle.net/7Xuep/6/

好的,因为使用CSS动画轻松实现彩虹颜色的旋转。问题在于将它们连接到所有标记上,使动画从正确的位置开始。(即,您需要绿色字母从绿色开始其动画等)为此,我们可以使用animation-delay属性:

https://developer.mozilla.org/zh-CN/docs/Web/CSS/animation-delay

我们可以使用此属性以每个字母的适当颜色开始彩虹动画。使用线性时间函数,很容易确定动画何时到达每种颜色。因此,只需将正确的animation-delay值附加到每个元素即可。我通过将已生成的HTML添加到每个元素的style属性中的CSS规则来实现这一点:

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');
    }
});

但是您可以在生成所有 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);
    }
}

这让我们来到这里:http://jsfiddle.net/P6WVg/7/

现在,如果您不想让颜色在某人不再悬停在.unicorn上时重置,则可以使用animation-play-state

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

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

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

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


嘿,我试图避免将任何CSS添加到样式表中,而是通过js操纵CSS。想要利用硬件加速,但仍将所有必需的代码放在单个js文件中。你的答案非常有帮助,所以我会选择它作为正确答案,但如果你有关于如何实现我上述描述的建议,那就太好了。 - Todd
@Todd 这应该使用JS动态插入CSS:http://jsfiddle.net/BYoassrian/7Xuep/4/ - Ben Jackson
@Todd 似乎使用动态注入CSS存在问题,所以我进行了一点微调以使其正常工作:http://jsfiddle.net/BYoassrian/7Xuep/5/ - Ben Jackson
抱歉回复这么晚。你的工作真是太棒了,朋友。你拿到赏金了吗?非常感谢你。 - Todd
我知道这个问题已经有4年了,但就硬件加速性能而言,这仍然可能是最好的方法吗?我知道在移动设备上渐变非常慢.. 你们觉得呢? - Oneezy

2
为什么不保持简单,(只需使用你的HTML)这是你所需要的全部内容:

演示实况

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

在Firefox、Chrome和Opera中进行了测试


我也非常喜欢这个解决方案。我的唯一问题是关于变量“lev”的。当长度大于360时,lev似乎为零。@Roko - Todd
1
抱歉有些含糊,@Roko。我不明白你为什么要使用parseInt()方法并将基数设置为10。当txt.length大于360时,这会返回0。为了解决这个问题,我将lev设置为360/len。当我遍历字符时,我设置hue = (Math.ceil(ilev)<=360)? Math.ceil(ilev) : 360。 - Todd
@Todd编辑,你完全正确,我不知道为什么要使用parseInt...感谢提醒。 - Roko C. Buljan
1
@IdanShechter 请看JS底部:http://jsbin.com/eZUwUZE/4/edit?html,js,output - Roko C. Buljan
@IdanShechter 我不会替你完成它。这很简单,变量 h 表示色调。色调值从0到360。作业:找出绿色和蓝色的范围。将 h 变量限制在该范围内(而不是整个360)。 - Roko C. Buljan
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接