react-planner
Version:
react-planner is a React Component for plans design. Draw a 2D floorplan and navigate it in 3D mode.
321 lines (257 loc) • 10.7 kB
JSX
import * as Three from 'three';
import React from 'react';
//color
let grey = new Three.MeshLambertMaterial({color: 0xd3d3d3});
let white = new Three.MeshLambertMaterial({color: 0xf5f5f5});
let darkGrey = new Three.MeshLambertMaterial({color: 0x3d3d3d});
let black = new Three.MeshLambertMaterial({color: 0x000000});
let boxMaterials = [ grey, darkGrey, grey, grey, grey, grey];
let boxMaterials2 = [ grey, grey, grey, grey, grey, darkGrey];
let boxMaterials3 = [ grey, grey, grey, grey, darkGrey, grey];
let textureLoader = new Three.TextureLoader();
let lcdTexture = textureLoader.load(require('./monitor.png'));
//dimensions
let width = 258;
let depth = 87;
let height = 195;
let filterWidth = 48;
let filterDepth = 10;
let filterHeight = 52;
let gridThickness = 3;
function makeObjectMaxLOD(){
let schneider = new Three.Mesh();
let gridVerticalElemGeometry = new Three.BoxGeometry(gridThickness/2,filterHeight,filterDepth);
let gridHorizontalElemGeometry = new Three.BoxGeometry(filterWidth,gridThickness,filterDepth);
let filter = new Three.Object3D();
for(let i=0.25; i<48; i+=3.32){
let gridVerticalElem = new Three.Mesh(gridVerticalElemGeometry, white);
gridVerticalElem.position.x = i;
gridVerticalElem.position.y = 26;
filter.add(gridVerticalElem);
}
for(let i=0; i<52; i+=7.4){
let gridHorizontalElem = new Three.Mesh(gridHorizontalElemGeometry, white);
gridHorizontalElem.position.x = 23.5;
gridHorizontalElem.position.y = i;
filter.add(gridHorizontalElem);
}
for(let k=0;k<=54;k+=46){
for(let j=10;j<240;j+=48){
let filterClone = filter.clone();
filterClone.position.x+=j;
filterClone.position.y+=k;
filterClone.rotation.x-=Math.PI/6;
if(k===0)
filterClone.position.z+=18;
else
filterClone.position.z-=10;
schneider.add(filterClone);
}
}
let panelSideElemGeometry = new Three.BoxGeometry(5,height,depth);
let panelSideElemLeft = new Three.Mesh(panelSideElemGeometry, boxMaterials);
panelSideElemLeft.rotation.y+=Math.PI;
schneider.add(panelSideElemLeft);
let panelSideElemRight = new Three.Mesh(panelSideElemGeometry, boxMaterials);
panelSideElemRight.position.x+=258;
schneider.add(panelSideElemRight);
let panelSideBackElemGeometry = new Three.BoxGeometry(width,height,5);
let panelSideElemBack = new Three.Mesh(panelSideBackElemGeometry, boxMaterials3);
panelSideElemBack.position.x+=129;
panelSideElemBack.position.z-=43.5;
schneider.add(panelSideElemBack);
let boxElemGeometry = new Three.BoxGeometry(width/3,height/3,depth/8);
let boxElem = new Three.Mesh(boxElemGeometry, grey);
boxElem.position.x+=212;
boxElem.position.y+=65;
boxElem.position.z+=35;
schneider.add(boxElem);
let panelSideFrontElemGeometry = new Three.BoxGeometry(width/3,height,5);
let panelSideElemFront_P1 = new Three.Mesh(panelSideFrontElemGeometry, boxMaterials2);
panelSideElemFront_P1.position.x+=43.5;
panelSideElemFront_P1.position.z+=43.5;
schneider.add(panelSideElemFront_P1);
let panelSideElemFront_P2 = new Three.Mesh(panelSideFrontElemGeometry, boxMaterials2);
panelSideElemFront_P2.position.x+=130;
panelSideElemFront_P2.position.z+=43.5;
schneider.add(panelSideElemFront_P2);
let panelSideElemFront_P3 = new Three.Mesh(panelSideFrontElemGeometry, boxMaterials2);
panelSideElemFront_P3.position.x+=217;
panelSideElemFront_P3.position.z+=43.5;
schneider.add(panelSideElemFront_P3);
let planeGeometryFront = new Three.PlaneGeometry(width/16,height/12);
let planeMaterialFront = new Three.MeshLambertMaterial({map:lcdTexture, transparent:true, overdraw:true});
let planeGeometryFront1 = new Three.PlaneGeometry(width/8,height/3);
let panelBase = new Three.Mesh(planeGeometryFront1,darkGrey);
panelBase.position.set(217,65,46.5);
schneider.add(panelBase);
let lcd = new Three.Mesh(planeGeometryFront,planeMaterialFront);
lcd.position.set(217,60,46.55);
schneider.add(lcd);
let panelSideMiddleElemGeometry = new Three.BoxGeometry(width,5,depth);
let panelSideElemMiddle = new Three.Mesh(panelSideMiddleElemGeometry, grey);
panelSideElemMiddle.position.x+=129;
panelSideElemMiddle.position.y-=10;
schneider.add(panelSideElemMiddle);
let panelSideElemFooter = new Three.Mesh(panelSideMiddleElemGeometry, black);
panelSideElemFooter.position.x+=129;
panelSideElemFooter.position.y-=97.5;
schneider.add(panelSideElemFooter);
return schneider
}
function makeObjectMinLOD(){
let schneider = new Three.Mesh();
let gridVerticalElemGeometry = new Three.BoxGeometry(gridThickness/2,filterHeight,filterDepth);
let gridHorizontalElemGeometry = new Three.BoxGeometry(filterWidth,gridThickness,filterDepth);
let filter = new Three.Object3D();
for(let i=0.25; i<48; i+=3.32){
let gridVerticalElem = new Three.Mesh(gridVerticalElemGeometry, white);
gridVerticalElem.position.x = i;
gridVerticalElem.position.y = 26;
filter.add(gridVerticalElem);
}
for(let i=0; i<52; i+=7.4){
let gridHorizontalElem = new Three.Mesh(gridHorizontalElemGeometry, white);
gridHorizontalElem.position.x = 23.5;
gridHorizontalElem.position.y = i;
filter.add(gridHorizontalElem);
}
for(let k=0;k<=54;k+=46){
for(let j=10;j<240;j+=48){
let filterClone = filter.clone();
filterClone.position.x+=j;
filterClone.position.y+=k;
filterClone.rotation.x-=Math.PI/6;
if(k===0)
filterClone.position.z+=18;
else
filterClone.position.z-=10;
schneider.add(filterClone);
}
}
let panelSideElemGeometry = new Three.BoxGeometry(5,height,depth);
let panelSideElemLeft = new Three.Mesh(panelSideElemGeometry, boxMaterials);
panelSideElemLeft.rotation.y+=Math.PI;
schneider.add(panelSideElemLeft);
let panelSideElemRight = new Three.Mesh(panelSideElemGeometry, boxMaterials);
panelSideElemRight.position.x+=258;
schneider.add(panelSideElemRight);
let panelSideBackElemGeometry = new Three.BoxGeometry(width,height,5);
let panelSideElemBack = new Three.Mesh(panelSideBackElemGeometry, boxMaterials3);
panelSideElemBack.position.x+=129;
panelSideElemBack.position.z-=43.5;
schneider.add(panelSideElemBack);
let boxElemGeometry = new Three.BoxGeometry(width/3,height/3,depth/8);
let boxElem = new Three.Mesh(boxElemGeometry, grey);
boxElem.position.x+=212;
boxElem.position.y+=65;
boxElem.position.z+=35;
schneider.add(boxElem);
let panelSideFrontElemGeometry = new Three.BoxGeometry(width/3,height,5);
let panelSideElemFront_P1 = new Three.Mesh(panelSideFrontElemGeometry, boxMaterials2);
panelSideElemFront_P1.position.x+=43.5;
panelSideElemFront_P1.position.z+=43.5;
schneider.add(panelSideElemFront_P1);
let panelSideElemFront_P2 = new Three.Mesh(panelSideFrontElemGeometry, boxMaterials2);
panelSideElemFront_P2.position.x+=130;
panelSideElemFront_P2.position.z+=43.5;
schneider.add(panelSideElemFront_P2);
let panelSideElemFront_P3 = new Three.Mesh(panelSideFrontElemGeometry, boxMaterials2);
panelSideElemFront_P3.position.x+=217;
panelSideElemFront_P3.position.z+=43.5;
schneider.add(panelSideElemFront_P3);
let planeGeometryFront = new Three.PlaneGeometry(width/16,height/12);
let planeMaterialFront = new Three.MeshLambertMaterial({map:lcdTexture, transparent:true, overdraw:true});
let planeGeometryFront1 = new Three.PlaneGeometry(width/8,height/3);
let panelBase = new Three.Mesh(planeGeometryFront1,darkGrey);
panelBase.position.set(217,65,46.5);
schneider.add(panelBase);
let lcd = new Three.Mesh(planeGeometryFront,planeMaterialFront);
lcd.position.set(217,60,46.55);
schneider.add(lcd);
let panelSideMiddleElemGeometry = new Three.BoxGeometry(width,5,depth);
let panelSideElemMiddle = new Three.Mesh(panelSideMiddleElemGeometry, grey);
panelSideElemMiddle.position.x+=129;
panelSideElemMiddle.position.y-=10;
schneider.add(panelSideElemMiddle);
let panelSideElemFooter = new Three.Mesh(panelSideMiddleElemGeometry, black);
panelSideElemFooter.position.x+=129;
panelSideElemFooter.position.y-=97.5;
schneider.add(panelSideElemFooter);
return schneider
}
export default {
name: "schneider",
prototype: "items",
info: {
tag: ['metal'],
title: "schneider",
description: "schneider",
image: require('./schneider.png')
},
properties: {
patternColor: {
label: "pattern colori",
type: "color",
defaultValue: "#f5f4f4"
},
altitude: {
label: "altitude",
type: "length-measure",
defaultValue: {
length: 0,
unit: 'cm'
}
}
},
render2D: function (element, layer, scene) {
let fillValue = element.selected ? "#99c3fb" : element.properties.get('patternColor');
let angle = element.rotation + 90;
let textRotation = 0;
if (Math.sin(angle * Math.PI / 180) < 0) {
textRotation = 180;
}
return (
<g transform={`translate(${-width / 2},${-depth / 2})`}>
<rect key="1" x="0" y="0" width={width} height={depth}
style={{stroke: element.selected ? '#0096fd' : '#000', strokeWidth: "2px", fill: fillValue}}/>
<text key="2" x="0" y="0"
transform={`translate(${width / 2}, ${depth / 2}) scale(1,-1) rotate(${textRotation})`}
style={{textAnchor: "middle", fontSize: "11px"}}>
{element.get('name')}
</text>
</g>
)
},
render3D: function (element, layer, scene) {
let newAltitude = element.properties.get('altitude').get('length');
/**************** LOD max ***********************/
let rackMaxLOD=new Three.Object3D();
let objectMaxLOD = makeObjectMaxLOD(width,height,depth);
rackMaxLOD.add(objectMaxLOD.clone());
rackMaxLOD.rotation.y=Math.PI;
rackMaxLOD.position.x+= width/2;
rackMaxLOD.position.y+= height/1.8 + newAltitude;
/**************** LOD min ***********************/
let rackMinLOD=new Three.Object3D();
let objectMinLOD = makeObjectMinLOD(width,height,depth);
rackMinLOD.add(objectMinLOD.clone());
rackMinLOD.rotation.y=Math.PI;
rackMinLOD.position.x+= width/2;
rackMinLOD.position.y+= height/1.8 + newAltitude;
/*** add all Level of Detail ***/
let lod = new Three.LOD();
lod.addLevel(rackMaxLOD, 100);
lod.addLevel(rackMinLOD, 1800);
lod.updateMatrix();
lod.matrixAutoUpdate = false;
if (element.selected) {
let bbox = new Three.BoxHelper(lod, 0x99c3fb);
bbox.material.linewidth = 5;
bbox.renderOrder = 1000;
bbox.material.depthTest = false;
lod.add(bbox);
}
return Promise.resolve(lod);
}
};