<html>
  <head>
    <meta name="viewport" content="width=device-width">
  </head>
  <body>

    <div class="container">
      <div class="controls">
        <label>
          Show Layers
          <input id="showLayers" type="checkbox" checked="checked" />
        </label>
        <br />
        <label>
          Show Grid
          <input id="showGrid" type="checkbox" checked="checked" />
        </label>
        <br />
        <br />
        <button id="next">Next Step</button>
        <button id="restart">Restart</button>
      </div>

      <div class="frame">
        <div class="layer background"></div>
        <div class="layer white-layer grid">
          <div class="white mask mask-layer"></div>
        </div>
        <div class="layer grid js-app-layer">
          <div class="mask mask-layer">
            <div class="app">
            </div>
          </div>
        </div>
       </div>
      <!-- <pre id="options"></pre> -->
    </div>
  </body>
</html>
.container {
  margin: auto;
  text-align: center;
}

.frame {
  width: 374px;
  height: 666px;
  margin: 50px auto;
  transform-style: preserve-3d;
  padding: 10px;
  perspective: 500px;
  transition: perspective-origin 1s;
}

.layer {
  position: absolute;
  height: 100%;
  width: 100%;
  opacity: 1;
  border: 1px solid black;
  transition: transform 1s;
}

.mask-layer {
  position: absolute;
  height: 100%;
  width: 100%;
  opacity: 1;
  border: 1px solid black;
}

.background {
   background-color: #1ea1f2;
   transition: opacity 1s;
}

.white {
  background-color: white;
}

.white-layer {
  transition: opacity 1s;
}

.app {
  background-image: url('https://letsbuildthatapp-videos.s3-us-west-2.amazonaws.com/2536fbe2-773e-4a67-832d-4d89e22846b3');
  position: absolute;
  height: 100%;
  width: 100%;
  background-size: cover;
  opacity: 0;
  transform: scale(1.2);
  transition: all 1s;
}

.mask {
  mask-image: url('https://upload.wikimedia.org/wikipedia/en/9/9f/Twitter_bird_logo_2012.svg');
  mask-repeat: no-repeat;
  mask-position: 50%;
  overflow: hidden;
  transition: -webkit-mask-size 1s;
}

.grid {
  background-image: linear-gradient(0deg, transparent 24%, rgba(0, 0, 0, .2) 25%, rgba(0, 0, 0, .2) 26%, transparent 27%, transparent 74%, rgba(0, 0, 0, .2) 75%, rgba(0, 0, 0, .2) 76%, transparent 77%, transparent), linear-gradient(90deg, transparent 24%, rgba(0, 0, 0, .2) 25%, rgba(0, 0, 0, .2) 26%, transparent 27%, transparent 74%, rgba(0, 0, 0, .2) 75%, rgba(0, 0, 0, .2) 76%, transparent 77%, transparent);
  height:100%;
  background-size:50px 50px;
}

.controls {
  padding: 20px;
  margin: 20px;
  display: inline-block;
  text-align: left;
  float: left;
}

@media only screen and (min-device-width : 320px) and (max-device-width : 480px) {
  .frame {
    width: 94px;
    height: 167px;
    margin-top: 0;
  }
  
  .controls { 
    float: none;
  }
}
const disableMask = false;
const showApp = false;
const doNotScaleApp = true;
const showBackground = true;

let shouldShowLayers = true;
let shouldShowGrid = true;

const keyFrames = [{
  disableMask: true,
  showApp: true,
  doNotScaleApp: true,
  showBackground: false,
  showWhite: false,
}, {
  disableMask: true,
  showApp: true,
  doNotScaleApp: true,
  showBackground: false,
  showWhite: true,
}, {
  disableMask: true,
  showApp: true,
  doNotScaleApp: true,
  showBackground: true,
  showWhite: true,
}, {
  disableMask: true,
  showApp: false,
  doNotScaleApp: true,
  showBackground: true,
  showWhite: true,
}, {
  disableMask: false,
  showApp: false,
  doNotScaleApp: true,
  showBackground: true,
  showWhite: true,
}, {
  disableMask: false,
  showApp: true,
  doNotScaleApp: true,
  showBackground: true,
  showWhite: true,
}, {
  disableMask: true,
  showApp: true,
  doNotScaleApp: true,
  showBackground: true,
  showWhite: true,
}, {
  disableMask: true,
  showApp: true,
  doNotScaleApp: false,
  showBackground: true,
  showWhite: true,
}, {
  disableMask: true,
  showApp: true,
  doNotScaleApp: false,
  showBackground: false,
  showWhite: false,
}];

let frameCounter = 0;

showLayers(shouldShowLayers);
showGrid(shouldShowGrid);

function run() {
  // frameCounter++;
  /*const args = {
    disableMask,
    showApp,
    doNotScaleApp,
    showBackground
  }
  */
   const args = keyFrames[frameCounter % keyFrames.length];
  // document.getElementById('options').textContent = JSON.stringify(args, null, 2);
  update(args); 
}

run();
// setInterval(run, 1000);


function update(args) {
  const {disableMask, showApp, doNotScaleApp, showBackground, showWhite} = args;
  document.querySelector('.background').style.opacity = showBackground ? 1 : 0;
  document.querySelector('.white-layer').style.opacity = showWhite ? 1 : 0;
  
  Array.from(document.querySelectorAll('.mask')).forEach(
    mask => {
      mask.style.webkitMaskSize = disableMask ? '2500px 2500px' : '50px 50px';
    }
  );
  
  document.querySelector('.app').style.opacity = showApp ? 1 : 0;
  const appScale = doNotScaleApp ? 1.2 : 1;
  document.querySelector('.app').style.transform = `scale(${appScale})`;
}

function showLayers(show) {
  Array.from(document.querySelectorAll('.layer')).forEach((item, index) => {
    const translate = show ? 1 * index : 0;
    const rotate = show ? -5 : 0;
    item.style.transform = `translateZ(${translate}em) rotateY(${rotate}deg)`;
  });
  
  document.querySelector('.frame').style.perspectiveOrigin = show ? '500% 50%' : '50% 50%';
}

function showGrid(show) {
  [
    document.querySelector('.white-layer'),
    document.querySelector('.js-app-layer'),
  ].forEach(item => { 
    if (show) {
      item.classList.add('grid');
    } else {
      item.classList.remove('grid');
    }
  })
}

document.getElementById('next').addEventListener('click', () => {
  frameCounter++;
  run();
});

document.getElementById('restart').addEventListener('click', () => {
  frameCounter = 0;
  run();
});

document.getElementById('showLayers').addEventListener('change', (e) => {
  shouldShowLayers = e.target.checked;
  showLayers(shouldShowLayers);
})

document.getElementById('showGrid').addEventListener('change', (e) => {
  shouldShowGrid = e.target.checked;
  showGrid(shouldShowGrid);
})

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. //cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js