You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

155 lines
4.4 KiB
Vue

3 years ago
<template>
<Headline
v-bind="{ labelFonts, themes }"
@select:font="setFont($event)"
@select:theme="setTheme($event)"
/>
<SystemDiagram v-bind="{ star, objects, selectedObject }"
@select="selectObject"
@update="updateSelectedObject"
/>
3 years ago
<section id="settings">
<ObjectSettings v-if="selectedObject"
v-model:name="selectedObject.name"
v-model:distance="selectedObject.distance"
v-model:type="selectedObject.type"
v-model:radius="selectedObject.radius"
v-model:rings="selectedObject.rings"
v-model:satellites="selectedObject.satellites"
:auto-name="autoName(selectedObject)"
@delete="deleteObject"
@close="editObject(null)"
/>
<Tips>
<li>Edit planets by clicking directly inside the graphic or in the table below.</li>
<li>Drag planets around to change their distance.</li>
<li>Use the scrollwheel to change their size (click first to activate).</li>
3 years ago
<li>The last removed planet can be restored from the table.</li>
<li><strong>ONLY THE LAST</strong> removed planet can be restored.</li>
</Tips>
<SystemSettings v-model:designation="star.designation" v-model:radius="star.radius" />
3 years ago
<ObjectList v-bind="{ objects, deletedObject, addObject, editObject, deleteObject, restoreDeleted }" />
</section>
3 years ago
</template>
<script setup>
import { ref, reactive } from 'vue'
import exampleData from './example-data'
import Headline from './components/Headline.vue'
import SystemDiagram from './components/SystemDiagram.vue'
import Tips from './components/Tips.vue'
import SystemSettings from './components/SystemSettings.vue'
import ObjectList from './components/ObjectList.vue'
import ObjectSettings from './components/ObjectSettings.vue'
3 years ago
import { MAX_DISTANCE_PLANET } from './constants'
3 years ago
const star = reactive({
designation: 'Sol',
radius: 400,
})
3 years ago
const objects = reactive(exampleData)
const labelFonts = ['xolonium', 'douar', 'lack']
const themes = ['default', 'retro', 'inverse', 'paper']
const selectedObject = ref(null)
const deletedObject = ref(null) // { index: Number, object: Object }
3 years ago
function addObject() {
const amount = objects.length
let distance = 100
if (amount) {
const lastObject = objects[amount - 1]
distance = Math.min(MAX_DISTANCE_PLANET, lastObject.distance + 2*lastObject.radius + 10)
}
objects.push({
type: 'planet',
name: `${star.designation}-${amount + 1}`,
radius: 1,
distance,
satellites: [],
rings: 0,
})
}
function editObject (object) {
if (object) {
document.documentElement.scrollTop = 0
document.body.scrollTop = 0
}
selectedObject.value = object
}
function selectObject (object) {
selectedObject.value = object
}
function updateSelectedObject (payload) {
for (const key in payload) {
selectedObject.value[key] = payload[key]
}
}
function deleteObject (object) {
if (deletedObject.value) {
const lost = deletedObject.value.object.name
const confirmed = confirm(`
Attention! Only the LAST deleted object can be restored.
${lost} will be lost forever! Proceed anyway?`
)
if (!confirmed) return
}
if (!object) object = selectedObject.value
const index = objects.indexOf(object)
console.debug('deleting object at index', index)
if (index >= 0) objects.splice(index, 1)
if (object === selectedObject.value) selectedObject.value = null
deletedObject.value = { index, object }
}
function restoreDeleted () {
const { index, object } = deletedObject.value
console.debug('restoring deleted object', index)
objects.splice(index, 0, object)
deletedObject.value = null
}
3 years ago
function autoName (obj) {
const index = objects.indexOf(obj)
return `${star.designation}-${index}`
}
3 years ago
function setTheme (theme) {
const classes = document.body.className.split(' ')
const currentTheme = classes.find(c => c.startsWith('theme-'))
const newTheme = `theme-${theme}`
3 years ago
if (currentTheme) {
document.body.classList.replace(currentTheme, newTheme)
} else {
document.body.classList.add(newTheme)
}
3 years ago
}
function setFont (font) {
const classes = document.body.className.split(' ')
const currentFont = classes.find(c => c.startsWith('title-'))
const newFont = `title-${font}`
if (currentFont) {
document.body.classList.replace(currentFont, newFont)
} else {
document.body.classList.add(newFont)
}
}
setTheme(themes[0])
setFont(labelFonts[0])
3 years ago
</script>