Караоке на HTML5 canvas



    Решил я попробовать сделать web-караоке, но чтобы текст красиво отображался — не по-буквенно, а плавно. Решение оказалось более простым, чем я думал.

    По-буквенный вариант совсем прост — достаточно обойтись CSS, см. пример на JSFiddle.

    Более красивый вариант заключается в использовании canvas и раскраске текста с помощью стиля gradient:
    var gradient = ctx.createLinearGradient(0, 0, 30, 0);
    gradient.addColorStop(0.00, 'yellow');
    gradient.addColorStop(0.01, 'black');
    gradient.addColorStop(1.00, 'black');
    ctx.fillStyle = gradient;
    

    Градиент сам по себе (в виде перехода одного цвета в другой — см. ниже рисунок слева) для отображения караоке не нужен, потому используется дополнительная точка — 0.01, чтобы основная часть «градиента» (0.01-1.00) оставалась черной, а маленькая часть (0.00-1.00) — желтой (см. ниже рисунок справа):

    (альтернативный вариант — задать малое значение третьего параметра — x1 (окончания градиента) — в createLinearGradient).

    Однако, если просто нарисовать текст:
    ctx.fillText(text, 0, 0);
    

    то он будет отображен лишь одним цветом — черным:


    Дело в том, что градиент применяется относительно начала системы координат. На рисунке выше точка 0 по оси x отображается черной вертикальной линией (смещена по оси х в середину canvas'a с помощью метода translate). Чтобы применить градиент, достаточно нарисовать текст со смещением. Та часть, которая окажется левее начала координат по оси x, будет окрашена в желтый цвет, а та, что правее — в черный:
    ctx.fillText(text, -190, 0);
    



    Для отображения караоке теперь достаточно лишь смещать начало системы координат по оси x (например, в цикле, на один пиксел) — текст будет постепенно окрашиваться в желтый цвет. Попробовать раскраску текста со смещением положения текста (без смещения начала координат) можно попробовать на JSFiddle (сетка и дизайн взяты из этой статьи). В финальном проекте можно посмотреть что получилось тут (нужен аккаунт ВКонтакте).
    Поделиться публикацией

    Похожие публикации

    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 15

      +7
      Закрашивание текста, это только начало. В реализации веб караоке наибольшую трудность представляют:
      1) Синхронизация закрашивания текста и музыки
      2) Реализация для мобильных устройств и планшетов

      Не сочтите за грубость, но проблем остаётся еще очень много
        0
        Конечно. Пункт 1 реализован. Пункт 2 — на мобильных и планшетах работает, но с мобильными пока есть проблема с версткой.
          0
          как вы делали синхронизацию на устройствах с низкой производительностью или fps?
          по ключевым кадрам с пропуском анимации, или за счет ускорения оной?
            0
            Пропуск анимации.

            Сейчас вообще сделано достаточно примитивно. Если есть строка текста
            [00:12.4]Ой <00:13.1>то <00:13.5>не <00:13.8>ве<00:14.2>чер <00:14.6>

            то как только наступает время, соответствующее метке времени, весь предыдущий текст тут же закрашивается и начинается новая анимация. А анимация пока всегда идет с одинаковой скоростью (т.е. нет расчета скорости анимации в зависимости от разницы во времени между метками).
              0
              Понятно. А что делаете если загрузка аудиодорожки происходит слишком медленно?
                +3
                Воспроизведение начинается лишь тогда, когда аудио полностью загружено.
                  0
                  Здравое решение, мы как правило делили на какие-то логические единицы и загружали в фоне. Но это уже от потребностей.
                  Успехов, развивайте свой продукт.
                    0
                    Спасибо! А можно ссылку на ваше решение?
                      +1
                      Это было 2 коммерческих видеоплеера с 2мя разными подходами, лупами и прочими плюшками. Код закрытый, так что не могу помочь.
                        +1
                        Меня скорее конечный результат интересовал, а не код. Но — ясно.
        +3
        мне кажется что все это легко укладывается в просто css + html, canvas здесь больше мешает чем работает
          0
          В CSS чуть менее красиво :).
          А так — это больше для изучения canvas было сделано.

          Но чем мешает canvas? Отсутствием поддержки в старых браузерах? Производительностью? Или чем-то другим?
            0
            Так в CSS можно же сделать тоже самое, что и в примере на Canvas'е, хоть побуквенно, хоть попиксельно.
              0
              Не могли бы вы показать попиксельный пример на CSS?
                +1
                Эм, уже поздно и фантазия неахти, но, на вскидку, пара варианртов:
                jsfiddle.net/vgo0bmdt/1/ — в теории, для всех браузеров.
                jsfiddle.net/8bL5g0cm/ — для браузеров из мира Chrome'ых и иже с ними (более красивое решение).

                Еще можно попробвоать функцию element(), которую пока только Firefox освоил. Можно попробовать функцию clip(), которую пока только Chrome'ые освоили. А еще есть SVG…

        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

        Самое читаемое