You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
170 lines
5.0 KiB
170 lines
5.0 KiB
// from https://medium.com/nicasource/building-an-interactive-web-portfolio-with-vue-three-js-part-three-implementing-three-js-452cb375ef80
|
|
|
|
import axios from "axios";
|
|
import { SpotLight } from "three";
|
|
import * as TWEEN from "@tweenjs/tween.js";
|
|
|
|
import { createCamera } from "./components/camera.js";
|
|
import { createLights } from "./components/lights.js";
|
|
import { createScene } from "./components/scene.js";
|
|
import { createCube, createTerrain } from "./components/objects/terrain.js";
|
|
import { Loop } from "./systems/Loop.js";
|
|
import { Resizer } from "./systems/Resizer.js";
|
|
import { createControls } from "./systems/controls.js";
|
|
import { createRenderer } from "./systems/renderer.js";
|
|
import { AppString } from "@/constants/app";
|
|
|
|
// These variables are module-scoped: we cannot access them
|
|
// from outside the module
|
|
|
|
const color = "#42b883";
|
|
const color2 = "#0055aa";
|
|
const PLATFORM_SIZE = 100;
|
|
const PLATFORM_BORDER = 10;
|
|
const PLATFORM_EDGE_FOR_UNKNOWNS = 10;
|
|
const BASE32 = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
|
|
|
|
function createLight() {
|
|
const light = new SpotLight(0xffffff, 100, 0, Math.PI / 8, 0.5, 0);
|
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
light.tick = () => {};
|
|
return light;
|
|
}
|
|
|
|
class World {
|
|
constructor(container) {
|
|
this.update = this.update.bind(this);
|
|
|
|
// Instances of camera, scene, and renderer
|
|
this.camera = createCamera();
|
|
this.scene = createScene(color2);
|
|
this.renderer = createRenderer();
|
|
|
|
this.light = null;
|
|
this.lights = [];
|
|
|
|
// Initializae Loop
|
|
this.loop = new Loop(this.camera, this.scene, this.renderer);
|
|
|
|
container.append(this.renderer.domElement);
|
|
|
|
// Orbit Controls
|
|
const controls = createControls(this.camera, this.renderer.domElement);
|
|
|
|
// Light Instance, with optional light helper
|
|
const { light } = createLights(color);
|
|
|
|
// Terrain Instance
|
|
const terrain = createTerrain({
|
|
color: color,
|
|
height: PLATFORM_SIZE + PLATFORM_BORDER,
|
|
width: PLATFORM_SIZE + PLATFORM_BORDER + PLATFORM_EDGE_FOR_UNKNOWNS,
|
|
});
|
|
|
|
this.loop.updatables.push(controls);
|
|
this.loop.updatables.push(light);
|
|
this.loop.updatables.push(terrain);
|
|
|
|
this.scene.add(light, terrain);
|
|
|
|
const cube = createCube(-10, 5, 0, 1, 1, 1);
|
|
this.loop.updatables.push(cube);
|
|
this.scene.add(cube);
|
|
|
|
new TWEEN.Tween(cube.position).to({ x: 10 }, 5000).start();
|
|
this.loadClaims();
|
|
|
|
requestAnimationFrame(this.update);
|
|
|
|
// Responsive handler
|
|
const resizer = new Resizer(container, this.camera, this.renderer);
|
|
resizer.onResize = () => {
|
|
this.render();
|
|
};
|
|
}
|
|
|
|
update(time) {
|
|
TWEEN.update(time);
|
|
this.lights.forEach((light) => {
|
|
light.updateMatrixWorld();
|
|
light.target.updateMatrixWorld();
|
|
});
|
|
requestAnimationFrame(this.update);
|
|
}
|
|
|
|
async loadClaims() {
|
|
const endorserApiServer = AppString.DEFAULT_ENDORSER_API_SERVER;
|
|
try {
|
|
const url = endorserApiServer + "/api/v2/report/claims";
|
|
const headers = { "Content-Type": "application/json" };
|
|
const resp = await axios.get(url, { headers: headers });
|
|
if (resp.status === 200) {
|
|
resp.data.data.map((claim) => {
|
|
const randomness = claim.id.substring(10);
|
|
const x =
|
|
(100 * BASE32.indexOf(randomness.substring(0, 1))) / 32 - 50;
|
|
const z =
|
|
(100 * BASE32.indexOf(randomness.substring(8, 9))) / 32 - 50;
|
|
console.log(
|
|
"randomness",
|
|
randomness,
|
|
randomness.substring(0, 1),
|
|
BASE32.indexOf(randomness.substring(0, 1)),
|
|
x,
|
|
randomness.substring(8, 9),
|
|
BASE32.indexOf(randomness.substring(8, 9)),
|
|
z
|
|
);
|
|
|
|
const light = createLight();
|
|
light.position.set(x, 20, z);
|
|
light.target.position.set(x, 0, z);
|
|
this.loop.updatables.push(light);
|
|
this.scene.add(light);
|
|
this.scene.add(light.target);
|
|
new TWEEN.Tween(light.position)
|
|
.to({ y: 5 }, 1000)
|
|
.start()
|
|
.onComplete(() => {
|
|
this.scene.remove(light);
|
|
light.dispose();
|
|
});
|
|
this.lights = [...this.lights, light];
|
|
});
|
|
console.log("done adding cube");
|
|
} else {
|
|
console.log(
|
|
"Got bad response status & data of",
|
|
resp.status,
|
|
resp.data
|
|
);
|
|
// this.alertTitle = "Error With Server";
|
|
// this.alertMessage =
|
|
// "Got an error retrieving your given time from the server.";
|
|
// this.isAlertVisible = true;
|
|
}
|
|
} catch (error) {
|
|
console.log("Got error of", error);
|
|
// this.alertTitle = "Error With Server";
|
|
// this.alertMessage =
|
|
// "Got an error retrieving your given time from the server.";
|
|
// this.isAlertVisible = true;
|
|
}
|
|
}
|
|
|
|
render() {
|
|
// draw a single frame
|
|
this.renderer.render(this.scene, this.camera);
|
|
}
|
|
|
|
// Animation handlers
|
|
start() {
|
|
this.loop.start();
|
|
}
|
|
|
|
stop() {
|
|
this.loop.stop();
|
|
}
|
|
}
|
|
|
|
export { World };
|
|
|