Внучки подрастают. Старшей осенью в школу. Хороший повод реинкарнировать в виде WEB-приложения дочкину тренировалку по арифметике. Собирался десятилетие, но все руки не доходили и напрямую с html-версткой и фронтендом не сталкивался. Под катом — процесс от ТЗ до готового изделия, который может быть интересен таким-же как я начинающим.
Тренировалку сделал в 2002-м с помощью gif-рисовальщика и VB5. История сохранила только .exe, скриншоты которого и станут основой графики нового приложения:
… а вот «педагогическую концепцию» стоит слегка подправить:
Итого требуется реализовать три основных сцены: настройка сложности, решение заданий и 'дневник' для устройств не менее фаблета (для смартфонов с естественной вертикальной ориентацией экрана компоновка сцен должна быть иной).
Вооружившись изложенным ТЗ и краткими напутствием мэтров [1] и [4], приступил к реализации проекта с рабочим названием «Арифмиша».
По ключевой фразе 'html editor' YaST предложил Bluefish. Среда разработки интерфейса далека в визуализации от подзабытого VB5. Для просмотра верстки необходимо вызвать дежурный браузер.
Cинтаксис html и js подсвечиваются. Автозаполнение имеется, но порой досаждают парные языковые конструкции (теги, скобки). Есть структуризатор Java-script кода.
За время разработки вряд ли успею оценить все возможности редактора.
Стоит сразу озаботиться хостингом для проверки верстки на разных платформах. Воспользовался советом sim3x на Тостерe. Немного поэкспериментировав c GitHub Project Pages получил то, что хотел. Шаблон index.html взял со StackOverflow, но это необязательно — можно просто ссылаться на корневую страницу в ветви gh-pages репозитория.
Приложение состоит из единственного файла html, содержащего отображаемые элементы, и подгружаемых файла стилей, java-скриптов, графики. Компонентов немного. Подумав, таки добавил две структурные папки: ./img и ./js.
Разработку начал с верстки и переключения сцен. По личной неопытности процесс имел характер эксперимента: сформировал сцену — проверь в браузерах.
Поскольку сцен всего три, не разбивал их на отдельные html-файлы, а регулировал переключением свойства visibility корневого div элемента слоя сцены. Все элементы сцен завязаны на базовое изображение, снабженное кликабельной картой и размещенное в нижнем слое вместе с виртуальной клавиатурой.
С целью горизонтального центрирования сцен, для базового слоя выбрал ширину 740px (при абсолютном позиционировании), с некоторым избытком охватывающую картинку и виртуальную клавиатуру. Позднее добавил анимированных Марьванну и Мишу, разогнав их по углам с помощью margin.
Для организации групп элементов в колонки пользовался стилевым атрибутом display:inline-block;
Использование соглашений — не самоцель: хороший тон и один из признаков профессионализма. Дело ведь не в количестве пробелов в отступах, а в едином читабельном оформлении компонентов. Желательно сразу продумать систему именования. В этом смысле мое изделие далеко от идеала.
Валидатор validator.w3.org/nu/#file помог выловить ляпы верстки, устранить избыточность и подсказал решение вопроса с устаревшими атрибутами типа align=”center”. Любое отклонение валидатор квалифицировал как ошибку. Для required alt в map area наличие ошибки понятно, интересно другое — почему required? Что в атрибуте alt такого важного для W3C?
При обращении из скрипта адресуемые элементы страницы должны быть уже загружены. На этот случай есть событие onload элемента body. Последовательность получилась следующая:
Элемент может принадлежать нескольким классам, разделяемых пробелом. В отличие от имен тегов, значения атрибутов id и class регистрозависимы.
Атрибуты элементов html обладают некоторой двойственностью: если для элемента input типа checkbox страницы атрибут checked='checked', то в js — это свойство элемента el.checked == true, а метод el.getAttribute('checked') вернет null.
Генерация примеров арифметики основана на случайном выборе из интервала целых чисел. Проверка ответа в VB5-реализации базировалась на логическом значении, возвращаемом функцией eval('2 * 2 = 5'). В этой реализации — на строковом сравнении правильного ответа и ответа пользователя. В связи с этим пришлось исключать неоднозначности вида: 2? 2 = 4 и округлять периодическую дробную часть чисел.
Назначение обработчиков события onclick для элементов area карты изображения возможно только из скрипта. Для подавления действия по-умолчанию (переход по html-ссылке, без которой событие не работает) обработчик должен вернуть false:
Ввод данных организован и c виртуальной и с физической клавиатур непосредственно в элементы (innerHTML). Вместо курсора использовал blinking border CSS. Для физической клавиатуры определены обработчики событий onkeypress (отображаемые символы), onkeydown (управляющие символы) тела страницы. Дело в следующем:
Отладчики в браузерах упрятаны довольно глубоко в меню (для FF: “Меню” — “Разработка” — “Отладчик”), но есть горячие клавиши.
Если что-то пошло не так, стоит заглянуть на вкладку “Консоль”, где выводятся синтаксические ошибки исполняемых скриптов. Ловятся по одной, что естественно для интерпретации. А если и в консоли пусто, самое время обратиться к js-валидатору www.jslint.com.
Для времени исполнения есть полный набор отладочных инструментов: просто песня в сравнении с бэкенд отладкой с клиента, когда порой располагаешь только контрольной печатью.
Программно-управляемую анимацию не планировал, поэтому не заострялся на CSS и js решениях. Тем не менее, понравилось предложение mefisto в комментах к [2]. Если склеить и двигать кадры вертикально получится вполне по-киношному.
APNG не прижился в Chrome. Выбрал старый, добрый и уже не проприетарный gif.
Для обработки скриншотов и формирования gif использовал GIMP. Редактор содержит все необходимое, включая gif-оптимизатор. Эффективность оптимизации можете оценить сами.
Коротко и наглядно об анимации в GIMP можно посмотреть здесь: http://www.progimp.ru/articles/sposobyi_sozdaniya_animatsii_v_gimp/
Пробовал animizer.net/ru/gif-apng-assembler. Интересно, но нет возможности дублировать загруженные кадры и при разбиении анимации теряются значения задержек.
Для хранения настроек и 'дневника' использовал cookie со сроком 2 недели. Есть ограничение — куки привязаны к конкретному браузеру.
Мои потребности исчерпывающе удовлетворил пакет из сети. Код использован с согласия автора.
Не есть предмет первой необходимости, но подумать об этом стоит. Целям локализации служат скрипты с постфиксом, соответствующим локальному языку (lang_ru.js), распихивающие строки текста по свойствам элементов и глобальным переменным приложения. В самом html — мой жуткий английский по-умолчанию. Для выбора и загрузки скрипта локализации в конце тела страницы добавлен код:
К локальным настройкам можно отнести и альтернативные знаки арифметических действий: деления (слэш /, двоеточие:, обелюс ?) и умножения (звездочка *, крестик ?, точка • ). Ну и, конечно, представление десятичной “точки”.
Процесс разработки доставил удовольствие. В чем прелесть программирования — всегда есть пусть не материальный, но результат: https://miktim.github.io/arithmisha/
1. Checkit ,“Создание веб-сайта. Курс молодого бойца”
2. Lord_D, “Анимированный PNG в Firefox, Opera и WebKit? Легко!”
3. Disturbed,“Нужна ли HTML-валидация?!”
4. перевод splincodewd, «Руководство по HTML/CSS/JavaScript»
Ax да,
У Мишки на майке есть место для логотипа спонсора :). Правда придется менять хостера…
Тренировалку сделал в 2002-м с помощью gif-рисовальщика и VB5. История сохранила только .exe, скриншоты которого и станут основой графики нового приложения:
… а вот «педагогическую концепцию» стоит слегка подправить:
- суть процесса, как и ранее, в помощи третьему лицу (ученик Миша);
- в случае ошибки необходимо предоставить правильный ответ;
- оценки отменяются (хорошо бы им придать характер игрового счета, конвертируя в очки время и соотношение правильных и ошибочных ответов);
- родительский контроль (как без него?) посредством 'дневника', в котором сохраняются последние три-четыре решенных задания (30-40 примеров) и минимальная статистика;
- желательна виртуальная специализированная клавиатура;
- для разрядки стоит добавить примитивной анимации.
Итого требуется реализовать три основных сцены: настройка сложности, решение заданий и 'дневник' для устройств не менее фаблета (для смартфонов с естественной вертикальной ориентацией экрана компоновка сцен должна быть иной).
Вооружившись изложенным ТЗ и краткими напутствием мэтров [1] и [4], приступил к реализации проекта с рабочим названием «Арифмиша».
Выбор средства разработки
По ключевой фразе 'html editor' YaST предложил Bluefish. Среда разработки интерфейса далека в визуализации от подзабытого VB5. Для просмотра верстки необходимо вызвать дежурный браузер.
Cинтаксис html и js подсвечиваются. Автозаполнение имеется, но порой досаждают парные языковые конструкции (теги, скобки). Есть структуризатор Java-script кода.
За время разработки вряд ли успею оценить все возможности редактора.
Хостинг
Стоит сразу озаботиться хостингом для проверки верстки на разных платформах. Воспользовался советом sim3x на Тостерe. Немного поэкспериментировав c GitHub Project Pages получил то, что хотел. Шаблон index.html взял со StackOverflow, но это необязательно — можно просто ссылаться на корневую страницу в ветви gh-pages репозитория.
Структура приложения
Приложение состоит из единственного файла html, содержащего отображаемые элементы, и подгружаемых файла стилей, java-скриптов, графики. Компонентов немного. Подумав, таки добавил две структурные папки: ./img и ./js.
Верстка
Структура html, <head>
В теге head определил кодировку страницы, заголовок, инструкции поисковым роботам и, на всякий случай, запрет кэширования на период разработки.<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="cache-control" content="max-age=0">
<meta http-equiv="cache-control" content="no-cache" >
<meta http-equiv="expires" content="0" >
<meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT" >
<meta http-equiv="pragma" content="no-cache">
<title>Arithmisha</title>
<meta name="viewport" content="width=device-width">
<meta name="keywords" lang="ru" content="Арифмиша арифметика пример упражнение">
<meta name="keywords" lang="en" content="Arithmisha arithmetic example exercise">
<meta name="robots" content="index, follow">
<script src="./js/cookie.js" type="text/javascript"></script>
<script src="./js/arithmisha.js" type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="arithmisha.css">
</head>
<body onload="postLoadInit();" onkeydown="catchControlKey(event);" onkeypress="keyboardHandle(event);" ondblclick="return false;">
<!-- ...элементы страницы... -->
</body>
</html>
Разработку начал с верстки и переключения сцен. По личной неопытности процесс имел характер эксперимента: сформировал сцену — проверь в браузерах.
Поскольку сцен всего три, не разбивал их на отдельные html-файлы, а регулировал переключением свойства visibility корневого div элемента слоя сцены. Все элементы сцен завязаны на базовое изображение, снабженное кликабельной картой и размещенное в нижнем слое вместе с виртуальной клавиатурой.
С целью горизонтального центрирования сцен, для базового слоя выбрал ширину 740px (при абсолютном позиционировании), с некоторым избытком охватывающую картинку и виртуальную клавиатуру. Позднее добавил анимированных Марьванну и Мишу, разогнав их по углам с помощью margin.
Для организации групп элементов в колонки пользовался стилевым атрибутом display:inline-block;
html сцены 'Настройка сложности'
<div id="divSettings" class="layer3" style="visibility:hidden; top:80px; font-size:15px;">
<!-- из кода удалены <var>, используемые при локализации -->
<div style="display:inline-block; text-align: left;"> <var id="setOp">Action</var>:<br>
<input class="setOp" type="checkbox" value="1"> addition<br>
<input class="setOp" type="checkbox" value="2"> subtraction<br>
<input class="setOp" type="checkbox" value="4"> multiplication<br>
<input class="setOp" type="checkbox" value="8"> division<br>
</div>
<div style="display:inline-block; text-align:left; vertical-align:top;"> Magnitude:<br>
<input class="setOrder" type="checkbox" value="16"> ones<br>
<input class="setOrder" type="checkbox" value="32"> tens<br>
<input class="setOrder" type="checkbox" value="64"> tenths<br>
</div>
<div style="display:inline-block; text-align:left;"> To find:<br>
<input class="setFind" type="checkbox" value="256"> result<br>
<input class="setFind" type="checkbox" value="640"> operand<br>
<input class="setFind" type="checkbox" value="1024"> action<br>
<input class="setFind" type="checkbox" value="2048"> relationship<br>
</div>
<div>
<var id="setOpd2nd">2nd operand</var>:
<var id="minOpd2nd" class="edited">1</var> - <var id="maxOpd2nd" class="editable">9</var>
</div>
</div>
Соглашения
Использование соглашений — не самоцель: хороший тон и один из признаков профессионализма. Дело ведь не в количестве пробелов в отступах, а в едином читабельном оформлении компонентов. Желательно сразу продумать систему именования. В этом смысле мое изделие далеко от идеала.
Валидация html
Валидатор validator.w3.org/nu/#file помог выловить ляпы верстки, устранить избыточность и подсказал решение вопроса с устаревшими атрибутами типа align=”center”. Любое отклонение валидатор квалифицировал как ошибку. Для required alt в map area наличие ошибки понятно, интересно другое — почему required? Что в атрибуте alt такого важного для W3C?
Java Script
При обращении из скрипта адресуемые элементы страницы должны быть уже загружены. На этот случай есть событие onload элемента body. Последовательность получилась следующая:
- вызов скрипта из header, объявление и инициализация глобальных переменных;
- загрузка элементов тела страницы и отработка встроенных скриптов;
- вызов процедуры события onload.
Элемент может принадлежать нескольким классам, разделяемых пробелом. В отличие от имен тегов, значения атрибутов id и class регистрозависимы.
Атрибуты элементов html обладают некоторой двойственностью: если для элемента input типа checkbox страницы атрибут checked='checked', то в js — это свойство элемента el.checked == true, а метод el.getAttribute('checked') вернет null.
Генерация примеров арифметики основана на случайном выборе из интервала целых чисел. Проверка ответа в VB5-реализации базировалась на логическом значении, возвращаемом функцией eval('2 * 2 = 5'). В этой реализации — на строковом сравнении правильного ответа и ответа пользователя. В связи с этим пришлось исключать неоднозначности вида: 2? 2 = 4 и округлять периодическую дробную часть чисел.
События
Назначение обработчиков события onclick для элементов area карты изображения возможно только из скрипта. Для подавления действия по-умолчанию (переход по html-ссылке, без которой событие не работает) обработчик должен вернуть false:
document.getElementById("areaBlackboard").onclick =
function() {
showTask();
return false; //disable default action
};
Ввод данных организован и c виртуальной и с физической клавиатур непосредственно в элементы (innerHTML). Вместо курсора использовал blinking border CSS. Для физической клавиатуры определены обработчики событий onkeypress (отображаемые символы), onkeydown (управляющие символы) тела страницы. Дело в следующем:
- не все броузеры инициируют onkeypress для Backspace;
- необходимо подавить действие клавиш в браузере (Backspace — возврат на домашнюю страницу, Enter — клик по сфокусированному элементу).
Отладка
Отладчики в браузерах упрятаны довольно глубоко в меню (для FF: “Меню” — “Разработка” — “Отладчик”), но есть горячие клавиши.
Если что-то пошло не так, стоит заглянуть на вкладку “Консоль”, где выводятся синтаксические ошибки исполняемых скриптов. Ловятся по одной, что естественно для интерпретации. А если и в консоли пусто, самое время обратиться к js-валидатору www.jslint.com.
Для времени исполнения есть полный набор отладочных инструментов: просто песня в сравнении с бэкенд отладкой с клиента, когда порой располагаешь только контрольной печатью.
Графика и анимация.
Программно-управляемую анимацию не планировал, поэтому не заострялся на CSS и js решениях. Тем не менее, понравилось предложение mefisto в комментах к [2]. Если склеить и двигать кадры вертикально получится вполне по-киношному.
APNG не прижился в Chrome. Выбрал старый, добрый и уже не проприетарный gif.
Для обработки скриншотов и формирования gif использовал GIMP. Редактор содержит все необходимое, включая gif-оптимизатор. Эффективность оптимизации можете оценить сами.
Коротко и наглядно об анимации в GIMP можно посмотреть здесь: http://www.progimp.ru/articles/sposobyi_sozdaniya_animatsii_v_gimp/
Пробовал animizer.net/ru/gif-apng-assembler. Интересно, но нет возможности дублировать загруженные кадры и при разбиении анимации теряются значения задержек.
Xранение данных
Для хранения настроек и 'дневника' использовал cookie со сроком 2 недели. Есть ограничение — куки привязаны к конкретному браузеру.
Мои потребности исчерпывающе удовлетворил пакет из сети. Код использован с согласия автора.
Локализация
Не есть предмет первой необходимости, но подумать об этом стоит. Целям локализации служат скрипты с постфиксом, соответствующим локальному языку (lang_ru.js), распихивающие строки текста по свойствам элементов и глобальным переменным приложения. В самом html — мой жуткий английский по-умолчанию. Для выбора и загрузки скрипта локализации в конце тела страницы добавлен код:
<html>
<body>
...
<script>
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "./js/lang_"+
(window.navigator.userLanguage || window.navigator.language).split("-")[0] + ".js";
document.body.appendChild(script); // добавить загрузку скрипта в конец документа
</script>
</body>
</html>
К локальным настройкам можно отнести и альтернативные знаки арифметических действий: деления (слэш /, двоеточие:, обелюс ?) и умножения (звездочка *, крестик ?, точка • ). Ну и, конечно, представление десятичной “точки”.
Итог
Процесс разработки доставил удовольствие. В чем прелесть программирования — всегда есть пусть не материальный, но результат: https://miktim.github.io/arithmisha/
ХаброБиблиография:
1. Checkit ,“Создание веб-сайта. Курс молодого бойца”
2. Lord_D, “Анимированный PNG в Firefox, Opera и WebKit? Легко!”
3. Disturbed,“Нужна ли HTML-валидация?!”
4. перевод splincodewd, «Руководство по HTML/CSS/JavaScript»
Ax да,
Монетизация
У Мишки на майке есть место для логотипа спонсора :). Правда придется менять хостера…
Поделиться с друзьями
miktim
Приношу извинения НЛО за неверную трактовку фразы о PNG из правил оформления публикаций.
С 10-летием.
Михаил.