Анимация адресной строки с помощью JavaScript и Emoji

JavaScript

Вы можете использовать эмодзи (и другие графические символы юникода) в адресной строке, что выглядит великолепно, но, похоже, никто этого не делает, почему? Может быть, эмодзи слишком экзотичны для обычных веб-платформ? Может быть, они боятся быть плохими для SEO?

Какова бы ни была причина, правдоподобный пункт диаграммы Венна «никто этого не делает, но это возможно» — вот что меня волнует. Поэтому я решил потратить некоторое время на изучение возможности использования графических символов в адресной строке, особенно анимацию этих символов с помощью JavaScript.

циклическая анимация

Во-первых, убедитесь, что код JavaScript вашей страницы имеет кодировку UTF-8, иначе смайлики не могут отображаться в вашем коде, чего можно добиться, установив заголовки HTTP или тег META страницы. Скорее всего, вам не нужно беспокоиться об этом, но вы можете найти дополнительную информацию здесь:Unicode in Javascript by Flavio.

Чтобы достичь желаемого эффекта, пусть эмодзи танцует как фея в адресной строке, нам нужен цикл, на самом деле, все, что нам нужно, это цикл, мы запускаем этот цикл, он продолжает цикл, наша цель достигнута. Это наша первая зацикленная анимация, вращающаяся луна-эмодзи. Я думаю, когда они добавили эту последовательность смайликов, у них тоже была эта идея?

moon.gif

    var f = ['🌑', '🌒', '🌓', '🌔', '🌝', '🌖', '🌗', '🌘'];

    function loop() {
        location.hash = f[Math.floor((Date.now()/100)%f.length)];

        setTimeout(loop, 50);
    }

    loop();

Запустите код, и вы увидите результат этого цикла в адресной строке.

Если вам не нравится вращающаяся луна, вы можете заменить этот массив любым эмодзи, который вам нравится, например, часами:

clock.gif

var f = ['🕐','🕑','🕒','🕓','🕔','🕕','🕖','🕗','🕘','🕙','🕚','🕛'];

Это очень простой пример, действительно очень простой, так что давайте улучшим цикл, чтобы отобразить кучу смайликов!skin tone modifiersСвойства регулировки тона кожи, чтобы сделать некоторых детей, меняющих цвет:

babies2.gif

    var e = ['🏻', '🏼', '🏽', '🏾', '🏿'];

    function loop() {
        var s = '',
            i, m;

        for (i = 0; i < 10; i ++) {
            m = Math.floor(e.length * ((Math.sin((Date.now()/100) + i)+1)/2));
            s += '👶' + e[m];
        }

        location.hash = s;

        setTimeout(loop, 50);
    }

    loop(); 

Мы можем использовать синусоиду с управлением по времени и положению, чтобы выбрать нужный цвет, что дает нам хороший эффект преобразования цвета!

Допустим, мы снова вращаем луну, заставляем ее расширяться и делаем анимацию, похожую на полосу загрузки? Хорошо, приступим к реализации:

moons.gif

    var f = ['🌑', '🌘', '🌗', '🌖', '🌕', '🌔', '🌓', '🌒'],
        d = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        m = 0;

    function loop() {
        var s = '', x = 0;

        if (!m) {
            while (d[x] == 4) {
                x ++;
            }

            if (x >= d.length) m = 1;
            else {
                d[x] ++;
            }
        }
        else {
            while (d[x] == 0) {
                x ++;
            }

            if (x >= d.length) m = 0;
            else {
                d[x] ++;

                if (d[x] == 8) d[x] = 0;
            }
        }

        d.forEach(function (n) {
            s += f[n];
        });

        location.hash = s;

        setTimeout(loop, 50);
    }

    loop();

Исследуйте других персонажей

Мало того, что смайлики дают нам возможность отображать графику в адресной строке, у нас также есть некоторые символы юникода в нашей цели.

Особенно интересно, чтопограничный символ:

box-characters.png

Многие из них лучше подходят для 2D-вывода, но они также отлично подходят для 1D-вывода, например, мы можем создать строку блоков разной высоты и построить симпатичную небольшую волновую анимацию:

wavy.gif

    function loop() {
        var i, n, s = '';

        for (i = 0; i < 10; i++) {
            n = Math.floor(Math.sin((Date.now()/200) + (i/2)) * 4) + 4;

            s += String.fromCharCode(0x2581 + n);
        }

        window.location.hash = s;

        setTimeout(loop, 50);
    }

    loop();

Мне так нравится эффект, что я наношу его постоянноwavyurl.comначальство.

Используя символы переменной ширины, мы даже покачиваем по горизонтали, создавая что-то вроде индикатора выполнения:

progress.gif

    function loop() {
        var s = '',
            p;

        p = Math.floor(((Math.sin(Date.now()/300)+1)/2) * 100);

        while (p >= 8) {
            s += '█';
            p -= 8;
        }
        s += ['⠀','▏','▎','▍','▌','▋','▊','▉'][p];

        location.hash = s;
        setTimeout(loop, 50);
    }

