<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/commons/thumb/4/4f/Twitter-logo.svg/2880px-Twitter-logo.svg.png');
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;
}
}
View Compiled
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);
})
This Pen doesn't use any external CSS resources.