JSFiddle - React, Tailwind, and code Playground
by Michael Prosser
HTML
<script src="https://maps.googleapis.com/maps/api/js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="stage">
<div id="googleMap"></div>
<div id="googleMapBack"></div>
<div class="playership thrust">
<div class="rotator">
<div class="playerfront"></div>
<div class="playerfrontwing"></div>
<div class="playerback"></div>
<div class="playerbottom"></div>
<div class="playertop"></div>
<div class="playerleft"></div>
<div class="playerlefttop"></div>
<div class="playerleftbottom"></div>
<div class="playerright"></div>
<div class="playerrighttop"></div>
<div class="playerrightbottom"></div>
<div class="playergun1"></div>
<div class="playergun2"></div>
<div class="playerthrust1"></div>
<div class="playerthrust2"></div>
</div>
</div>
</div>
CSS
html,
body{
height: 100%;
width: 100%;
margin: 0px;
padding: 0px;
perspective:500px;
background-color:#000;
}
.stage{
position:fixed;
left:50%;
top:50%;
right:50%;
bottom:50%;
height:0px;
width:0px;
transform-style:preserve-3d;
transform:rotateX(-10deg);
}
#googleMap {
height: 1000px;
width: 1000px;
margin: 0px;
padding: 0px;
margin-top:1500px;
margin-left:-1000px;
transform:rotateX(90deg) translateZ(500px) scaleX(10) scaleY(10) scaleZ(10);
background-color:#000;
backface-visibility:hidden;
pointer-events:none;
position:absolute;
}
#googleMapBack {
height: 1000px;
width: 1000px;
margin: 0px;
padding: 0px;
margin-top:1500px;
margin-left:-1000px;
background-color:#ff0000;
backface-visibility:hidden;
pointer-events:none;
transform:rotateX(45deg) translateZ(-3000px) translateY(-3500px) scaleX(10) scaleY(10) scaleZ(10);
position:absolute;
}
.playership{
width:0px;
height:0px;
left:50%;
top:50%;
transform-style:preserve-3d;
position:absolute;
transform-origin:50% 50% !important;
}
.playership>.rotator{
width:0px;
height:0px;
left:50%;
top:50%;
transform-style:preserve-3d;
position:absolute;
transform-origin:50% 50% !important;
transform:rotateY(180deg);
}
.playership.killed>.rotator{
animation:spin infinite 3s ease-in;
}
@keyframes rotate {
0% { transform:rotateY(0deg) rotateX(-30deg); }
100% { transform:rotateY(360deg) rotateX(-30deg); }
}
@keyframes spin {
0% { transform:rotateY(180deg) rotateX(0deg) rotateZ(0deg); }
100% { transform:rotateY(180deg) rotateX(-40deg) rotateZ(1840deg); }
}
.playership>.rotator div{
filter: hue-rotate(90deg) opacity(1);
}
.playership .playerfront{
width:200px;
height:60px;
position:absolute;
margin-left:-100px;
margin-top:-40px;
transform:translateZ(35px);
background-image:url(http://aninoob.com/particles/assets/player/player-front.png?1);
background-size:cover;
}
.playership .playerback{
width:200px;
height:40px;
...
JavaScript
var terrain = {
mapid: 'googleMap',
map: null,
mapid2: 'googleMapBack',
map2: null,
latitude: 49.2404653,
longitude: -123.1050752,
zoom: 17,
inc: .00001,
tilt: 0,
key_left_down: false,
key_up_down: false,
key_right_down: false,
key_down_down: false,
x: 0,
y: 0,
z: 0,
rx: 0,
ry: 0,
rz: 0,
speed: .1,
pixel_ratio: .0002,
init: function(){
var mapProp = {
center: new google.maps.LatLng(this.latitude+(this.x*this.pixel_ratio), this.longitude+(this.z*this.pixel_ratio)),
zoom: this.zoom,
keyboardShortcuts: false,
mapTypeId: google.maps.MapTypeId.SATELLITE
};
this.map = new google.maps.Map(document.getElementById(this.mapid), mapProp);
this.map.setTilt(this.tilt);
this.map2 = new google.maps.Map(document.getElementById(this.mapid2), mapProp);
this.map2.setTilt(this.tilt);
// setup keyhandlers
$(document).keydown(function(event){
switch(event.keyCode){
case 37: // left arrow
terrain.key_left_down = true;
break;
case 38: // up arrow
terrain.key_up_down = true;
break;
case 39: // right arrow
terrain.key_right_down = true;
break;
case 40: // down arrow
terrain.key_down_down = true;
break;
}
}).keyup(function(event){
switch(event.keyCode){
case 37: // left arrow
terrain.key_left_down = false
break;
case 38: // up arrow
terrain.key_up_down = false;
break;
case 39: // right arrow
terrain.key_right_down = false;
break;
case 40: // down arrow
terrain.key_down_down = false;
break;
}
});
requestAnimationFrame(terrain.render);
},
normalizeAngle: function(angle){
var newAngle = angle;
while...