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.

268 lines (213 loc) 8.34 kB
import React from 'react'; import * as Three from 'three'; import {loadObjWithMaterial} from '../../utils/load-obj'; import path from 'path'; let cached3DWindow = null; export default { name: 'venetian-blind-window', prototype: 'holes', info: { tag: ['Window'], title: 'Venetian Blind Window', description: 'Venetian Blind Window', image: require('./venetian.jpg') }, properties: { width: { label: 'Width', type: 'length-measure', defaultValue: { length: 90 } }, height: { label: 'Height', type: 'length-measure', defaultValue: { length: 100 } }, altitude: { label: 'Altitude', type: 'length-measure', defaultValue: { length: 90 } }, thickness: { label: 'Thickness', type: 'length-measure', defaultValue: { length: 10 } }, flip: { label: 'Flip', type: 'checkbox', defaultValue: 'false', }, }, render2D: function (element, layer, scene) { const STYLE_HOLE_BASE = {stroke: '#000', strokeWidth: '3px', fill: '#000'}; const STYLE_HOLE_SELECTED = {stroke: '#0096fd', strokeWidth: '3px', fill: '#0096fd', cursor: 'move'}; let epsilon = 3; let holeWidth = element.properties.get('width').get('length'); let holePath = `M${0} ${ -epsilon} L${holeWidth} ${-epsilon} L${holeWidth} ${epsilon} L${0} ${epsilon} z`; let holeStyle = element.selected ? STYLE_HOLE_SELECTED : STYLE_HOLE_BASE; let length = element.properties.get('width').get('length'); return ( <g transform={`translate(${-length / 2}, 0)`}> <path key='1' d={holePath} style={holeStyle}/> <line key='2' x1={holeWidth / 2} y1={-10 - epsilon} x2={holeWidth / 2} y2={10 + epsilon} style={holeStyle}/> </g> ); }, render3D: function (element, layer, scene) { 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 flip = element.properties.get('flip'); let onLoadItem = (object) => { let venetian = new Three.Object3D(); let boundingBox = new Three.Box3().setFromObject(object); let initialWidth = boundingBox.max.x - boundingBox.min.x; let initialHeight = boundingBox.max.y - boundingBox.min.y; let initialThickness = boundingBox.max.z - boundingBox.min.z; if (element.selected) { let box = new Three.BoxHelper(object, 0x99c3fb); box.material.linewidth = 2; box.material.depthTest = false; box.renderOrder = 1000; object.add(box); } let width = element.properties.get('width').get('length'); let height = element.properties.get('height').get('length'); let thickness = element.properties.get('thickness').get('length'); object.scale.set(width / initialWidth, height / initialHeight, thickness/2 / initialThickness); venetian.add(object); venetian.add(createTenda()); if(flip === true) venetian.rotation.y += Math.PI; return venetian; }; if(cached3DWindow) { return Promise.resolve(onLoadItem(cached3DWindow.clone()));; } let mtl = require('./venetian.mtl'); let obj = require('./venetian.obj'); let img = require('./texture.png'); return loadObjWithMaterial(mtl, obj, path.dirname(img) + '/') .then(object => { cached3DWindow = object; return onLoadItem(cached3DWindow.clone()); }); function createTenda() { var venetian = new Three.Object3D(); //colors var white = new Three.MeshLambertMaterial( {color: 0xffffff, opacity:0.5, transparent:true} ); var grey = new Three.MeshLambertMaterial( {color: 0xCCCCCC} ); var roundedRectShape = new Three.Shape(); var x=0; var y=0; var width=1; var height=18; var radius=0.25; roundedRectShape.moveTo( x, y + radius ); roundedRectShape.lineTo( x, y + height - radius ); roundedRectShape.quadraticCurveTo( x, y + height, x + radius, y + height ); roundedRectShape.lineTo( x + width - radius, y + height) ; roundedRectShape.quadraticCurveTo( x + width, y + height, x + width, y + height - radius ); roundedRectShape.lineTo( x + width, y + radius ); roundedRectShape.quadraticCurveTo( x + width, y, x + width - radius, y ); roundedRectShape.lineTo( x + radius, y ); roundedRectShape.quadraticCurveTo( x, y, x, y + radius ); var holePath1 = new Three.Path(); holePath1.moveTo( 0.5, 0.6 ); holePath1.arc(0, .7, .15 ,0, Math.PI,false); holePath1.arc(0.15, -.09, .15 ,Math.PI,0,false); roundedRectShape.holes.push( holePath1 ); var holePath2 = new Three.Path(); holePath2.moveTo( 0.5, 4.6 ); holePath2.arc(0, .7, .15 ,0, Math.PI,false); holePath2.arc(0.15, -.09, .15 ,Math.PI,0,false); roundedRectShape.holes.push( holePath2 ); var holePath3 = new Three.Path(); holePath3.moveTo( 0.5, 8.6 ); holePath3.arc(0, .7, .15 ,0, Math.PI,false); holePath3.arc(0.15, -.09, .15 ,Math.PI,0,false); roundedRectShape.holes.push( holePath3 ); var holePath4 = new Three.Path(); holePath4.moveTo( 0.5, 12.6 ); holePath4.arc(0, .7, .15 ,0, Math.PI,false); holePath4.arc(0.15, -.09, .15 ,Math.PI,0,false); roundedRectShape.holes.push( holePath4 ); var holePath5 = new Three.Path(); holePath5.moveTo( 0.5, 16.6 ); holePath5.arc(0, .7, .15 ,0, Math.PI,false); holePath5.arc(0.15, -.09, .15 ,Math.PI,0,false); roundedRectShape.holes.push( holePath5 ); var extrudeSettings = { steps: 1, depth: 0.2, bevelEnabled: false, bevelThickness: .4, bevelSize: .4, bevelSegments: 1 }; for (var i = 0; i < 25; i+=.7) { var geometry = new Three.ExtrudeGeometry( roundedRectShape, extrudeSettings ); var mesh = new Three.Mesh( geometry, grey ) ; mesh.position.set(0,i,0.86); mesh.rotation.z+=Math.PI/2; mesh.rotation.x+=-Math.PI/2; venetian.add(mesh); } for (var j = -1.25; j > -19; j+=-4) { var geometry1 = new Three.CylinderGeometry( 0.105, 0.105, 26, 32 ); var tubo = new Three.Mesh(geometry1,white); tubo.position.set(j,12.5,.35); venetian.add(tubo); } var roundedRectShape2 = new Three.Shape(); var x1=0; var y1=0; var width1=1; var height1=18; var radius1=0.25; roundedRectShape2.moveTo( x1, y1 + radius1 ); roundedRectShape2.lineTo( x1, y1 + height1 - radius1 ); roundedRectShape2.quadraticCurveTo( x1, y1 + height1, x1 + radius1, y1 + height1 ); roundedRectShape2.lineTo( x1 + width1 - radius1, y1 + height1) ; roundedRectShape2.quadraticCurveTo( x1 + width1, y1 + height1, x1 + width1, y1 + height1 - radius1 ); roundedRectShape2.lineTo( x1 + width1, y1 + radius1 ); roundedRectShape2.quadraticCurveTo( x1 + width1, y1, x1 + width1 - radius1, y1 ); roundedRectShape2.lineTo( x1 + radius1, y1 ); roundedRectShape2.quadraticCurveTo( x1, y1, x1, y1 + radius1 ); var extrudeSettings2 = { steps: 1, depth: 0.4, bevelEnabled: false, bevelThickness: .4, bevelSize: .4, bevelSegments: 1 }; for (var k = -.5; k < 27; k+=26) { var geometry2 = new Three.ExtrudeGeometry( roundedRectShape2, extrudeSettings2 ); var mesh2 = new Three.Mesh( geometry2, grey ) ; mesh2.position.set(0,k,1); mesh2.rotation.z+=Math.PI/2; mesh2.rotation.x+=-Math.PI/2; venetian.add(mesh2); } let valueObject = new Three.Box3().setFromObject(venetian); let deltaX = Math.abs(valueObject.max.x - valueObject.min.x); let deltaY = Math.abs(valueObject.max.y - valueObject.min.y); let deltaZ = Math.abs(valueObject.max.z - valueObject.min.z); venetian.position.x+=width1/.025; venetian.position.y+=-height1/.4; venetian.scale.set(5.2*width1 / deltaZ, 5.45*height1 / deltaY, 2.5*thickness / deltaX); return venetian; } } };