adds key controls, star info and more stars
This commit is contained in:
parent
d2b31f895a
commit
3bac2bd865
5 changed files with 86 additions and 26 deletions
|
@ -33,7 +33,7 @@
|
|||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="info"></div>
|
||||
<div id="info">Click a star to get options.</div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
26
src/main.ts
26
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<Object3D<Event>>[] = []
|
||||
|
||||
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<Object3D<Event>>[] = []
|
||||
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)
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
50
src/stars.ts
50
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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
]
|
||||
|
|
Loading…
Add table
Reference in a new issue