JSFiddle - React, Tailwind, and code Playground
by neonDog
HTML
<!--The Main Thing-->
<div class="neon-3d-rotation-wrapper">
<div class="phone-parent" data-view="front">
<div class="phone-rotate-z">
<div class="phone" style="width: 360px; height: 640px;">
<div class="phone-body">
<iframe src="https://howdoweb.com/" id="frame_1"></iframe>
</div>
<div class="phone-shadow"></div>
</div>
<div class="phone-table-background"></div>
</div>
</div>
</div>
<!--Controls etc.-->
<div id="controls">
<!--Idea by /u/aerosole-->
<div>
<label for="iframePerspective">Add perspective:</label>
<input type="checkbox" id="iframePerspective" checked="true">
</div>
<div>
<label for="freerotate">Free rotate:</label>
<input type="checkbox" id="treerotate" checked="true">
</div>
</div>
<div id="phone-controls">
<div id="views">
<button value="table">Table View</button>
<button value="front">Front View</button>
</div>
<div id="phones">
<button value="iphone6">iPhone 6</button>
<button value="samsung">Samsung Galaxy Note</button>
<button value="microsoft">Microsoft Lumia 1020</button>
<button value="htc">HTC One</button>
<button value="ipadMini">iPad Mini</button>
<button value="desktop">Desktop</button>
</div>
</div>
SCSS
@import url(https://fonts.googleapis.com/css?family=Open+Sans:400,600,300);
html{
height:100%;
}
* {
box-sizing: border-box;
}
body {
font-family: 'Open Sans', sans-serif;
height:100%;
color:#fff;
background: #1b1b1b!important;
}
.pointer-events-none {
pointer-events: none;
}
.neon-3d-rotation-wrapper {
overflow: hidden;
background: #112;
height: 100%;
perspective: 1300px;
}
/*Basic Phone styling*/
.phone-parent {
transform-style: preserve-3d;
cursor: move;
transition: all 0.5s ease;
width: 100%;
height: 100%;
&.dragging {
transition: none;
}
}
.phone-rotate-z {
width: 100%;
height: 100%;
transform-style: preserve-3d;
display: flex;
align-items: center;
justify-content: center;
}
.phone-table-background {
position: absolute;
transform-style: preserve-3d;
width: 500%;
height: 500%;
background: url('https://cutewallpaper.org/21/tumblr-background-black-and-white/150-Luxury-Black-Grid-for-You-Cameeron-Web.jpg');
//background: url('https://i.pinimg.com/originals/6b/2b/4f/6b2b4f2aadd70ed2f11771203d13f5e1.jpg');
//background: url('https://image.freepik.com/free-photo/close-up-rustic-dark-wood-table-surface-with-grunge-texture-vintage-style_54178-393.jpg');
transform: translate3d(0, 0, -13px);
}
.phone {
transform-style: preserve-3d;
position: relative;
border-radius: 40px;
transition: all 0.5s ease;
animation: fadein 2s;
z-index: 2;
}
.phone-shadow {
position: absolute;
background: #121212;
width: 100%;
height: 100%;
border-radius: 40px;
}
.phone-body {
position: absolute;
z-index: 2;
width: 100%;
height: 100%;
overflow: hidden;
border-radius: 40px;
...
JavaScript
class NeonMobileSimulator {
constructor(el, settings={}) {
const defaults = {
deviceDefaults: {
width: '100vw',
height: '100vh',
scale: 1
},
devices: {
iphone6: {
width: 375,
height: 667,
},
samsung: {
width: 400,
height: 640,
},
microsoft: {
width: 320,
height: 480
},
htc: {
width: 360,
height: 640,
},
ipadMini: {
width: 768,
height: 1024,
scale: 0.5
},
desktop: {
}
}
};
this.options = Object.assign({}, defaults, settings);
this.wrapper = el.getElementsByClassName('neon-3d-rotation-wrapper')[0];
this.phoneParent = this.wrapper.firstElementChild;
this.phoneRotateZ = this.phoneParent.firstElementChild;
this.phone = this.phoneRotateZ.firstElementChild;
this.iframe = this.phone.firstElementChild.firstElementChild;
this.iframe.onload = () => {
this.afterLoading();
};
this.initRotatable();
}
afterLoading() {
setTimeout(() => {
this.setView('table');
setTimeout(() => {
//Start rotating the phone
//this.phoneRotateZ.classList.add('rotate');
}, 1000);
}, 1000);
}
setView(view) {
if (!view) return;
//Clear transforms
this.phoneParent.style.transform = '';
this.phoneRotateZ.style.transform = '';
//Set view
this.phoneParent.setAttribute('data-view', view);
}
setPerspective(perspective='1300px') {
this.wrapper.style.perspective = perspective;
}
setDevice(name) {
if (!this.options.devices[name]) return;
const device = Object.assign({}, this.options.deviceDefaults, this.options.devices[name]);
this.phone.style.width = typeof device.width === 'number' ? device.width + 'px' : device.width;
this.phone.style.height = typeof...