A Pen by Chris Shier on CodePen.
Created
August 29, 2022 23:04
-
-
Save cshier/b9323067fb6b70d7f170831de7f33a31 to your computer and use it in GitHub Desktop.
trivision-public (test)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src="https://js.upload.io/upload-js/v1"></script> | |
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/tweakpane.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/0.139.1/three.min.js"></script> | |
<div id="scene-container"></div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// import { Upload } from "upload-js"; | |
// import uploadJs from 'https://cdn.skypack.dev/upload-js'; | |
// import Pane from "https://cdn.skypack.dev/[email protected]"; | |
// import * as THREE from "https://cdn.skypack.dev/[email protected]"; | |
// import * as Upload from "https://cdn.skypack.dev/[email protected]"; | |
/* | |
TODO: | |
Screenshot resolution | |
Controls cleanup | |
Image upload | |
Set up backblaze hosting | |
Shareable URL | |
Find & select hashing function or use DB ref | |
*/ | |
// import OrbitControls from "three-orbitcontrols"; | |
// import { getGPUTier } from "detect-gpu"; | |
// import { Pane } from "./tweakpane-3.1.0.min.js"; | |
const upload = new Upload({ apiKey: "public_FW25au8414mD1b8ErD179P3JNWyv" }); | |
// const { MongoClient } = require("mongodb"); | |
// // Connection URI | |
// const uri = | |
// "mongodb+srv://trivision:[email protected]/?retryWrites=true&w=majority"; | |
// // Create a new MongoClient | |
// const client = new MongoClient(uri); | |
// async function run() { | |
// try { | |
// // Connect the client to the server (optional starting in v4.7) | |
// await client.connect(); | |
// // Establish and verify connection | |
// await client.db("admin").command({ ping: 1 }); | |
// console.log("Connected successfully to server"); | |
// } finally { | |
// // Ensures that the client will close when you finish/error | |
// await client.close(); | |
// } | |
// } | |
// run().catch(console.dir); | |
// console.clear(); | |
const cfg = { | |
slat: { | |
count: 13, | |
width: 0.75, | |
height: 50, | |
spread: 1.2, | |
radius: 1 / 3.5, | |
rFreq: 0, | |
rRate: 0.0025, | |
rRot: 0, | |
rTime: 0, | |
colourA: "rgb(255,0,0)", | |
colourB: "rgb(0,255,0)", | |
colourC: "rgb(0,0,255)", | |
time: 0.0011, | |
play: 1, | |
now: 0, | |
time1: 0, | |
time2: 0, | |
wave1: { x: 2.35, y: 1.18 }, | |
wave2: { x: -2.65, y: -0.29 } | |
}, | |
tex: [ | |
{ | |
// src: "https://i.imgur.com/8aX47FA.png", | |
// src: "https://82xup.csb.app/img/layer1small.png", | |
// src: "/img/layer1small.png", | |
src: "https://upcdn.io/FW25au8UtuPXoWf3PfU8gh4", | |
rep: { u: 16 / 9 / 40, t: 1 }, | |
off: { x: 0, y: 0 } | |
}, | |
{ | |
// src: "https://i.imgur.com/ticsWCb.png", | |
// src: "/img/layer2.png", | |
src: "https://upcdn.io/FW25au8XNu4cNyFQJ5474Ke", | |
rep: { u: 16 / 9 / 40, t: 1 }, | |
off: { x: 0, y: 0 } | |
}, | |
{ | |
// src: "https://i.imgur.com/1AqgzIF.png", | |
// src: "/img/layer3small.png", | |
src: "https://upcdn.io/FW25au822kovm1bLqxHyErT", | |
rep: { u: 16 / 9 / 40, t: 1 }, | |
off: { x: 0, y: 0 } | |
} | |
], | |
scene: { | |
mainLight: 1 | |
}, | |
camera: { | |
near: 0.1, | |
far: 0, | |
zoom: 2 | |
}, | |
bg: { | |
url: "/img/bghires.png" | |
}, | |
title: "Default", | |
preset: "", | |
outputSize: { x: window.innerWidth, y: window.innerHeight } | |
}; | |
function hidePane(e) { | |
if (e.key === "`") { | |
pane.hidden = !pane.hidden; | |
} | |
} | |
window.addEventListener("keydown", hidePane); | |
const pane = new Tweakpane.Pane({ | |
hidden: false, | |
expanded: true | |
}); | |
pane.folders = {}; | |
pane.folders.slats = pane.addFolder({ | |
title: "Slats", | |
expanded: true | |
}); | |
pane.folders.tex = pane.addFolder({ | |
title: "Textures", | |
expanded: true, | |
hidden: false | |
}); | |
pane.folders.bg = pane.addFolder({ | |
title: "background", | |
expanded: true, | |
hidden: true | |
}); | |
pane.folders.waves = pane.addFolder({ | |
title: "Waves", | |
hidden: false, | |
index: 0 | |
}); | |
// pane.folders.waves.addMonitor(cfg.slat, "now"); | |
pane.folders.waves.addInput(cfg.slat, "time", { | |
min: -0.05, | |
max: 0.05, | |
presetKey: "time" | |
}); | |
pane.folders.waves.addInput(cfg.slat, "wave1", { presetKey: "wave1" }); | |
// pane.folders.waves.addMonitor(cfg.slat, "time1", { presetKey: "time1" }); | |
pane.folders.waves.addInput(cfg.slat, "wave2", { presetKey: "wave2" }); | |
// pane.folders.waves.addMonitor(cfg.slat, "time2", { presetKey: "wave2" }); | |
pane.pauseButton = pane.folders.waves.addButton({ | |
title: "Pause" | |
}); | |
pane.pauseButton.count = 0; | |
pane.pauseButton.on("click", () => { | |
pane.pauseButton.count += 1; | |
if (pane.pauseButton.count % 2 === 0) { | |
console.log("Playing"); | |
cfg.slat.play = 1; | |
pane.pauseButton.title = "Pause"; | |
} else { | |
console.log("Paused"); | |
cfg.slat.play = 0; | |
pane.pauseButton.title = "Play"; | |
} | |
}); | |
pane.folders.slats | |
.addInput(cfg.slat, "count", { | |
min: 1, | |
max: 300, | |
step: 1, | |
presetKey: "slatCount" | |
}) | |
.on("change", (e) => { | |
console.log(e.value); | |
}); | |
pane.folders.slats.addInput(cfg.slat, "width", { | |
min: 0, | |
max: 10, | |
disabled: false, | |
presetKey: "slatWidth" | |
}); | |
pane.folders.slats.addInput(cfg.slat, "radius", { | |
min: 0, | |
max: 2, | |
disabled: false, | |
presetKey: "slatRadius" | |
}); | |
pane.folders.slats.addInput(cfg.slat, "spread", { | |
min: 0.01, | |
max: 10, | |
disabled: false, | |
presetKey: "slatSpread" | |
}); | |
// pane.folders.slats.addInput(cfg.slat, "colourA", { | |
// picker: "inline", | |
// expanded: false, | |
// hidden: true | |
// }); | |
// pane.folders.slats.addInput(cfg.slat, "colourB", { | |
// picker: "inline", | |
// expanded: false, | |
// hidden: true | |
// }); | |
// pane.folders.slats.addInput(cfg.slat, "colourC", { | |
// picker: "inline", | |
// expanded: false, | |
// hidden: true | |
// }); | |
pane.folders.slats | |
.addButton({ | |
title: "createMeshes", | |
hidden: true | |
}) | |
.on("click", () => { | |
console.log("createMeshes button clicked, ", cfg.slat); | |
createMeshes(); | |
}); | |
pane.folders.slats.on("change", (e) => { | |
console.log("Slats Folder Changed", e.value); | |
createMeshes(); | |
}); | |
let inputA = document.createElement("input"); | |
inputA.type = "file"; | |
const uploadA = upload.createFileInputHandler({ | |
onUploaded: ({ fileUrl, fileId }) => { | |
cfg.tex[0].src = fileUrl; | |
console.log("uploadA", fileId, fileUrl, cfg.tex); | |
images.load(); | |
// pane.disabled = false | |
pane.refresh(); | |
} | |
}); | |
inputA.addEventListener("change", uploadA, false); | |
pane.folders.tex | |
.addButton({ | |
title: "upload Texture A" | |
}) | |
.on("click", () => { | |
console.log("inputA clicked"); | |
// pane.disabled = true | |
inputA.click(); | |
}); | |
let inputB = document.createElement("input"); | |
inputB.type = "file"; | |
const uploadB = upload.createFileInputHandler({ | |
onUploaded: ({ fileUrl, fileId }) => { | |
cfg.tex[1].src = fileUrl; | |
console.log("uploadB", fileId, fileUrl, cfg.tex); | |
images.load(); | |
pane.refresh(); | |
} | |
}); | |
inputB.addEventListener("change", uploadB, false); | |
pane.folders.tex | |
.addButton({ | |
title: "upload Texture B" | |
}) | |
.on("click", () => { | |
console.log("inputB clicked"); | |
inputB.click(); | |
}); | |
let inputC = document.createElement("input"); | |
inputC.type = "file"; | |
const uploadC = upload.createFileInputHandler({ | |
onUploaded: ({ fileUrl, fileId }) => { | |
cfg.tex[2].src = fileUrl; | |
console.log("uploadC", fileId, fileUrl, cfg.tex); | |
images.load(); | |
pane.refresh(); | |
} | |
}); | |
inputC.addEventListener("change", uploadC, false); | |
pane.folders.tex | |
.addButton({ | |
title: "upload Texture C" | |
}) | |
.on("click", () => { | |
console.log("inputC clicked"); | |
inputC.click(); | |
}); | |
pane.folders.tex.addInput(cfg.tex[0], "src", { | |
label: "src A", | |
presetKey: "texAsrc", | |
hidden: false | |
}); | |
pane.folders.tex.addInput(cfg.tex[1], "src", { | |
label: "src B", | |
presetKey: "texBsrc", | |
hidden: false | |
}); | |
pane.folders.tex.addInput(cfg.tex[2], "src", { | |
label: "src C", | |
presetkey: "texCsrc", | |
hidden: false | |
}); | |
pane.folders.tex.loadButtonA = pane.folders.tex | |
.addButton({ | |
title: "Load" | |
// label: "texA" // optional | |
}) | |
.on("click", () => { | |
images.load(); | |
}); | |
pane.folders.tex.addInput(cfg.tex[0], "off", { label: "Ax", hidden: true }); | |
pane.folders.tex.addInput(cfg.tex[1], "off", { label: "Bx", hidden: true }); | |
pane.folders.tex.addInput(cfg.tex[2], "off", { label: "Cx", hidden: true }); | |
// pane.folders.bg.addInput(cfg.bg, "url").on("change", (ev) => { | |
// document.body.style.backgroundImage = "url(" + ev.value + ")"; | |
// }); | |
pane.folders.tex.on("change", (ev) => { | |
console.log("changed: " + JSON.stringify(ev.value)); | |
createMeshes(); | |
}); | |
const OUTPUT = { | |
string: "", | |
json: "" | |
}; | |
pane.folders.preset = pane.addFolder({ | |
hidden: false, | |
title: "presets" | |
}); | |
pane.folders.preset.addInput(cfg, "title", { | |
index: 0 | |
}); | |
let presetDropdown = {}; | |
let presetList = {}; | |
presetDropdown.spawn = function () { | |
presetDropdown.folder = pane.folders.preset | |
.addInput(cfg, "preset", { | |
index: 1, | |
label: "load", | |
options: (function () { | |
for (let i = 0; i < localStorage.length; i++) { | |
let storedValue = localStorage.getItem(localStorage.key([i])); | |
let presetBody = {}; | |
if (storedValue.includes("title")) { | |
// console.log("storedValue,", i, JSON.parse(storedValue)); | |
presetBody = JSON.parse(storedValue); | |
presetList[presetBody.title] = presetBody.title; | |
} | |
} | |
console.log("presetList", presetList); | |
if (typeof presetList !== undefined) { | |
console.log("localStored presets found", presetList); | |
return presetList; | |
} else { | |
console.log("no localStorage presets found"); | |
pane.save(); | |
return { | |
Default: "" | |
}; | |
} | |
})() | |
}) | |
.on("change", (e) => { | |
console.log("switch change", e.value); | |
cfg.title = e.value; | |
pane.load(); | |
pane.refresh(); | |
}); | |
}; | |
presetDropdown.spawn(); | |
presetDropdown.refresh = function () { | |
presetDropdown.folder.dispose(); | |
presetDropdown.spawn(); | |
}; | |
pane.save = function () { | |
cfg.preset = cfg.title; | |
updatePaneOutput(); | |
localStorage.setItem(cfg.title, OUTPUT.string); | |
console.log("saving ", cfg.title, OUTPUT.string); | |
presetDropdown.refresh(); | |
}; | |
pane.saveButton = pane.folders.preset.addButton({ | |
title: "save as title" | |
}); | |
pane.saveButton.on("click", () => { | |
pane.save(); | |
}); | |
pane.load = function () { | |
console.log( | |
"loading", | |
cfg.title, | |
cfg.preset, | |
localStorage.getItem(cfg.title) | |
); | |
pane.importPreset(JSON.parse(localStorage.getItem(cfg.preset))); | |
}; | |
pane.loadButton = pane.folders.preset | |
.addButton({ | |
title: "load", | |
// , disabled: true | |
hidden: true | |
}) | |
.on("click", () => { | |
pane.load(); | |
}); | |
pane.reset = function () { | |
localStorage.clear(); | |
pane.save(); | |
presetDropdown.refresh(); | |
pane.refresh(); | |
console.log("cleared localstorage", localStorage); | |
}; | |
pane.clearButton = pane.folders.preset | |
.addButton({ | |
title: "clear all presets" | |
}) | |
.on("click", () => { | |
pane.reset(); | |
}); | |
pane.folders.preset | |
.addButton({ | |
title: "console.log(localStorage)", | |
hidden: true | |
}) | |
.on("click", () => { | |
console.log(localStorage); | |
}); | |
pane.folders.preset | |
.addButton({ | |
title: "pane.refresh()", | |
hidden: true | |
}) | |
.on("click", () => { | |
pane.refresh(); | |
}); | |
pane.folders.output = pane.addFolder({ | |
title: "Export", | |
expanded: true | |
}); | |
pane.folders.output.addMonitor(OUTPUT, "string", { | |
hidden: false, | |
multiline: true | |
}); | |
// pane.folders.output.addInput(cfg, "outputSize", { | |
// label: 'width & height', | |
// x: { step: 1 }, | |
// y: { step: 1 } | |
// }); | |
pane.folders.output.addInput(cfg.outputSize, "x", { | |
label: "width", | |
step: 1 | |
}); | |
pane.folders.output.addInput(cfg.outputSize, "y", { | |
label: "height", | |
step: 1 | |
}); | |
pane.saveImageButton = pane.folders.output | |
.addButton({ | |
title: "Save Image" | |
}) | |
.on("click", () => { | |
let oldWidth = renderer.width; | |
let oldHeight = renderer.height; | |
camera.aspect = container.clientWidth / container.clientHeight; | |
// Update camera frustum | |
camera.updateProjectionMatrix(); | |
renderer.setSize(cfg.outputSize.x, cfg.outputSize.y); | |
renderer.render(scene, camera); | |
let dataURL = renderer.domElement.toDataURL(); | |
// window.open(dataURL); | |
const link = document.createElement("a"); | |
link.download = "download.png"; | |
link.href = dataURL; | |
link.click(); | |
// link.delete; | |
renderer.setSize(oldWidth, oldHeight); | |
// renderer.width = oldWidth | |
// renderer.height = oldHeight | |
}); | |
function updatePaneOutput() { | |
OUTPUT.json = pane.exportPreset(); | |
OUTPUT.string = JSON.stringify(pane.exportPreset(), null, 2); | |
} | |
pane.on("change", (e) => { | |
console.log(e.value); | |
updatePaneOutput(); | |
pane.refresh(); | |
}); | |
// const gpu = getGPUTier(); | |
// console.log(gpu); | |
let container; | |
let camera; | |
let renderer; | |
let scene; | |
// let mesh; | |
// let group; | |
// let controls; | |
let mainLight; | |
let slats = []; | |
// let f = 0; | |
// let currentSlatCount = 0; | |
const PI = Math.PI; | |
const TAU = Math.PI * 2; | |
function sin(n) { | |
return Math.sin(n); | |
} | |
function cos(n) { | |
return Math.cos(n); | |
} | |
function createCamera() { | |
const fov = 35; | |
const aspect = container.clientWidth / container.clientHeight; | |
const near = 0.1; | |
const far = 500; | |
camera = new THREE.PerspectiveCamera(fov, aspect, near, far); | |
camera.position.set(0, 0, cfg.slat.count / aspect); | |
} | |
function createLights() { | |
mainLight = new THREE.AmbientLight(0xffffff, 1.75); | |
scene.add(mainLight); | |
} | |
// function updateCamera() { | |
// camera.position.set(0, 0, cfg.slat.count / 1.25); | |
// } | |
function returnProxy(url) { | |
// disabled for local file hosting | |
return url; | |
// return "http://198.199.72.134/cors/" + url.replace(/^https?:\/\//, ""); | |
// return "https://cors-anywhere.herokuapp.com/" + url; | |
// if (url.split(".")[0] == "https://82xup") { | |
// console.log("image hosted on sandbox"); | |
// return url; | |
// } else { | |
// return "https://cors.bridged.cc/" + url; | |
// } | |
} | |
const textureLoader = new THREE.TextureLoader(); | |
textureLoader.crossOrigin = "anonymous"; | |
textureLoader.setCrossOrigin("anonymous"); | |
const textures = []; | |
const mats = []; | |
for (let i = 0; i < 3; i++) { | |
mats[i] = new THREE.MeshStandardMaterial({ color: 0xffffff }); | |
} | |
let slatGeometry = new THREE.PlaneBufferGeometry( | |
cfg.slat.width, | |
cfg.slat.height | |
); | |
const images = { | |
loaded: 0, | |
hasLoaded: function (index, e) { | |
images.loaded++; | |
const tex = textures[index]; | |
tex.minFilter = THREE.LinearFilter; | |
tex.encoding = THREE.sRGBEncoding; | |
// tex.wrapS = ClampToEdgeWrapping; | |
// tex.wrapT = ClampToEdgeWrapping; | |
tex.repeat.set(cfg.tex[index].rep.u, cfg.tex[index].rep.t); | |
updateSlatsTexture(index); | |
if (images.loaded === 3) { | |
container.style.visibility = "visible"; | |
} | |
}, | |
load: function () { | |
console.log("images.load begun"); | |
images.loaded = 0; | |
for (let i = 0; i < 3; i++) { | |
textures[i] = textureLoader.load( | |
returnProxy(cfg.tex[i].src), | |
images.hasLoaded.bind(null, i) | |
); | |
} | |
} | |
}; | |
function xOffset(slatIndex) { | |
return slatIndex * cfg.slat.spread - (cfg.slat.count / 2) * cfg.slat.spread; | |
} | |
function createSlatGroup(slatIndex) { | |
const group = new THREE.Group(); | |
for (let i = 0; i < 3; i++) { | |
const mat = createSlatMat(slatIndex, i); | |
const mesh = new THREE.Mesh(slatGeometry, mat); | |
mesh.position.set( | |
sin(((i + 1) * TAU) / 3) * cfg.slat.radius, | |
0, | |
cos(((i + 1) * TAU) / 3) * cfg.slat.radius | |
); | |
mesh.rotation.y = ((i + 1) * TAU) / 3; | |
group.add(mesh); | |
} | |
group.position.x = xOffset(slatIndex); | |
return group; | |
} | |
function createSlatMat(slatIndex, textureIndex) { | |
const mat = mats[textureIndex].clone(); | |
if (textures?.[textureIndex]?.clone) { | |
mat.map = textures[textureIndex].clone(); | |
const x = xOffset(slatIndex); | |
mat.map.offset.set(Math.abs(x / cfg.slat.count + 0.5), 0); | |
mat.map.needsUpdate = true; | |
} | |
return mat; | |
} | |
function updateSlatsTexture(textureIndex) { | |
for (let i = 0; i < slats.length; i++) { | |
const slat = slats[i].children[textureIndex]; | |
slat.material.dispose(); | |
slat.material = createSlatMat(i, textureIndex); | |
} | |
} | |
function createMeshes() { | |
console.log("begin createMeshes()"); | |
if (slats.length > 0) { | |
console.log("createMeshes removing slats"); | |
for (let i = 0; i < slats.length; i++) { | |
for (let j = 0; j < slats[i].children.length; j++) { | |
const object = slats[i].children[j]; | |
object.geometry.dispose(); | |
object.material.dispose(); | |
scene.remove(object); | |
} | |
scene.remove(slats[i]); | |
} | |
} | |
slats.length = 0; | |
cfg.slat.height = cfg.slat.count * (9 / 16); | |
// addSlat(); | |
slatGeometry = new THREE.PlaneBufferGeometry(cfg.slat.width, cfg.slat.height); | |
for (let i = 0; i < cfg.slat.count; i++) { | |
slats[i] = createSlatGroup(i); | |
scene.add(slats[i]); | |
} | |
// updateCamera(); | |
camera.position.set(0, 0, cfg.slat.count / 1.25); | |
console.log("createMeshes completed", slats[0].children[0].material); | |
} | |
function createRenderer() { | |
renderer = new THREE.WebGLRenderer({ | |
antialias: true, | |
alpha: true, | |
preserveDrawingBuffer: true | |
}); | |
renderer.setSize(container.clientWidth, container.clientHeight); | |
renderer.setPixelRatio(1); | |
// renderer.setPixelRatio(window.devicePixelRatio); | |
renderer.gammaFactor = 2.2; | |
renderer.gammaOutput = true; | |
// renderer.toneMapping = ReinhardToneMapping; | |
renderer.outputEncoding = THREE.sRGBEncoding; | |
renderer.physicallyCorrectLights = false; | |
// renderer.alpha = true; | |
container.appendChild(renderer.domElement); | |
} | |
function update() { | |
cfg.slat.height = cfg.slat.count * (9 / 16); | |
// addSlat(); | |
for (let i = 0; i < slats.length; i++) { | |
// var sx = slats[i].x; | |
// var wave_one = sin(sx * cfg.slat.wave1.y + cfg.slat.now / 10 * cfg.slat + cfg.offset) * cfg.amp; | |
// var wave_two = sin(sx * cfg.slat.wave2.y + cfg.slat.now / 10 * cfg.speed2 + cfg.offset2) * cfg.amp2; | |
// var waves = wave_one + wave_two; | |
var wave = | |
cfg.slat.rRot + | |
((slats[i].position.x / cfg.slat.count) * PI * cfg.slat.wave1.y + | |
cfg.slat.time1) + | |
TAU * | |
sin( | |
(slats[i].position.x / cfg.slat.count) * PI * cfg.slat.wave2.y + | |
cfg.slat.time2 | |
); | |
slats[i].rotation.y = wave + cfg.slat.now; | |
// cfg.slat.rRot + | |
// TAU * sin((i / cfg.slat.count) * PI * cfg.slat.rFreq) + | |
// cfg.slat.rTime; | |
} | |
cfg.slat.now += cfg.slat.time * cfg.slat.play; | |
cfg.slat.time1 -= (cfg.slat.wave1.x / 600) * cfg.slat.play; | |
cfg.slat.time2 -= (cfg.slat.wave2.x / 1200) * cfg.slat.play; | |
} | |
function render() { | |
renderer.render(scene, camera); | |
} | |
function onWindowResize() { | |
camera.aspect = container.clientWidth / container.clientHeight; | |
// Update camera frustum | |
camera.updateProjectionMatrix(); | |
renderer.setSize(container.clientWidth, container.clientHeight); | |
} | |
window.addEventListener("resize", onWindowResize, false); | |
function init() { | |
console.log("init begun"); | |
container = document.querySelector("#scene-container"); | |
images.load(); | |
scene = new THREE.Scene(); | |
// const loader = new TextureLoader(); | |
// const bgTexture = loader.load("img/concrete.jpg"); | |
// scene.background = bgTexture; | |
// scene.background = new Color("rgb(20,20,20)"); | |
createCamera(); | |
createLights(); | |
createMeshes(); | |
// createControls(); | |
createRenderer(); | |
renderer.setAnimationLoop(() => { | |
update(); | |
render(); | |
}); | |
pane.hidden = false; | |
updatePaneOutput(); | |
console.log("init completed"); | |
} | |
init(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
body { | |
margin: 0; | |
overflow: hidden; | |
color: white; | |
text-align: center; | |
background-color: black; | |
background: url(https://82xup.csb.app/img/bghires.png) no-repeat center center | |
fixed; | |
background-size: cover; | |
} | |
h1 { | |
position: absolute; | |
width: 100%; | |
z-index: 1; | |
font-size: 1.5rem; | |
} | |
a { | |
color: white; | |
} | |
a:hover { | |
color: purple; | |
} | |
#scene-container { | |
position: absolute; | |
width: 100%; | |
height: 100%; | |
} | |
canvas { | |
/* background-image: url('../img/all.jpg'); */ | |
/* background-color: green; */ | |
} | |
:root { | |
--tp-base-background-color: hsla(0, 0%, 10%, 0.9); | |
--tp-base-shadow-color: hsla(0, 0%, 0%, 0.2); | |
--tp-button-background-color: hsla(0, 0%, 80%, 1); | |
--tp-button-background-color-active: hsla(0, 0%, 100%, 1); | |
--tp-button-background-color-focus: hsla(0, 0%, 95%, 1); | |
--tp-button-background-color-hover: hsla(0, 0%, 85%, 1); | |
--tp-button-foreground-color: hsla(0, 0%, 0%, 0.9); | |
--tp-container-background-color: hsla(0, 0%, 0%, 0.8); | |
--tp-container-background-color-active: hsla(0, 0%, 0%, 0.6); | |
--tp-container-background-color-focus: hsla(0, 0%, 0%, 0.5); | |
--tp-container-background-color-hover: hsla(0, 0%, 0%, 0.4); | |
--tp-container-foreground-color: hsla(0, 0%, 100%, 1); | |
--tp-groove-foreground-color: hsla(0, 0%, 0%, 0.2); | |
--tp-input-background-color: hsla(0, 0%, 0%, 0.3); | |
--tp-input-background-color-active: hsla(0, 0%, 0%, 0.6); | |
--tp-input-background-color-focus: hsla(0, 0%, 0%, 0.5); | |
--tp-input-background-color-hover: hsla(0, 0%, 0%, 0.4); | |
--tp-input-foreground-color: hsla(0, 0%, 100%, 0.9); | |
--tp-label-foreground-color: hsla(0, 0%, 100%, 0.9); | |
--tp-monitor-background-color: hsla(0, 0%, 0%, 0.3); | |
--tp-monitor-foreground-color: hsla(0, 0%, 100%, 0.3); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment