更多有趣示例 尽在 小红砖社区
示例
HTML
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/61062/map.png" crossorigin="anonymous" id="map">
CSS
*{
margin:0;
box-sizing:border-box;
}
body{
background:linear-gradient(#00ADFF 0%,#eee 100%);
}
img{
display:none;
}
JS
//____ FIRE
init();
//_______________
function init(){
var models = {};
var plantRadius = 20;
var canvas_height = window.innerHeight;
var canvas_width = window.innerWidth;
//Workaround for Texture
//Codepen doesn't allow cross-origin
//so we have to load it in the html
//and get by the id
// texture = new THREE.Texture(map);
var img_tex = document.getElementById('map');
//__________________________________________ Helper Functions
function randNum(min,max,bool){
// this will get a number between min and max;
var num = Math.floor(Math.random()*max) + min;
if(bool || typeof bool == "undefined"){
num *= Math.floor(Math.random()*2) == 1 ? 1 : -1;
}
return num;
}
// Check of point is in radius
function pointInCircle(point,target, radius) {
var distsq = (point.x - target.x) * (point.x - target.x) + (point.y - target.y) * (point.y - target.y) + (point.z - target.z) * (point.z - target.z);
// returns bool , distance to target origin
return [distsq <= radius * radius * radius,distsq];
}
// Get Random Point in Circle
function calculatePointInCircle(r) {
x = Math.random() * 2 * r - r;
zlim = Math.sqrt(r * r - x * x);
z = Math.random() * 2 * zlim - zlim;
return [x,z];
}
//__________________________________________ Renderer Setup
var renderer = new THREE.WebGLRenderer({
alpha: true,
transparent : true,
antialias:true
});
renderer.setSize( canvas_width, canvas_height );
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
document.body.appendChild( renderer.domElement );
//_____________________ Create Scene
var scene = new THREE.Scene();
//______________________ Camera
var camera = new THREE.PerspectiveCamera( 55, canvas_width/canvas_height, 0.1, 1000 );
camera.position.set(-10,2,22);
camera.lookAt(new THREE.Vector3(0,50,0));
scene.add(camera);
//______________________ Camera Helper for rotation
var helperGeo = new THREE.BoxGeometry(1,1,1);
var cam_helper = new THREE.Mesh(helperGeo);
cam_helper.visible = false;
scene.add(cam_helper);
cam_helper.add(camera);
//____________________ Resizer
window.onresize = function(){
canvas_height = window.innerHeight;
canvas_width = window.innerWidth;
camera.aspect = canvas_width / canvas_height;
camera.updateProjectionMatrix();
renderer.setSize( canvas_width, canvas_height );
}
//____________________ Controls
controls = new THREE.OrbitControls( camera );
controls.damping = 0.2;
controls.minPolarAngle = 73 * Math.PI/180;
controls.maxPolarAngle = 85 * Math.PI/180;
controls.minDistance = 15;
controls.maxDistance = 25;
//______________________ Lights
//____ Ambient
var ambient = new THREE.AmbientLight(0xaaaaaa,1);
scene.add(ambient);
//____ spot
var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set( 0, 500, 100 );
spotLight.intensity = 2;
scene.add(spotLight);
//____________________ Load Models
var loader = new THREE.JSONLoader();
var texture_loader = new THREE.TextureLoader();
var base_url = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/61062/";
// Different Plant Models
var plants = [
'plant_1',
'plant_2',
'plant_3',
'plant_4',
'plant_5',
'plant_6',
'plant_7',
'plant_8',
'gras',
'dandelion',
'flower_1',
'flower_2'
]
//_________ Create Plants if image texture is complete
img_tex.onload = function(){
createPlants(new THREE.Texture(this));
}
// Plant Creator
// Setup texture
// and load Models
function createPlants(tex){
//reduce flickering
tex.minFilter = tex.magFilter = THREE.LinearMipMapNearestFilter;
tex.needsUpdate = true;
var material = new THREE.MeshPhongMaterial({
color : new THREE.Color(0xffffff),
side : THREE.DoubleSide,
shininess :0,
map :tex,
bumpMap : tex,
bumpScale : -.05,
transparent : true,
depthTest : true,
depthWrite : true,
alphaTest : .25,
});
//load individual plant
function loadPlant(id,name,url){
var ID = id;
var name = name;
loader.load(url,function(geometry){
var plant = new THREE.Mesh(geometry,material);
models[name] = plant;
models[name].id = ID;
creator(name);
});
}
//load each Plant in Array plants
plants.forEach(function(p,index){
loadPlant(index,p,base_url+p+'.json');
});
}
// Setup the count for each plant
// default is 5
function creator(name){
switch(name){
case 'gras':
createRandomObject(700,name,plantRadius);
break;
case 'flower_1':
createRandomObject(200,name,plantRadius);
break;
case 'flower_2':
createRandomObject(200,name,plantRadius);
break;
default:
createRandomObject(5,name,plantRadius);
break;
}
}
// Create Bunch of plant objects and add it to a group
function createRandomObject(count,name,r){
var group = new THREE.Object3D();
for(var g=0;g<count;g++){
var p = calculatePointInCircle(r);
group.children[g] = models[name].clone();
group.children[g].position.x = p[0];
group.children[g].position.z = p[1];
group.children[g].rotation.y = randNum(0,360,true) * Math.PI / 180;
var scaler = randNum(.92,1,false);
group.children[g].scale.set(scaler,scaler,scaler);
}
scene.add(group);
return group;
}
// Ground + surrounding
var planeMat = new THREE.MeshPhongMaterial({
color : 0x455029,
specular : 0x000000,
shininess : 0,
side : THREE.DoubleSide,
});
var radius = 22;
var segments = 32;
var circleGeometry = new THREE.RingGeometry(0, radius, segments, segments, 0, Math.PI * 2);
// Ground
var ground = new THREE.Mesh(circleGeometry,planeMat);
ground.rotation.x = 90 * Math.PI / 180;
scene.add(ground);
var boundMat = new THREE.MeshPhongMaterial({
color : 0x111111,
specular : 0x000000,
shininess : 0,
side : THREE.DoubleSide,
shading : THREE.FlatShading
});
var boundGeometry = new THREE.TorusGeometry( 21.5, 1, 6, 180);
var bound = new THREE.Mesh( boundGeometry, boundMat );
bound.rotation.x = 90 * Math.PI/180;
scene.add( bound );
//____________________________ Render
function render() {
animation();
controls.update();
renderer.render(scene, camera);
requestAnimationFrame( render );
};
//___________________________ on each frame
function animation(){
cam_helper.rotation.y += .0005;
};
//___________________________ kickoff
render();
}