<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>熊猫宇航员和3D炫彩星云</title>
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
#viewport {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
overflow: hidden;
background: #000000;
background: -moz-linear-gradient(top, #000000 0%, #261423 100%);
background: -webkit-linear-gradient(top, #000000 0%, #261423 100%);
background: linear-gradient(to bottom, #000000 0%, #261423 100%);
filter: progid: DXImageTransform.Microsoft.gradient( startColorstr='#000000', endColorstr='#261423', GradientType=0);
}
#world {
position: absolute;
left: 50%;
top: 50%;
margin-left: -256px;
margin-top: -256px;
height: 512px;
width: 512px;
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
-o-transform-style: preserve-3d;
}
#world div {
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
-o-transform-style: preserve-3d;
}
.cloudBase {
height: 20px;
left: 256px;
margin-left: -10px;
margin-top: -10px;
position: absolute;
top: 256px;
width: 20px;
}
.cloudLayer {
position: absolute;
left: 50%;
top: 50%;
width: 256px;
height: 256px;
margin-left: -128px;
margin-top: -128px;
-webkit-transition: opacity .5s ease-out;
-moz-transition: opacity .5s ease-out;
-o-transition: opacity .5s ease-out;
}
</style>
</head>
<body>
<div id="viewport">
<div id="world">
</div>
</div>
<script>
const world = document.getElementById('world');
const viewport = document.getElementById('viewport');
const d = 0;
const p = 400;
let worldYAngle = 0
let worldXAngle = 0;
let objects = [];
let layers = [];
viewport.style.webkitPerspective = p;
viewport.style.MozPerspective = p;
viewport.style.oPerspective = p;
window.addEventListener('mousemove', onMouseMove);
window.addEventListener('touchmove', onMouseMove);
function onMouseMove(e) {
e.preventDefault();
let x = e.clientX || e.touches[0].clientX;
let y = e.clientY || e.touches[0].clientY;
worldYAngle = -(0.5 - (x / window.innerWidth)) * 180;
worldXAngle = (0.5 - (y / window.innerHeight)) * 180;
updateView();
}
function updateView() {
let t = `translateZ(${d}px ) rotateX(${worldXAngle}deg) rotateY(${worldYAngle}deg)`;
world.style.transform = t;
world.style.webkitTransform = t;
world.style.MozTransform = t;
world.style.oTransform = t;
}
function generate() {
//removes previous clouds
objects = [];
layers = [];
if (world.hasChildNodes()) {
while (world.childNodes.length >= 1) {
world.removeChild(world.firstChild);
}
}
//adds new clouds
for (let j = 0; j < 5; j++) {
objects.push(createCloud());
}
}
function randomizer(range) {
let randomX = Math.floor(Math.random() * range) + 1;
randomX *= Math.floor(Math.random() * 2) == 1 ? 1 : -1;
return randomX;
}
function createCloud() {
const random_x = randomizer(256);
const random_y = randomizer(256);
const random_z = randomizer(256);
const div = document.createElement('div');
div.className = 'cloudBase';
let transform = `translateX(${random_x}px) translateY(${random_y}px) translateZ(${random_z}px)`;
div.style.transform = transform;
div.style.webkitTransform = transform;
div.style.MozTransform = transform;
div.style.oTransform = transform;
world.appendChild(div);
for (let j = 0; j < 5 + Math.round(Math.random() * 10); j++) {
const cloud = document.createElement('img');
cloud.style.opacity = 0.8;
let x = Math.floor((Math.random() * 3) + 1);
if (x === 1) {
cloud.setAttribute('src', 'img/cloud.png');
} else if (x === 2) {
cloud.setAttribute('src', 'img/cloud2.png');
} else {
cloud.setAttribute('src', 'img/cloud3.png');
}
cloud.className = 'cloudLayer';
cloud.data = {
x: randomizer(random_x),
y: randomizer(random_y),
z: randomizer(100),
a: Math.round(Math.random() * 360),
s: 0.25 + Math.random(),
speed: 0.1 * Math.random()
};
let cloudT = `translateX( ${cloud.data.x}px ) translateY(${cloud.data.y}px ) translateZ(${cloud.data.z}px ) rotateZ(${cloud.data.a}deg ) scale(${cloud.data.s} )`;
cloud.style.transform = cloudT;
cloud.style.webkitTransform = cloudT;
cloud.style.MozTransform = cloudT;
cloud.style.oTransform = cloudT;
div.appendChild(cloud);
layers.push(cloud);
}
return div;
}
function update() {
layers.forEach(layer => {
layer.data.a += layer.data.speed;
let t = `translateX(${layer.data.x}px) translateY(${layer.data.y}px) translateZ(${layer.data.z}px) rotateY( ${( - worldYAngle )}deg) rotateX(${( - worldXAngle )}deg) rotateZ( ${layer.data.a}deg) scale(${layer.data.s})`;
layer.style.webkitTransform = t;
layer.style.MozTransform = t;
layer.style.oTransform = t;
});
requestAnimationFrame(update);
}
function addPanda() {
let randomCloud = layers[Math.floor(Math.random() * layers.length)];
randomCloud.setAttribute('src', 'img/panda.png');
randomCloud.style.opacity = 1;
}
generate();
addPanda();
update();
</script>
</body>
</html>