UNPKG

react-planner

Version:

react-planner is a React Component for plans design. Draw a 2D floorplan and navigate it in 3D mode.

200 lines (157 loc) 5.35 kB
import * as Three from 'three'; import React from 'react'; const RADIUS = 3; const PlaneMaterial = new Three.MeshLambertMaterial( {color: 0x9b8c75} ); const material_legs = new Three.MeshLambertMaterial( {color: 0xd9d7d7} ); function makeObjectMaxLOD(newWidth,newHeight,newDepth) { let table = new Three.Mesh(); let PlaneGeometry = new Three.BoxGeometry( newWidth, newHeight/20, newDepth ); let plane = new Three.Mesh( PlaneGeometry, PlaneMaterial ); plane.position.y = newHeight; table.add(plane); let geometry_legs = new Three.CylinderGeometry( RADIUS, RADIUS, newHeight, 32, 32 ); let leg1 = new Three.Mesh( geometry_legs, material_legs ); leg1.position.x = newWidth/2; leg1.position.z = newDepth/2; leg1.position.y = newHeight/2; table.add(leg1); let leg2 = new Three.Mesh( geometry_legs, material_legs ); leg2.position.x = newWidth/2; leg2.position.z = -newDepth/2; leg2.position.y = newHeight/2; table.add(leg2); let leg3 = new Three.Mesh( geometry_legs, material_legs ); leg3.position.x = -newWidth/2; leg3.position.z = newDepth/2; leg3.position.y = newHeight/2; table.add(leg3); let leg4 = new Three.Mesh( geometry_legs, material_legs ); leg4.position.x = -newWidth/2; leg4.position.z = -newDepth/2; leg4.position.y = newHeight/2; table.add(leg4); return table; } function makeObjectMinLOD(newWidth,newHeight,newDepth) { let table = new Three.Mesh(); let PlaneGeometry = new Three.BoxGeometry( newWidth, newHeight/20, newDepth ); let plane = new Three.Mesh( PlaneGeometry, PlaneMaterial ); plane.position.y = newHeight; table.add(plane); let geometry_legs = new Three.CylinderGeometry( RADIUS, RADIUS, newHeight, 8, 8 ); let leg1 = new Three.Mesh( geometry_legs, material_legs ); leg1.position.x = newWidth/2; leg1.position.z = newDepth/2; leg1.position.y = newHeight/2; table.add(leg1); let leg2 = new Three.Mesh( geometry_legs, material_legs ); leg2.position.x = newWidth/2; leg2.position.z = -newDepth/2; leg2.position.y = newHeight/2; table.add(leg2); let leg3 = new Three.Mesh( geometry_legs, material_legs ); leg3.position.x = -newWidth/2; leg3.position.z = newDepth/2; leg3.position.y = newHeight/2; table.add(leg3); let leg4 = new Three.Mesh( geometry_legs, material_legs ); leg4.position.x = -newWidth/2; leg4.position.z = -newDepth/2; leg4.position.y = newHeight/2; table.add(leg4); return table; } export default { name: "table", prototype: "items", info: { tag: ['furnishings', 'wood'], title: "table", description: "table", image: require('./table.png') }, properties: { width: { label: "width", type: "length-measure", defaultValue: { length: 90, unit: 'cm' } }, depth: { label: "depth", type: "length-measure", defaultValue: { length: 50, unit: 'cm' } }, height: { label: "height", type: "length-measure", defaultValue: { length: 80, unit: 'cm' } }, altitude: { label: "altitude", type: "length-measure", defaultValue: { length: 0, unit: 'cm' } } }, render2D: function (element, layer, scene) { let newWidth = element.properties.get('width').get('length'); let newDepth = element.properties.get('depth').get('length'); let angle = element.rotation + 90; let textRotation = 0; if (Math.sin(angle * Math.PI / 180) < 0) { textRotation = 180; } return ( <g transform={`translate(${-newWidth / 2},${-newDepth / 2})`}> <rect key="1" x="0" y="0" width={newWidth} height={newDepth} style={{stroke: element.selected ? '#0096fd' : '#000', strokeWidth: "2px", fill: "#84e1ce"}}/> <text key="2" x="0" y="0" transform={`translate(${newWidth / 2}, ${newDepth / 2}) scale(1,-1) rotate(${textRotation})`} style={{textAnchor: "middle", fontSize: "11px"}}> {element.type} </text> </g> ) }, render3D: function (element, layer, scene) { let newWidth = element.properties.get('width').get('length'); let newDepth = element.properties.get('depth').get('length'); let newHeight = element.properties.get('height').get('length'); let newAltitude = element.properties.get('altitude').get('length'); /********** lod max ************/ let tableMaxLOD = new Three.Object3D(); let objectMaxLod = makeObjectMaxLOD(newWidth,newHeight,newDepth); tableMaxLOD.add(objectMaxLod.clone()); tableMaxLOD.position.y += newHeight/20 + newAltitude; /********** lod min ************/ let tableMinLOD = new Three.Object3D(); let objectMinLod = makeObjectMinLOD(newWidth,newHeight,newDepth); tableMinLOD.add(objectMinLod.clone()); tableMinLOD.position.y += newHeight/20 + newAltitude; /**** all level of detail ***/ let lod = new Three.LOD(); lod.addLevel(tableMaxLOD, 200); lod.addLevel(tableMinLOD, 900); 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); } };