Привет, меня зовут Александр, я старший разработчик ПО в Центре разработки Orion Innovation и я люблю делиться своими мыслями с людьми, разумеется, любимые форматы – статьи на Хабре и доклады на конференциях и митапах. Сложно представить доклад без презентации, о них и хочу поговорить.

Практически 10 лет слова презентация, слайды, PowerPoint (KeyNote) были для меня равносильны. Однажды мне необходимо было продемонстрировать большое количество кода (80 из 100 слайдов содержали код), и моя работа в PowerPoint превратилась в «День сурка»:

  1. Взять пример из кода.

  2. Отформатировать и убрать всё лишнее.

  3. Скопировать код в VS Code, чтобы получить подсветку синтаксиса.

  4. Выбрать тему, подходящую к фону слайдов.

  5. Скопировать код в презентацию как Rich Text.

  6. Просмотреть слайд, понять, есть ли что-то не так.

  7. Повторить с пункта 1.

Тот доклад я, конечно, доделал в PP, однако твёрдо решил найти альтернативу:

  • чтобы вся работа с кодом сводилась к «скопировать из источника и редактировать на месте» (а всё форматирование и подсветку синтаксиса отдать на усмотрение инструмента);

  • чтобы можно было привлечь внимание к под-фрагменту кода (строка, переменная, синтаксическая конструкция);

  • чтобы можно было отображать большие объемы кода (40 строк и более) на одном слайде (путём прокрутки фрейма с кодом до места, о котором идёт речь).

И в результате поисков я открыл для себя HTML-презентации (они же веб-слайды) на примере reveal.js.

Следует заметить, что reveal.js далеко не единственный фреймворк веб-презентаций, наверное, самые популярные альтернативы: Impress.js и Webslides.tv.

И, разумеется, на Хабре так же были статьи про HTML-слайды:

О reveal.js

Reveal.js — движок презентаций, разработанный Хакимом Эль-Хаттабом, привлекающий своей простотой и 3D-эффектами из коробки.

HTML-презентация — особым образом размеченная HTML-страница, которая превращается в слайды посредством JS & CSS. Позвольте продемонстрировать простейшую презентацию на reveal.js:

<html>
<head>
	<link rel="stylesheet" href="dist/reveal.css">
	<link rel="stylesheet" href="dist/theme/white.css" id="theme">
</head>
<body>
	<div class="reveal">
		<div class="slides">
			<section>Slide 1</section>
			<section>Slide 2</section>
		</div>
	</div>
	<script src="dist/reveal.js"></script>
	<script>
		Reveal.initialize({/* config */});
	</script>
</body>
</html>

Ничего сверхъестественного и архисложного: обычная веб-страница со скриптом и парой css-include’ов. Открыв такую страницу в браузере мы обнаружим два слайда:

Пример онлайн (осторожно, откроется в этой же вкладке)

Разумеется, вы можете указывать заголовки, под-заголовки, под-под-заголовки и т.д.

<section>
  <h1>Заголовок</h1>
  <h2>Под-заголовок</h2>
  <h3>Под-под-заголовок</h3>
  <h4>Под-под-под-заголовок</h4>
  <p>Тело слайда</p>
</section>

Пример онлайн (осторожно, откроется в этой же вкладке)

И списки

<section>
  <ul>
    <li>Первый</li>
    <li>Второй</li>
    <li>Третий</li>
  </ul>
  <ol>
    <li>Первый</li>
    <li>Второй</li>
    <li>Третий</li>
  </ol>
</section>

Пример онлайн (осторожно, откроется в этой же вкладке)

Таким образом вы получаете структурированные слайды.

Так же вам доступны фрагменты — возможность отображения содержимого слайда по частям (по клику) (Аналог Appearance Animation по клику из PP).

<section>
  <ul>
    <li class="fragment">Первый</li>
    <li class="fragment">Второй</li>
    <li class="fragment">Третий</li>
  </ul>
</section>

Пример онлайн (осторожно, откроется в этой же вкладке)

Или укажите свой собственный порядок отображения:

<section>
  <ul>
    <li class="fragment" data-fragment-index="0">Первый</li>
    <li class="fragment" data-fragment-index="2">Третий</li>
    <li class="fragment" data-fragment-index="1">Второй</li>
  </ul>
</section>

Пример онлайн (осторожно, откроется в этой же вкладке)

Или же используйте разные варианты фрагментов:

<section>
  <ul>
    <li class="fragment fade-out">Первый</li>
    <li class="fragment grow">Второй</li>
    <li class="fragment strike">Третий</li>
  </ul>
</section>

Пример онлайн (осторожно, откроется в этой же вкладке)

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

Особенности reveal.js

Удобная работа с кодом

Одна из самых замечательных особенностей: способность форматировать код, подсвечивать синтаксис, а также отображать большой объем кода, прокручивая область с кодом по клику.

