Course Player Renderer

Testing the renderer and the css transitions.

by petersendidit

HTML

<div id="slides">
</div>

CSS

#slides {
  width: 502px;
  height: 502px;
  overflow: hidden;
  display: block;
  position: relative;
}
.slide {
  width: 500px;
  height: 500px;
  border: 1px solid black;
  background: #FFF;
  position: absolute;
  color: red;
}
.slide > div {
   width: 500px;
  height: 500px;
}
.crossfade .slide {
  transition: opacity 1s ease-in-out;
}
.crossfade .current {
  z-index: 1;
  background: #FFF;
  opacity: 1;
}
.crossfade .next {
  z-index: 0;
  opacity: 0;
}
.crossfade .previous {
  z-index: 0;
  opacity: 0;
}

.slideleft .slide {
  transition: transform 1s ease-in-out;
}
.slideleft .next {
  transform: translate3d(500px, 0, 0);
}
.slideleft .current {
  transform: translate3d(0, 0, 0);
}
.slideleft .previous {
  transform: translate3d(-500px, 0, 0);
}

.throughBlack .current {
  z-index: 1;
  background: #FFF;
  transition: background 1s ease-in-out 1s,
    opacity 1ms ease-in-out 1s;
}
.throughBlack .next {
  z-index: 0;
  background: black;
  opacity: 0;
  transition: background 1s ease-in-out 1s,
    opacity 1ms ease-in-out 1s;
}
.throughBlack .previous {
  z-index: 0;
  background: black;
  opacity: 0;
  transition: background 1s ease-in-out,
    opacity 1ms ease-in-out 1s;
}

Babel + JSX

function transitionCompleted(event) {
  event.target.removeEventListener('transitionend', transitionCompleted);
}

function removeElement(event) {
  event.target.parentNode.removeChild(event.target);
}

const TRANSITION_TYPES = [
  'crossfade',
  'throughBlack',
  'slideleft'
];

class Renderer {
  /**
   * @param {object} container - DOM Element to use to render templates in to
   */
  constructor(container) {
    this.container = container;
  }

  // should take the current slide, which is already rendered, and render
  // the next slide. It then should transition to the next slide and destroy
  // the current slide when completed.
  transition(nextSlide, transitionType) {
    if (!TRANSITION_TYPES.includes(transitionType)) {
      throw new Error(`Transition type ${transitionType} is not valid`);
    }
    return new Promise((resolve, reject) => {
      // Add the transition type as a class on the container so the css transitions will work
      this.container.className = transitionType;

      const currentSlideWrapper = document.querySelectorAll('.current');

      // Create a container for the next slide
      const nextSlideWrapper = document.createElement('div');
      nextSlideWrapper.className = 'slide next';
      nextSlideWrapper.appendChild(nextSlide.render());

      //nextSlideWrapper.addEventListener('transitionend', transitionCompleted, false);
      this.container.appendChild(nextSlideWrapper);

      // Timeout needed so that the element gets added to the DOM and gets painted
      // before we remove the class so that the browser the class change up.
      setTimeout(() => {
        if (currentSlideWrapper.length) {
          const wrapper = currentSlideWrapper[0];
          wrapper.addEventListener('transitionend', removeElement, false);
          wrapper.className = 'slide previous';
        }
        nextSlideWrapper.className = 'slide current';
        resolve(nextSlide);
      }, 0);
    });
  }
}

const container =...