From 3bac2bd865608c167ce00b5655d16c42edd51945 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Norman=20K=C3=B6hring?= Date: Sun, 22 Jan 2023 21:49:34 +0100 Subject: [PATCH] adds key controls, star info and more stars --- index.html | 2 +- src/main.ts | 26 ++++++++++++++++++------ src/plane.ts | 2 +- src/stars.ts | 50 ++++++++++++++++++++++++++++++----------------- src/testdata.json | 32 ++++++++++++++++++++++++++++++ 5 files changed, 86 insertions(+), 26 deletions(-) diff --git a/index.html b/index.html index 0c2d023..3f14e0f 100644 --- a/index.html +++ b/index.html @@ -33,7 +33,7 @@ -
+
Click a star to get options.
diff --git a/src/main.ts b/src/main.ts index f31f971..ad6bcdb 100644 --- a/src/main.ts +++ b/src/main.ts @@ -9,13 +9,13 @@ import { } from 'three' import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js' import { planeGeometry } from './plane' -import { renderStars } from './stars' +import { renderStars, Star } from './stars' function init() { const w = window.innerWidth const h = window.innerHeight - const radius = 50 + const infoEl = document.getElementById('info')! const renderer = new WebGLRenderer({ antialias: true }) renderer.setSize(w, h) @@ -29,9 +29,10 @@ function init() { const controls = new OrbitControls(camera, renderer.domElement) controls.enableZoom = true controls.enableRotate = true - controls.enablePan = false + controls.enablePan = true controls.maxDistance = radius * 2.5 controls.minDistance = 0.1 + controls.listenToKeyEvents(window) const plane = planeGeometry(radius) const stars = renderStars(radius) @@ -41,6 +42,7 @@ function init() { const pointer = new Vector2() const raycaster = new Raycaster() + const intersections: Intersection>[] = [] window.addEventListener('resize', () => { camera.aspect = window.innerWidth / window.innerHeight @@ -52,15 +54,27 @@ function init() { pointer.x = (event.clientX / window.innerWidth) * 2 - 1 pointer.y = -(event.clientY / window.innerHeight) * 2 + 1 }) + document.addEventListener('click', () => { + infoEl.innerText = 'Click a star to get options.' + for (let star of stars.children) { + ;(star as Star).highlighted = false + } - const intersections: Intersection>[] = [] + for (let i of intersections) { + const star = i.object.parent as Star + if (star.isStar) { + star.highlighted = true + infoEl.innerText = JSON.stringify(star.starData) + } + } + }) renderer.setAnimationLoop(() => { raycaster.setFromCamera(pointer, camera) intersections.length = 0 - raycaster.intersectObject(stars, false, intersections) - if (intersections.length) console.log(intersections) + raycaster.intersectObject(stars, true, intersections) + renderer.render(scene, camera) }) document.body.appendChild(renderer.domElement) diff --git a/src/plane.ts b/src/plane.ts index 8108c4a..b0d92c3 100644 --- a/src/plane.ts +++ b/src/plane.ts @@ -2,7 +2,7 @@ import { BufferGeometry, Group, Line, LineBasicMaterial, Shape, Vector3 } from ' export function planeGeometry(radius: number, n = 5) { const material = new LineBasicMaterial({ - color: 0xa0a0a0, + color: 0x303030, }) const plane = new Group() diff --git a/src/stars.ts b/src/stars.ts index 1347a08..71e8e49 100644 --- a/src/stars.ts +++ b/src/stars.ts @@ -21,13 +21,20 @@ export interface StarData { theta: number } -class Star extends Group { +export class Star extends Group { + public isStar = true + public starData: StarData + private tangentialCoords = new Vector3() private cartesianCoords = new Vector3() private sphericalCoords = new Spherical() + private isHighlighted = false + private normalPointSize = 2 + private highlightedPointSize = 3 + private lineMaterial = new LineBasicMaterial({ color: 0xffffff }) - private pointMaterial = new PointsMaterial({ size: 1, vertexColors: true }) + private pointMaterial = new PointsMaterial({ size: this.normalPointSize, vertexColors: true }) private pointGeometry = new BufferGeometry() private whiteColor = new Float32BufferAttribute([255, 255, 255], 3) @@ -35,10 +42,11 @@ class Star extends Group { private poleLine = new Line(new BufferGeometry(), this.lineMaterial) - constructor(star: StarData) { + constructor(starData: StarData) { super() - const { radius, phi, theta } = star + const { radius, phi, theta } = starData + this.starData = starData this.sphericalCoords.set(radius, phi, theta) this.cartesianCoords.setFromSpherical(this.sphericalCoords) @@ -58,30 +66,36 @@ class Star extends Group { this.add(point) } - setHighlight(isHighlight = true) { - this.pointGeometry.setAttribute('color', isHighlight ? this.yellowColor : this.whiteColor) + private setHighlight(isHighlight = true) { + const color = isHighlight ? this.yellowColor : this.whiteColor + this.pointGeometry.setAttribute('color', color) + this.pointMaterial.setValues({ + size: isHighlight ? this.highlightedPointSize : this.normalPointSize, + }) + } + + public get highlighted() { + return this.isHighlighted + } + + public set highlighted(isHighlighted) { + this.isHighlighted = isHighlighted + this.setHighlight(isHighlighted) + } + + public toggleHighlight() { + this.isHighlighted = !this.isHighlighted + this.setHighlight(this.isHighlighted) } } export function renderStars(maxRadius: number) { const group = new Group() - const infoEl = document.getElementById('info')! data.forEach((starData) => { if (starData.radius > maxRadius) return const star = new Star(starData) group.add(star) - - let highlighted = false - - const btnEl = document.createElement('button') - btnEl.addEventListener('click', () => { - highlighted = !highlighted - star.setHighlight(highlighted) - btnEl.classList.toggle('highlighted', highlighted) - }) - btnEl.innerText = starData.name - infoEl.appendChild(btnEl) }) return group diff --git a/src/testdata.json b/src/testdata.json index 4cd4c7e..5802adb 100644 --- a/src/testdata.json +++ b/src/testdata.json @@ -38,5 +38,37 @@ "phi": -13.0693645782006, "spectral": "M4.0Ve", "radius": 5.0515 + }, + { + "name": "Proxima Centauri", + "type": "Eruptive Variable", + "theta": 313.9398620493784, + "phi": -1.9271491330428, + "spectral": "M5.5Ve", + "radius": 1.3019 + }, + { + "name": "Teegarden's Star", + "type": "Low-mass Star", + "theta": 160.2632765789228, + "phi": -37.0261176452823, + "spectral": "dM6", + "radius": 3.8315 + }, + { + "name": "Barnard's star", + "type": "BY Dra Variable", + "theta": 31.0087027177046, + "phi": 14.0626510150033, + "spectral": "M4V", + "radius": 1.8282 + }, + { + "name": "Wolf 359", + "type": "Eruptive Variable", + "theta": 244.0543969618636, + "phi": 56.1197323657577, + "spectral": "dM6", + "radius": 2.4086 } ]