Справка по анимации для текста

Версия 1

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

Основы

Для работы во всех браузерах обязательно вынести скрипты после блока, т.е. порядок в DOM выходит таким:

  • Блок с анимацией
  • Список скриптов и стилей
  • Настройки

Суть работы изменений

У нас есть 2 неизменных элемента, влияющих на данный вид кода: движок браузера и движок JS.

В движке JS крутится наш код по правилу «1 момент — один простейший кусочек кода». Учитывая, что связь между движком браузера и JS не моментальна, это может приводить к тому, что одни блоки отрисовываются быстрее, а другие медленнее. А значит, становится сложнее реализовать различные трюки.

На что можно повлиять, чтобы решить эту проблему?

На синхронность исполнения, как минимум.
Например, определять блоки в 1 шаг, когда их печать требуется быстрее. Для этого я ввёл поддержку списков, в которых всё исполняется в один шаг:

[Команда_1, команда_2]

В старой версии движка я по ошибке начал использовать блокировки всего скрипта. Это значит, что он будет ждать окончания некоторого времени, заданного в миллисекундах, что не слишком полезно: надо переводить время и рассуждать не в терминах условных шагов, а в терминах времени. Таким образом, сейчас код будет позволять больше, немного в ущерб краткости.

Новая логика:

Опредение первого прогрессбара;
Определение второго прогрессбара;
Задержка, включающая время работы каждого из них

Что ещё можно было сделать лучше?

Все команды вывода строки, посимвольного вывода и прогрессбаров можно сделать совместимыми между собой, чтобы в любой момент свободно править содержимое. Таким образом, они интегрированы в общее «пространство имён»: var_name, а без сброса можно поставить текст на месте progress-bar'a в любой момент.
Пространство имён также позволяет хранить настройки progress-bar'ов и переписывать их так, как это удобно на данный момент.

Наконец, глобальный таймер, от которого зависит ритм анимации, теперь является управляемым. Для простоты, команда type совместима с этим лишь до и после своей работы, но можно перестроить её на работу с задержками, если это понадобится.

Образец настроек

Базовая настройка выглядит аналогично старой:

// Список кадров.
// Отдельные кадры помещаются здесь через запятую.
var frame_list = [];
// Экземпляр анимации, с которым производятся все действия от настройки до пуска
var NTA = new window.Term_animation({
  $parent: $('.wireCell'), // Ищем блок с классом CSS "wireCell"
  pause_between_steps: 40, // Задаём паузу для отрисовки
  frames: frame_list // Задаём список кадров
});
// Пуск анимации
NTA.start();

Виды кадров

Любой кадр определяется через синтаксис вида:

{
    "c": "ИМЯ_КОМАНДЫ",
    ОПЦИИ...
}

Пауза в шагах, step_delay

Устанавливает задержку, которая не блокирует выполнение команд.

Гораздо удобнее представить это не как кусок кода, а графически, отметив на линейке с долями секунды время начала одного элемента анимации, время задержки step_delay, в которое продолжается эта анимация и другой элемент анимации.

В это время будут работать progress-bar'ы, а используя больше одной такой задержки, можно определить точный момент для перезаписи состояния одного из них, подменить текст или сделать любую другую хитрость.

Атрибут cnt задаёт количество шагов, которые код будет ожидать.

Образец:

{"c": "step_delay", "cnt": 5},

Полная остановка на заданное время, pause

Когда требуется остановить всю анимацию на конкретное время, используется эта команда. В это время не будут выполняться другие участки кода.

Образец:

{"c": "pause", "time": 500},

Очистка экрана, rst

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

Образец:

{"c": "rst"}

Вывод строки, print

Выводит строку, как HTML. На данный момент, функционал команды поменялся: вывод может происходить в старые параграфы, когда задан атрибут "var_name".

Образец 1:

"Текст для вывода"

Образец 2:

{"c": "print", "txt": "ТЕСТ."}

Образец 3:

// Запоминаем параграф под именем "demo_paragraph_a"
{"c": "print", "txt": "9", "var_name": "demo_paragraph_a"},
// Устанавливаем задержку на 5 мс
{"c": "step_delay", "cnt": 5},
// Обновляем значение параграфа
{"c": "print", "txt": "8", "var_name": "demo_paragraph_a"},

Посимвольный вывод, type

Выводит строку символ за символом, поэтому разметка HTML не поддерживается.
Добавлена поддержка опции "var_name", что позволяет вывод в места, где до этого находились результаты работы других команд.

Образец 1:

{"c": "type", "txt": "ТЕСТ."}

Образец 2:

{"c": "type", "txt": "Первый текст.", "var_name": "demo_1",},
{"c": "step_delay", "cnt": 10},
{"c": "type", "txt": "Второй текст.", "var_name": "demo_1",},

Замена строки, replace_paragraph (устарела, удаляю?)

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

Образец:

{"c": "print", "txt": "9", "var_name": "demo_paragraph_a"},
{"c": "step_delay", "cnt": 5},
{"c": "replace_paragraph", "txt": "8", "var_name": "demo_paragraph_a"},

Замена последней записанной строки, replace_last (удобно? Оставляю?)

Удаляет старое содержимое заданного параграфа, заменяет на новое.

Образец:

{"c": "replace_last", "txt": "Тест"}

Определение и переопределение progressbar'a

Старые progressbar'ы просто выводились через команду печати. Это был костыль, а сейчас мне захотелось добавить функционала.
Часть описания pb_opts позволяет определять диапазон значений, принимаемых progressbar'ом, а также менять стиль его оформления.
Использование переменной вместе с progressbar'ом позволяет заменять старые progressbar'ы, делать более сложную анимацию и менять посреди неё направление движения.

Параметр len задаёт длину progressbar'a в символах.
Параметр pb_opts позволяет детально настроить работу progressbar'a.

  • Внутренний параметр replace_range позволяет заменить диапазон значений, принимаемых progressbar'ом:
    • start задаёт начальное значение
    • end задаёт конечное значение
    • step задаёт шаг значений, который может быть вещественным числом. Логично задавать его в виде 1/2^N, т.е. (0.5, 0.25, 0.125, 0.0625, 0.03125, 0.015625, 0.0078125…), и т.д., чтобы вычисляемый диапазон значений мог дойти до конечного значения.
  • Внутренний параметр style позволяет изменить стиль оформления:
    • empty_start задаёт html-код начала пустого сегмента
    • empty_end задаёт html-код конца пустого сегмента
    • fill_start задаёт html-код начала заполненного сегмента
    • fill_end задаёт html-код конца заполненного сегмента
    • fill_char задаёт символ, которым заполняется progressbar

Пример 1:

{
    "c": "define_progressbar",
    "len": 25,
},
{"c": "step_delay", "cnt": 25},
{"c": "rst"},

Здесь мы определили простейший progressbar длиной в 25 символов. Он будет заполнен слева-направо, а цвета и символ, которым он будет заполнен определены в настройках по умолчанию.

Пример 2:

{
    "c": "define_progressbar",
    "var_name": "demo_progressbar_3",
    "len": 5,
    "pb_opts": {
          "replace_range": {"start": 0, "end": 5, "step": 0.25},
    },
},
{"c": "step_delay", "cnt": 50},
{"c": "rst"},

Здесь мы определили длину progressbar'a, как 5 символов. В опциях мы задали отсчёт значений от нуля до пяти с шагом 1/4.

Пример 3:

"Регулировка цветов progressbar'a",
{
    "c": "define_progressbar",
    "var_name": "demo_progressbar_4",
    "len": 30,
    "pb_opts": {
        "style": {
            'empty_start': "<span style=\"color: #ffc555;\">",
            'empty_end': "</span>",
            'fill_start': "<span style=\"color: #ff9155;\">",
            'fill_end': "</span>",
            'fill_char': "█"
        },
        "replace_range": {"start": 0, "end": 30, "step": 0.5},
    },
},
{"c": "step_delay", "cnt": 80},
{"c": "rst"},

Перенастройка задержек

Игнорирование задержки, ignore_delay_between_frames

В соответствие с названием, эта команда отключает задержку между шагами, после чего они будут выполнены с той скоростью, которую позволяет движок браузера.
Это может быть полезно для параллельной отрисовки.

Образец:

{"c": "ignore_delay_between_frames"}

Восстановление задержки, restore_delay_between_frames

Образец:

{"c": "restore_delay_between_frames"}

Смена времени задержки, change_global_delay

Параметр delay_ms задаёт задержку между шагами в миллисекундах. Таким образом можно точно управлять анимацией progresbar'a, задавая неравномерный темп его работы и, например, одновременно меняя текст в другом месте.

Образец:

{"c": "change_global_delay", "delay_ms": 640},

Восстановление времени задержки, reset_global_delay

Восстанавливает задержку между шагами до той, которая задана в опции "pause_between_steps" при создании компонента анимации (40 мс по умолчанию).

Образец:

{"c": "reset_global_delay"},

Разбор демо

Обновлённая версия заставки

var frame_list = [
    // 0
    "Проверка наличия контрмемагента...",
    // 1
    {
        "c": "define_progressbar",
        "len": 25,
    },
    // 2
    {"c": "change_global_delay", "delay_ms": 320},
    {"c": "step_delay", "cnt": 10},
    // 3
    {"c": "reset_global_delay"},
    {"c": "step_delay", "cnt": 15},
    {"c": "rst"},
    "<span>Не удалось связаться с когнисхемой.<br/><br/>Наличие контрмема не подтверждено.<br/><br/>Изображение не может быть показано.</span>"
];
  • 0: просто выводим строку в отдельный тег P.
  • 1: создаём progressbar ниже
  • 2: изменяем задержку для создания эффекта наличия нескольких операций, создаём задержку для 10 шагов
  • 3: сбрасываем задержку и ожидаем заполнения progressbar'a целиком; сбрасываем экран и выводим итоговую строку заставки

Демонстрация

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

1

// 1
{"c": "type", "txt": "Итак, долгожданная демка.", "var_name": "demo_title_1",},
{"c": "step_delay", "cnt": 10},
{"c": "type", "txt": "С ней вышло много проблем.", "var_name": "demo_title_1",},
{"c": "step_delay", "cnt": 10},
{"c": "type", "txt": "Надеюсь, она стоит того.", "var_name": "demo_title_1",},
{"c": "step_delay", "cnt": 10},
"Начинаем.",
// 2
{
    "c": "define_progressbar",
    "len": 25,
},
{"c": "step_delay", "cnt": 25},
// 3
{"c": "rst"},
  • 1. В параграф под именем "demo_title_1" выводятся несколько предложений, между которыми установлены задержки. Выводится отдельный текстовый блок.
  • 2. После этого создаётся обычный progressbar, задаётся задержка на время его выполнения
  • 3. Выполняется сброс.

2

"Перезапись параграфа",
{"c": "print", "txt": "3", "var_name": "demo_paragraph_a"},
{"c": "step_delay", "cnt": 5},
{"c": "print", "txt": "2", "var_name": "demo_paragraph_a"},
{"c": "step_delay", "cnt": 5},
{"c": "print", "txt": "1", "var_name": "demo_paragraph_a"},
{"c": "step_delay", "cnt": 5},
{"c": "print", "txt": "0", "var_name": "demo_paragraph_a"},
{"c": "step_delay", "cnt": 5},
{"c": "rst"},

Обратный отсчёт; здесь всё крайне просто:

  • Выводится текстовая строка
  • Очередная строка выводится в переменную, после чего добавлена задержка
  • Выполняется очистка экрана

3

[
    "Простая задержка на увеличенное время",
    {
        "var_name": "demo_progressbar_2",
        "c": "define_progressbar",
        "len": 25
    },
],
{"c": "step_delay", "cnt": 85},
{"c": "rst"},

В список ([]) упакованы две операции для одновременного выполнения: вывод текста и создание progressbar'a.
Далее добавлены задержка и сброс экрана. Задержка задана так, чтобы быть дольше, чем время вывода progressbar'a.

4

"Регулировка скорости progressbar'a",
{
    "c": "define_progressbar",
    "var_name": "demo_progressbar_3",
    "len": 5,
    "pb_opts": {
        "replace_range": {"start": 0, "end": 5, "step": 0.25},
    },
},
{"c": "step_delay", "cnt": 50},
{"c": "rst"},

Здесь интересным моментом является то, что диапазон значений progressbar'a задаётся через опцию step в replace_range.
Таким образом, значения progressbar'а меняются реже: каждый единичный шаг складывается из значений, равных 0.25.
Аналогичным образом можно задать шаг с числом больше единицы.

5

"Регулировка цветов progressbar'a",
{
    "c": "define_progressbar",
    "var_name": "demo_progressbar_4",
    "len": 30,
    "pb_opts": {
         "style": {
              'empty_start': "<span style=\"color: #ffc555;\">",
              'empty_end': "</span>",
              'fill_start': "<span style=\"color: #ff9155;\">",
              'fill_end': "</span>",
              'fill_char': "█"
         },
         "replace_range": {"start": 0, "end": 30, "step": 0.5},
    },
},
{"c": "step_delay", "cnt": 80},
{"c": "rst"},

В опциях empty_start и fill_start показано, как заменить цвета, используемые progressbar'ом.

6

