VUE中使用Three.js所遇到的问题

由于公司要使用动画效果,分析了一段时间以后,决定使用Three.js,一般官网给的demo大部分都是在HTML静态界面中应用引用,但是自己想使用import引用,那么问题就来了,先上之前安装方法和引用方法:

1
2
npm install three --save
import * as THREE from "three";

项目引用上以后,发现问题还真不少
首先在引用完成以后,代码写完以后,在编译时出现警告:
"export ‘ParticleCanvasMaterial’ (imported as ‘THREE’) was not found in ‘three’

以为没有问题,直接运行,结果

原因是ParticleCanvasMaterial这个函数在Three.js的r62版本中已经被废弃了。而且npm中无法安装这个老版本。

实在不行,就想尝试修改这个老版本three.js的代码,在thress.js的最后一行加上export default {THREE},然后放入代码中引用,

1
import THREE from "@js/three.min.js";

发现还是不行,项目还是报错,刚开始以为这样不可以,后来想着先先找下原因试试,然后代码分析,发现问题的所在,在使用的时候不能直接new THREE.ParticleCanvasMaterial而是要new THREE.THREE.ParticleCanvasMaterial再次刷新界面,效果达到了预期

最终login.vue的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
<script>
import THREE from "../../utils/three";

let SEPARATION = 100,
AMOUNTX = 100,
AMOUNTY = 70;

let container;
let camera, scene, renderer;

let particles,
particle,
count = 0;

let mouseX = 85,
mouseY = -342;

let windowHalfX = window.innerWidth / 2;
let windowHalfY = window.innerHeight / 2;
export default {
data() {
return {
};
},
methods: {
init() {
container = document.createElement("div");
document.body.appendChild(container);
camera = new THREE.THREE.PerspectiveCamera(
120,
window.innerWidth / window.innerHeight,
1,
10000
);
// 下面这行是控制特效的css样式,如果在网站上找的是其它特效,没有这一行的话特效可能不显示,因为上层div把特效遮挡了
container.style.cssText = "position:fixed;top:0;left:0;cursor:pointer;opacity:0.9;z-index:10000";
camera.position.z = 1000;

scene =new THREE.THREE.Scene();

particles = new Array();

var PI2 = Math.PI * 2;
var material =new THREE.THREE.ParticleCanvasMaterial({
color: 0xe1e1e1,
program: function(context) {
context.beginPath();
context.arc(0, 0, 0.6, 0, PI2, true);
context.fill();
}
});

var i = 0;

for (var ix = 0; ix < AMOUNTX; ix++) {
for (var iy = 0; iy < AMOUNTY; iy++) {
particle = particles[i++] = new THREE.THREE.Particle(material);
particle.position.x = ix * SEPARATION - AMOUNTX * SEPARATION / 2;
particle.position.z = iy * SEPARATION - AMOUNTY * SEPARATION / 2;
scene.add(particle);
}
}

renderer =new THREE.THREE.CanvasRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);

document.addEventListener("mousemove", this.onDocumentMouseMove, false);
document.addEventListener("touchstart", this.onDocumentTouchStart, false);
document.addEventListener("touchmove",this. onDocumentTouchMove, false);

//

window.addEventListener("resize", this.onWindowResize, false);
},
onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;

camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();

renderer.setSize(window.innerWidth, window.innerHeight);
},
onDocumentMouseMove(event) {
mouseX = event.clientX - windowHalfX;
mouseY = event.clientY - windowHalfY;
},
onDocumentTouchStart(event) {
if (event.touches.length === 1) {
event.preventDefault();

mouseX = event.touches[0].pageX - windowHalfX;
mouseY = event.touches[0].pageY - windowHalfY;
}
},
onDocumentTouchMove(event) {
if (event.touches.length === 1) {
event.preventDefault();

mouseX = event.touches[0].pageX - windowHalfX;
mouseY = event.touches[0].pageY - windowHalfY;
}
},
animate() {
requestAnimationFrame(this.animate);

this.render();
},
render() {
camera.position.x += (mouseX - camera.position.x) * 0.05;
camera.position.y += (-mouseY - camera.position.y) * 0.05;
camera.lookAt(scene.position);

var i = 0;

for (var ix = 0; ix < AMOUNTX; ix++) {
for (var iy = 0; iy < AMOUNTY; iy++) {
particle = particles[i++];
particle.position.y =
Math.sin((ix + count) * 0.3) * 50 +
Math.sin((iy + count) * 0.5) * 50;
particle.scale.x = particle.scale.y =
(Math.sin((ix + count) * 0.3) + 1) * 2 +
(Math.sin((iy + count) * 0.5) + 1) * 2;
}
}

renderer.render(scene, camera);

count += 0.1;
}
},
mounted() {
this.getImgCode();
this.init()
this.animate()
}
};
</script>