Files
portfolio/scripts/scripts.js

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;
}