"Параллельная работа нескольких progressbar'ов",
{
    "c": "define_progressbar",
    "var_name": "demo_progressbar_5.0",
    "len": 30,
    "pb_opts": {
        "replace_range": {"start": 0, "end": 30, "step": 0.5},
    },
},
{
    "c": "define_progressbar",
    "var_name": "demo_progressbar_5.1",
    "len": 30,
    "pb_opts": {
        "replace_range": {"start": 30, "end": 0, "step": 0.5},
    },
},
{
    "c": "define_progressbar",
    "var_name": "demo_progressbar_5.2",
    "len": 30,
    "pb_opts": {
        "replace_range": {"start": 0, "end": 30, "step": 0.5},
    },
},
{"c": "step_delay", "cnt": 80},
{"c": "rst"},

Значения трёх progressbar'ов меняются в одно время. Добавить нечего.

7

"Перехват состояния progressbar'a",
{
    "c": "define_progressbar",
    "var_name": "demo_progressbar_6",
    "len": 10,
    "pb_opts": {
        "replace_range": {"start": 0, "end": 10, "step": 0.5},
    },
},
{"c": "step_delay", "cnt": 10},
{
    "c": "define_progressbar",
    "var_name": "demo_progressbar_6",
    "len": 10,
    "pb_opts": {
        "replace_range": {"start": 10, "end": 0, "step": 0.5},
        "style": {
            'empty_start': "<span style=\"color: #ffc555;\">",
            'empty_end': "</span>",
            'fill_start': "<span style=\"color: #ff9155;\">",
            'fill_end': "</span>",
            'fill_char': "█"
        },
    },
},
{"c": "step_delay", "cnt": 10},
{
    "c": "define_progressbar",
    "var_name": "demo_progressbar_6",
    "len": 10,
    "pb_opts": {
        "replace_range": {"start": 5, "end": 10, "step": 1},
        "style": {
            'empty_start': "<span style=\"color: #ffc555;\">",
            'empty_end': "</span>",
            'fill_start': "<span style=\"color: #5591ff;\">",
            'fill_end': "</span>",
            'fill_char': "█"
        },
    },
},
{"c": "step_delay", "cnt": 15},
{"c": "rst"},

Progressbar сохраняется в памяти с названием "demo_progressbar_6".
В процессе его работы переопределения сбрасывают его диапазоны работы и цвета, меняя его поведение.

8

{"c": "print", "txt": "Перенастройка глобального таймера", "var_name": "demo_paragraph_gtimer"},
{
    "c": "define_progressbar",
    "var_name": "demo_progressbar_7.0",
    "len": 10,
    "pb_opts": {
        "replace_range": {"start": 0, "end": 10, "step": 1},
    },
},
{
    "c": "define_progressbar",
    "var_name": "demo_progressbar_7.1",
    "len": 20,
    "pb_opts": {
        "replace_range": {"start": 0, "end": 20, "step": 1},
    },
},
{
    "c": "define_progressbar",
    "var_name": "demo_progressbar_7.2",
    "len": 30,
    "pb_opts": {
        "replace_range": {"start": 0, "end": 30, "step": 1},
    },
},
{"c": "change_global_delay", "delay_ms": 640},
{"c": "step_delay", "cnt": 10},
{"c": "change_global_delay", "delay_ms": 320},
{"c": "step_delay", "cnt": 10},
{"c": "change_global_delay", "delay_ms": 160},
{"c": "step_delay", "cnt": 20},
{"c": "reset_global_delay"},

3 работающих параллельно progressbar'a замедляются и ускоряются в зависимости от настройки задержки.

Версия 0

Основы

Для работы во всех браузерах обязательно вынести скрипты после блока:

  • Блок с анимацией
  • Список скриптов и стилей
  • Настройки

Настройки

Базовая настройка выглядит так:

// Список кадров.
// Отдельные кадры помещаются здесь через запятую.
var frame_list = [];
// Экземпляр анимации, с которым производятся все действия от настройки до пуска
var NTA = new window.Term_animation({
  $parent: $('.wireCell'), // Ищем блок с классом CSS "wireCell"
  pause_between_steps: 40, // Задаём паузу для отрисовки
  frames: frame_list // Задаём список кадров
});
// Пуск анимации
NTA.start();

Виды кадров

Посимвольный вывод, type

Выводит строку символ за символом, поэтому разметка HTML не поддерживается.

Образец:

{"c": "type", "txt": "ТЕСТ."}

Вывод строки, print

Выводит строку, как HTML.

Образец:

{"c": "print", "txt": "ТЕСТ."}

Очистка экрана, rst

Очищает рабочую область от данных, убирая всё содержимое.

Образец:

{"c": "rst"}

Замена последней записанной строки, replace_last

Очищает рабочую область от данных, убирая всё содержимое.

Образец:

{"c": "replace_last", "txt": "Тест"}
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License