Объёмный код
<section data-auto-animate>
  <h2>Объемный код</h2>
  <pre><code data-trim data-noescape data-line-numbers="1-14|28-41|1-14|14-28|1-14" class="cpp"><script type="text/template">
					#include <iostream>
					using namespace std;
					bool checkPrimeNumber(int);
					int main() {
						int n;
						cout << "Enter a positive  integer: ";
						cin >> n;
						if (checkPrimeNumber(n))
							cout << n << " is a prime number.";
						else
							cout << n << " is not a prime number.";
						return 0;
					}
					bool checkPrimeNumber(int n) {
						bool isPrime = true;
						// 0 and 1 are not prime numbers
						if (n == 0 || n == 1) {
							isPrime = false;
						}
						else {
							for (int i = 2; i <= n / 2; ++i) {
								if (n % i == 0) {
									isPrime = false;
									break;
								}
							}
						}
						return isPrime;
					}
					float calculateSD(float data[]) {
						float sum = 0.0, mean, standardDeviation = 0.0;
						int i;
						for(i = 0; i < 10; ++i) {
							sum += data[i];
						}
						mean = sum / 10;
						for(i = 0; i < 10; ++i) {
							standardDeviation += pow(data[i] - mean, 2);
						}
						return sqrt(standardDeviation / 10);
					}
  </script></code></pre>
</section>

Пример онлайн (осторожно, откроется в этой же вкладке)

Всё, что нужно для отображения кода: скопировать код, вставить его в нужное место, после чего указать какие строки в какой момент должны отображаться. При необходимости код можно исправить прямо на месте без кучи дополнительных копи-пастов. Главное — не забыть обновить номера строк кода для отображения.

Автоанимирование

Автоанимирование, оно же Morph transition в PowerPoint, - анимация смены слайдов, при которой объекты предыдущего слайда плавно превращаются в объекты следующего.

<section data-auto-animate>
  <h2>Auto-Animate</h2>
  <div class="r-hstack justify-center">
    <div data-id="box1" style="background: #999; width: 50px; height: 50px; margin: 10px; border-radius: 5px;"></div>
    <div data-id="box2" style="background: #999; width: 50px; height: 50px; margin: 10px; border-radius: 5px;"></div>
    <div data-id="box3" style="background: #999; width: 50px; height: 50px; margin: 10px; border-radius: 5px;"></div>
  </div>
</section>
<section data-auto-animate>
  <div class="r-hstack justify-center">
    <div data-id="box1" data-auto-animate-delay="0" style="background: cyan; width: 150px; height: 100px; margin: 10px;"></div>
    <div data-id="box2" data-auto-animate-delay="0.1" style="background: magenta; width: 150px; height: 100px; margin: 10px;"></div>
    <div data-id="box3" data-auto-animate-delay="0.2" style="background: yellow; width: 150px; height: 100px; margin: 10px;"></div>
  </div>
  <h2 style="margin-top: 20px;">Auto-Animate</h2>
</section>
<section data-auto-animate>
  <div class="r-stack">
    <div data-id="box1" style="background: cyan; width: 300px; height: 300px; border-radius: 200px;"></div>
    <div data-id="box2" style="background: magenta; width: 200px; height: 200px; border-radius: 200px;"></div>
    <div data-id="box3" style="background: yellow; width: 100px; height: 100px; border-radius: 200px;"></div>
  </div>
  <h2 style="margin-top: 20px;">Auto-Animate</h2>
</section>

Пример онлайн (осторожно, откроется в этой же вкладке)

Разумеется, превращение форм — не единственное проявление:

Пример онлайн (осторожно, откроется в этой же вкладке)

Задний план

Разумеется, фон — имеет значение. И reveal.js позволяет вам использовать в качестве фона: сплошной цвет, изображения (в том числе анимированные, например .gif), видеозаписи, и даже целые веб-сайты.

К сожалению, гифка этого примера получается совсем уж невменяемого размера, так что предлагаю просто посмотреть пример онлайн (осторожно, откроется в этой же вкладке).

Ну и помимо всего прочего, можно добавлять различные css-фишки и трюки. Например, красивые листочки в честь уже почти ушедшей осени:

Пример онлайн (осторожно, откроется в этой же вкладке)

Использование Markdown

Reveal.js позволяет описывать как контент одного слайда, так и контент всей презентации не HTML-тэгами, а обычным markdown, что бывает довольно полезно, если необходимо условный README.md превратить в презентацию.

<section data-markdown>
  ## Markdown
  ### Подзаголовок
  ``` [1-4]
  int main() {
  printf("Hello!");
  return 0;
  }
  ```
</section>

Пример онлайн (осторожно, откроется в этой же вкладке)

Это всего лишь веб-страница

Ну и напоследок особенность, которая всё это время скрывалась на виду. Формально, reveal.js-презентация это всего лишь HTML-страница, а это значит, что ваша презентация всегда готова к публикации в сети (например, Github pages) и её можно встроить куда угодно, используя обычный <iframe>

Немного критики

