旧项目的实现 需要vue3自己改改
安装依赖 npm install three --save
main.js
import * as THREE from 'three'
Vue.prototype.THREE = THREE
组件
<template>
<div ref="threeDom"></div>
</template>
<script>
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
export default {
name: 'StarrySky',
props: {
list: {
type: Array,
default() {
return [ //模拟数据
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
},
{
name: 'hello'
}
]
}
},
isPlay: { // 加速旋转
type: Boolean,
default: false
}
},
computed: {
currentSpeed() {
// 为true时球体动画加速;false回到默认缓速
return this.isPlay ? 0.04 : 0.001
}
},
data() {
return {
renderer: null,
group: null,
controls: null,
scene: null,
camera: null
}
},
mounted() {
/**
* 创建场景对象Scene
*/
this.scene = new this.THREE.Scene()
this.scene.background = null
/**
* 光源设置
*/
//点光源
const point = new this.THREE.PointLight(0xffffff)
point.position.set(400, 200, 300) //点光源位置
//环境光
const ambient = new this.THREE.AmbientLight(0x444444)
this.scene.add(ambient)
/**
* 相机设置
*/
const width = window.innerWidth //窗口宽度
const height = window.innerHeight //窗口高度
this.camera = new this.THREE.PerspectiveCamera(
40,
width / height,
1,
10000
)
this.camera.position.set(0, 0, 3000) // 3000这个值可以修改,比如需要适配移动端和pc端的话,一般设置为6000的话就适配移动端
this.group = new this.THREE.Group()
const texts = this.list
for (var i = 0, l = texts.length; i < l; i++) {
const phi = Math.acos(-1 + (2 * i) / l)
const theta = Math.sqrt(l * Math.PI) * phi
// 渲染list数据
const sprite = this.createS(texts[i].name)
// 这里的.scale.set对点进行了缩放,可自行调整点大小
sprite.scale.set(160, 160, 1)
sprite.position.setFromSphericalCoords(800, phi, theta)
//sphere.push(sprite)
this.group.add(sprite)
}
this.scene.add(this.group)
/**
* 创建渲染器对象
*/
this.renderer = new this.THREE.WebGLRenderer({
antialias: true,
alpha: true // 该属性为true就隐藏自身的背景颜色;false就是默认黑色背景
})
this.renderer.setSize(width, height) //设置渲染区域尺寸
this.renderer.shadowMap.enabled = false
this.renderer.setPixelRatio(window.devicePixelRatio)
this.$refs.threeDom.appendChild(this.renderer.domElement) //body元素中插入canvas对象
//执行渲染操作指定场景、相机作为参数
this.renderer.render(this.scene, this.camera)
this.controls = new OrbitControls(this.camera, this.renderer.domElement)
this.render()
},
methods: {
render() {
this.renderer.render(this.scene, this.camera) //执行渲染操作
this.group.rotateY(-this.currentSpeed) //每次绕y轴旋转0.01弧度
this.group.rotateX(this.currentSpeed)
this.controls.update()
requestAnimationFrame(this.render) //请求再次执行渲染函数render
},
createS(_text) {
function makeTextCanvas(text, width, height) {
var canvas = document.createElement('canvas')
canvas.width = width
canvas.height = height
var c = canvas.getContext('2d')
c.clearRect(0, 0, c.canvas.width, c.canvas.height)
// 文字
c.beginPath()
c.translate(width / 2, height / 2)
c.fillStyle = '#9F9FA2' //文本填充颜色
c.font = '78px Arial' //字体样式设置
c.textBaseline = 'middle' //文本与fillText定义的纵坐标
c.textAlign = 'center' //文本居中(以fillText定义的横坐标)
c.fillText(text, 0, 0)
c.setTransform(1, 0, 0, 1, 0, 0)
const textHeight = 78
const circleY = height / 2 + textHeight / 2 + 50
c.beginPath()
c.arc(width / 2, circleY, 50, 0, Math.PI * 2, false)
c.fillStyle = 'rgba(217, 217, 217, 1)'
c.fill()
return c.canvas
}
var textCanvas = makeTextCanvas(_text, 300, 300)
var texture = new this.THREE.CanvasTexture(textCanvas)
texture.generateMipmaps = false
texture.minFilter = this.THREE.LinearFilter
texture.magFilter = this.THREE.LinearFilter
let pinMaterial = new this.THREE.SpriteMaterial({
map: texture
})
let mesh = new this.THREE.Sprite(pinMaterial)
return mesh
}
}
}
</script>
<style scoped lang="less"></style>
页面导入组件并加上背景图后的效果, 可自动旋转,手动拖拽旋转,手动缩放球体