数据可视化大屏 开发过程中,需要图片在3d层面的点缀,今天我们来实现一张平面图如何在3d层面旋转。
准备一张图
我们首先准备一张平面图,这张图片各个角度要有差异,不能像一个圆环,不然转起来也看不出图片在旋转。
效果截图
动态效果
插件
"three": "^0.159.0",
实例代码
<script>
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import img from './assets/lun.png';
let renderer = null;
let camera = null;
let width = 0;
let height = 0;
let scene = null;
let mesh = null;
export default {
name: 'GLTFCanvas',
mounted() {
const viewElem = document.body;
this.$nextTick(this.init);
const resizeObserver = new ResizeObserver(this.handleResize);
resizeObserver.observe(viewElem);
},
methods: {
async init() {
const canvasGLTF = this.$refs.canvasGLTF;
width = canvasGLTF.offsetWidth;
height = canvasGLTF.offsetHeight;
// Create scene, camera, renderer, controls
this.createScene();
this.createCamera();
this.createRenderer();
this.createControls();
// Load texture and start animation
await this.loadTexture();
this.animate();
canvasGLTF.appendChild(renderer.domElement);
},
createScene() {
scene = new THREE.Scene();
},
createCamera() {
camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000);
camera.position.set(-0.003236905604211045, -0.5120776906761103, 0.2721449110235568);
scene.add(camera);
},
createRenderer() {
renderer = new THREE.WebGLRenderer({
logarithmicDepthBuffer: true,
antialias: true,
});
renderer.setSize(width, height);
renderer.shadowMap.enabled = true;
renderer.physicallyCorrectLights = true;
renderer.setClearColor(0xcccccc, 1);
renderer.autoClear = false;
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.outputEncoding = THREE.sRGBEncoding;
renderer.sortObjects = true;
renderer.logarithmicDepthBuffer = true;
renderer.setPixelRatio(window.devicePixelRatio);
},
createControls() {
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
},
async loadTexture() {
const loader = new THREE.TextureLoader();
const texture = await loader.loadAsync(img);
const material = new THREE.MeshBasicMaterial({
map: texture,
transparent: true,
depthWrite: false,
opacity: 0.5
});
const geometry = new THREE.PlaneGeometry(1, 1);
mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
},
animate() {
requestAnimationFrame(this.animate);
if (mesh) {
mesh.rotation.z += 0.005;
}
renderer.render(scene, camera);
},
handleResize() {
const canvasGLTF = this.$refs.canvasGLTF;
width = canvasGLTF.offsetWidth;
height = canvasGLTF.offsetHeight;
camera.aspect = width / height;
camera.updateProjectionMatrix();
renderer.setSize(width, height);
renderer.setPixelRatio(window.devicePixelRatio);
}
}
}
</script>
应用
我们可以添加到项目中,作为装饰效果,比如给地图做背景装饰threejs 3d地图粒子效果.
项目应用
装饰效果2
动态效果
完整实例代码下载
项目运行环境 vue3 vite js nodejs 14