forked from GreggJuanEduardoPH/vue-gl
-
Notifications
You must be signed in to change notification settings - Fork 0
/
vgl-camera.js
89 lines (87 loc) · 3.03 KB
/
vgl-camera.js
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
import { Camera, Vector3 } from 'three';
import VglObject3d from '../core/vgl-object3d';
import { parseVector3, parseSpherical } from '../parsers';
import { vector3, spherical, name } from '../types';
import { validateVector3, validateSpherical, validateName } from '../validators';
/**
* This is abstract base component for cameras,
* corresponding [THREE.Camera](https://threejs.org/docs/index.html#api/cameras/Camera).
* This component should always be mixined (inherited).
* You probably want a [VglPerspectiveCamera](vgl-perspective-camera)
* and [VglOrthographicCamera](vgl-orthographic-camera).
*
* Properties of [VglObject3d](../core/vgl-object3d) are also available as mixin.
*/
export default {
mixins: [VglObject3d],
props: {
/**
* Position in 3D space for the camera to point towards.
* This property overwrite rotation property when both defined.
*/
orbitTarget: { type: vector3, validator: validateVector3 },
/**
* Spherical position around orbitTarget.
* This property overwrite position and rotation properties.
* If orbitTarget is not defined, automatically set to (0, 0, 0).
*/
orbitPosition: { type: spherical, validator: validateSpherical },
/** Name of the camera */
name: { type: name, required: true, validator: validateName },
},
computed: {
/** The THREE.Camera instance. */
inst: () => new Camera(),
},
methods: {
/** Emit an event in the `cameras` namespace. */
emitAsCamera() { this.vglNamespace.cameras.emit(this.name, this.inst); },
},
created() {
this.vglObject3d.listen(this.emitAsCamera);
},
beforeDestroy() {
this.vglObject3d.unlisten(this.emitAsCamera);
this.vglNamespace.cameras.delete(this.name, this.inst);
},
watch: {
inst: {
handler(inst) {
if (this.orbitPosition || this.orbitTarget) {
let target;
if (this.orbitTarget) target = parseVector3(this.orbitTarget);
if (this.orbitPosition) {
inst.position.setFromSpherical(parseSpherical(this.orbitPosition));
if (target) inst.position.add(target);
}
inst.lookAt(target || new Vector3());
}
this.vglNamespace.cameras.set(this.name, inst);
},
immediate: true,
},
name(newName, oldName) {
this.vglNamespace.cameras.delete(oldName, this.inst);
this.vglNamespace.cameras.set(newName, this.inst);
},
orbitTarget(orbitTarget) {
const target = parseVector3(orbitTarget);
if (this.orbitPosition) {
this.inst.position.setFromSpherical(parseSpherical(this.orbitPosition)).add(target);
}
this.inst.lookAt(target);
this.vglObject3d.emit();
},
orbitPosition(orbitPosition) {
this.inst.position.setFromSpherical(parseSpherical(orbitPosition));
if (this.orbitTarget) {
const target = parseVector3(this.orbitTarget);
this.inst.position.add(target);
this.inst.lookAt(target);
} else {
this.inst.lookAt(new Vector3());
}
this.vglObject3d.emit();
},
},
};