Moved root page to space/
This commit is contained in:
parent
4c54e1e62f
commit
310fa09baf
23 changed files with 1 additions and 2 deletions
22
space/js/anim.js
Normal file
22
space/js/anim.js
Normal file
|
@ -0,0 +1,22 @@
|
|||
const fadeAnimIn = [
|
||||
'show',
|
||||
'animated',
|
||||
'tdFadeIn',
|
||||
]
|
||||
|
||||
const fadeAnimOut = [
|
||||
'animated',
|
||||
'tdFadeOut',
|
||||
]
|
||||
|
||||
|
||||
const bounceAnimIn = [
|
||||
'show',
|
||||
'animated',
|
||||
'tdExpandInBounce',
|
||||
]
|
||||
|
||||
const bounceAnimOut = [
|
||||
'animated',
|
||||
'tdShrinkOutBounce',
|
||||
]
|
19
space/js/control.js
Normal file
19
space/js/control.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
/** @type {HTMLImageElement} */
|
||||
const spaceObj = document.querySelector('#space-obj')
|
||||
|
||||
/** @type {HTMLDivElement} */
|
||||
const space = document.querySelector('.space')
|
||||
|
||||
|
||||
function changePicture(/** @type {Event} */ ev) {
|
||||
spaceObj.src = ev.target.dataset.img || 'img/earth.gif'
|
||||
hideContextMenu()
|
||||
}
|
||||
|
||||
function changeSpeed(/** @type {Event} */ ev) {
|
||||
spaceObj.style.animationDuration = `${1200 - ev.target.value}s`
|
||||
}
|
||||
|
||||
function landToEarth() {
|
||||
hideContextMenu()
|
||||
}
|
24
space/js/handlers.js
Normal file
24
space/js/handlers.js
Normal file
|
@ -0,0 +1,24 @@
|
|||
context.addEventListener('mousedown', ev => ev.stopPropagation())
|
||||
|
||||
space.addEventListener('mousedown', ev => ev.preventDefault())
|
||||
space.addEventListener('contextmenu', contextMenu)
|
||||
|
||||
document.querySelectorAll('.copylink>.profile-link').forEach(
|
||||
elem => elem.addEventListener('click', copyLink)
|
||||
)
|
||||
|
||||
document.querySelectorAll('li.change-img>a').forEach(
|
||||
elem => elem.addEventListener('click', changePicture)
|
||||
)
|
||||
|
||||
document.querySelector('li.change-speed a').addEventListener('mousedown', ev => ev.preventDefault())
|
||||
document.querySelector('li.change-speed input').addEventListener('input', changeSpeed)
|
||||
document.querySelector('li.change-speed input').addEventListener('mousedown', ev => ev.stopPropagation())
|
||||
document.querySelector('li.land-to').addEventListener('click', landToEarth)
|
||||
|
||||
move.addEventListener('mousedown', moveMenu)
|
||||
move.addEventListener('mouseup', moveMenu)
|
||||
move.addEventListener('mousemove', moveMenu)
|
||||
body.addEventListener('mousemove', moveMenu)
|
||||
body.addEventListener('mouseup', moveMenu)
|
||||
body.addEventListener('mousedown', hideContextMenu)
|
86
space/js/init.js
Normal file
86
space/js/init.js
Normal file
|
@ -0,0 +1,86 @@
|
|||
function init() {
|
||||
initStars()
|
||||
computeAge()
|
||||
insertSystemInfo()
|
||||
}
|
||||
|
||||
function initStars() {
|
||||
|
||||
const colors = [
|
||||
'#999','#9999ac','#ac9999','#acac99',
|
||||
'#bbb','#bbbbcf','#cfbbbb','#cfcfbb',
|
||||
'#eee','#e5e5ff','#ffe5e5','#ffffe5',
|
||||
'#fff'
|
||||
]
|
||||
const len = colors.length
|
||||
|
||||
const canvas = document.getElementById('stars')
|
||||
const css = getComputedStyle(canvas)
|
||||
|
||||
const w = canvas.width = styleValue(css.getPropertyValue('width'))
|
||||
const h = canvas.height = styleValue(css.getPropertyValue('height'))
|
||||
|
||||
// if CSS hasn't been loaded yet
|
||||
// (w and h contains NaN)
|
||||
const err = [w,h].some(n => isNaN(n))
|
||||
if (err) {
|
||||
setTimeout(init, 200)
|
||||
return
|
||||
}
|
||||
|
||||
const ctx = canvas.getContext('2d')
|
||||
const radius = 3
|
||||
const circle = 2 * Math.PI
|
||||
|
||||
ctx.clearRect(0, 0, w, h)
|
||||
for (let star = 0; star < 200; star++) {
|
||||
|
||||
let color = Math.floor(Math.random() * len)
|
||||
ctx.fillStyle = colors[color]
|
||||
|
||||
ctx.beginPath()
|
||||
ctx.arc(
|
||||
Math.round(Math.random() * w),
|
||||
Math.round(Math.random() * h),
|
||||
radius, 0, circle, false
|
||||
)
|
||||
ctx.fill()
|
||||
}
|
||||
}
|
||||
|
||||
function computeAge() {
|
||||
|
||||
const birthday = new Date(2009, 7, 13, 12, 30)
|
||||
const timedelta = Date.now() - birthday.getTime()
|
||||
|
||||
/*
|
||||
The line below is equivalent to:
|
||||
const age = timedelta / 1000 / 60 / 60 / 24 / 365.25
|
||||
where:
|
||||
1000: convert milliseconds -> seconds
|
||||
60: secs -> minutes
|
||||
60: minutes -> hours
|
||||
24: hours -> days
|
||||
365.25: average count of days in a year:
|
||||
(366 + (365 * 3)) / 4 = 365.25
|
||||
*/
|
||||
const age = timedelta / (1000 * 60 * 60 * 24 * 365.25)
|
||||
|
||||
document.getElementById('age-js').textContent = Math.floor(age)
|
||||
}
|
||||
|
||||
function insertSystemInfo() {
|
||||
|
||||
const inxi = document.getElementById('inxi')
|
||||
|
||||
let xhr = new XMLHttpRequest()
|
||||
xhr.open('GET', '/inxi.txt')
|
||||
|
||||
xhr.onreadystatechange = () => {
|
||||
if (xhr.readyState != xhr.DONE) return
|
||||
if (xhr.status != 200) return
|
||||
inxi.textContent = xhr.response
|
||||
}
|
||||
|
||||
xhr.send()
|
||||
}
|
76
space/js/menu.js
Normal file
76
space/js/menu.js
Normal file
|
@ -0,0 +1,76 @@
|
|||
/** @type {HTMLDivElement} */
|
||||
const menu = document.querySelector('.about-menu')
|
||||
|
||||
/** @type {HTMLLIElement} */
|
||||
const move = document.querySelector('.about-menu li#move')
|
||||
|
||||
/** @type {HTMLDivElement} */
|
||||
const context = document.querySelector('.context-menu')
|
||||
|
||||
|
||||
var contextShown = false
|
||||
var contextTimeout
|
||||
|
||||
var menuDragging = false
|
||||
var mousePos = {x: 0, y: 0}
|
||||
|
||||
|
||||
function moveMenu(/** @type {MouseEvent} */ ev) {
|
||||
switch (ev.type) {
|
||||
|
||||
case 'mousedown':
|
||||
menuDragging = true
|
||||
mousePos.y = ev.clientY - styleValue(menu.style.top)
|
||||
mousePos.x = ev.clientX - styleValue(menu.style.left)
|
||||
menu.classList.add('dragging')
|
||||
ev.preventDefault()
|
||||
break
|
||||
|
||||
case 'mouseup':
|
||||
menuDragging = false
|
||||
menu.classList.remove('dragging')
|
||||
break
|
||||
|
||||
case 'mousemove':
|
||||
if (menuDragging) {
|
||||
let top = ev.clientY - mousePos.y
|
||||
let left = ev.clientX - mousePos.x
|
||||
menu.style.top = `${top}px`
|
||||
menu.style.left = `${left}px`
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
function contextMenu(/** @type {MouseEvent} */ ev) {
|
||||
|
||||
clearTimeout(contextTimeout)
|
||||
context.classList.remove(...bounceAnimOut)
|
||||
|
||||
context.style.top = `${ev.clientY + 5}px`
|
||||
context.style.left = `${ev.clientX + 5}px`
|
||||
|
||||
context.classList.add(...bounceAnimIn)
|
||||
contextShown = true
|
||||
|
||||
ev.preventDefault()
|
||||
return false
|
||||
}
|
||||
|
||||
function hideContextMenu(/** @type {MouseEvent} */ ev) {
|
||||
|
||||
if (!contextShown) return
|
||||
if (ev && ev.button != 0) return
|
||||
|
||||
context.classList.remove(...bounceAnimIn)
|
||||
|
||||
context.classList.add('show')
|
||||
context.classList.add(...bounceAnimOut)
|
||||
contextShown = false
|
||||
|
||||
// animation-duration: 0.6s;
|
||||
contextTimeout = setTimeout(() => {
|
||||
context.classList.remove('show')
|
||||
context.classList.remove(...bounceAnimOut)
|
||||
}, 600)
|
||||
}
|
32
space/js/script.js
Normal file
32
space/js/script.js
Normal file
|
@ -0,0 +1,32 @@
|
|||
const body = document.body
|
||||
|
||||
function copyLink(/** @type {Event} */ ev) {
|
||||
|
||||
/** @type {HTMLSpanElement} */
|
||||
let elem = ev.currentTarget
|
||||
|
||||
navigator.clipboard.writeText(elem.dataset.link)
|
||||
|
||||
let wrapper = elem.parentElement.parentElement.parentElement
|
||||
let msg = wrapper.querySelector('.copied')
|
||||
|
||||
msg.classList.add(...fadeAnimIn)
|
||||
|
||||
setTimeout(() => {
|
||||
|
||||
msg.classList.remove(...fadeAnimIn)
|
||||
|
||||
msg.classList.add('show')
|
||||
msg.classList.add(...fadeAnimOut)
|
||||
|
||||
setTimeout(() => {
|
||||
msg.classList.remove(...fadeAnimOut)
|
||||
msg.classList.remove(...fadeAnimIn)
|
||||
}, 600)
|
||||
|
||||
}, 1500)
|
||||
}
|
||||
|
||||
function styleValue(/** @type {string} */ prop) {
|
||||
return prop.replace('px', '') * 1
|
||||
}
|
Loading…
Add table
Reference in a new issue