257 lines
9.4 KiB
JavaScript
257 lines
9.4 KiB
JavaScript
var activeFlag = 'active';
|
|
var darkThemeFlag = 'dark';
|
|
var darkThemeIconFlag = 'dark-mode-icon';
|
|
var hashAttribute = 'data-hash';
|
|
var homePageHash = 'home';
|
|
var lightThemeFlag = 'light';
|
|
var lightThemeIconFlag = 'light-mode-icon';
|
|
var themeAttribute = 'data-theme';
|
|
var themeFlag = 'theme';
|
|
var themeIconFlag = 'theme-icon';
|
|
var themeSwitchFlag = 'theme-switch';
|
|
|
|
function hookupPage() {
|
|
hookupPageLocalStorage();
|
|
hookupNav();
|
|
hookupThemeSwitch();
|
|
hookupScroll();
|
|
// hookupProjectThumbnails();
|
|
hookupProjectDetailButtons();
|
|
hookupGitHubContributionsCalendar();
|
|
}
|
|
function hookupPageLocalStorage() {
|
|
let pageLocalStorage = getPageLocalStorage();
|
|
// Colour theme
|
|
let theme = pageLocalStorage[themeFlag];
|
|
if (!theme) {
|
|
let prefersDark = window.matchMedia(`(prefers-color-scheme: ${darkThemeFlag})`).matches;
|
|
theme = prefersDark ? darkThemeFlag : lightThemeFlag;
|
|
}
|
|
setPageTheme(theme);
|
|
}
|
|
function getPageLocalStorage() {
|
|
let pageHash = getPageHash();
|
|
let pageLocalStorage = localStorage.getItem(pageHash);
|
|
let decodedPageLocalStorage;
|
|
if (pageLocalStorage) {
|
|
decodedPageLocalStorage = JSON.parse(pageLocalStorage);
|
|
}
|
|
else {
|
|
decodedPageLocalStorage = {};
|
|
}
|
|
return decodedPageLocalStorage;
|
|
}
|
|
function getPageHash() {
|
|
return document.documentElement.getAttribute(hashAttribute) || homePageHash;
|
|
}
|
|
function setPageTheme(theme) {
|
|
document.documentElement.setAttribute(themeAttribute, theme);
|
|
let pageLocalStorage = getPageLocalStorage();
|
|
pageLocalStorage[themeFlag] = theme;
|
|
setPageLocalStorage(pageLocalStorage);
|
|
}
|
|
function setPageLocalStorage(pageLocalStorage) {
|
|
let pageHash = getPageHash();
|
|
localStorage.setItem(pageHash, JSON.stringify(pageLocalStorage));
|
|
}
|
|
function hookupNav() {
|
|
hookupNavLinks();
|
|
// Google Translate feature hooked up by plugin call
|
|
}
|
|
function hookupNavLinks() {
|
|
document.querySelectorAll('nav a').forEach(anchor => {
|
|
anchor.addEventListener('click', function(e) {
|
|
e.preventDefault();
|
|
const section = document.querySelector(this.getAttribute('href'));
|
|
section.scrollIntoView({
|
|
behavior: 'smooth'
|
|
});
|
|
});
|
|
});
|
|
}
|
|
function hookupThemeSwitch() {
|
|
makeLightThemeIcon();
|
|
/*
|
|
let themeSwitch = document.querySelector('#' + themeSwitchId);
|
|
themeSwitch.addEventListener('click', function() {
|
|
let theme = document.documentElement.getAttribute(themeAttribute);
|
|
let newTheme = theme === darkThemeFlag ? lightThemeFlag : darkThemeFlag;
|
|
setPageTheme(newTheme);
|
|
});
|
|
*/
|
|
let themeSwitch = getThemeSwitchButton();
|
|
themeSwitch.addEventListener('click', function() {
|
|
let theme = getPageTheme();
|
|
let newTheme = theme === darkThemeFlag ? lightThemeFlag : darkThemeFlag;
|
|
setPageTheme(newTheme);
|
|
});
|
|
}
|
|
function makeLightThemeIcon() {
|
|
let themeSwitch = getThemeSwitchButton();
|
|
const backgroundRadius = 500;
|
|
const sunRadius = 250;
|
|
// const sunColour = "var(--text-colour)"; // "var(--text-background-colour)";
|
|
// const backgroundColour = "var(--secondary-colour)";
|
|
|
|
// Create the SVG element
|
|
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
svg.setAttribute("xmlns", "http://www.w3.org/2000/svg");
|
|
svg.setAttribute("viewBox", "0 0 1000 1000");
|
|
svg.classList.add(themeIconFlag);
|
|
svg.classList.add(lightThemeIconFlag);
|
|
|
|
// Create the background circle
|
|
const background = document.createElementNS("http://www.w3.org/2000/svg", "circle");
|
|
background.setAttribute("cx", backgroundRadius);
|
|
background.setAttribute("cy", backgroundRadius);
|
|
background.setAttribute("r", backgroundRadius);
|
|
// background.setAttribute("fill", backgroundColour);
|
|
background.setAttribute("class", "background");
|
|
|
|
// Create the sun body
|
|
const sunBody = document.createElementNS("http://www.w3.org/2000/svg", "circle");
|
|
sunBody.setAttribute("cx", backgroundRadius);
|
|
sunBody.setAttribute("cy", backgroundRadius);
|
|
sunBody.setAttribute("r", sunRadius);
|
|
// sunBody.setAttribute("fill", sunColour);
|
|
sunBody.setAttribute("class", "sun");
|
|
|
|
// Add background and sun body to the SVG
|
|
svg.appendChild(background);
|
|
svg.appendChild(sunBody);
|
|
|
|
// Parameters for rays
|
|
const centerX = 500;
|
|
const centerY = 500;
|
|
const numberOfRays = 8;
|
|
const rayRadialSpacing = 75;
|
|
const innerRadius = sunRadius + rayRadialSpacing; // Where the sun body ends
|
|
const outerRadius = sunRadius + rayRadialSpacing + (backgroundRadius - sunRadius - rayRadialSpacing) * 0.5; // Where the rays extend to
|
|
const strokeWidth = 75;
|
|
|
|
// Create rays using a loop and trigonometry
|
|
for (let i = 0; i < numberOfRays; i++) {
|
|
// Calculate angle in radians
|
|
const angle = (i * 2 * Math.PI) / numberOfRays;
|
|
|
|
// Calculate start point (inner circle)
|
|
const startX = centerX + innerRadius * Math.cos(angle);
|
|
const startY = centerY + innerRadius * Math.sin(angle);
|
|
|
|
// Calculate end point (outer radius)
|
|
const endX = centerX + outerRadius * Math.cos(angle);
|
|
const endY = centerY + outerRadius * Math.sin(angle);
|
|
|
|
// Create the line element
|
|
const line = document.createElementNS("http://www.w3.org/2000/svg", "line");
|
|
line.setAttribute("x1", startX);
|
|
line.setAttribute("y1", startY);
|
|
line.setAttribute("x2", endX);
|
|
line.setAttribute("y2", endY);
|
|
// line.setAttribute("stroke", sunColour);
|
|
line.setAttribute("class", "sun");
|
|
line.setAttribute("stroke-width", strokeWidth);
|
|
line.setAttribute("stroke-linecap", "round");
|
|
|
|
// Append the line to the SVG
|
|
svg.appendChild(line);
|
|
}
|
|
|
|
// Append the completed SVG to the container
|
|
themeSwitch.appendChild(svg);
|
|
}
|
|
function getThemeSwitchButton() {
|
|
return document.querySelector('button.' + themeSwitchFlag);
|
|
}
|
|
function getPageTheme() {
|
|
return document.documentElement.getAttribute(themeAttribute);
|
|
}
|
|
function hookupScroll() {
|
|
window.addEventListener('scroll', function() {
|
|
const sections = document.querySelectorAll('section');
|
|
const navLinks = document.querySelectorAll('nav a');
|
|
|
|
let current = '';
|
|
|
|
sections.forEach(section => {
|
|
const sectionTop = section.offsetTop;
|
|
if (scrollY >= sectionTop - 60) {
|
|
current = section.getAttribute('id');
|
|
}
|
|
});
|
|
|
|
navLinks.forEach(link => {
|
|
link.classList.remove(activeFlag);
|
|
if (link.getAttribute('href').substring(1) === current) {
|
|
link.classList.add(activeFlag);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
/*
|
|
function hookupProjectThumbnails() {
|
|
let demoButtonSelector = '.project-links .button';
|
|
document.querySelectorAll(demoButtonSelector).forEach(demoButton => {
|
|
let projectName = getProjectNameFromDemoButton(demoButton);
|
|
demoButton.addEventListener('mouseover', function() {
|
|
let projectName = getProjectNameFromDemoButton(this);
|
|
let thumbnailContainer = getProjectThumbnailContainer(projectName);
|
|
thumbnailContainer.classList.add(activeFlag);
|
|
});
|
|
demoButton.addEventListener('mouseout', function() {
|
|
let projectName = getProjectNameFromDemoButton(this);
|
|
let thumbnailContainer = getProjectThumbnailContainer(projectName);
|
|
thumbnailContainer.classList.remove(activeFlag);
|
|
});
|
|
});
|
|
}
|
|
function getProjectNameFromDemoButton(demoButton) {
|
|
let projectName = demoButton.getAttribute('data-project');
|
|
return projectName;
|
|
}
|
|
function getProjectThumbnailContainer(projectName) {
|
|
let container = document.querySelector(`div.project-thumbnail[data-project="${projectName}"]`);
|
|
return container;
|
|
}
|
|
*/
|
|
function hookupProjectDetailButtons() {
|
|
let detailButtonSelector = '.project-detail-button';
|
|
document.querySelectorAll(detailButtonSelector).forEach(detailButton => {
|
|
detailButton.addEventListener('click', function() {
|
|
let projectDetailContainer = this.parentElement.querySelector('.project-detail-container');
|
|
let wasActive = projectDetailContainer.classList.contains(activeFlag);
|
|
if (wasActive) {
|
|
projectDetailContainer.classList.remove(activeFlag);
|
|
detailButton.innerText = 'Show Details';
|
|
}
|
|
else {
|
|
projectDetailContainer.classList.add(activeFlag);
|
|
detailButton.innerText = 'Hide Details';
|
|
}
|
|
});
|
|
});
|
|
}
|
|
function hookupGitHubContributionsCalendar() {
|
|
// Basic implementation
|
|
// e - statistics are all 0
|
|
GitHubCalendar(".github-calendar", "Teddy-1024");
|
|
|
|
// Or with responsive option enabled:
|
|
// e - statistics are all 0
|
|
// GitHubCalendar(".github-calendar", "Teddy-1024", { responsive: true });
|
|
|
|
/*
|
|
// Or with proxy option enabled:
|
|
// e - statistics are all 0
|
|
GitHubCalendar(".github-calendar", "Teddy-1024", {
|
|
responsive: true,
|
|
proxy: function(username) {
|
|
return fetch(`https://cors-anywhere.herokuapp.com/https://github.com/users/${username}/contributions`)
|
|
.then(response => response.text());
|
|
}
|
|
});
|
|
*/
|
|
|
|
const scrollableElement = document.querySelector('.github-calendar .js-calendar-graph-table');
|
|
scrollableElement.scrollLeft = scrollableElement.scrollWidth - scrollableElement.clientWidth;
|
|
} |