Rewritten in less, new floating menu, separated js
This commit is contained in:
parent
e0629a750a
commit
e9f60236a4
16 changed files with 1663 additions and 535 deletions
10
js/age.js
10
js/age.js
|
@ -1,10 +0,0 @@
|
|||
// Computing My Age
|
||||
// Вычисление моего возраста
|
||||
var birthday = new Date(2009, 7, 13, 13);
|
||||
try {
|
||||
// https://ru.stackoverflow.com/questions/576478/javascript-Вычисление-возраста-по-дате-рождения
|
||||
document.getElementById('age-js').innerHTML = Math.floor((Date.now() - birthday.getTime()) / (24 * 3600 * 365.25 * 1000));
|
||||
}
|
||||
catch (ex) {
|
||||
console.log('Произошла ошибка при попытке рендеринга моего возраста! Подробнее:\n' + ex.message);
|
||||
}
|
22
js/anim.js
Normal file
22
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
js/control.js
Normal file
19
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
js/handlers.js
Normal file
24
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)
|
69
js/init.js
Normal file
69
js/init.js
Normal file
|
@ -0,0 +1,69 @@
|
|||
function init() {
|
||||
initStars()
|
||||
computeAge()
|
||||
}
|
||||
|
||||
function initStars() {
|
||||
|
||||
const colors = [
|
||||
'#999','#9999ac','#ac9999','#acac99',
|
||||
'#bbb','#bbbbcf','#cfbbbb','#cfcfbb',
|
||||
'#eee','#e5e5ff','#ffe5e5','#ffffe5',
|
||||
'#fff'
|
||||
]
|
||||
const len = colors.length
|
||||
|
||||
const canvas = document.querySelector('canvas#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)
|
||||
}
|
76
js/menu.js
Normal file
76
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)
|
||||
}
|
136
js/script.js
136
js/script.js
|
@ -1,128 +1,32 @@
|
|||
function setupUi() {
|
||||
// Context Menu
|
||||
document.body.addEventListener('contextmenu', (e) => {
|
||||
var menu = document.querySelector('.context-menu');
|
||||
menu.style.top = e.pageY + 'px';
|
||||
menu.style.left = e.pageX + 'px';
|
||||
togglePopup(menu);
|
||||
e.preventDefault();
|
||||
return false;
|
||||
});
|
||||
// Hide Pop-ups
|
||||
document.body.addEventListener('click', () => {
|
||||
var popups = document.querySelectorAll('.popup');
|
||||
for (var i = 0; i < popups.length; i++) {
|
||||
togglePopup(popups[i], 0);
|
||||
}
|
||||
});
|
||||
// Initialize Hints
|
||||
var itemswh = document.querySelectorAll('.withhint');
|
||||
for (var j = 0; j < itemswh.length; j++) {
|
||||
itemswh[j].addEventListener('mouseover', showHint);
|
||||
//itemswh[j].addEventListener('mousemove', showHint);
|
||||
itemswh[j].addEventListener('mouseleave', hideHint);
|
||||
}
|
||||
};
|
||||
const body = document.body
|
||||
|
||||
function initStars() {
|
||||
var colors = ['#aaa','#ddd','#eee','#fff'];
|
||||
var canvas = document.querySelector('canvas#stars');
|
||||
var w = canvas.width;
|
||||
var h = canvas.height;
|
||||
var ctx = canvas.getContext('2d');
|
||||
ctx.clearRect(0, 0, w, h);
|
||||
for (var star = 0; star < 200; star++) {
|
||||
ctx.fillStyle = colors[Math.floor(Math.random()*colors.length)];
|
||||
ctx.fillRect(Math.round(Math.random()*w), Math.round(Math.random()*h), 1, 1);
|
||||
}
|
||||
};
|
||||
function copyLink(/** @type {Event} */ ev) {
|
||||
|
||||
function togglePopup(el, mode=1) {
|
||||
var displaying = (el.accessKey.trim() != '' && el.accessKey != '0');
|
||||
/** @type {HTMLSpanElement} */
|
||||
let elem = ev.currentTarget
|
||||
|
||||
if (mode != 1 && !displaying)
|
||||
return;
|
||||
navigator.clipboard.writeText(elem.dataset.link)
|
||||
|
||||
if (!displaying) {
|
||||
el.style.animation = 'tdExpandInBounce 0.3s ease 0s forwards';
|
||||
el.style.pointerEvents = 'auto';
|
||||
el.accessKey = '1';
|
||||
}
|
||||
else {
|
||||
el.style.animation = 'tdShrinkOutBounce 0.3s ease 0s forwards';
|
||||
el.style.pointerEvents = 'none';
|
||||
el.accessKey = '0';
|
||||
}
|
||||
};
|
||||
let wrapper = elem.parentElement.parentElement.parentElement
|
||||
let msg = wrapper.querySelector('.copied')
|
||||
|
||||
function showDiscordSubmenu(e) {
|
||||
var submenu = document.querySelector('li#item-discord').querySelector('nav.submenu');
|
||||
togglePopup(submenu);
|
||||
e.stopPropagation();
|
||||
};
|
||||
msg.classList.add(...fadeAnimIn)
|
||||
|
||||
function showAboutCard(e) {
|
||||
var about = document.querySelector('div.about-card-wrapper');
|
||||
togglePopup(about);
|
||||
e.stopPropagation();
|
||||
};
|
||||
|
||||
function copyDiscordTag(e) {
|
||||
var dtag = e.target.innerText;
|
||||
var text = document.createElement('textarea');
|
||||
text.style.position = 'absolute';
|
||||
text.style.left = '-9999px';
|
||||
text.style.top = '0';
|
||||
text.innerHTML = dtag;
|
||||
text.classList.add('copyarea');
|
||||
e.target.append(text);
|
||||
text.select();
|
||||
|
||||
document.execCommand('copy');
|
||||
setTimeout(() => {
|
||||
document.querySelector('textarea.copyarea').remove();
|
||||
togglePopup(document.querySelector('li#item-discord').querySelector('nav.submenu'));
|
||||
}, 100);
|
||||
|
||||
togglePopup(document.querySelector('.msg-wrapper'));
|
||||
setTimeout(() => {
|
||||
togglePopup(document.querySelector('.msg-wrapper'), 0);
|
||||
}, 1500);
|
||||
e.stopPropagation();
|
||||
};
|
||||
msg.classList.remove(...fadeAnimIn)
|
||||
|
||||
function changePicture(e, num) {
|
||||
var img = document.querySelector('.space-obj > img');
|
||||
switch (num) {
|
||||
case 0:
|
||||
img.src = 'img/earth.gif';
|
||||
break;
|
||||
case 1:
|
||||
img.src = 'img/moon.gif';
|
||||
break;
|
||||
case 2:
|
||||
img.src = 'img/sun.gif';
|
||||
break;
|
||||
}
|
||||
togglePopup(document.querySelector('.context-menu'));
|
||||
};
|
||||
msg.classList.add('show')
|
||||
msg.classList.add(...fadeAnimOut)
|
||||
|
||||
function spaceObjSpeed(spd) {
|
||||
document.querySelector('.space-obj>img').style.animationDuration = `${spd}s`;
|
||||
};
|
||||
setTimeout(() => {
|
||||
msg.classList.remove(...fadeAnimOut)
|
||||
msg.classList.remove(...fadeAnimIn)
|
||||
}, 600)
|
||||
|
||||
function showHint(e) {
|
||||
var elid = e.target.id;
|
||||
var hintid = 'hint-' + (elid.startsWith('item-') ? elid.slice(5) : 'elem');
|
||||
var hintel = document.getElementById(hintid);
|
||||
if (hintel)
|
||||
hintel.style.opacity = '1';
|
||||
};
|
||||
}, 1500)
|
||||
}
|
||||
|
||||
function hideHint(e) {
|
||||
var elid = e.target.id;
|
||||
var hintid = 'hint-' + (elid.startsWith('item-') ? elid.slice(5) : 'elem');
|
||||
var hintel = document.getElementById(hintid);
|
||||
if (hintel)
|
||||
hintel.style.opacity = '0';
|
||||
};
|
||||
function styleValue(/** @type {string} */ prop) {
|
||||
return prop.replace('px', '') * 1
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue