class Bookmark extends THREE.Object3D { constructor(position, target, scale = 500.0) { super(); position = new THREE.Vector3().copy(position); target = new THREE.Vector3().copy(target); this.position.copy(position); this.target = new THREE.Vector3().copy(target); this.t = 0; let material = new THREE.LineBasicMaterial({ color: 0xffffff, linewidth: 3, }); let geometry = new THREE.Geometry(); let direction = this.target.clone().sub(position).normalize().multiplyScalar(this.length()); geometry.vertices.push(new THREE.Vector3(0.0, -1000000.0, 0.0)); geometry.vertices.push(new THREE.Vector3(0.0, 0.0, 0.0)); this.line = new THREE.Line(geometry, material); this.add(this.line); this.numberOfPoints = 20; this.createCircle(); this._shining = false; this.t = 0; } createCircle() { let map = new THREE.TextureLoader().load("assets/eye.png"); let material = new THREE.SpriteMaterial({ map: map, color: 0xfffffff, transparent: true, }); let geometry = new THREE.Geometry(); this.circle = new THREE.Sprite(material); this.add(this.circle); } length() { return 25 * (Math.cos(this.t) + 5); } get shining() { return this._shining; } set shining(other) { this._shining = other; if (!other) { this.circle.material.color = new THREE.Color(1, 1, 1); this.line.material.color = new THREE.Color(1, 1, 1); } } update(camera) { // super.update(camera); /// assert(camera instanceof THREE.Camera); let distance = this.localToWorld(this.position.clone()).distanceTo(camera.position); this.t += 0.05; let l = this.length(); this.circle.scale.x = l * Math.log(1 + distance); this.circle.scale.y = l * Math.log(1 + distance); this.circle.scale.z = l * Math.log(1 + distance); this.line.geometry.vertices[1].y = -this.circle.scale.x / 2; this.line.geometry.verticesNeedUpdate = true; if (this.shining) { let value = (1 + Math.cos(Math.PI / 2 + this.t * 2)) / 2; this.circle.material.color = new THREE.Color(1 - value, value, 0); this.line.material.color = new THREE.Color(1 - value, value, 0); } } }