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.

396 lines (345 loc) 14.9 kB
import React from 'react'; import * as Three from 'three'; const black = new Three.MeshLambertMaterial({color : 0x000000}); const green = new Three.MeshLambertMaterial( {color : 0x348781}); const red = new Three.MeshLambertMaterial({color : 0xFF0000}); const turquoise = new Three.MeshLambertMaterial({color : 0x43C6DB,opacity :0.7,transparent: true}); const metalBlue = new Three.MeshLambertMaterial({color : 0xB7CEEC}); const darkGrey = new Three.MeshLambertMaterial({color : 0x313131}); const darkGrey2 = new Three.MeshLambertMaterial({color : 0x212121}); const metalBlueGrey = new Three.MeshLambertMaterial({color : 0x566D7E}); function makePanicDoor() { let panicDoorDouble = new Three.Mesh(); let doorLeft = makeDoorStructure(); let doorRight = makeDoorStructure(); let handle = makeHandle(); let doorLeftPivot = makePivot(); let doorRightPivot = makePivot(); let safetyHandleLeft = makeSafetyHandle(); let safetyHandleRight = makeSafetyHandle(); let lock = makeLock(); let doorLockLeft = makeDoorLock(); let doorLockRight = makeDoorLock(); lock.position.set(-0.05, -0.02, 0.03); handle.position.set(-0.47 / 2, 0.85 / 2, -0.03); doorLeftPivot.position.set(0.595 / 2, 0, -0.06 / 2); doorRightPivot.position.set(0.6 / 2, 0, 0.077 / 2); doorRight.rotation.y = Math.PI; doorRight.position.set(-0.35 / 2 - 0.084, 0, 0.0043); doorLeft.position.set(0.35 / 2 + 0.084, 0, -0.0043); safetyHandleLeft.position.set(0, 0.4, 0.06 / 2); safetyHandleRight.position.set(0, 0.4, -0.062 / 2); handle.add(lock); doorLeft.add(handle); doorLeft.add(safetyHandleLeft); doorRight.add(safetyHandleRight); doorLeft.add(doorLeftPivot); panicDoorDouble.add(doorLeft); doorRight.add(doorRightPivot); doorLeft.add(doorLockLeft); doorRight.add(doorLockRight); panicDoorDouble.add(doorRight); return panicDoorDouble } function makeDoorLock() { let block = new Three.Object3D(); let DoorLockGeometry1 = new Three.CylinderGeometry(0.012, 0.012, 1.905, Math.round(32)); let DoorLockGeometry2 = new Three.CylinderGeometry(0.007, 0.007, 1.907, Math.round(32)); let DoorLock1 = new Three.Mesh(DoorLockGeometry1, metalBlue); let DoorLock2 = new Three.Mesh(DoorLockGeometry2, metalBlueGrey); block.position.set(-0.275, 0.7 / 2, 0); block.scale.x = 1 / 1.3; DoorLock1.add(DoorLock2); block.add(DoorLock1); return block; } function makeLock() { let mechanism = new Three.Object3D(); let BaseGeometry = new Three.BoxGeometry(0.01, 0.1, 0.02); let FirstBlockGeometry = new Three.BoxGeometry(0.01, 0.02, 0.01); let SecondBlockGeometry = new Three.BoxGeometry(0.006, 0.04, 0.008); let base = new Three.Mesh(BaseGeometry, metalBlue); let FirstBlock = new Three.Mesh(FirstBlockGeometry, metalBlueGrey); let SecondBlock = new Three.Mesh(SecondBlockGeometry, metalBlueGrey); FirstBlock.position.set(-0.008 / 2, 0.03, 0); SecondBlock.position.y = -0.05; FirstBlock.add(SecondBlock); base.add(FirstBlock); mechanism.add(base); return mechanism; } function makeSafetyHandle() { let handle = new Three.Object3D(); let handleSupportGeometry = new Three.BoxGeometry(0.5, 0.1, 0.005); let PushButtonGeometry = new Three.CylinderGeometry(0.04, 0.04, 0.48, Math.round(32 )); let PushButtonCoverGeometry = new Three.CylinderGeometry(0.042, 0.042, 0.01, Math.round(32 )); let handleSupport = new Three.Mesh(handleSupportGeometry, black); let pushButton = new Three.Mesh(PushButtonGeometry, red); let pushButtonCover1 = new Three.Mesh(PushButtonCoverGeometry, black); let pushButtonCover2 = new Three.Mesh(PushButtonCoverGeometry, black); handleSupport.position.z = 0.005 / 2; pushButton.rotation.z = Math.PI / 2; pushButtonCover1.position.y = 0.48 / 2 + 0.01 / 2; pushButtonCover2.position.y = -0.48 / 2 - 0.01 / 2; pushButton.add(pushButtonCover1); pushButton.add(pushButtonCover2); handleSupport.add(pushButton); handle.add(handleSupport); return handle; } function makePivot() { let DoorPivot = new Three.Object3D(); let DownPivotGeometry = new Three.CylinderGeometry(0.009, 0.009, 0.04, Math.round(32 )); let UpPivotGeometry = new Three.CylinderGeometry(0.01, 0.01, 0.04, Math.round(32 )); let downPivot1 = new Three.Mesh(DownPivotGeometry, green); let upPivot1 = new Three.Mesh(UpPivotGeometry, green); let downPivot2 = new Three.Mesh(DownPivotGeometry, green); let upPivot2 = new Three.Mesh(UpPivotGeometry, green); downPivot1.position.y = -0.4; upPivot1.position.y = 0.04; downPivot2.position.y = 1; upPivot2.position.y = 0.04; downPivot2.add(upPivot2); downPivot1.add(upPivot1); DoorPivot.add(downPivot2); DoorPivot.add(downPivot1); return DoorPivot; } function makeHandle() { let handle = new Three.Object3D(); let handleBase = makeHandleBase(); let hilt = makeHilt(); hilt.rotation.x = Math.PI / 2; hilt.position.set(0, 0.04, -0.03 / 2 - 0.01 / 2); handle.add(handleBase); handle.add(hilt); handle.scale.set(1.1, 1.1, 1.1); return handle; } function makeHilt() { let hilt = new Three.Object3D(); let GeometryPiece1 = new Three.CylinderGeometry(0.01, 0.01, 0.03, Math.round(32 )); let GeometryPiece2 = new Three.SphereGeometry(0.01, Math.round(32 ), Math.round(32 )); let GeometryPiece3 = new Three.CylinderGeometry(0.01, 0.01, 0.07, Math.round(32 )); let piece1 = new Three.Mesh(GeometryPiece1, black); let piece2 = new Three.Mesh(GeometryPiece2, black); let piece3 = new Three.Mesh(GeometryPiece3, black); let piece4 = new Three.Mesh(GeometryPiece2, black); piece3.rotation.z = Math.PI / 2; piece3.position.x = 0.07 / 2; piece2.position.y = -0.03 / 2; piece4.position.y = -0.07 / 2; piece3.add(piece4); piece2.add(piece3); piece1.add(piece2); hilt.add(piece1); return hilt; } function makeHandleBase() { let base = new Three.Object3D(); let BaseGeometry1 = new Three.BoxGeometry(0.038, 0.14, 0.01); let BaseGeometry2 = new Three.CylinderGeometry(0.023, 0.023, 0.01, Math.round(32 )); let lock = makeLockKey(); let base1 = new Three.Mesh(BaseGeometry1, black); let base2 = new Three.Mesh(BaseGeometry2, black); lock.rotation.x = Math.PI / 2; lock.position.y = -0.03; base2.rotation.x = Math.PI / 2; base2.position.y = -0.033; base2.scale.z = 1.5; base1.add(lock); base1.add(base2); base.add(base1); return base; } function makeLockKey() { let lock = new Three.Object3D(); let geometryLock1 = new Three.CylinderGeometry(0.005, 0.005, 0.02, Math.round(32 )); let geometryLock2 = new Three.BoxGeometry(0.008, 0.02, 0.02); let geometryLock3 = new Three.BoxGeometry(0.007, 0.0203, 0.0018); let lockPiece1 = new Three.Mesh(geometryLock1, metalBlue); let lockPiece2 = new Three.Mesh(geometryLock2, metalBlue); let lockPiece3 = new Three.Mesh(geometryLock3, metalBlueGrey); lockPiece2.position.z = 0.01; lockPiece1.add(lockPiece2); lockPiece1.add(lockPiece3); lock.add(lockPiece1); return lock; } function makeDoorStructure() { let door = new Three.Object3D(); let lowBaseDoorGeometry = new Three.BoxGeometry(0.6,1.2,0.01); let middleBaseDoorGeometry = new Three.BoxGeometry(0.2,0.7,0.01); let highBaseDoorGeometry = new Three.BoxGeometry(0.2,0.2,0.01); let BorderCoverDoorGeometry1 = new Three.CylinderGeometry(0.005,0.005,1.9,Math.round(32)); let BorderCoverDoorGeometry2 = new Three.BoxGeometry(0.03,1.9,0.01); let MiddleDoorGeometry2 = new Three.BoxGeometry(0.2,0.7,0.06); let MiddleDoorGeometry1 = new Three.BoxGeometry(0.19,0.7,0.06); let HighDoorGeometry = new Three.BoxGeometry(0.2,0.2,0.06); let glassGeometry = new Three.BoxGeometry(0.2,0.5,0.05); let LowDoorGeometry = new Three.BoxGeometry(0.59,1.2,0.06); let glassCoverVertical = new Three.BoxGeometry(0.01,0.52,0.064); let glassCoverHorizontal = new Three.BoxGeometry(0.224,0.01,0.064); let lowCoverDoor = new Three.Mesh( lowBaseDoorGeometry , green ); let middleDoor1 = new Three.Mesh( MiddleDoorGeometry1, green); let middleDoor2 = new Three.Mesh( MiddleDoorGeometry2, green); let baseDoor = new Three.Mesh( LowDoorGeometry, green ); let middleCoverDoor1 = new Three.Mesh( middleBaseDoorGeometry, green); let middleCoverDoor2 = new Three.Mesh( middleBaseDoorGeometry, green); let highCoverDoor = new Three.Mesh( highBaseDoorGeometry, green); let highDoor = new Three.Mesh( HighDoorGeometry, green); let borderCoverDoor1 = new Three.Mesh( BorderCoverDoorGeometry1, green); let borderCoverDoor2 = new Three.Mesh( BorderCoverDoorGeometry2, green); let glass = new Three.Mesh( glassGeometry, turquoise); let glassVerticalCover1 = new Three.Mesh( glassCoverVertical, green); let glassVerticalCover2 = new Three.Mesh( glassCoverVertical, green); let glassHorizontalCover1 = new Three.Mesh( glassCoverHorizontal, green); let glassHorizontalCover2 = new Three.Mesh( glassCoverHorizontal, green); lowCoverDoor.position.set(-(0.6-0.59)/2,0,-0.05/2); middleCoverDoor1.position.set(-0.2,1.2/2 +0.7/2,0); middleCoverDoor2.position.set(0.2,1.2/2 +0.7/2,0); highCoverDoor.position.set(0,(0.5 +0.2)/2,-0.05/2); highDoor.position.set(0,(0.5 +0.2)/2,-0.05/2 +0.05/2); glass.position.set(-0.01/2,1.2/2 +0.5/2,0); middleDoor2.position.z =0.05/2; middleDoor1.position.set(0.005,0,0.05/2); borderCoverDoor1.position.set(-0.6/2,0.7/2,0); glassVerticalCover1.position.x = 0.2/2 +0.014/2; glassVerticalCover2.position.x =-0.2/2 -0.014/2; glassHorizontalCover1.position.y = 0.5/2 +0.014/2; glassHorizontalCover2.position.y =-0.5/2 -0.014/2; borderCoverDoor2.position.set(0.02/2,0,-0.01/2 ); borderCoverDoor1.add(borderCoverDoor2); glass.add(highCoverDoor); glass.add(glassVerticalCover1); glass.add(glassVerticalCover2); glass.add(glassHorizontalCover1); glass.add(glassHorizontalCover2); glass.add(highCoverDoor); glass.add(highDoor); baseDoor.add(glass); middleCoverDoor1.add(middleDoor1); middleCoverDoor2.add(middleDoor2); lowCoverDoor.add(borderCoverDoor1); lowCoverDoor.add(middleCoverDoor1); lowCoverDoor.add(middleCoverDoor2); baseDoor.add(lowCoverDoor); door.add(baseDoor); door.scale.x = 0.9; return door; } export default { name: 'double panic door', prototype: 'holes', info: { tag: ['door'], title: 'double panic door', description: 'iron door', image: require('./panicDoorDouble.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: 'flip', type: 'checkbox', defaultValue: false, values: { 'none': false, 'yes': true } } }, render2D: function (element, layer, scene) { const STYLE_HOLE_BASE = {stroke: '#ff0000', strokeWidth: '3px', fill: '#ff0000'}; const STYLE_HOLE_SELECTED = {stroke: '#ff0000', strokeWidth: '4px', fill: '#ff0000', cursor: 'move'}; const STYLE_ARC_BASE = {stroke: '#ff0000', strokeWidth: '3px', strokeDasharray: '5,5', fill: 'none'}; const STYLE_ARC_SELECTED = {stroke: '#ff0000', strokeWidth: '4px', strokeDasharray: '5,5', fill: 'none', cursor: 'move'}; let epsilon = 3; let flip = element.properties.get('flip_horizontal'); let holeWidth = element.properties.get('width').get('length'); let holePath = `M${0} ${ -epsilon} L${holeWidth} ${-epsilon} L${holeWidth} ${epsilon} L${0} ${epsilon} z`; let arcPath = `M${0},${0} A${holeWidth/2},${holeWidth/2} 0 0,1 ${holeWidth/2},${holeWidth/2}`; let arcPath2 =`M${0},${0} A${holeWidth/2},${holeWidth/2} 0 0,0 ${holeWidth/2},${holeWidth/2}`; let holeStyle = element.selected ? STYLE_HOLE_SELECTED : STYLE_HOLE_BASE; let arcStyle = element.selected ? STYLE_ARC_SELECTED : STYLE_ARC_BASE; let length = element.properties.get('width').get('length'); if(flip){ return ( <g transform={`translate(${-element.properties.get('width').get('length') / 2}, 0)`}> <path key='1' d={arcPath} style={arcStyle} transform={`translate(${0},${-holeWidth/2})`}/> <line key='2' x1={0} y1={0 - epsilon} x2={0} y2={-holeWidth/2 - epsilon} style={holeStyle}/> <path key='3' d={arcPath2} style={arcStyle} transform={`translate(${holeWidth},${-holeWidth/2}) rotate(90)`}/> <line key='4' x1={holeWidth} y1={0 - epsilon} x2={holeWidth} y2={-holeWidth/2 - epsilon} style={holeStyle}/> <path key='5' d={holePath} style={holeStyle}/> </g> ) } else { return ( <g transform={`translate(${-element.properties.get('width').get('length') / 2}, 0)`}> <path key='1' d={arcPath} style={arcStyle} transform={`translate(${holeWidth},${holeWidth/2}) rotate(180)`}/> <line key='2' x1={0} y1={0 - epsilon} x2={0} y2={holeWidth/2 - epsilon} style={holeStyle}/> <path key='3' d={arcPath2} style={arcStyle} transform={`translate(${0},${holeWidth/2}) rotate(270)`}/> <line key='4' x1={holeWidth} y1={0 - epsilon} x2={holeWidth} y2={holeWidth/2 - epsilon} style={holeStyle}/> <path key='5' d={holePath} style={holeStyle}/> </g> ) } }, render3D: function (element, layer, scene) { let flip = element.properties.get('flip_horizontal'); 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'); let panicDoorDouble = new Three.Object3D(); panicDoorDouble.add(makePanicDoor().clone()); let valuePosition = new Three.Box3().setFromObject(panicDoorDouble); 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(panicDoorDouble, 0x99c3fb); boundingBox.material.linewidth = 5; boundingBox.renderOrder = 1000; boundingBox.material.depthTest = false; panicDoorDouble.add(boundingBox); } if(flip) panicDoorDouble.rotation.y+=Math.PI; panicDoorDouble.position.y+= newAltitude; panicDoorDouble.scale.set( width / deltaX, height / deltaY,thickness / deltaZ); return Promise.resolve(panicDoorDouble); } };