1export const beHereNowShadowScript = ` 2const rad = Math.PI / 180 3const norm = a => ((a % (2 * Math.PI)) + 2 * Math.PI) % (2 * Math.PI) 4const j2000 = date => date.getTime() / 864e5 + 2440587.5 - 2451545 6const horizontal = (date, lat, lng, ra, dec) => { 7 const d = j2000(date), phi = lat * rad 8 const gmst = norm((280.46061837 + 360.98564736629 * d) * rad) 9 const ha = gmst + lng * rad - norm(ra) 10 const sinAlt = Math.sin(phi) * Math.sin(dec) + Math.cos(phi) * Math.cos(dec) * Math.cos(ha) 11 const elevation = Math.asin(Math.max(-1, Math.min(1, sinAlt))) 12 const azimuth = norm(Math.atan2(Math.sin(ha), Math.cos(ha) * Math.sin(phi) - Math.tan(dec) * Math.cos(phi)) + Math.PI) 13 return { elevation, azimuth } 16const sunPos = (date, lat, lng) => { 18 const L = norm((280.460 + 0.9856474 * d) * rad) 19 const g = norm((357.528 + 0.9856003 * d) * rad) 20 const lambda = L + 1.915 * rad * Math.sin(g) + 0.020 * rad * Math.sin(2 * g) 21 const eps = (23.439 - 0.0000004 * d) * rad 22 const ra = Math.atan2(Math.cos(eps) * Math.sin(lambda), Math.cos(lambda)) 23 const dec = Math.asin(Math.sin(eps) * Math.sin(lambda)) 24 return horizontal(date, lat, lng, ra, dec) 27const moonPos = (date, lat, lng) => { 29 const mL = norm((218.316 + 13.176396 * d) * rad) 30 const mM = norm((134.963 + 13.064993 * d) * rad) 31 const mF = norm((93.272 + 13.229350 * d) * rad) 32 const lon = mL + 6.289 * rad * Math.sin(mM) - 1.274 * rad * Math.sin(2 * mF - 2 * mM) 33 const beta = 5.128 * rad * Math.sin(mF) 34 const eps = (23.439 - 0.0000004 * d) * rad 35 const ra = Math.atan2(Math.sin(lon) * Math.cos(eps) - Math.tan(beta) * Math.sin(eps), Math.cos(lon)) 36 const sinDec = Math.sin(beta) * Math.cos(eps) + Math.cos(beta) * Math.sin(eps) * Math.sin(lon) 37 const dec = Math.asin(Math.max(-1, Math.min(1, sinDec))) 38 const h = horizontal(date, lat, lng, ra, dec) 39 const sunL = norm((280.460 + 0.9856474 * d) * rad) 40 const sunG = norm((357.528 + 0.9856003 * d) * rad) 41 const sunLambda = sunL + 1.915 * rad * Math.sin(sunG) 42 const elong = Math.acos(Math.max(-1, Math.min(1, Math.cos(lon - sunLambda) * Math.cos(beta)))) 43 return Object.assign(h, { illumination: (1 - Math.cos(elong)) / 2 }) 46const VIEWING_AZ = 315 * rad 49 'America/New_York': [40.71, -74.01], 'America/Chicago': [41.88, -87.63], 50 'America/Denver': [39.74, -104.99], 'America/Los_Angeles': [34.05, -118.24], 51 'America/Anchorage': [61.22, -149.9], 'America/Sao_Paulo': [-23.55, -46.63], 52 'America/Mexico_City': [19.43, -99.13], 'America/Toronto': [43.65, -79.38], 53 'America/Vancouver': [49.28, -123.12], 'America/Buenos_Aires': [-34.61, -58.38], 54 'Europe/London': [51.51, -0.13], 'Europe/Paris': [48.86, 2.35], 55 'Europe/Berlin': [52.52, 13.4], 'Europe/Madrid': [40.42, -3.7], 56 'Europe/Rome': [41.9, 12.5], 'Europe/Amsterdam': [52.37, 4.9], 57 'Europe/Stockholm': [59.33, 18.07], 'Europe/Moscow': [55.76, 37.62], 58 'Europe/Istanbul': [41.01, 28.98], 'Asia/Tokyo': [35.68, 139.69], 59 'Asia/Shanghai': [31.23, 121.47], 'Asia/Hong_Kong': [22.32, 114.17], 60 'Asia/Singapore': [1.35, 103.82], 'Asia/Dubai': [25.2, 55.27], 61 'Asia/Seoul': [37.57, 126.98], 'Asia/Kolkata': [19.08, 72.88], 62 'Asia/Bangkok': [13.76, 100.5], 'Australia/Sydney': [-33.87, 151.21], 63 'Australia/Perth': [-31.95, 115.86], 'Pacific/Auckland': [-36.85, 174.76], 64 'Africa/Johannesburg': [-26.2, 28.05], 'Africa/Cairo': [30.04, 31.24], 68var getCoords = () => { 69 var tz = Intl.DateTimeFormat().resolvedOptions().timeZone 71 if (c) return { lat: c[0], lng: c[1] } 72 var offset = -new Date().getTimezoneOffset() / 60 73 return { lat: 40, lng: offset * 15 } 77 var figure = document.querySelector('.be-here-now-figure') 81 var sun = sunPos(now, loc.lat, loc.lng) 83 var elevation = Math.max(sun.elevation, 15 * rad), azimuth = sun.azimuth 85 var img = figure.querySelector('.be-here-now-img') 86 var imgH = (img && img.offsetHeight) || 300 87 var shadowLen = imgH / Math.tan(elevation) 88 var darkEnd = Math.min(100, shadowLen / 220 * 100) 90 var relAz = azimuth - VIEWING_AZ 91 var dx = Math.sin(relAz) 92 var dy = Math.max(0.15, Math.cos(relAz)) 93 var skew = Math.max(-15, Math.min(15, Math.atan(dx / dy) / rad)) 95 var opacity = Math.sin(elevation), r = 0, g = 0, b = 0 96 var warmth = Math.max(0, 1 - elevation / (15 * rad)) 97 r = Math.round(50 * warmth); g = Math.round(20 * warmth); b = Math.round(5 * warmth) 98 if (elevation < 2 * rad) opacity *= Math.max(0, elevation) / (2 * rad) 100 figure.style.setProperty('--bh-skew', skew.toFixed(2) + 'deg') 101 figure.style.setProperty('--bh-dark-end', darkEnd.toFixed(1) + '%') 102 figure.style.setProperty('--bh-opacity', opacity.toFixed(3)) 103 figure.style.setProperty('--bh-r', r) 104 figure.style.setProperty('--bh-g', g) 105 figure.style.setProperty('--bh-b', b) 109var img = document.querySelector('.be-here-now-img') 110if (img && !img.complete) img.addEventListener('load', update, { once: true }) 111setInterval(update, 60000) 112window.addEventListener('resize', update) 113document.addEventListener('visibilitychange', () => { if (!document.hidden) update() })