индикатор? Это выглядит, все еще полезно, и это заставляет меня задуматься...

Показывать прогресс видео в адресной строке

Чтобы увеличить возможности нашего маленького эксперимента, я придумал показывать прогресс веб-видео в адресной строке. Я просто добавляю функцию, которая определяет нашу строку прогресса в видео.timeupdateсобытие, и вуаля! Индикатор выполнения видео в адресной строке содержит время и продолжительность!

video-progress.gif

    var video;

    function formatTime(seconds) {
        var minutes = Math.floor(seconds/60),
            seconds = Math.floor(seconds - (minutes*60));

        return ('0'+minutes).substr(-2) + ':' + ('0'+seconds).substr(-2);
    }

    function renderProgressBar() {
        var s = '',
            l = 15,
            p = Math.floor(video.currentTime / video.duration * (l-1)),
            i;

        for (i = 0; i < l; i ++) {
            if (i == p) s +='◯';
            else if (i < p) s += '─';
            else s += '┄';
        }

        location.hash = '╭'+s+'╮'+formatTime(video.currentTime)+'╱'+formatTime(video.duration);
    }

    video = document.getElementById('video');
    video.addEventListener('timeupdate', renderProgressBar);

Я предпочитаю этот индикатор выполнения, состоящий из линий и кругов.Если вам нравятся другие смайлики, такие как луна, я также могу вас удовлетворить:

video-moons.gif

    var e = ['🌑', '🌘', '🌗', '🌖', '🌕'],
        video;

    function formatTime(seconds) {
        var minutes = Math.floor(seconds/60),
            seconds = Math.floor(seconds - (minutes*60));

        return ('0'+minutes).substr(-2) + ':' + ('0'+seconds).substr(-2);
    }

    function renderProgressBar() {
        var s = '',
            c = 0,
            l = 10,
            p = Math.floor(video.currentTime / video.duration * ((l*5)-1)),
            i;

        while (p >= 5) {
            s += e[4];
            c ++;
            p -= 5;
        }
        s += e[p];
        c ++;

        while (c < l) {
            s += e[0];
            c ++;
        }

        location.hash = s+formatTime(video.currentTime)+'╱'+formatTime(video.duration);
    }

    video = document.getElementById('video');
    video.addEventListener('timeupdate', renderProgressBar);

Хорошо, назовите это «полезным» расширением индикатора выполнения. С первого взгляда я также могу увидеть прогресс в URL-адресе общего доступа к видео. Как и в YouTube, вы можете создать ссылку на видео в определенное время, разве не здорово добавить визуальную индикацию? Хорошо?

Возможно, я не придумал более полезную «техническую» реализацию, я буду думать об этом. Эй, может быть, вы можете попробовать что-нибудь?

Наконец

Вам может быть интересно, почему я используюlocation.hash =, вместо нового и классногоHTML5 History API. Есть две причины:

Первый вопросHistory APIОдна особенность: он фактически изменяет весь путь URL, а не толькоhash. Итак, если я используюHistory APIи измените страницу на/🌑🌘🌗🌖🌕, это будет выглядеть лучше, чем добавление # . Но это также означает, что мой веб-сервер должен иметь возможность отвечать/🌑🌘🌗🌖🌕, в противном случае произойдет сбой, если пользователь обновит или иным образом перейдет к измененному URL-адресу. Это работает, но быстрее, чем использованиеlocation.hash =Более сложный и потребовал от меня изменить конфигурацию сервера.

Второй вопрос несколько неожиданный. Фактически, из 3 протестированных мной браузеров 2 API истории были ограничены. Если я молниеносно вставлю свой волновой URL-адрес в адресную строку, я получу следующую ошибку в Chrome:

Throttling history state changes to prevent the browser from hanging.

Safari дает нам более подробную информацию:

SecurityError: Attempt to use history.pushState() more than 100 times per 30.000000 seconds

Теперь все в порядке, если я оставлю это ограничение, но 3 кадра в секунду просто не влияют на мою текущую анимацию.

Хороший мальчик, Firefox, кажется, не заботится о том, сколько раз или как быстро я добавляю новую историю, что действительно продумано. Однако тот факт, что затронуты два основных браузера, а также необходимость настройки веб-сервера для устранения первой проблемы, заставляет меня с большей готовностью мириться с # в URL-адресе.

Эпилог

Я остановлюсь здесь. Но я собираюсь сказать вам, что у меня все еще есть некоторые идеи, чтобы мини-игра отображалась в адресной строке. особенно учитываясимволы БрайляМы еще не исследовали, так что следите за обновлениями.

Если у вас есть какие-либо вопросы, комментарии или вы просто хотите быть в курсе моих достижений, подписывайтесь на меня в Твиттере:@MatthewRayfield. или указатьздесьПодпишитесь на мои письма, которые почти никогда не беспокоят.

О, и если вам нужен исходный код для приведенного выше примера,Нажмите сюда для того, чтобы скачать.