Никакого GUI

Крайне непривычно после PowerPoint’а размечать слайды на html, особенно, если есть желание переместить какой-либо объект на слайде “на глаз” (разумеется, есть GUI в виде slides.com, но бесплатная версия имеет свои ограничения). Однако, если вы любите bash/cmd/vim, то процесс создания слайдов вам определенно может понравиться. А уж если вы слышали про Emmet...

Как ни странно, проблемы с кодом

Поскольку такие символы как <, > и некоторые другие интерпретируются браузером как части тегов, могут возникать сложности с демонстрацией кода, где эти символы активно используются. Например, include’ы С++, метапрограммирование в C++, Rust и т.д.

<section data-auto-animate>
  <pre><code data-trim data-noescape data-line-numbers class="cpp">
		#include <vector>
  </code></pre>
</section>

Благо, вложив код в еще один тэг об этой проблеме можно забыть:

<section data-auto-animate>
	<pre><code data-trim data-noescape data-line-numbers class="cpp"><script type="text/template">
		#include <vector>
	</script></code></pre>
</section>

Произвольные анимации

PowerPoint имеет крайне широкий спектр возможностей по анимированию контента на слайдах: десятки вариантов появления и исчезновения, возможность от руки задавать сколь угодно сложный путь движения того или иного объекта на слайде и так далее. Однако, если попробовать сделать что-нибудь очень простое: превратить один текст в другой, зачеркнуть несколько слов и т.д., приходится создавать слайды-дубликаты, целую кучу анимированных графических объектов и т.д.  

В свою очередь, в reveal.js крайне сложно, например, создать движение объекта по произвольной траектории, но замена текста/зачёркивание и т.д. делаются буквально за 2 секунды. 

Иными словами, PowerPoint — это сложно, но с богатыми возможностями, а reveal.js — это просто и со вкусом, автоматически, но где-то без богатых возможностей. 

Заключение

Reveal.js имеет широкую возможность кастомизации: внушительное количество плагинов (весьма вероятно, что то, что вам необходимо уже реализовано в виде плагина) 

Reveal.js идеально подходит для демонстрации кода, а также для дальнейшей публикации слайдов в сети. Наличие возможности отображать markdown, а также html-формат в целом, позволяют генерировать контент слайдов автоматически. 

Взамен нет возможности использовать GUI (за исключением slides.com), а также добавление произвольного функционала (например, анимации) времязатратно. 

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

Ссылки

  1. Веб-сайт reveal.js

  2. Плагины для reveal.js

Комментарии (5)


  1. nin-jin
    24.11.2021 18:04
    +2

    Вот ещё в копилку подобных решений: https://habr.com/ru/post/465763/


    1. alex-ganyukhin Автор
      24.11.2021 18:50

      Спасибо, добавил в пост.


  1. thegriglat
    24.11.2021 22:43
    +1

    Не знаю, это наверное зависит от цели презентации и аудитории, по мне самый лучший вариант презентаций (делаю в основном научные) -- простой pdf, сверстанный в LaTeX. Например в overleaf.com или локально. Примеры темплейтов тут -- https://www.overleaf.com/gallery/tagged/presentation

    У LaTeX свои "недостатки" -- неудобно вставлять много текста, много картинок, нет анимации (а зачем они?), но после некоторых мучений понимаешь, что это лишь улучшает восприятие доклада. Зачем длинная "портянка" кода, если надо сконцентрироваться на 3-5 строчках? Зачем куча картинок, если по ним получится только быстро пробежаться? А если про все детально рассказывать, так может вынести просто в отдельный слайд?

    В общем, ограничения заставляют выкидывать лишнее.

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


    1. alex-ganyukhin Автор
      25.11.2021 00:20

      Я бы предположил, что это еще и дело вкуса. Мне гораздо проще воспринимать презентацию, когда речь спикера перекликается со слайдом, в том числе и анимациями появления/подсветки элементов на слайде.

      По поводу кода, соглашусь, всегда следует максимально упрощать код для слайда, желательно до тех самых 4-5 строчек, однако это не всегда возможно:

      • Например, если речь заходит про метапрограммирование в C++, то тут 5 строчками никак не обойтись

      • Может быть важен контекст, т.е. еще 5-6 срок помимо тех, на которых концентрируется внимание

      По поводу печати, я пробовал только сохранять в pdf (возможно это и имелось в виду), сохраняет вполне сносно, есть какая-никакая кастомизация: фрагменты можно сохранить или "все сразу видимые" или же "по одному на слайд".

      Ну а локальное сохранение(хранение) выглядит аналогично сохранённой локально веб-странице: .html-страница + папка со скриптами/изображениями/...

      P.S. Сам в LaTeX никогда не верстал, лишь запланировал попробовать такой подход.


  1. vovs
    25.11.2021 09:23

    Когда то давно у Google бала библиотека для создание презентаций. С программным кодом, как тут, она работать так не умела, но все равно. Возьму в закладки :-)