421 lines
No EOL
12 KiB
JavaScript
Executable file
421 lines
No EOL
12 KiB
JavaScript
Executable file
// <CRYPTO_DONATION>
|
|
|
|
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;
|
|
copyButton.textContent = "✚ Copy";
|
|
}
|
|
|
|
function copyText() {
|
|
var input = document.createElement("input");
|
|
document.body.appendChild(input);
|
|
input.value = walletAddress.value;
|
|
input.select();
|
|
document.execCommand("copy");
|
|
document.body.removeChild(input);
|
|
copyButton.textContent = "✔ Copied";
|
|
}
|
|
|
|
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);
|
|
|
|
// </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 = 12;
|
|
controls.enableDamping = true;
|
|
controls.autoRotate = false;
|
|
|
|
// <GLOBE>
|
|
|
|
let counter = 30000;
|
|
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.16,
|
|
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.7493266;
|
|
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);
|
|
});
|
|
|
|
function onWindowResize() {
|
|
camera.aspect = innerWidth / innerHeight;
|
|
camera.updateProjectionMatrix();
|
|
renderer.setSize(innerWidth, innerHeight);
|
|
labelRenderer.setSize(innerWidth, innerHeight);
|
|
} |