2023-10-14 23:14:04 -04:00
// <CRYPTO_DONATION>
2023-09-03 23:48:44 -04:00
var donateButton = document . getElementById ( 'donateButton' ) ;
var card = document . getElementById ( 'card' ) ;
donateButton . addEventListener ( 'click' , function ( event ) {
event . stopPropagation ( ) ;
if ( card . classList . contains ( 'card-out' ) ) {
card . classList . remove ( 'card-out' ) ;
card . classList . add ( 'card-in' ) ;
} else {
card . classList . remove ( 'card-in' ) ;
card . classList . add ( 'card-out' ) ;
}
} ) ;
window . addEventListener ( 'click' , function ( event ) {
if ( event . target === card || card . contains ( event . target ) ) {
return ;
}
if ( card . classList . contains ( 'card-in' ) ) {
card . classList . remove ( 'card-in' ) ;
card . classList . add ( 'card-out' ) ;
}
} ) ;
var cryptoWallets = [
{
symbol : 'XMR' ,
name : 'Monero' ,
address : '49r2aeun8DtV5VqZpZSwRpS83WfUWEaLt4NG8HJwwVkbiT1vSsXTXrPFKkKTdc6MPX9iezbTidNPvhGZKCnM1338TfK6Hgi' ,
} ,
{
symbol : 'LTC' ,
name : 'Litecoin' ,
address : 'LRAm7h5XENknfYEpbdVsvyGY8D6MiXGTDV' ,
} ,
{
symbol : 'BTC' ,
name : 'Bitcoin' ,
address : 'bc1qkv97ajh7f0a72l9rsjd3fmmly5q5uywr06q3x0' ,
}
] ;
var walletsContainer = document . getElementById ( 'wallets' ) ;
var qrImage = document . getElementById ( 'qrImage' ) ;
var donateTitle = document . getElementById ( 'donateTitle' ) ;
var donateWarn = document . getElementById ( 'donateWarn' ) ;
var walletAddress = document . getElementById ( 'walletAddress' ) ;
var copyButton = document . getElementById ( 'copyButton' ) ;
function selectWallet ( symbol ) {
var wallet = cryptoWallets . find ( function ( w ) {
return w . symbol === symbol ;
} ) ;
if ( ! wallet ) return ;
var buttons = Array . from ( walletsContainer . children ) ;
buttons . forEach ( function ( button ) {
button . classList . remove ( 'active' ) ;
if ( button . textContent === symbol ) {
button . classList . add ( 'active' ) ;
}
} ) ;
qrImage . src = 'https://api.qrserver.com/v1/create-qr-code/?size=180x180&data=' + wallet . address ;
donateTitle . textContent = 'Donate ' + wallet . name ;
donateWarn . textContent = 'Send only ' + wallet . name + ' (' + wallet . symbol + ') to this deposit address. Sending any other coin or token to this address may result in the loss of your donation. Thanks!' ;
walletAddress . value = wallet . address ;
2023-10-14 23:14:04 -04:00
copyButton . textContent = '✚ Copy' ;
2023-09-03 23:48:44 -04:00
}
function copyText ( ) {
var input = document . createElement ( 'input' ) ;
document . body . appendChild ( input ) ;
input . value = walletAddress . value ;
input . select ( ) ;
document . execCommand ( 'copy' ) ;
document . body . removeChild ( input ) ;
2023-10-14 23:14:04 -04:00
copyButton . textContent = '✔ Copied' ;
2023-09-03 23:48:44 -04:00
}
cryptoWallets . forEach ( function ( wallet ) {
var button = document . createElement ( 'button' ) ;
button . textContent = wallet . symbol ;
button . addEventListener ( 'click' , function ( ) {
selectWallet ( wallet . symbol ) ;
} ) ;
walletsContainer . appendChild ( button ) ;
} ) ;
copyButton . addEventListener ( 'click' , copyText ) ;
selectWallet ( cryptoWallets [ 0 ] . symbol ) ;
2023-10-14 23:14:04 -04:00
// </CRYPTO_DONATION>
let globalUniforms = {
time : { value : 0 }
} ;
import * as THREE from "https://cdn.skypack.dev/three@0.136.0" ;
import { OrbitControls } from "https://cdn.skypack.dev/three@0.136.0/examples/jsm/controls/OrbitControls" ;
import { CSS2DRenderer , CSS2DObject } from 'https://cdn.skypack.dev/three@0.136.0/examples/jsm/renderers/CSS2DRenderer.js' ;
let scene = new THREE . Scene ( ) ;
let camera = new THREE . PerspectiveCamera ( 45 , innerWidth / innerHeight , 1 , 2000 ) ;
camera . position . set ( - 5 , 4 , - 0.8 ) . setLength ( 14 ) ;
let renderer = new THREE . WebGLRenderer ( {
antialias : true
} ) ;
renderer . setSize ( innerWidth , innerHeight ) ;
renderer . setClearColor ( 0x241917 ) ;
document . body . appendChild ( renderer . domElement ) ;
let labelRenderer = new CSS2DRenderer ( ) ;
labelRenderer . setSize ( window . innerWidth , window . innerHeight ) ;
labelRenderer . domElement . style . position = 'absolute' ;
labelRenderer . domElement . style . top = '0px' ;
document . body . appendChild ( labelRenderer . domElement ) ;
window . addEventListener ( "resize" , onWindowResize ) ;
let controls = new OrbitControls ( camera , labelRenderer . domElement ) ;
controls . enablePan = false ;
controls . minDistance = 8 ;
controls . maxDistance = 10 ;
controls . enableDamping = true ;
controls . autoRotate = false ;
// <GLOBE>
let counter = 200000 ;
let rad = 5 ;
let sph = new THREE . Spherical ( ) ;
let r = 0 ;
let dlong = Math . PI * ( 3 - Math . sqrt ( 5 ) ) ;
let dz = 2 / counter ;
let long = 0 ;
let z = 1 - dz / 2 ;
let pts = [ ] ;
let clr = [ ] ;
let c = new THREE . Color ( ) ;
let uvs = [ ] ;
for ( let i = 0 ; i < counter ; i ++ ) {
r = Math . sqrt ( 1 - z * z ) ;
let p = new THREE . Vector3 (
Math . cos ( long ) * r ,
z ,
- Math . sin ( long ) * r
) . multiplyScalar ( rad ) ;
pts . push ( p ) ;
z = z - dz ;
long = long + dlong ;
c . setHSL ( 0.45 , 0.5 , Math . random ( ) * 0.25 + 0.25 ) ;
c . toArray ( clr , i * 3 ) ;
sph . setFromVector3 ( p ) ;
uvs . push ( ( sph . theta + Math . PI ) / ( Math . PI * 2 ) , 1.0 - sph . phi / Math . PI ) ;
}
let g = new THREE . BufferGeometry ( ) . setFromPoints ( pts ) ;
g . setAttribute ( "color" , new THREE . Float32BufferAttribute ( clr , 3 ) ) ;
g . setAttribute ( "uv" , new THREE . Float32BufferAttribute ( uvs , 2 ) ) ;
let m = new THREE . PointsMaterial ( {
size : 0.1 ,
vertexColors : false ,
color : new THREE . Color ( 0x743c2f ) ,
onBeforeCompile : ( shader ) => {
shader . uniforms . globeTexture = {
value : new THREE . TextureLoader ( ) . load ( imgData )
} ;
shader . vertexShader = `
uniform sampler2D globeTexture ;
varying float vVisibility ;
varying vec3 vNormal ;
varying vec3 vMvPosition ;
$ { shader . vertexShader }
` .replace(
` gl_PointSize = size; ` ,
`
vVisibility = texture ( globeTexture , uv ) . g ;
gl _PointSize = size * ( vVisibility < 0.5 ? 1. : 0.75 ) ;
vNormal = normalMatrix * normalize ( position ) ;
vMvPosition = - mvPosition . xyz ;
gl _PointSize *= 0.4 + ( dot ( normalize ( vMvPosition ) , vNormal ) * 0.6 ) ;
`
) ;
shader . fragmentShader = `
varying float vVisibility ;
varying vec3 vNormal ;
varying vec3 vMvPosition ;
$ { shader . fragmentShader }
` .replace(
` vec4 diffuseColor = vec4( diffuse, opacity ); ` ,
`
bool circ = length ( gl _PointCoord - 0.5 ) > 0.5 ;
bool vis = dot ( vMvPosition , vNormal ) < 0. ;
if ( circ || vis ) discard ;
vec3 col = diffuse + ( vVisibility > 0.5 ? 0.5 : 0. ) ;
vec4 diffuseColor = vec4 ( col , opacity ) ; `
) ;
}
} ) ;
let globe = new THREE . Points ( g , m ) ;
scene . add ( globe ) ;
// </GLOBE>
// <LABEL>
const pinGeometryAtlanta = new THREE . SphereGeometry ( 0.05 , 32 , 32 ) ;
const pinMaterialAtlanta = new THREE . MeshBasicMaterial ( { color : 0x31302c } ) ;
const pinMeshAtlanta = new THREE . Mesh ( pinGeometryAtlanta , pinMaterialAtlanta ) ;
const labelDivAtlanta = document . createElement ( 'div' ) ;
labelDivAtlanta . className = 'label-atl' ;
labelDivAtlanta . textContent = 'Atlanta' ;
const labelObjectAtlanta = new CSS2DObject ( labelDivAtlanta ) ;
const pinLatitudeAtlanta = 33.74932660 ;
const pinLongitudeAtlanta = - 95.39035664 ;
const sphericalAtlanta = new THREE . Spherical ( ) ;
sphericalAtlanta . phi = ( 90 - pinLatitudeAtlanta ) * ( Math . PI / 180 ) ;
sphericalAtlanta . theta = ( 180 - pinLongitudeAtlanta ) * ( Math . PI / 180 ) ;
sphericalAtlanta . radius = 5 ;
const positionAtlanta = new THREE . Vector3 ( ) ;
positionAtlanta . setFromSpherical ( sphericalAtlanta ) ;
pinMeshAtlanta . position . copy ( positionAtlanta ) ;
labelObjectAtlanta . position . copy ( positionAtlanta ) ;
scene . add ( pinMeshAtlanta ) ;
scene . add ( labelObjectAtlanta ) ;
// San Jose
const pinGeometrySanJose = new THREE . SphereGeometry ( 0.05 , 32 , 32 ) ;
const pinMaterialSanJose = new THREE . MeshBasicMaterial ( { color : 0x31302c } ) ;
const pinMeshSanJose = new THREE . Mesh ( pinGeometrySanJose , pinMaterialSanJose ) ;
const labelDivSanJose = document . createElement ( 'div' ) ;
labelDivSanJose . className = 'label-san' ;
labelDivSanJose . textContent = 'San Jose' ;
const labelObjectSanJose = new CSS2DObject ( labelDivSanJose ) ;
const pinLatitudeSanJose = 38 ;
const pinLongitudeSanJose = - 58 ;
const sphericalSanJose = new THREE . Spherical ( ) ;
sphericalSanJose . phi = ( 90 - pinLatitudeSanJose ) * ( Math . PI / 180 ) ;
sphericalSanJose . theta = ( 180 - pinLongitudeSanJose ) * ( Math . PI / 180 ) ;
sphericalSanJose . radius = 5 ;
const positionSanJose = new THREE . Vector3 ( ) ;
positionSanJose . setFromSpherical ( sphericalSanJose ) ;
pinMeshSanJose . position . copy ( positionSanJose ) ;
labelObjectSanJose . position . copy ( positionSanJose ) ;
scene . add ( pinMeshSanJose ) ;
scene . add ( labelObjectSanJose ) ;
// Vint Hill
const pinGeometryVintHill = new THREE . SphereGeometry ( 0.05 , 32 , 32 ) ;
const pinMaterialVintHill = new THREE . MeshBasicMaterial ( { color : 0x31302c } ) ;
const pinMeshVintHill = new THREE . Mesh ( pinGeometryVintHill , pinMaterialVintHill ) ;
const labelDivVintHill = document . createElement ( 'div' ) ;
labelDivVintHill . className = 'label-vint' ;
labelDivVintHill . textContent = 'Vint Hill' ;
const labelObjectVintHill = new CSS2DObject ( labelDivVintHill ) ;
const pinLatitudeVintHill = 38 ;
const pinLongitudeVintHill = - 101 ;
const sphericalVintHill = new THREE . Spherical ( ) ;
sphericalVintHill . phi = ( 90 - pinLatitudeVintHill ) * ( Math . PI / 180 ) ;
sphericalVintHill . theta = ( 180 - pinLongitudeVintHill ) * ( Math . PI / 180 ) ;
sphericalVintHill . radius = 5 ;
const positionVintHill = new THREE . Vector3 ( ) ;
positionVintHill . setFromSpherical ( sphericalVintHill ) ;
pinMeshVintHill . position . copy ( positionVintHill ) ;
labelObjectVintHill . position . copy ( positionVintHill ) ;
scene . add ( pinMeshVintHill ) ;
scene . add ( labelObjectVintHill ) ;
// Chicago
const pinGeometryChicago = new THREE . SphereGeometry ( 0.05 , 32 , 32 ) ;
const pinMaterialChicago = new THREE . MeshBasicMaterial ( { color : 0x31302c } ) ;
const pinMeshChicago = new THREE . Mesh ( pinGeometryChicago , pinMaterialChicago ) ;
const labelDivChicago = document . createElement ( 'div' ) ;
labelDivChicago . className = 'label-cha' ;
labelDivChicago . textContent = 'Chicago' ;
const labelObjectChicago = new CSS2DObject ( labelDivChicago ) ;
const pinLatitudeChicago = 42 ;
const pinLongitudeChicago = - 92.5 ;
const sphericalChicago = new THREE . Spherical ( ) ;
sphericalChicago . phi = ( 90 - pinLatitudeChicago ) * ( Math . PI / 180 ) ;
sphericalChicago . theta = ( 180 - pinLongitudeChicago ) * ( Math . PI / 180 ) ;
sphericalChicago . radius = 5 ;
const positionChicago = new THREE . Vector3 ( ) ;
positionChicago . setFromSpherical ( sphericalChicago ) ;
pinMeshChicago . position . copy ( positionChicago ) ;
labelObjectChicago . position . copy ( positionChicago ) ;
scene . add ( pinMeshChicago ) ;
scene . add ( labelObjectChicago ) ;
// New York
const pinGeometryNewYork = new THREE . SphereGeometry ( 0.05 , 32 , 32 ) ;
const pinMaterialNewYork = new THREE . MeshBasicMaterial ( { color : 0x31302c } ) ;
const pinMeshNewYork = new THREE . Mesh ( pinGeometryNewYork , pinMaterialNewYork ) ;
const labelDivNewYork = document . createElement ( 'div' ) ;
labelDivNewYork . className = 'label-york' ;
labelDivNewYork . textContent = 'New York' ;
const labelObjectNewYork = new CSS2DObject ( labelDivNewYork ) ;
const pinLatitudeNewYork = 40 ;
const pinLongitudeNewYork = - 105 ;
const sphericalNewYork = new THREE . Spherical ( ) ;
sphericalNewYork . phi = ( 90 - pinLatitudeNewYork ) * ( Math . PI / 180 ) ;
sphericalNewYork . theta = ( 180 - pinLongitudeNewYork ) * ( Math . PI / 180 ) ;
sphericalNewYork . radius = 5 ;
const positionNewYork = new THREE . Vector3 ( ) ;
positionNewYork . setFromSpherical ( sphericalNewYork ) ;
pinMeshNewYork . position . copy ( positionNewYork ) ;
labelObjectNewYork . position . copy ( positionNewYork ) ;
scene . add ( pinMeshNewYork ) ;
scene . add ( labelObjectNewYork ) ;
// ARCS
function renderArc ( startPosition , endPosition ) {
const curve = new THREE . QuadraticBezierCurve3 (
startPosition ,
new THREE . Vector3 (
( startPosition . x + endPosition . x ) / 1.8 ,
( startPosition . y + endPosition . y ) / 1.8 ,
( startPosition . z + endPosition . z ) / 2
) ,
endPosition
) ;
const points = curve . getPoints ( 50 ) ;
const geometry = new THREE . BufferGeometry ( ) . setFromPoints ( points ) ;
const material = new THREE . LineBasicMaterial ( { color : 0xffffff } ) ;
const arc = new THREE . Line ( geometry , material ) ;
scene . add ( arc ) ;
}
renderArc ( positionAtlanta , positionSanJose ) ;
renderArc ( positionAtlanta , positionNewYork ) ;
renderArc ( positionAtlanta , positionVintHill ) ;
renderArc ( positionAtlanta , positionChicago ) ;
renderArc ( positionSanJose , positionNewYork ) ;
renderArc ( positionSanJose , positionVintHill ) ;
renderArc ( positionSanJose , positionChicago ) ;
renderArc ( positionNewYork , positionVintHill ) ;
renderArc ( positionNewYork , positionChicago ) ;
// </LABEL>
let clock = new THREE . Clock ( ) ;
renderer . setAnimationLoop ( ( ) => {
let t = clock . getElapsedTime ( ) ;
globalUniforms . time . value = t ;
controls . update ( ) ;
renderer . render ( scene , camera ) ;
labelRenderer . render ( scene , camera ) ;
2023-09-03 23:48:44 -04:00
} ) ;
2023-10-14 23:14:04 -04:00
function onWindowResize ( ) {
camera . aspect = innerWidth / innerHeight ;
camera . updateProjectionMatrix ( ) ;
renderer . setSize ( innerWidth , innerHeight ) ;
labelRenderer . setSize ( innerWidth , innerHeight ) ;
}