react-planner
Version:
react-planner is a React Component for plans design. Draw a 2D floorplan and navigate it in 3D mode.
159 lines (120 loc) • 4.94 kB
JSX
import * as Three from 'three';
import React from 'react';
const WIDTH = 200;
const DEPTH = 20;
const HEIGHT = 40;
export default {
name: 'coat-hook',
prototype: 'items',
info: {
tag: ['furnishings', 'optional'],
title: 'Coat hook',
description: 'Coat hook',
image: require('./coat-hook.png')
},
properties: {
altitude: {
label: 'altitude',
type: 'length-measure',
defaultValue: {
length: 120,
unit: 'cm'
}
}
},
render2D: function (element, layer, scene) {
let angle = element.rotation + 90;
let textRotation = 0;
if (Math.sin(angle * Math.PI / 180) < 0) {
textRotation = 180;
}
let rect_style = {stroke: element.selected ? '#0096fd' : '#000', strokeWidth: '2px', fill: '#84e1ce'};
let arrow_style = {stroke: element.selected ? '#0096fd' : null, strokeWidth: '2px', fill: '#84e1ce'};
return (
<g transform={`translate(${-WIDTH / 2},${-DEPTH / 2})`}>
<rect key='1' x='0' y='0' width={WIDTH} height={DEPTH} style={rect_style}/>
<line key='2' x1={WIDTH / 2} x2={WIDTH / 2} y1={DEPTH} y2={1.5 * DEPTH} style={arrow_style}/>
<line key='3' x1={.45 * WIDTH} x2={WIDTH / 2} y1={1.2 * DEPTH} y2={1.5 * DEPTH} style={arrow_style}/>
<line key='4' x1={WIDTH / 2} x2={.55 * WIDTH} y1={1.5 * DEPTH} y2={1.2 * DEPTH} style={arrow_style}/>
<text key='5' x='0' y='0'
transform={`translate(${WIDTH / 2}, ${DEPTH / 2}) scale(1,-1) rotate(${textRotation})`}
style={{textAnchor: 'middle', fontSize: '11px'}}>
{element.type}
</text>
</g>
)
},
render3D: function (element, layer, scene) {
let newAltitude = element.properties.get('altitude').get('length');
let coatHook = new Three.Object3D();
let newWidth = 2.15;
let newDepth = .04;
let newHeight = .1;
let radius = .0125;
let texture = new Three.TextureLoader().load(require('./wood.jpg'));
let materialTexture = new Three.MeshLambertMaterial({map: texture});
let geometry = new Three.BoxGeometry(newWidth, 1.5 * newHeight, newDepth);
//let material = new Three.MeshLambertMaterial( {color: 0x9b8c75} );
let plane = new Three.Mesh(geometry, materialTexture);
plane.position.y = newHeight / 2;
coatHook.add(plane);
let geometry_legs = new Three.CylinderGeometry(radius, radius, newHeight / 1.7, 32);
let material_legs = new Three.MeshLambertMaterial({color: 0xd9d7d7});
let p1 = new Three.Mesh(geometry_legs, material_legs);
p1.rotation.x += Math.PI / 2;
p1.position.set(1, 0.05, 0.05);
coatHook.add(p1);
let p2 = new Three.Mesh(geometry_legs, material_legs);
p2.rotation.x += Math.PI / 2;
p2.position.set(-.95, 0.05, 0.05);
coatHook.add(p2);
let geometrySphereUp = new Three.SphereGeometry(0.035, 32, 32);
let sphere = new Three.Mesh(geometrySphereUp, material_legs);
sphere.position.set(1, 0.05, 0.08);
sphere.scale.set(1, 1, .5);
coatHook.add(sphere);
let sphere2 = new Three.Mesh(geometrySphereUp, material_legs);
sphere2.position.set(-.95, 0.05, 0.08);
sphere2.scale.set(1, 1, .5);
coatHook.add(sphere2);
let newHeight2 = .2;
let curve = new Three.CatmullRomCurve3([
new Three.Vector3(.05, 0.125, 0),
new Three.Vector3(.125, .025, 0),
new Three.Vector3(-.05, -.075, 0),
]);
for (let i = -0.95; i <= 1.05; i += 0.15) {
let geometry_legs2 = new Three.CylinderGeometry(radius, radius, newHeight2, 32);
let p3 = new Three.Mesh(geometry_legs2, material_legs);
p3.position.set(i, -0.05, 0);
coatHook.add(p3);
let geometry3 = new Three.TubeGeometry(curve, 32, .015, 16, false);
let mesh3 = new Three.Mesh(geometry3, material_legs);
mesh3.position.set(i, -.05, .045);
mesh3.rotation.y -= Math.PI / 2;
mesh3.rotation.x += Math.PI + Math.PI / 7.5;
mesh3.rotation.z += Math.PI / 2;
coatHook.add(mesh3);
let geometrySphere = new Three.SphereGeometry(0.035, 32, 32);
let sphereTop = new Three.Mesh(geometrySphere, material_legs);
sphereTop.position.set(i, -0.142, 0.15);
sphereTop.rotation.x += Math.PI / 2 + Math.PI / 3;
coatHook.add(sphereTop);
}
let value = new Three.Box3().setFromObject(coatHook);
let deltaX = Math.abs(value.max.x - value.min.x);
let deltaY = Math.abs(value.max.y - value.min.y);
let deltaZ = Math.abs(value.max.z - value.min.z);
if (element.selected) {
let bbox = new Three.BoxHelper(coatHook, 0x99c3fb);
bbox.material.linewidth = 5;
bbox.renderOrder = 1000;
bbox.material.depthTest = false;
coatHook.add(bbox);
}
coatHook.rotation.y += Math.PI;
coatHook.position.y += HEIGHT / 1.5 + newAltitude;
coatHook.scale.set(WIDTH / deltaX, HEIGHT / deltaY, DEPTH / deltaZ);
return Promise.resolve(coatHook);
}
};