Хочу начать с того, что мне жутко надоели презентации со стандартным лейаутом: сверху шапка с темой, потом набор пунктов, снизу футер ну и справа и/или по центру картинка может какая-то или диаграмма.
Скучно!
Где же креатиффность? Неужели не хочется не просто раскрыть свою тему, а сделать это так, чтоб даже тем, кому не интересна тема, будут заинтересованны подачей материала? Блин, мы ж веб-девелоперы, так почему же мы создаем презентации в левых программах, а не там, где мы лучше всех?
История
Для начала я попробовал такую штуку, как Prezi (И вот что у меня вышло). Да, необычно. Но меня жутко удивило сложность и практическая невозможность кастомизации — нет своих тем, шрифтов, анимацией… разве что видео добавлять. Но концепция очень заинтересовала, хотя и смутила «круговерть» переходов — аж голова кружится когда пускаешь презентацию на большом проекторе. Хотя тогда мое выступление, судя по отзывам, неплохо прошло.
В этом году меня снова пригласили выступить (на этот раз на JEEConf) и передо мною снова встал вопрос о том, каким образом я буду показывать то, о чем я буду рассказывать (почти стих). И снова захотелось необычного :)
Сначала решил сделать что-то вроде Prezi, но на GWT и воспользоваться всей силой HTML. Но в процессе разработки как-то потихоньку выплыла другая идея: а почему бы не использовать CSS3-Transitions для анимации и CSS3-2D-Transforms для поворотов? Ведь тогда можно с минимальными усилиями сделать красивые переходы между «слайдами».
Дальше больше: я вспомнил что CSS это каскадные стили. То есть если у нас есть одно определение, и потом другое, которое частично или полностью заменяет некоторые параметры первого, то броузер должен будет отрендерить по второму определению.
То есть если есть два определения
.class1 {
left: 100px;
}
.class2 {
left: 200px;
}
И какому-то элементу будет установлено два класса (class=«class1 class2») то в результате броузер должен будет позиционировать элемент с свойством left равному 200px. Данное свойство знакомо любому, кто только начал изучать CSS.
И если у элемента был класс class1 и потом мы ему присвоим class2 то left изменится со 100 на 200. Изменится. То есть если у элемента к тому же был «включен» css3 transition, то броузер должен будет плавно передвинуть элемент с 100px до 200px. А это именно то что нам и нужно!
Первый блин
Для того, чтоб «обкатать» идею я написал небольшой кусок кода на jQuery, который все что делал — это добавлял класс при переходе на следующий «слайд» и удалял его когда нужно было вернутся на предыдущий.
Весь контент, который появлялся и исчезал я поместил в контейнер с определенным id («cont») что позволило меняя класс(ы) этого контейнера менять стили контентов.
В итоге код установки слайда выглядел как:
if (stage>current_stage) {
for (current_stage++;current_stage<=stage;current_stage++) {
$("#cont").addClass("s"+current_stage);
}
current_stage--;
} else if (stage<current_stage) {
for (;current_stage>stage;current_stage--) {
$("#cont").removeClass("s"+current_stage);
}
}
После этого я сосредоточился в основном на контенте.
В результате на JEEConf'е я выступил вот с такой презентацией: CQRS+GAE+GWT
Этап 2: JACSS
После доклада, которое, кстати, было довольно интересно проводить, захотелось как-то упорядочить эту, так сказать, технологию для того, чтоб следующий доклад легче было бы готовить.
Во-первых я решил что jQuery в моем случае не нужен — ведь есть classList.
Во-вторых надо было сделать минимальную конфигурацию — сколько слайдов, где контролы находятся и т.д. Для этого я вынес эти параметры в отдельный объект для конфигурации и воспользовался querySelectorAll
В итоге и вышел вот такой вот проект: JaCSS (как помесь слов Javascript и CSS).
Внутри кода нет ровным счетом ничего сложного. После добавления jacss делает следующее:
- Экспортирует две функции: jacss.next(), javss.prev() — переключение «слайдов»
- Вешает обработчик клавиш стелочек и пробела на окно (которые переключают «слайды»)
- Вешает обработчик изменения «хеша» урл (для корректной обработки навигации «назад»/«вперед» броузера)
- Смотрит хеш урл, и если там что-то есть пытается перейти на слайд, указанный в хеше урл
При переключении слайдов происходит:
- Добавление-удаление классов вида «sN», где N — номер слайда. Таким образом если текущий слайд был пятый то при навигации на 7-ой произойдет добавление классов s6, s7. А при навигации на 2, будет попытка удалить классы s5, s4
- будет установлен хеш урл равным новому «текущему» слайду
Самое интересное, что дальше я расскажу предлагаемый мною вариант использования этой «библиотеки». На самом деле структура HTML и CSS файлов может кардинально отличатся от моей. Более того, я бы даже попросил хорошим веб-дизайнеров подумать и предложить более удобные варианты центрирования и позиционирования контентов. Мои же примеры можно считать как proof of concept, на основе которых уже можно сделать «нормальные» решения.
В общем, предлагаю мой вариант:
Как создать свою презентацию с JACSS
Презентация делится (не четко, см. ниже) на две части: «контенты» (текст, картинки), и «поведение» (набор определений css). По этому создадим два файла: simple.html и simple.css
С кодом html хабрапарсер как-то тяжко справляется, по этому прошу вот сюда: github.com/olostan/jacss/tree/master/examples/simple
В html мы подключаем jacss-овские js/css. Потом конфигурируем его (максимальное количество «слайдов») и задаем собственно текст:
<span id='texample'>Example</span>
Cразу скажу, что если использовать мой jacss.common.css (что не обязательно), то айдишники блоков с контентом должны начинаться с буквы «t».
В CSS-ке же сначала мы задаем начальное положение контента. При использовании моего набора стилей, каждый контент изначально спрятан (opacity: 0, visibility: hidden), кроме того левый верхний угол позиционирован примерно по центру. Итого чтоб расположить изначально по центру наш текст надо:
#texample {
color: blue;
font-size: 50px;
left: -80px;
top: -35px;
}
Потом идут описания стиля (цвета, видимости, положения) контента для каждого «слайда»:
.s1 > #texample {
opacity: 1;
visibility: visible;
}
.s2 > #texample {
left: -400px;
top: 200px;
}
.s3 > #texample {
top: -200px;
color: red;
}
.....
Записываем мы только изменения относительно предыдущего «слайда».
Результат можно посмотреть вот тут (или взять с гитхаба).
Более сложный пример (с градиентами, тенями, RGBA-фоном и т.д.) так же можно посмотреть.
Пару слов про разделение между html и css: важно понимать, что в css находится наше поведение. То есть записаны изменения. Что же делать, если нужно менять картинку/текст при смене кадра? Если для картинки просто — можно ее пустить на background, то с текстом сложнее. Я нашел такое решение: использовать псевдо-селекторы :before, :after и «content» — см. изменение «Вася» на «Коля» тут.
Что дальше?
А дальше все в Ваших руках: форкайте на здоровье! Ведь реально пока готова только концепция, к которой можно еще столько всего прикрутить:
- Поддержку браузеров (я в основном смотрел на Chrome/FF4). Не вижу причин почему не должно так же работать на Opera, IE9
- Поддержка мобильных устройств (жесты). Я проверил на своем iPad — в основном работает, надо только «заточить» CSS и добавить обработчики на жесты
- Попробовать прикрутить LESS (http://lesscss.org/) c node.js как без-энд
- Более красивую навигационную панель (может с авто-хайдом), или разные «скины» для нее
Я постепенно буду стараться двигаться по этому чеклисту, но и приветствую любую помощь в виде pull request'ов :) А так же предложения, советы и замечания.
Спасибо и до встречи на красивых и увлекательных докладах!
Linklist:
Моя первая презентация
JaCSS на GitHub
Простейшая демка на jacss
Чуть более сложная демка на jacss