-
产品最近看上了腾讯云首页的banner效果,跟我一顿称兄道弟后,让我搞一搞

-
主要的难点在Ui建模,前端这边选用tree.js 去实现效果。
难点分析
- 模型要跟随鼠标旋转,而不是移动,
- 鼠标无需点击,要使用 mousemove 监听移动。
- 生成的3d 要背景透明
- 灯光
直接上代码
<template>
<div>
<canvas id="mainCanvas"></canvas>
</div>
</template>
<script>
import * as THREE from 'three'
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader'
var data = {
camera: null,
scene: null,
mesh: null,
modelPath: './qing.fbx'
}
export default {
data() {
return {
renderer: null,
controls: null,
targetRotation: 0,
plane: null,
cube: null,
mouse: 0,
time1: null,
time: null,
raycaster: null,
targetRotationOnMouseDown: 0,
x: 0,
y: 0,
z: 0
}
},
methods: {
init() {
data.scene = new THREE.Scene()
this.renderer = new THREE.WebGLRenderer({
canvas: document.getElementById('mainCanvas'),
antialias: true,
alpha: true
})
this.renderer.setSize(600, 600)
this.renderer.setClearColor(0xb9d3ff, 0)
data.camera = new THREE.PerspectiveCamera(55, 1, 0.1, 1000)
data.camera.position.set(30, 10, 55)
this.mouse = new THREE.Vector2()
this.raycaster = new THREE.Raycaster()
var dianLight = new THREE.PointLight('#f3f8ff')
dianLight.intensity = 1
dianLight.position.set(20, 30, 20)
data.scene.add(dianLight)
var directionalLight = new THREE.DirectionalLight(0xbcd2ee)
directionalLight.position.set(1, 0.75, 0.5).normalize()
data.scene.add(directionalLight)
let fbxLoader = new FBXLoader()
fbxLoader.load(data.modelPath, function (object) {
data.mesh = object
data.scene.add(object)
})
},
animate() {
requestAnimationFrame(this.animate)
this.renderer.render(data.scene, data.camera)
},
MouseMove(event) {
data.mesh.rotation.x += event.movementY / 1500
data.mesh.rotation.y += event.movementX / 1500
this.x = data.mesh.rotation.x
this.y = data.mesh.rotation.y
},
MouseLeave() {
let x = this.x
let y = this.y
clearInterval(this.time1)
clearInterval(this.time)
x = Number(x)
let count1 = Number(x / 10)
y = Number(y)
let count2 = Number(y / 10)
this.time = setInterval(() => {
if (x > 0.01 || x < -0.01) {
x = Number(x - count1)
data.mesh.rotation.x = x
} else {
data.mesh.rotation.x = 0
clearInterval(this.time)
}
}, 20)
this.time1 = setInterval(() => {
if (y > 0.01 || y < -0.01) {
y = Number(y - count2)
data.mesh.rotation.y = y
} else {
data.mesh.rotation.y = 0
clearInterval(this.time1)
}
}, 20)
}
},
mounted() {
this.init()
this.animate()
document.getElementById('mainCanvas').addEventListener('mousemove', this.MouseMove, false)
document.getElementById('mainCanvas').addEventListener('mouseleave', this.MouseLeave, false)
}
}
</script>
<style scoped></style>
实现效果如下

背景跟随移动,这个简单,只要使用mosemove 监听鼠标移动事件 mousemoveX 和mousemoveY 改变背景div 的transfrom下的translate 坐标即可,需要注意的是3d模型的旋转速率要跟 背景图的移动距离保持一致,这里需要不断微调。