Files
pronature-platform/src/lib/Dashboard.js
T

107 lines
3.5 KiB
JavaScript

import { PlaneGeometry, CylinderGeometry, CanvasTexture, Group, Mesh, MeshStandardMaterial, DoubleSide } from "three";
import Utils from "./Utils";
class DashBoard {
constructor(engine) {
let svg = p=>`<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<g>
<rect x="0" y="85%" width="100%" height="15%" opacity="0.73" fill="#98d696"/>
<rect x="80%" y="0" width="20%" height="15%" opacity="0.73" fill="#98d696"/>
<rect x="0" y="0" width="20%" height="15%" opacity="0.73" fill="#98d696" visibility="hidden"/>
<circle r="10%" cx="11%" cy="85%" opacity="0.73" fill="#98d696" visibility="hidden"/>
</g>
<text id="hint" text-anchor="middle" x="50%" y="92%" font-family="MyriadPro-Regular, &apos;Myriad Pro&apos;" font-size="150%">${p.hint || ''}</text>
<text x="90%" text-anchor="middle" y="8%" font-family="MyriadPro-Regular, &apos;Myriad Pro&apos;" font-size="150%">Points</text>
</svg>`;
let img = new Image(), url, progressCylinder;
let canvas = document.createElement('canvas');
let ctx = canvas.getContext('2d');
let texture = new CanvasTexture(canvas)
let updating = false;
let params = {}
img.addEventListener('load', function () {
ctx.drawImage(img, 0, 0, engine.w, engine.h);
URL.revokeObjectURL(url);
texture.needsUpdate = true;
updating = false;
})
const dash = new Group();
this.group = dash;
dash.visible = false;
const dashGeometry = new PlaneGeometry(engine.aspect, 1);
const dashMesh = new Mesh(dashGeometry, new MeshStandardMaterial({
roughness: 0, metalness:0.1, transparent: true,
map: texture
}))
dash.add(dashMesh);
engine.scene.add(dash)
engine.addEventListener('beforeRender', ()=>{
dash.quaternion.copy(engine.camera.quaternion)
dash.position.copy(engine.camera.position)
dash.translateZ(-1.2 * engine.camera.zoom);
})
this.update = function(p = {}){
Object.assign(params, p);
if (updating) return false;
updating = true;
canvas.width = engine.w;
canvas.height = engine.h;
url = URL.createObjectURL(new Blob([svg(params)],{ type:"image/svg+xml;charset=utf-8" }));
img.src = url;
}
this.createProgressBar = function(){
const padLeft = engine.aspect/30;
const progressGeometry = new CylinderGeometry( 0.5, 0.5, 1, 3, 1, false, 0, Math.PI );
const staticCylinder = new Mesh( progressGeometry, new MeshStandardMaterial({
roughness: 0, metalness:0.1, transparent: true, opacity:0.52, color: 0x55ff00, side: DoubleSide
}) );
staticCylinder.rotation.set(-Math.PI/2, 0, Math.PI/2,)
staticCylinder.scale.set(0.02, engine.aspect/3, 0.02)
staticCylinder.position.set(padLeft - engine.aspect/3, 0.45, 0);
dash.add( staticCylinder );
progressCylinder = new Mesh( progressGeometry, new MeshStandardMaterial({
roughness: 0, metalness:0.1, transparent: true, opacity:0.77, color: 0x11ff00
}) );
progressCylinder.rotation.set(Math.PI/2, 0, Math.PI/2,)
progressCylinder.scale.set(0.017, 0, 0.017)
progressCylinder.position.set(0, 0.45, 0);
dash.add( progressCylinder );
}
this.updateProgress = function(value){
const padLeft = engine.aspect/30;
progressCylinder.scale.y = engine.aspect/3 * value;
progressCylinder.position.x = padLeft - engine.aspect/2 + progressCylinder.scale.y/2
}
this.enable = ()=>{
dash.visible = true;
}
this.disable = ()=>{
dash.visible = false;
}
this.createProgressBar();
this.update();
}
get active(){
return this.group.visible;
}
set active(v){
this.group.visible = v;
}
}
export { DashBoard };