Велосипедная анимация радужного текста

ЦИЛИНДРОВЫЕ ЦВЕТА НА HOVER С JavaScript/jQuery

Я пытаюсь взять блок текста, покрасьте каждую букву в соответствии с рассчитанной позицией между HSL 0deg и 360deg и наведите курсор на анимированные цвета справа. Я знаю, что это странно, но неся со мной. То, что я хочу, это анимированный текст радуги при наведении курсора.

Я рассмотрел логику сделать все это один раз, но не могу заставить поведение на велосипеде для зависания работать.

здесь ссылка на codepen.io: http://cdpn.io/txmlf

Я пробовал использовать события мыши JavaScript и jQuery.hover(). Моя первоначальная мысль заключалась в том, чтобы установить интервал ввода мыши и очистить его при выходе.

Я по-настоящему ценю любую помощь по этому явно очень важному проекту.

Ответ 1

Вы можете подумать, как это повлияет на UX, но как насчет этого: http://jsfiddle.net/7Xuep/6/

Хорошо, поэтому поворот по всем цветам радуги достаточно прост, используя CSS-анимацию. Проблема заключается в том, чтобы связать их со всеми вашими тегами span, чтобы анимация начиналась в нужном месте. (т.е. вам нужно зеленое письмо, чтобы запустить его анимацию с зеленого цвета и т.д.). Для этого мы можем использовать animation-delay:

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

который мы можем использовать для запуска анимации радуги с соответствующим цветом для каждой буквы. Используя функцию времени 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');
    }
});

но вы можете сделать это одновременно с созданием всех ваших элементов 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/

Теперь, если вы не хотите, чтобы цвета reset, когда кто-то больше не витает над .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)

Ответ 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);

Протестировано в FF, Chrome, Opera