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.

453 lines (400 loc) 15.1 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}); let flip_value; let handleSide_value; function makePanicDoor(handleSide) { let panicDoor = new Three.Mesh(); let leftDoor = makeDoorStructure(); let handle = makeHandle(handleSide); let leftDoorPivot = makePivot(); let rightDoorPivot = makePivot(); let safetyHandleLeft = makeSafetyHandle(); let safetyHandleRight = makeSafetyHandle(); let hilt = makeLock(); let doorLock = makeDoorLock(); hilt.position.set(-0.05,-0.02,0.03); handle.position.set(-0.47/2,0.85/2,-0.03); if(handleSide) { leftDoorPivot.position.set(0.595 / 2, 0, -0.06 / 2); } else { leftDoorPivot.position.set(-0.595 / 2, 0, -0.06 / 2); } rightDoorPivot.position.set(0.6/2 ,0,0.077/2); safetyHandleLeft.position.set(0,0.4,0.06/2); safetyHandleRight.position.set(0,0.4,-0.062/2); handle.add(hilt); leftDoor.add(handle); leftDoor.add(safetyHandleLeft); leftDoor.add(leftDoorPivot); panicDoor.add(leftDoor); leftDoor.add(doorLock); return panicDoor } function makeDoorLock () { let DoorLock = 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); DoorLock.position.set(-0.275,0.7/2,0); DoorLock.scale.x =1/1.3; doorLock1.add(doorLock2); DoorLock.add(doorLock1); return DoorLock; } function makeLock () { let mechanism = new Three.Object3D(); let BaseGeometry = new Three.BoxGeometry(0.01,0.1,0.02); let PieceGeometry1 = new Three.BoxGeometry(0.01,0.02,0.01); let PieceGeometry2 = new Three.BoxGeometry(0.006,0.04,0.008); let base = new Three.Mesh( BaseGeometry, metalBlue); let piece1 = new Three.Mesh( PieceGeometry1, metalBlueGrey); let piece2 = new Three.Mesh( PieceGeometry2, metalBlueGrey); piece1.position.set(-0.008/2,0.03,0); piece2.position.y =-0.05; piece1.add(piece2); base.add(piece1); mechanism.add(base); return mechanism; } function makeSafetyHandle () { let handle = new Three.Object3D(); let HandleSupportGeometry = new Three.BoxGeometry(0.5,0.1,0.005); let PushGeometry = new Three.CylinderGeometry(0.04,0.04,0.48,Math.round(32)); let CoverPushGeometry = new Three.CylinderGeometry(0.042,0.042,0.01,Math.round(32)); let handleSupport = new Three.Mesh( HandleSupportGeometry, black); let PushButton = new Three.Mesh( PushGeometry, red); let CoverPush1 = new Three.Mesh( CoverPushGeometry, black); let CoverPush2 = new Three.Mesh( CoverPushGeometry, black); handleSupport.position.z =0.005/2; PushButton.rotation.z =Math.PI/2; CoverPush1.position.y =0.48/2 +0.01/2; CoverPush2.position.y =-0.48/2 -0.01/2; PushButton.add(CoverPush1); PushButton.add(CoverPush2); 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 (handleSide_value) { let handle = new Three.Object3D(); let handleBase = makeHandleBase(handleSide_value); let hilt = makeHilt(); hilt.rotation.x = Math.PI / 2; if(handleSide_value) { hilt.position.set(0, 0.04, -0.03 / 2 - 0.01 / 2); } else { hilt.position.set(0.4, 0.04, -0.03 / 2 - 0.01 / 2); hilt.rotation.y = Math.PI ; } 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 Geometry_p1 = new Three.CylinderGeometry(0.01,0.01,0.03,Math.round(32)); let Geometry_p2 = new Three.SphereGeometry(0.01,Math.round(32),Math.round(32)); let Geometry_p3 = new Three.CylinderGeometry(0.01,0.01,0.07,Math.round(32)); let piece1 = new Three.Mesh( Geometry_p1, black); let piece2 = new Three.Mesh( Geometry_p2, black); let piece3 = new Three.Mesh( Geometry_p3, black); let piece4 = new Three.Mesh( Geometry_p2, 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 (handleSide_value) { 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; base2.rotation.x =Math.PI/2; lock.position.y = -0.03; base2.position.y = -0.033; if(!handleSide_value) base1.position.x = 0.4; base2.scale.z =1.5; base1.add(lock); base1.add(base2); base.add(base1); return base; } function makeLockKey () { let Lock = new Three.Object3D(); let geometry1 = new Three.CylinderGeometry(0.005,0.005,0.02,Math.round(32)); let geometry2 = new Three.BoxGeometry(0.008,0.02,0.02); let geometry3 = new Three.BoxGeometry(0.007,0.0203,0.0018); let LockPiece1 = new Three.Mesh( geometry1, metalBlue); let LockPiece2 = new Three.Mesh( geometry2, metalBlue); let LockPiece3 = new Three.Mesh( geometry3, 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 = 1.3; return door; } export default { name: 'panic door', prototype: 'holes', info: { tag: ['door'], title: 'panic door', description: 'iron door', image: require('./panicDoor.png') }, properties: { width: { label: 'width', type: 'length-measure', defaultValue: { length: 100, 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: '#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 handleSide = element.properties.get('flip_vertical'); 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},${holeWidth} 0 0,1 ${holeWidth},${holeWidth}`; 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'); let scaleX, scaleY; let rotateAngle; let tX, tY; let pX1, pX2, pY1, pY2; flip ? flip_value = 'yes' : flip_value = 'none'; handleSide ? handleSide_value = 'right' : handleSide_value = 'left'; if(flip_value === 'yes') { scaleX = 1; if (handleSide_value === 'right') { tX = holeWidth; tY = -holeWidth; pX1 = -holeWidth; pY1 = 0; pX2 = -holeWidth; pY2 = holeWidth; rotateAngle = 180; scaleY = -1; } else { tX = 0; tY = -holeWidth; pX1 = 0; pY1 = 0; pX2 = 0; pY2 = -holeWidth; scaleY = 1; rotateAngle = 0; } } else if (flip_value === 'none') { scaleX = -1; if (handleSide_value === 'left') { tX = holeWidth; tY = 0; pX1 = 0; pY1 = 0; pX2 = 0; pY2 = -holeWidth; rotateAngle = -90; scaleY = -1; } else{ tX = 0; tY = 0; pX1 = holeWidth; pY1 = 0; pX2 = holeWidth; pY2 = holeWidth; rotateAngle = 90; scaleY = 1; } } return ( <g transform={`translate(${-element.properties.get('width').get('length') / 2}, 0)`}> <path key='1' d={arcPath} style={arcStyle} transform={`translate(${tX},${tY}) scale(${scaleX},${scaleY}) rotate(${rotateAngle})`}/> <line key='2' x1={pX1} y1={pY1 - epsilon} x2={pX2} y2={pY2 - epsilon} style={holeStyle} transform={`scale(${-scaleX},${scaleY})`}/> <path key='5' d={holePath} style={holeStyle}/> </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'); let panicDoor = new Three.Object3D(); panicDoor.add(makePanicDoor(handleSide).clone()); if (element.selected) { let boundingBox = new Three.BoxHelper(panicDoor, 0x99c3fb); boundingBox.material.linewidth = 5; boundingBox.renderOrder = 1000; boundingBox.material.depthTest = false; panicDoor.add(boundingBox); } let valuePosition = new Three.Box3().setFromObject(panicDoor); 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(flip) panicDoor.rotation.y += Math.PI; panicDoor.position.y+= newAltitude; panicDoor.scale.set(width / deltaX, height / deltaY, thickness / deltaZ); return Promise.resolve(panicDoor); } };