@ -1,5 +1,7 @@
window . glmdev = window . glmdev || { }
window . glmdev . themeStats = window . glmdev . themeStats || [ ]
window . glmdev . taglines = [
'...is proud that this site is Google-free' ,
'...is a supporter of FLOSS' ,
@ -20,7 +22,7 @@ window.glmdev.taglines = [
]
document . querySelector ( '#tagline' )
. addEventListener ( 'click' , event => {
? . addEventListener ( 'click' , event => {
if ( typeof glmdev . tagline _index === 'undefined' ) glmdev . tagline _index = 0
else if ( glmdev . tagline _index === glmdev . taglines . length - 1 ) glmdev . tagline _index = 0
else glmdev . tagline _index += 1
@ -29,7 +31,7 @@ document.querySelector('#tagline')
} )
document . querySelector ( '#timeline-view-all' )
. addEventListener ( 'click' , event => {
? . addEventListener ( 'click' , event => {
const hidden = document . querySelectorAll ( '.work-container.theme-hide' )
for ( const item of hidden ) {
item . classList . remove ( 'theme-hide' )
@ -37,3 +39,125 @@ document.querySelector('#timeline-view-all')
document . querySelector ( '#timeline-view-all' ) . classList . add ( 'theme-hide' )
} , false )
function getRandomArbitrary ( min , max ) {
min = Math . ceil ( min )
max = Math . floor ( max )
return Math . floor ( Math . random ( ) * ( max - min + 1 ) ) + min
}
const calculateMean = ( values ) => {
return ( values . reduce ( ( sum , current ) => sum + current ) ) / values . length ;
}
const calculateVariance = ( values ) => {
const average = calculateMean ( values ) ;
const squareDiffs = values . map ( ( value ) => {
const diff = value - average ;
return diff * diff ;
} ) ;
return calculateMean ( squareDiffs ) ;
}
const calculateStdev = ( values ) => {
return Math . sqrt ( calculateVariance ( values ) )
}
function calculateDistance ( ax , ay , bx , by ) {
return Math . sqrt ( Math . pow ( ax - bx , 2 ) + Math . pow ( ay - by , 2 ) )
}
function placeStars ( ) {
const widths = [ ]
const heights = [ ]
document . querySelectorAll ( '.stars svg' )
. forEach ( function ( star ) {
var width = window . innerWidth - 50
var height = ( window . innerHeight / 3 ) - 50
var widthOffset = getRandomArbitrary ( 50 , width )
var heightOffset = getRandomArbitrary ( 50 , height )
star . style . left = widthOffset + 'px'
star . style . top = heightOffset + 'px'
widths . push ( widthOffset )
heights . push ( heightOffset )
} )
return [ widths , heights ]
}
function isGoodStarPattern ( widths , heights ) {
const starCount = document . querySelectorAll ( '.stars svg' ) . length
const minWidthStdev = window . innerWidth / ( starCount / 1.5 )
const widthStdev = calculateStdev ( widths )
const minHeightStdev = ( window . innerHeight / 3 ) / ( starCount )
const heightStdev = calculateStdev ( heights )
const [ centroidWidth , centroidHeight ] = [ window . innerWidth / 2 , ( window . innerHeight / 3 ) / 2 ]
const distances = widths . map ( ( w , i ) => [ w , heights [ i ] ] )
. map ( ( [ w , h ] ) => calculateDistance ( w , h , centroidWidth , centroidHeight ) )
const minDistanceStdev = Math . min ( window . innerWidth , window . innerHeight ) / 10
const distanceStdev = calculateStdev ( distances )
return widthStdev > minWidthStdev && heightStdev > minHeightStdev && distanceStdev > minDistanceStdev
}
function placeStarsWithRetry ( ) {
if ( ! document . querySelectorAll ( '.stars svg' ) . length ) {
return
}
let tries = 30
do {
var [ widths , heights ] = placeStars ( )
tries -= 1
} while ( ! isGoodStarPattern ( widths , heights ) && tries > 0 )
const [ centroidWidth , centroidHeight ] = [ window . innerWidth / 2 , ( window . innerHeight / 3 ) / 2 ]
const distances = widths . map ( ( w , i ) => [ w , heights [ i ] ] )
. map ( ( [ w , h ] ) => calculateDistance ( w , h , centroidWidth , centroidHeight ) )
window . glmdev . themeStats . push (
` # of constellations generated: ${ 30 - tries } ` ,
` Width stdev: ${ Math . round ( calculateStdev ( widths ) ) } ` ,
` Height stdev: ${ Math . round ( calculateStdev ( heights ) ) } ` ,
` Distance stdev: ${ Math . round ( calculateStdev ( distances ) ) } `
)
}
window . placeStars = placeStars
window . isGoodStarPattern = isGoodStarPattern
window . placeStarsWithRetry = placeStarsWithRetry
placeStarsWithRetry ( )
function updateThemeStatsDisplay ( ) {
const ul = document . querySelector ( 'footer.theme-stats ul' )
for ( const stat of glmdev . themeStats ) {
const li = document . createElement ( 'li' )
li . innerText = stat
ul . appendChild ( li )
}
ul . style . display = glmdev . themeStats . length ? 'unset' : 'none'
}
var resizeDebufHandle = false
window . onresize = ( ) => {
if ( resizeDebufHandle ) {
clearTimeout ( resizeDebufHandle )
}
resizeDebufHandle = setTimeout ( ( ) => {
placeStarsWithRetry ( )
resizeDebufHandle = false
} , 500 )
}
window . updateThemeStatsDisplay = updateThemeStatsDisplay
updateThemeStatsDisplay ( )