Реализация автограф-сессии автора для iBooks

в 14:43, , рубрики: canvas, cookie, ePub, localStorage, метки: , , ,

Я работаю в маленьком издательстве. И, после выпуска бумажной версии детской книжки решили сделать и ее электронный вариант для iPad. Не приложение, а именно книгу в формате eEub.
Договорились о презентации в крупном торговом центре: бумажные книжки продаются, автор их подписывает, iPad-версия скачивается посетителями центра, плюс они же играются с анимацией на предоставленных iPad'ах.
Но, если автор подписывает бумажные книги, почему бы не подписать и электронную?
Идея новая и оригинальная, но реализуемая ли?
Скажу сразу, реализовать подписывание не удалось, и вот почему...

Технически всё просто — берем индукционный стилус, в книге размещаем canvas-блок с обработчиками рисования и два секретных места, для стирания неудачно написанного и для его сохранения. Сохранять будем в LocalStorage.

C написанием текстов в книге проблем не возникло. Кода для рисования по канве – полный интернет, основная «хитрость» – рисовать надо отрезками, а не точками. Код рисования был подчерпнут тут.

Сохранять канву будем с помощью getImageData().
Поскольку подпись у нас черно-белая, можно сохранять не все три значения RGB, а только одно. Затем преобразуем полученное число в код символа и получаем здоровенную строку, описывающую нашу картинку.

Для сохранения использован jQuery-плагин jStorage.
Отлично. Все работает, правда на компе. Переносим на iPad.

Написанный текст не восстанавливается. Расставляем alert’ы, смотрим. Оказывается, нарисованное не сохраняется. Упрощаем код, заменяем плагин jStorage на банальное, но точно рабочее – LocalStorage.name=”бла-бла”.
Не работает. Гуглим. Выясняется, что где-то между iBooks 1.3 и iBooks 2 – Apple обрезала поддержку LocalStorage, но есть поддержка cookie.

Наша канва размером 767х600 пикселей, это больше 400 килобайт данных.
Cookie может сохранить только 4 килобайта. Значит разрежем данные картинки на куски по 4КБ.
Кук может быть 20 штук на сайт. На всякий случай создаем в цикле 150 кук — работает.
Пытаемся распределить в них данные картинки — не работает. Выясняется, что суммарная емкость кук — 20*4096, т. е. около 80 килобайт, и кук может быть не 20, а больше, но с меньшим количеством данных, так чтобы суммарно не превысило 80 килобайт.
Попутно отгребаем еще одну проблему — Apache, под которым отлаживается версия перестает открывать страничку, с которой передаются такие большие заголовки, приходится чистить куки каждый раз.

Нужно сократить объем картинки. Можно кодировать каждую точку не байтом, а битом, но картинка из градаций серого становится черно-белой, что некрасиво.
Гуглим, находим библиотеку Canvas2Image. Библиотека возвращает либо объект типа image, либо сохраняет канву на диск в формате jpeg, png или bmp. Нам объект не нужен, нужны чистые данные, поэтому в из кода библиотеки был выкинут ненужный кусок. Теперь у нас есть base64 кодированный png.
Размер картинки начинает колебаться между 20 и 50 КБ, что нас устраивает. Автор получит инструкции, чтобы не увлекался пожеланиями к читателям.

Пробуем восстановить нарисованное… Используем для этого функцию drawImage() из canvas. Хм, восстанавливается со второго раза. Проблема в том, что объект image, который нужно скормить drawImage – не успевает заполниться данными. Для меня это было неожиданно, ведь в качестве image.src были использованы base64 данные, которые уже вроде как загружены.
Проблема решилась вызовом drawImage по событию load для картинки.

Проверяем на компе — работает.
Переносим на ipad – не работает. Орять используем alert'ы. Картинка сохраняется успешно, восстанавливается — нет. Ставим alert для просмотра каждой куки. Первая кука читается, вторая уже нет, javascript в iBooks, судя по всему, падает.
Пробуем делать куки меньшего размера. Чтобы удалить старые — пришлось удалить и снова поставить iBooks.
Теперь всё останавливается после второй куки по 200 байт. Похоже, что размер данных под cookie существенно меньше чем в браузере. Fail…

На этом месте разработка была прекращена. Можно было бы перебором выяснить размер хранилища iBooks, но отладка интерактива книжки на устройстве слишком утомительна и, похоже, в данном случае бесперспективна. Придётся автору подписывать только бумажные книжки…

Автор: shornikov

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js