示例
HTML
<div id="text-wrapper">
<div id="text">Click and drag to rotate the camera. Scroll to zoom in/out.</div>
</div>
<div id="container"></div>
CSS
body {
background-color: #000;
margin: 0;
overflow: hidden;
padding: 0;
}
#text-wrapper {
position: fixed;
width: 100%;
}
#text {
border: 1px solid #555;
background-color: rgba(150, 150, 150, 0.2);
border-radius: 10px;
color: #ddd;
display: block;
font-size: 20px;
margin: 4px auto 0;
min-width: 320px;
padding: 10px;
position: relative;
text-align: center;
width: 50%;
z-index: 1000;
}
JS
const TEXTURE_PATH = 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/123879/';
var cubeCount = 1000;
var test = 0;
var camera,
scene,
renderer,
effect,
controls,
element,
container,
rotationPoint;
var cubes = [];
var textureFlare0;
var textureFlare2;
var textureFlare3;
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
scene = new THREE.Scene();
rotationPoint = new THREE.Object3D();
rotationPoint.position.set( 0, 0, 0 );
scene.add(rotationPoint);
camera = new THREE.PerspectiveCamera(
50,
window.innerWidth / window.innerHeight,
1,
23000
);
camera.position.z = -1000;
rotationPoint.add( camera );
renderer = new THREE.WebGLRenderer( { antialias: true, alpha: true } );
element = renderer.domElement;
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.shadowMap.enabled;
container.appendChild( element );
controls = new THREE.OrbitControls( camera, element );
controls.enablePan = true;
controls.enableZoom = true;
controls.maxDistance = 2000;
controls.minDistance = 500;
controls.target.copy( new THREE.Vector3( 0, 0, 0 ) );
function setOrientationControls(e) {
if (!e.alpha) {
return;
}
controls = new THREE.DeviceOrientationControls( camera );
controls.connect();
window.removeEventListener('deviceorientation', setOrientationControls, true);
}
window.addEventListener('deviceorientation', setOrientationControls, true);
var ambient = new THREE.AmbientLight( 0x555555);
scene.add( ambient );
addSkybox();
var counter = cubeCount;
while (counter > 0) {
buildObject();
counter--;
}
window.addEventListener('resize', onWindowResize, false);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function update() {
camera.updateProjectionMatrix();
}
function render() {
renderer.render(scene, camera);
var timer = 0.0001 * Date.now();
for (var i = 0; i < cubeCount; i++) {
var cube = cubes[i];
if (cube.in == true) {
var posX = Math.abs(cube.position.x);
var posY = Math.abs(cube.position.y);
var posZ = Math.abs(cube.position.z);
var distance = Math.sqrt((posY * posY) + Math.sqrt(posX * posX + posZ * posZ));
var multiplierX = 1;
var multiplierY = 1;
var multiplierZ = 1;
if (cube.position.x > 0) {
multiplierX = -1;
}
if (cube.position.y > 0) {
multiplierY = -1;
}
if (cube.position.z > 0) {
multiplierZ = -1;
}
cube.position.x = cube.position.x + ((posX/distance)) * multiplierX;
cube.position.y = cube.position.y + ((posY/distance)) * multiplierY;
cube.position.z = cube.position.z + ((posZ/distance)) * multiplierZ;
var red = 0;
var green = Math.floor(14000/distance);
var blue = Math.floor(20000/distance);
if (red > 255) {
red = 255;
}
if (green > 255) {
green = 255;
}
if (blue > 255) {
blue = 255;
}
var hex = rgbToHex(red, green, blue);
hex = parseInt(hex);
cube.material.color = new THREE.Color(hex);
cube.material.emissive = new THREE.Color(hex);
if (distance < 5) {
cube.in = false;
}
}
if (cube.in == false) {
var posX = Math.abs(cube.originalPositionX - cube.position.x);
var posY = Math.abs(cube.originalPositionY - cube.position.y);
var posZ = Math.abs(cube.originalPositionZ - cube.position.z);
var distance = Math.sqrt((posY * posY) + Math.sqrt(posX * posX + posZ * posZ));
var red = Math.floor(0.5 * distance);
var green = Math.floor(.05 * distance);
var blue = Math.floor(.05 * distance);
if (red > 255) {
red = 255;
}
if (green > 255) {
green = 255;
}
if (blue > 255) {
blue = 255;
}
var hex = rgbToHex(red, green, blue);
hex = parseInt(hex);
cube.material.color = new THREE.Color(hex);
cube.material.emissive = new THREE.Color(hex);
var multiplierX = 1;
var multiplierY = 1;
var multiplierZ = 1;
if (posX > cube.originalPositionX) {
multiplierX = -1;
}
if (posY > cube.originalPositionY) {
multiplierY = -1;
}
if (posZ > cube.originalPositionZ) {
multiplierZ = -1;
}
cube.position.x = cube.position.x + (posX/distance) * multiplierX;
cube.position.y = cube.position.y + (posY/distance) * multiplierY;
cube.position.z = cube.position.z + (posZ/distance) * multiplierZ;
if (Math.abs(cube.position.x - cube.originalPositionX) < 20 && Math.abs(cube.position.y - cube.originalPositionY) < 20 && Math.abs(cube.position.z - cube.originalPositionZ) < 20) {
cube.in = true;
}
}
}
rotationPoint.rotation.y -= 0.0005;
rotationPoint.rotation.x = Math.cos(timer);
}
function animate() {
requestAnimationFrame(animate);
update();
render();
}
function addSkybox() {
var urlPrefix = TEXTURE_PATH;
var urls = [
urlPrefix + 'test.jpg',
urlPrefix + 'test.jpg',
urlPrefix + 'test.jpg',
urlPrefix + 'test.jpg',
urlPrefix + 'test.jpg',
urlPrefix + 'test.jpg',
];
var loader = new THREE.CubeTextureLoader();
loader.setCrossOrigin( 'https://s.codepen.io' );
var textureCube = loader.load( urls );
textureCube.format = THREE.RGBFormat;
var shader = THREE.ShaderLib[ "cube" ];
shader.uniforms[ "tCube" ].value = textureCube;
var material = new THREE.ShaderMaterial( {
fragmentShader: shader.fragmentShader,
vertexShader: shader.vertexShader,
uniforms: shader.uniforms,
depthWrite: false,
side: THREE.BackSide
} );
var geometry = new THREE.BoxGeometry( 20000, 20000, 20000 );
var skybox = new THREE.Mesh( geometry, material );
scene.add( skybox );
}
function onDocumentMouseMove( event ) {
event.preventDefault();
}
function buildObject() {
var randNumX = Math.floor(Math.random() * (3 - 1) + 1);
var randNumY = Math.floor(Math.random() * (3 - 1) + 1);
var randNumZ = Math.floor(Math.random() * (3 - 1) + 1);
var multiplierX = 1;
if (randNumX == 1) {
multiplierX = -1;
} else if (randNumX == 2) {
multiplierX = 1;
}
var multiplierY = 1;
if (randNumY == 1) {
multiplierY = -1;
} else if (randNumY == 2) {
multiplierY = 1;
}
var multiplierZ = 1;
if (randNumZ == 1) {
multiplierZ = -1;
} else if (randNumZ == 2) {
multiplierZ = 1;
}
var geometry = new THREE.SphereGeometry(5, 8, 8);
var material = new THREE.MeshPhongMaterial( {color: 0xffffff, emissive: 0xffffff} );
var cube = new THREE.Mesh( geometry, material );
cube.position.x = Math.floor((Math.random() * 1000) + 250) * multiplierX;
cube.position.y = Math.floor((Math.random() * 1000) + 250) * multiplierY;
cube.position.z = Math.floor((Math.random() * 1000) + 250) * multiplierZ;
cube.originalPositionX = cube.position.x;
cube.originalPositionY = cube.position.y;
cube.originalPositionZ = cube.position.z;
cube.in = true;
cube.scale.x = cube.scale.y = cube.scale.z = Math.random() * 0.5 + 0.1;
scene.add( cube );
cubes.push( cube );
}
function rgbToHex(r, g, b) {
return "0x" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).toUpperCase().slice(1);
}