Онлайн книга своїми руками на JavaScript

image

Отже, потрібно: опублікувати книгу з ілюстраціями онлайн так, щоб її можна було дописувати і переписувати, і сповіщати про це читачів. Швидке і витончене рішення під катом.

Спочатку планувалося написати повноцінну адмінку з WYSIWYG-редактором, у якого обов'язково повинна бути хороша перевірка орфографії, зручний інтерфейс і можливість причепити до запису анімацію. У планах було анімувати малювання олівцевих начерків на полях. Забігаючи трохи вперед, скажу, що робили саму малювання за допомогою vivus.

Загалом, купили домен, але розробка серверної частини ніяк не йшла: виходили якісь громіздкі виродки, у яких зайвого було більше, ніж корисного. Може так би все і залишилося, якби мені на очі не потрапило опис одного продукту (jekyll), де в перевагах за інших було відзначено відсутність бази даних. Тут-то мене і осяяло, що книзі база даних як корові сідло не потрібна.

І закрутилося: вирішено було хостити книгу на github, а сторінки розмічати markdown, благо для улюбленого автором word'а швидко знайшовся плагін для збереження в цьому форматі (Writage). Ну а для перетворення в html підвернулася бібліотека ShowDown

Досить швидко задумане було реалізовано. Книга складається з файлів-сторінок у форматі .md і файлу .json, в якому перераховано що за чим іде, яку анімацію вантажити і чи треба взагалі.

Ось так виглядає конфігураційний файл:

[{
"file": "файл.md",
"hash": "хештег",
"animation": {
"svg": "анімація.svg",
"duration": 2000,//Тривалість анімації в мілісекундах
"style": "width:400px;height:300px;opacity:0.5;float:right;margin-right:20px;"//Стиль для блоку анімації, щоб було зрозуміло де його розміщувати
},
{
"file": "имяфайла2.md",
"hash": "хештег2"
}]

Власне, самі сторінки завантажуються асинхронно при прокрутці і за хештегом, щоб користувач міг продовжити читати з того ж місці, де зупинився. При завантаженні сторінки за хештегом підвантажується ще й попередня запис, якщо вона є, щоб не здавалося, що це початок книги.

Синхронний Ajax браузер мені використовувати не дав, але може воно й на краще. Робила так: спочатку створюються блоки з id=хештег, потім надсилаються запити до безпосередніх сторінкам. Таким чином, всі запитані сторінки стають на своє місце, незалежно від того, який із запитів виконається швидше.

функція завантаження сторінки, яка приймає об'єкт сторінки з конфігураційного файлу і опціонально параметри: чи потрібно змінювати хеш сторінки, додати цю сторінку після поточної або перед і потрібно скролл на новій сторінці після завантаження. Параметри дають можливість фонової завантаження сторінок.

function loadPage(page, options = {}) {
$("#loader").show(); 
if (options.changeHash === undefined) {
options.changeHash = true;
}
if (options.next === undefined) {
options.next = true;
}
if (options.scroll === undefined) {
options.scroll = true;
}
if (options.changeHash) {
document.location.hash = "#" + page.hash;
}
if ($("#" + page.hash).size() == 0) {
if (options.next) {
$("#content").append('<div id="' + page.hash + '"></div>');
} else {
$("#content").prepend('<div id="' + page.hash + '"></div>');
}
jQuery.ajax({
url: "/book/" + page.file,
success: function(result) {
//Перетворимо markdown в html
var converter = new showdown.Converter();
var html = converter.makeHtml(result);
$("#" + page.hash).html(html);
if(page.animation!==undefined){
//Малюємо малюнок, якщо вона є
$("#" + page.hash).prepend('<div id="animation-'+page.hash+'" style="'+page.animation.style+'"></div>');
var vivus=new Vivus('animation-'+page.hash, {duration: page.animation.duration, file: '/svg/'+page.animation.svg, type:'oneByOne'}, finishedDrawing);
}
$("#loader").fadeOut();
if (options.scroll) {
//Повземо до завантаженій сторінці, якщо потрібно
$('html,body').animate({
scrollTop: $("#" + page.hash).offset().top
}, 300, 'swing');
}
}
});
}
}

Власне, ось і вся магія. Автор спокійно пише собі книгу і в пару кліків публікує (з редактурою json файлу він теж впорався сам).

Готову книгу (вона англійською) можна почитати тут, а розглянути нутрощі детальніше коді на github.

Дякую за приділений час, сподіваюся, що ви не визнали його витраченим даремно!
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.