Threejs 3D implements goods switching dynamic effect
Without further ado, let’s look at the presentation
Before I start writing the code, LET me explain a few concepts to make it easier for you to understand
Concept to explain
Scenario (Sence)
All elements are in the scene, and all drawn elements are added to the scene
cosnt scene = new Three.Scene();
Copy the code
Camera
A camera is like a human eye. Only with a camera can you see all objects and light sources in the scene. Camera has orthogonal projection camera and perspective projection camera two kinds. Perspective projection and human eyes see the world is the same, near large and far small; The orthogonal projection is the same size from far to far, so any line that is parallel in three dimensions must be parallel in two dimensions. Perspective cameras are good for most scenes because they look just like the real world; Orthogonal projection camera is suitable for mapping, modeling and other scenes, which is convenient to observe the size proportion between models.
Orthogonal projection camera
OrthographicCamera is a rectangular body determined by six parameters: THREE.OrthographicCamera(left, right, Top, bottom, near, far). These six parameters specify the position of the left, right, top, bottom, front and rear sides of the camera’s display body.
Perspective projection camera
Perspective cameras are the most common type of camera that simulate the vision of the human eye, large near and small (perspective). Fov stands for perspective, and the bigger the Fov, the bigger your eyes open, and the farther away you are, the more you see. PerspectiveCamera(FOV, aspect, near, far) is used for simulating reality.
Light
The main sources of light are as follows: 1. Ambient light, which has the same brightness from all angles, is usually used to specify a base brightness for the whole scene without specifying the position of the light source. 2. Point light source, a light source from a point, the brightness of different object surfaces decreases linearly; 3, parallel light, brightness has nothing to do with the distance between the light source and the object, only with the Angle of parallel light and the object in the plane; The spotlight casts a conical light.
Spot light (Figure 1), parallel light (Figure 2), point light source (Figure 3)
Material
Much of an object’s physical properties depend on its materials, which also determine the appearance of its geometry. Threejs provides several representative materials, commonly used basic materials, specular highlight materials, in addition to Threejs provides the material can also introduce external images, stick to the surface of the object, called texture map.
Renderer
Threejs draws things that eventually need to be displayed on a rectangular canvas on the screen. At this point, we need to render with the WebGLRenderer
const renderer = new Three.WebGLRenderer();
Copy the code
The code
The JS framework uses the Vue UI framework as element-UI
Initialize the DOM node
<div id="app">
<div id="content" style="height: 500px"></div>
<div class="selct">
<div class="title">Part of the selection</div>
<ul class="list">
<li v-for="(item, index) in meshList" @click="selectMesh(index)" :class="activeIndex == index ? 'active' : ''">{{item.name}}</li>
</ul>
<div class="title">Color choices</div>
<el-color-picker v-model="color" color-format="rgb" @change="setSelectColor"></el-color-picker>
</div>
</div>
Copy the code
initEL() {
this.root = document.getElementById('content');
this.canvas = document.createElement('canvas');
this.width = this.root.offsetWidth;
this.height = this.root.offsetHeight;
console.log(this.width, this.height);
}
Copy the code
Initialize the scene value
initSence() {
this.scene = new THREE.Scene();
}
Copy the code
Initialize the light source
initLight() {
/ / the ambient light
const ambient = new THREE.AmbientLight(0xffffff.0.9);
/ / the point light source
const point = new THREE.PointLight(0xcccccc.0.1.100);
/ / parallel light
const directional = new THREE.DirectionalLight(0xffffff.0.5);
this.scene.add(ambient);
this.scene.add(point);
this.scene.add(directional);
}
Copy the code
Initializing the camera
initCamera() {
const aspect = this.width / this.height;
this.camera = new THREE.PerspectiveCamera(45, aspect, 1.1000);
this.camera.position.z = 15;
this.camera.aspect = aspect;
this.camera.updateProjectionMatrix();
}
Copy the code
Initialize the renderer
initRenderer() {
this.renderer = new THREE.WebGLRenderer({ antialias: true });
this.renderer.setSize(this.width, this.height);
this.renderer.setClearColor(0xeeeeee.1);
this.canvas = this.renderer.domElement;
}
Copy the code
Initializing the Controller
initControls() {
this.controls = new THREE.OrbitControls(this.camera, this.canvas);
this.controls.minPolarAngle = (Math.PI * 1) / 6;
this.controls.maxPolarAngle = (Math.PI * 3) / 4;
this.controls.smooth = true;
this.controls.smoothspeed = 0.95;
this.controls.autoRotateSpeed = 2;
this.controls.maxDistance = 20;
this.controls.minDistance = 12;
this.controls.update();
}
Copy the code
Render the canvas
render() {
this.camera.lookAt(this.scene.position);
this.renderer.render(this.scene, this.camera);
}
Copy the code
Load model
loadModel() {
this.loader = new THREE.GLTFLoader();
this.loader.load('./model/scene.gltf'.(model) = > {
let index = 1;
model.scene.traverse((child) = > {
if (child instanceof THREE.Mesh) {
// Reset the material
child.material.map = null;
child.name = 'modules' + index;
index++;
this.meshList.push(child);
this.meshColorList.push('rgb(0, 0, 0)');
}
this.activeMesh = this.meshList[0];
});
this.scene.add(model.scene);
this.renderer.render(this.scene, this.camera);
});
}
Copy the code
Select module/color
selectMesh(index) {
let mesh = this.meshList[index];
this.activeMesh = mesh;
this.activeIndex = index;
this.color = this.meshColorList[index];
this.setSelectColor(this.color);
},
// Set the color
setSelectColor(value) {
let rgb = value.replace(/[rgb]|[(]|[)]|\s/g.' ').split(', ');
let text = this.setTexture(rgb);
this.activeMesh.material = text;
this.activeMesh.material.map.needsUpdate = true;
this.activeMesh.material.needsUpdate = true;
this.meshColorList[this.activeIndex] = value;
},
// Set the material
setTexture(rgb) {
var size = 200 * 200;
var data = new Uint8Array(3 * size);
for (var i = 0; i < size; i++) {
var stride = i * 3;
data[stride] = Number(rgb[0]);
data[stride + 1] = Number(rgb[1]);
data[stride + 2] = Number(rgb[2]);
}
var texture = new THREE.DataTexture(data, 100.100, THREE.RGBFormat);
texture.needsUpdate = true;
return new THREE.MeshPhongMaterial({ map: texture });
}
Copy the code
Update renderer
update() {
requestAnimationFrame(() = > this.update());
this.controls.update();
this.render();
}
Copy the code
The relevant code
Github.com/liyanan666/…