|
|
@ -20,7 +20,7 @@ let metrics = { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const scene = new THREE.Scene() |
|
|
|
const scene = new THREE.Scene() |
|
|
|
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ) |
|
|
|
const camera = new THREE.PerspectiveCamera(80, window.innerWidth / window.innerHeight, 0.1, 1000 ) |
|
|
|
let homeContainer = new THREE.Group() |
|
|
|
let homeContainer = new THREE.Group() |
|
|
|
scene.add(homeContainer) |
|
|
|
scene.add(homeContainer) |
|
|
|
let home = new THREE.Group() |
|
|
|
let home = new THREE.Group() |
|
|
@ -49,6 +49,12 @@ const renderer = new THREE.WebGLRenderer({ |
|
|
|
renderer.setSize( window.innerWidth, window.innerHeight ) |
|
|
|
renderer.setSize( window.innerWidth, window.innerHeight ) |
|
|
|
document.body.appendChild( renderer.domElement ) |
|
|
|
document.body.appendChild( renderer.domElement ) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let info = document.createElement('div') |
|
|
|
|
|
|
|
info.className = "info" |
|
|
|
|
|
|
|
info.innerHTML = "HELLO" |
|
|
|
|
|
|
|
info.style.color = metrics.color4 |
|
|
|
|
|
|
|
document.body.appendChild(info) |
|
|
|
|
|
|
|
|
|
|
|
const light = new THREE.AmbientLight(0xFFAAAA, 1) |
|
|
|
const light = new THREE.AmbientLight(0xFFAAAA, 1) |
|
|
|
light.position.z = 100 |
|
|
|
light.position.z = 100 |
|
|
|
scene.add(light) |
|
|
|
scene.add(light) |
|
|
@ -56,17 +62,18 @@ scene.background = new THREE.Color(metrics.backgroundColor) |
|
|
|
|
|
|
|
|
|
|
|
// back the camera up
|
|
|
|
// back the camera up
|
|
|
|
camera.position.z = 25 |
|
|
|
camera.position.z = 25 |
|
|
|
|
|
|
|
camera.position.y = -10 |
|
|
|
|
|
|
|
|
|
|
|
// flip home on x axis
|
|
|
|
// flip home on x axis
|
|
|
|
home.rotation.x = Math.PI |
|
|
|
home.rotation.x = Math.PI |
|
|
|
|
|
|
|
|
|
|
|
// Rotate container a bit for comfort
|
|
|
|
// Rotate container a bit for comfort
|
|
|
|
homeContainer.rotation.x = 0.6 * (-Math.PI / 2) |
|
|
|
homeContainer.rotation.x = 0.7 * (-Math.PI / 2) |
|
|
|
|
|
|
|
|
|
|
|
// Returns the first child (or container) whose name matches
|
|
|
|
// Returns the first child (or container) whose name matches
|
|
|
|
function childWithName(container, name) { |
|
|
|
function childWithName(container, name) { |
|
|
|
if (container.userData.name == name) { |
|
|
|
if (container.userData.name == name) { |
|
|
|
return container; |
|
|
|
return container |
|
|
|
} |
|
|
|
} |
|
|
|
for (var child of container.children) { |
|
|
|
for (var child of container.children) { |
|
|
|
let childMatches = childWithName(child, name) |
|
|
|
let childMatches = childWithName(child, name) |
|
|
@ -86,14 +93,25 @@ function animate() { |
|
|
|
let updatedEntities = areasWithEntitiesToUpdate[area] |
|
|
|
let updatedEntities = areasWithEntitiesToUpdate[area] |
|
|
|
if (updatedEntities.length > 0) { |
|
|
|
if (updatedEntities.length > 0) { |
|
|
|
areasToUpdate.add(area) |
|
|
|
areasToUpdate.add(area) |
|
|
|
} else { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
let label = childWithName(scene, area + "LABEL") |
|
|
|
let label = childWithName(scene, area + "LABEL") |
|
|
|
label.lookAt(camera.position) |
|
|
|
label.lookAt(camera.position) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var infoText = ""; |
|
|
|
|
|
|
|
|
|
|
|
for (var area of areasToUpdate) { |
|
|
|
for (var area of areasToUpdate) { |
|
|
|
|
|
|
|
let updatedEntities = areasWithEntitiesToUpdate[area] |
|
|
|
|
|
|
|
for (entity of updatedEntities) { |
|
|
|
|
|
|
|
let friendlyName = entity.attributes.friendly_name || entity.entity_id |
|
|
|
|
|
|
|
let unit = entity.attributes.unit_of_measurement || '' |
|
|
|
|
|
|
|
infoText += friendlyName |
|
|
|
|
|
|
|
infoText += (': ' + entity.state + ' ') |
|
|
|
|
|
|
|
infoText += unit |
|
|
|
|
|
|
|
infoText += '<br>' |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
let areaContainer = childWithName(scene, area) |
|
|
|
let areaContainer = childWithName(scene, area) |
|
|
|
let box = childWithName(areaContainer, "box") |
|
|
|
let box = childWithName(areaContainer, "box") |
|
|
|
|
|
|
|
|
|
|
@ -139,6 +157,10 @@ function animate() { |
|
|
|
sunContainer.rotation.y = (elevation / 360) * 2 * Math.PI |
|
|
|
sunContainer.rotation.y = (elevation / 360) * 2 * Math.PI |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (infoText.length > 1) { |
|
|
|
|
|
|
|
info.innerHTML = infoText |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
renderer.render( scene, camera ) |
|
|
|
renderer.render( scene, camera ) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -147,20 +169,22 @@ animate() |
|
|
|
function createTextMesh(text, colorName) { |
|
|
|
function createTextMesh(text, colorName) { |
|
|
|
let canvas = document.createElement('canvas') |
|
|
|
let canvas = document.createElement('canvas') |
|
|
|
let context = canvas.getContext('2d') |
|
|
|
let context = canvas.getContext('2d') |
|
|
|
|
|
|
|
let font = '144px monospace' |
|
|
|
context.textAlign = "center" |
|
|
|
context.textAlign = "center" |
|
|
|
context.textBaseline = "middle" |
|
|
|
context.font = font |
|
|
|
context.font = '144pt sans-serif' |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let size = context.measureText(text) |
|
|
|
let size = context.measureText(text) |
|
|
|
let height = context.measureText('M').width |
|
|
|
let height = context.measureText('M').width * 1.5 |
|
|
|
size.height = height |
|
|
|
size.height = height |
|
|
|
|
|
|
|
|
|
|
|
let canvasScale = 0.1 |
|
|
|
let canvasScale = 1 |
|
|
|
canvas.width = size.width * canvasScale * 0.6 |
|
|
|
canvas.width = size.width * canvasScale |
|
|
|
canvas.height = size.height * canvasScale |
|
|
|
canvas.height = size.height * canvasScale |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
context.font = font |
|
|
|
|
|
|
|
|
|
|
|
context.fillStyle = colorName |
|
|
|
context.fillStyle = colorName |
|
|
|
context.fillText(text, 5, 10) |
|
|
|
context.fillText(text, 0, 100) |
|
|
|
|
|
|
|
|
|
|
|
let texture = new THREE.CanvasTexture(canvas) |
|
|
|
let texture = new THREE.CanvasTexture(canvas) |
|
|
|
texture.needsUpdate = true |
|
|
|
texture.needsUpdate = true |
|
|
@ -170,7 +194,7 @@ function createTextMesh(text, colorName) { |
|
|
|
material.transparent = true |
|
|
|
material.transparent = true |
|
|
|
material.depthTest = false |
|
|
|
material.depthTest = false |
|
|
|
|
|
|
|
|
|
|
|
let scaleFactor = 0.05 |
|
|
|
let scaleFactor = 0.005 |
|
|
|
|
|
|
|
|
|
|
|
let plane = new THREE.PlaneGeometry(canvas.width * scaleFactor, canvas.height * scaleFactor) |
|
|
|
let plane = new THREE.PlaneGeometry(canvas.width * scaleFactor, canvas.height * scaleFactor) |
|
|
|
let mesh = new THREE.Mesh(plane, material) |
|
|
|
let mesh = new THREE.Mesh(plane, material) |
|
|
@ -192,7 +216,7 @@ function updateWithHAData(data) { |
|
|
|
|
|
|
|
|
|
|
|
let sortedAreaNames = areaNames |
|
|
|
let sortedAreaNames = areaNames |
|
|
|
sortedAreaNames.sort(function(a, b) { |
|
|
|
sortedAreaNames.sort(function(a, b) { |
|
|
|
return b.length - a.length; |
|
|
|
return b.length - a.length |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
for (var entity of data) { |
|
|
|
for (var entity of data) { |
|
|
|