Skip to content

presentation engine running in electron, featuring live js coding, terminal support, remote mobile clients

License

Notifications You must be signed in to change notification settings

wouterverweirder/presentation-engine

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

58 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

#Presentation Engine

Interactive presentation built with electron & nodejs.

building

npm run develop

running

Presentation:

npm run presentation

Server (optional):

npm run server

People can surf to http://REPLACE_WITH_YOUR_IP:5000 and follow the slides on their screen.

slides

The content of the dist/presentation/slides folder will be used for the slides, configuration happens via the file names.

  • Content is read alphabetically (images, videos or html files)
  • Use .desktop or .mobile in the filename, to host a different version of a slide for desktop or mobile:
    • slide.jpg and slide.mobile.jpg (slide.jpg will be shown on desktop, mobile version is the .mobile.jpg)
    • slide.jpg and slide.desktop.jpg (slide.jpg will be shown on mobile, slide.desktop.jpg on desktop)
  • Wrap html slides in a template tag:
<template>
  <article class="slide">
<script type="text/template">
(function($slideHolder){

  function init() {
    //$slideHolder contains the wrapping div for this slide
    $slideHolder.trigger('load'); //this lets the presentation know the slide has loaded
  }

  init();

})(document.$slideHolder);
</script><img onLoad="var s = document.createElement('script'); s.innerHTML = this.previousSibling.innerHTML; document.$slideHolder = $(this).closest('.slide-frame'); this.parentNode.appendChild(s);" style="display: none;" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="/>
  </article>
</template>
  • Image slides can have the following options in the filename:
    • image.jpg (show entire image, letterboxed by default)
    • image.cover.jpg (fill the entire slide)
  • Video slides can have a couple of options in the filename:
    • video.mp4
    • video.loop.mp4
    • video.muted.mp4

live code

You can add slides with support for live coding & running html/js, nodejs and embedding terminal windows.

Example:

<template>
  <article class="slide">
    <div class="slide-content">
      <div class="live-code" data-entry-path="demos/kinect-skeleton-websockets" data-output-path="tmp/kinect-skeleton-websockets">
        <ul class="nav nav-tabs" role="tablist">
          <li class="nav-item"><a class="nav-link" href="#" aria-controls="nodejs" role="tab">nodejs</a></li>
          <li class="nav-item"><a class="nav-link" href="#" aria-controls="html-code" role="tab">html code</a></li>
          <li class="nav-item"><a class="nav-link" href="#" aria-controls="html-output" role="tab">html output</a></li>
        </ul>
        <div class="tab-content" style="height: 66rem; overflow: auto;">
          <div role="tabpanel" class="tab-pane" data-tab-id="nodejs" style="position: relative;">
            <div class="split-pane fixed-bottom">
              <div class="split-pane-component top-pane" style="bottom: 3em; margin-bottom: 5px; min-height: 5em;">
                <textarea data-type="code" data-mode="javascript" data-language="javascript" data-file="server.js"></textarea>
                <div class="btn-group" role="group" style="position: absolute; top: 1em; right: 1em; z-index: 10;">
                  <button type="button" data-target="server.js" data-type="reload-button" class="btn btn-secondary"><i class="fa fa-4x fa-refresh"></i></button>
                  <button type="button" data-target="server.js" data-type="save-button" class="btn btn-secondary"><i class="fa fa-4x fa-save"></i></button>
                  <button type="button" data-target="node-console" data-type="run-button" class="btn btn-secondary"><i class="fa fa-4x fa-play"></i></button>
                </div>
              </div>
              <div class="split-pane-divider divider" style="background: #aaa; bottom: 3em; height: 5px;"></div>
              <div class="split-pane-component bottom-pane" style="height: 3em; min-height: 3em;">
                <div data-id="node-console" style="height: 100%" data-type="console" data-file="server.js"></div>
              </div>
            </div>
          </div>
          <div role="tabpanel" class="tab-pane" data-tab-id="html-code" style="position: relative;">
            <textarea data-type="code" data-mode="htmlmixed" data-language="html" data-file="index.html"></textarea>
            <div class="btn-group" role="group" style="position: absolute; top: 1em; right: 1em; z-index: 10;">
              <button type="button" data-target="index.html" data-type="reload-button" class="btn btn-secondary"><i class="fa fa-4x fa-refresh"></i></button>
              <button type="button" data-target="index.html" data-type="save-button" class="btn btn-secondary"><i class="fa fa-4x fa-save"></i></button>
              <button type="button" data-target="web-preview" data-type="run-button" class="btn btn-secondary"><i class="fa fa-4x fa-play"></i></button>
            </div>
          </div>
          <div role="tabpanel" class="tab-pane" data-tab-id="html-output" style="position: relative;">
            <div class="split-pane fixed-bottom">
              <div class="split-pane-component top-pane" style="bottom: 3em; margin-bottom: 5px; min-height: 5em;">
                <div data-id="web-preview" data-type="web-preview" data-console="web-preview-console" data-file="index.html"></div>
              </div>
              <div class="split-pane-divider divider" style="background: #aaa; bottom: 3em; height: 5px;"></div>
              <div class="split-pane-component bottom-pane" style="height: 3em; min-height: 3em;">
                <div data-id="web-preview-console" style="height: 100%" data-type="console"></div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
<script type="text/template">
(function($slideHolder){

  var LiveCodeSlide = require('LiveCodeSlide').default;

  function init() {
    var liveCode = new LiveCodeSlide($slideHolder);

    //manual manage tabs, as we don't want to work with element ids
    $slideHolder.find('a[role=tab]').click(function (e) {
      e.preventDefault();
      var tabId = $(e.target).attr('aria-controls');
      var $tab = $slideHolder.find('[data-tab-id="' + tabId + '"]');
      $slideHolder.find(".nav-tabs .active, .tab-content .active").removeClass("active");
      $(e.target).addClass('active');
      $tab.addClass("active");
      liveCode.layout();
    });

    $slideHolder.find('div.split-pane').splitPane();
    $slideHolder.find('div.split-pane').on('resize', function(){
      liveCode.layout();
    });

    //focus webpreview tab on run click
    $slideHolder.find('[data-tab-id="html-code"] [data-type="run-button"]').on('click', function(){
      $slideHolder.find('a[role=tab][aria-controls="html-output"]').click();
    });

    requestAnimationFrame(function(){
      $slideHolder.find('a[role=tab]').first().click();
    });
  }

  init();

})(document.$slideHolder);
</script><img onLoad="var s = document.createElement('script'); s.innerHTML = this.previousSibling.innerHTML; document.$slideHolder = $(this).closest('.slide-frame'); this.parentNode.appendChild(s);" style="display: none;" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="/>
  </article>
</template>

About

presentation engine running in electron, featuring live js coding, terminal support, remote mobile clients

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published