UNPKG

react-planner-electron

Version:

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

245 lines (209 loc) 7 kB
import React from 'react'; import * as Three from 'three'; const grey = new Three.MeshLambertMaterial({color: 0x3f3f3f}); const white = new Three.MeshLambertMaterial({color: 0xffffff, transparent:true, opacity:0.5}); const black = new Three.MeshLambertMaterial({color: 0x000000}); function makeDoor(handleSide) { let slidingDoor = new Three.Mesh(); let doorShape = new Three.Shape(); doorShape.moveTo( 1, 2 ); doorShape.lineTo( 0, 2); doorShape.lineTo( 0, 0); doorShape.lineTo( 1, 0); let doorHole = new Three.Path(); doorHole.moveTo(.65, 1.75 ); doorHole.lineTo(.35, 1.75); doorHole.lineTo(.35, 1.25); doorHole.lineTo(.65, 1.25); doorShape.holes.push( doorHole ); let extrudeSettings = { steps: 2, depth: 0.05, bevelEnabled: false, bevelThickness: 1, bevelSize: 1, bevelSegments: 1 }; let geometry = new Three.ExtrudeGeometry( doorShape, extrudeSettings ); let door = new Three.Mesh( geometry, grey ) ; if(handleSide === 'right') door.position.set(-1,0,0); else door.position.set(0,0,0); slidingDoor.add(door); let doorGeometry = new Three.BoxGeometry(1,2,0.05); let door2 = new Three.Mesh(doorGeometry,grey); if (handleSide === 'right') door2.position.set(1.5,1,0.065); else door2.position.set(-.5,1,0.065); door.add(door2); let barGeometry = new Three.BoxGeometry(2,0.1,0.1); let doorBar = new Three.Mesh(barGeometry,grey); doorBar.position.set(-0,2.07,0.05); slidingDoor.add(doorBar); let glassGeometry = new Three.BoxGeometry(0.3,0.5,0.05); let glass = new Three.Mesh(glassGeometry,white); glass.position.set(0.5,1.5,0.025); door.add(glass); let HandleGeometry1 = new Three.CylinderGeometry(0.051,0.051,0.0625,80,80,true); black.side=Three.DoubleSide; let handle_p1 = new Three.Mesh(HandleGeometry1,black); handle_p1.position.set(0.2,1,0.025); handle_p1.rotation.x=Math.PI/2; door.add(handle_p1); let HandleGeometry2 = new Three.BoxGeometry(0.1,0.02,0.0625); let handle_p2 = new Three.Mesh( HandleGeometry2,black ); handle_p2.position.set(0.2,1,0.025); door.add(handle_p2); if (handleSide === 'left'){ handle_p1.position.x=0.8; handle_p2.position.x=0.8; } return slidingDoor } export default { name: 'sliding door', prototype: 'holes', info: { tag: ['door'], title: 'sliding door', description: 'iron door', image: require('./slidingDoor.png') }, properties: { width: { label: 'width', type: 'length-measure', defaultValue: { length: 200, unit: 'cm' } }, height: { label: 'height', type: 'length-measure', defaultValue: { length: 215, unit: 'cm' } }, thickness: { label: 'thickness', type: 'length-measure', defaultValue: { length: 30, unit: 'cm' } }, altitude: { label: 'altitude', type: 'length-measure', defaultValue: { length: 0, unit: 'cm' } }, flip_horizontal: { label: 'horizontal flip', type: 'checkbox', defaultValue: 'none', values: { 'none': 'none', 'yes': 'yes' } }, flip_vertical: { label: 'vertical flip', type: 'checkbox', defaultValue: 'right', values: { 'right': 'right', 'left': 'left' } } }, render2D: function (element, layer, scene) { const STYLE_HOLE_BASE = {stroke: '#000', strokeWidth: '14px', fill: '#000'}; const STYLE_HOLE_BASE2 = {stroke: '#000', strokeWidth: '16px', fill: '#000'}; const STYLE_HOLE_SELECTED = {stroke: '#0096fd', strokeWidth: '14px', fill: '#0096fd', cursor: 'move'}; let epsilon = 3; let flip = element.properties.get('flip_horizontal'); let handleSide = element.properties.get('flip_vertical'); let holeWidth = element.properties.get('width').get('length'); let holeStyle = element.selected ? STYLE_HOLE_SELECTED : STYLE_HOLE_BASE; let holeStyle2 = element.selected ? STYLE_HOLE_SELECTED : STYLE_HOLE_BASE2; let length = element.properties.get('width').get('length'); let scaleX, scaleY; let scaleX2, scaleY2; let pX1, pX2; flip ? flip = 'yes' : flip = 'none'; handleSide ? handleSide = 'right' : handleSide = 'left'; if(flip === 'yes') { scaleX = 1; if (handleSide === 'right') { pX1 = 0; pX2 = holeWidth/2; scaleY = -1; } else { pX1 = holeWidth/2; pX2 = holeWidth; scaleY = -1; } } else { scaleX = 1; if (handleSide === 'right') { pX1 = holeWidth/2; pX2 = holeWidth; scaleY = 1; } else { pX1 = 0; pX2 = holeWidth/2; scaleY = 1; } } return ( <g transform={`translate(${-element.properties.get('width').get('length') / 2}, 0)`}> <line key='1' x1='0' y1={0 - epsilon} x2={holeWidth} y2={0 - epsilon} style={holeStyle} transform={`scale(${scaleX},${scaleY})`}/> <line key='2' x1={pX1} y1={5 - epsilon} x2={pX2} y2={5 - epsilon} style={holeStyle2} transform={`scale(${scaleX},${scaleY})`}/> <line key='3' x1={holeWidth} y1={0 - epsilon} x2={holeWidth} y2={15 + epsilon} style={holeStyle2} transform={`scale(${scaleX},${scaleY})`}/> <line key='4' x1='0' y1={0 - epsilon} x2='0' y2={15 + epsilon} style={holeStyle2} transform={`scale(${scaleX},${scaleY})`}/> </g> ) }, render3D: function (element, layer, scene) { let flip = element.properties.get('flip_horizontal'); let handleSide = element.properties.get('flip_vertical'); let width = element.properties.get('width').get('length'); let height = element.properties.get('height').get('length'); let thickness = element.properties.get('thickness').get('length'); let newAltitude = element.properties.get('altitude').get('length'); flip ? flip = 'yes' : flip = 'none'; handleSide ? handleSide = 'right' : handleSide = 'left'; let slidingDoor = new Three.Object3D(); slidingDoor.add(makeDoor(handleSide).clone()); let valuePosition = new Three.Box3().setFromObject(slidingDoor); let deltaX = Math.abs(valuePosition.max.x - valuePosition.min.x); let deltaY = Math.abs(valuePosition.max.y - valuePosition.min.y); let deltaZ = Math.abs(valuePosition.max.z - valuePosition.min.z); if (element.selected) { let boundingBox = new Three.BoxHelper(slidingDoor, 0x99c3fb); boundingBox.material.linewidth = 5; boundingBox.renderOrder = 1000; boundingBox.material.depthTest = false; slidingDoor.add(boundingBox); } if(flip === 'yes') slidingDoor.rotation.y += Math.PI; slidingDoor.position.y+= newAltitude; slidingDoor.scale.set(width / deltaX, height / deltaY, thickness / deltaZ); return Promise.resolve(slidingDoor); } };