hart-estate-widget 0.0.6 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +78 -4
- package/build/assets/img/grass.png +0 -0
- package/build/assets/sass/components/loader.sass +51 -0
- package/build/assets/sass/components/model.sass +14 -0
- package/build/assets/sass/components/panorama.sass +98 -0
- package/build/assets/sass/index.sass +3 -0
- package/build/{Application.js → components/Application.js} +18 -8
- package/build/components/Loader.js +22 -0
- package/build/components/ModelTab.js +115 -0
- package/build/components/PanoramaTab.js +215 -0
- package/build/components/RotationTab.js +1 -1
- package/build/{Widget.js → components/Widget.js} +5 -10
- package/build/{defaultConfig.js → config/defaultConfig.js} +4 -1
- package/build/config/defaultJSON.js +2432 -0
- package/build/index.css +1 -0
- package/build/index.css.map +1 -0
- package/build/index.js +63 -5
- package/build/{lib/threesixty → threesixty}/events.js +0 -0
- package/build/{lib/threesixty → threesixty}/index.js +0 -0
- package/build/utils/modelHelpers.js +81 -0
- package/build/utils/panoramaHelpers.js +83 -0
- package/package.json +27 -11
package/README.md
CHANGED
@@ -1,7 +1,81 @@
|
|
1
|
-
# Компонент HART Estate
|
1
|
+
# Компонент HART Estate Widget
|
2
2
|
|
3
|
-
## Список доступных команд
|
4
3
|
|
5
|
-
|
4
|
+
## Способ установки с помощью NPM:
|
5
|
+
|
6
|
+
`npm install hart-estate-widget --save`
|
7
|
+
|
8
|
+
## Пример использования:
|
9
|
+
|
10
|
+
```js
|
11
|
+
import React, { useEffect, useState } from 'react';
|
12
|
+
import { Widget } from 'hart-estate-widget';
|
13
|
+
import 'hart-estate-widget/build/index.css';
|
14
|
+
|
15
|
+
const WIDGET_OPTIONS = {
|
16
|
+
tabs: ['planImage', 'topView', 'topDownView', 'rotation',],
|
17
|
+
tabPanes: true,
|
18
|
+
planImage: '/path/to/plan.jpg',
|
19
|
+
topView: '/path/to/top_view.jpg',
|
20
|
+
topDownView: '/path/to/top_down_view.jpg',
|
21
|
+
rotationImages: [
|
22
|
+
'/path/to/rotation_image_1.jpg',
|
23
|
+
'/path/to/rotation_image_2.jpg',
|
24
|
+
'/path/to/rotation_image_3.jpg',
|
25
|
+
'/path/to/rotation_image_4.jpg',
|
26
|
+
'/path/to/rotation_image_5.jpg',
|
27
|
+
],
|
28
|
+
};
|
29
|
+
|
30
|
+
const App = () => {
|
31
|
+
const [widget, setWidget] = useState(null);
|
32
|
+
|
33
|
+
useEffect(() => {
|
34
|
+
const createdWidget = new Widget('#widget-container', WIDGET_OPTIONS);
|
35
|
+
|
36
|
+
setState(createdWidget);
|
37
|
+
}, []);
|
38
|
+
|
39
|
+
return (
|
40
|
+
<div>
|
41
|
+
<div id="#widget-container" />
|
42
|
+
</div>
|
43
|
+
);
|
44
|
+
}
|
45
|
+
|
46
|
+
export App;
|
47
|
+
|
48
|
+
```
|
49
|
+
|
50
|
+
|
51
|
+
## Параметры:
|
52
|
+
|
53
|
+
```js
|
54
|
+
{
|
55
|
+
// элементы
|
56
|
+
tabs: ['planImage', 'topView', 'topDownView', 'rotation'], // включенные элементы
|
57
|
+
tabPanes: true,
|
58
|
+
|
59
|
+
// ширина/высота
|
60
|
+
width: 500,
|
61
|
+
height: 750,
|
62
|
+
|
63
|
+
// значения
|
64
|
+
planImage: '', // путь к изображению планировки
|
65
|
+
topView: '', // путь к изображению вида сверху
|
66
|
+
topDownView: '', // путь к изображению вида сверху под углом
|
67
|
+
rotationImages: [], // пути к изображениям кругового просмотра (порядок обязателен)
|
68
|
+
}
|
69
|
+
|
70
|
+
```
|
71
|
+
|
72
|
+
## Типы элементов
|
73
|
+
```js
|
74
|
+
tabs: [
|
75
|
+
'planImage', // изображение планировки
|
76
|
+
'topView', // изображение вида сверху
|
77
|
+
'topDownView', // изображение вида сверху под углом
|
78
|
+
'rotation', // изображения кругового просмотра (порядок обязателен)
|
79
|
+
]
|
80
|
+
```
|
6
81
|
|
7
|
-
### `npm run build` - билд приложения
|
Binary file
|
@@ -0,0 +1,51 @@
|
|
1
|
+
@import '../vars'
|
2
|
+
|
3
|
+
.widget-loader
|
4
|
+
display: block
|
5
|
+
position: relative
|
6
|
+
width: 80px
|
7
|
+
height: 80px
|
8
|
+
&--absolute
|
9
|
+
position: absolute
|
10
|
+
left: 50%
|
11
|
+
top: 50%
|
12
|
+
transform: translate(-50%, -50%)
|
13
|
+
div
|
14
|
+
position: absolute
|
15
|
+
top: 33px
|
16
|
+
width: 13px
|
17
|
+
height: 13px
|
18
|
+
border-radius: 50%
|
19
|
+
background: $mainColor
|
20
|
+
animation-timing-function: cubic-bezier(0, 1, 1, 0)
|
21
|
+
&:nth-child(1)
|
22
|
+
left: 8px
|
23
|
+
animation: widget-loader-1 0.6s infinite
|
24
|
+
&:nth-child(2)
|
25
|
+
left: 8px
|
26
|
+
animation: widget-loader-2 0.6s infinite
|
27
|
+
&:nth-child(3)
|
28
|
+
left: 32px
|
29
|
+
animation: widget-loader-2 0.6s infinite
|
30
|
+
&:nth-child(4)
|
31
|
+
left: 56px
|
32
|
+
animation: widget-loader-3 0.6s infinite
|
33
|
+
|
34
|
+
@keyframes widget-loader-1
|
35
|
+
0%
|
36
|
+
transform: scale(0)
|
37
|
+
100%
|
38
|
+
transform: scale(1)
|
39
|
+
|
40
|
+
@keyframes widget-loader-3
|
41
|
+
0%
|
42
|
+
transform: scale(1)
|
43
|
+
100%
|
44
|
+
transform: scale(0)
|
45
|
+
|
46
|
+
@keyframes widget-loader-2
|
47
|
+
0%
|
48
|
+
transform: translate(0, 0)
|
49
|
+
|
50
|
+
100%
|
51
|
+
transform: translate(24px, 0)
|
@@ -0,0 +1,98 @@
|
|
1
|
+
@import '../vars'
|
2
|
+
|
3
|
+
.widget-application
|
4
|
+
.widget-tab
|
5
|
+
&__panorama
|
6
|
+
width: 100%
|
7
|
+
height: 100%
|
8
|
+
position: absolute
|
9
|
+
left: 0
|
10
|
+
top: 0
|
11
|
+
&-overlay
|
12
|
+
width: 100%
|
13
|
+
height: 100%
|
14
|
+
overflow: hidden
|
15
|
+
&-mode,
|
16
|
+
&-standart
|
17
|
+
position: absolute
|
18
|
+
right: 15px
|
19
|
+
bottom: 20px
|
20
|
+
color: $black
|
21
|
+
background-color: $mainColor
|
22
|
+
padding: 5px 15px
|
23
|
+
border-radius: 10px
|
24
|
+
font-size: 1rem
|
25
|
+
font-weight: bold
|
26
|
+
border: none
|
27
|
+
cursor: pointer
|
28
|
+
@include noSelect
|
29
|
+
&:hover
|
30
|
+
box-shadow: 1px 1px 10px rgba(0, 0, 0, .15)
|
31
|
+
&-standart
|
32
|
+
right: 100px
|
33
|
+
&-map
|
34
|
+
position: absolute
|
35
|
+
right: 15px
|
36
|
+
bottom: 70px
|
37
|
+
z-index: 10000
|
38
|
+
img
|
39
|
+
width: 100px
|
40
|
+
border-radius: 10px
|
41
|
+
&.active
|
42
|
+
width: 240px
|
43
|
+
&:hover
|
44
|
+
box-shadow: 1px 1px 10px rgba(0,0,0,0.15)
|
45
|
+
&__dot
|
46
|
+
position: absolute
|
47
|
+
left: 0
|
48
|
+
top: 0
|
49
|
+
transform: translate(-50%, -50%)
|
50
|
+
width: 5px
|
51
|
+
height: 5px
|
52
|
+
background-color: $mainColor
|
53
|
+
border-radius: 50%
|
54
|
+
cursor: pointer
|
55
|
+
z-index: 10
|
56
|
+
&--big
|
57
|
+
border: 2px solid $mainColor
|
58
|
+
box-shadow: inset 0 0 0 2px #ffffff
|
59
|
+
width: 15px
|
60
|
+
height: 15px
|
61
|
+
&--active
|
62
|
+
background-color: red
|
63
|
+
border: 2px solid red
|
64
|
+
&-menu
|
65
|
+
position: absolute
|
66
|
+
z-index: 3
|
67
|
+
left: 15px
|
68
|
+
top: 15px
|
69
|
+
max-height: 100%
|
70
|
+
overflow-y: auto
|
71
|
+
padding-bottom: 30px
|
72
|
+
ul
|
73
|
+
list-style-type: none
|
74
|
+
li
|
75
|
+
color: $black
|
76
|
+
background-color: $mainColor
|
77
|
+
padding: 5px 15px
|
78
|
+
border-radius: 10px
|
79
|
+
font-size: .8rem
|
80
|
+
border: none
|
81
|
+
cursor: pointer
|
82
|
+
margin-bottom: 15px
|
83
|
+
width: 150px
|
84
|
+
@include noSelect
|
85
|
+
&:hover
|
86
|
+
box-shadow: 1px 1px 10px rgba(0, 0, 0, .15)
|
87
|
+
&:nth-child(1)
|
88
|
+
position: relative
|
89
|
+
&::after
|
90
|
+
content: '|||'
|
91
|
+
transform: translateY(-50%) rotate(90deg)
|
92
|
+
font-size: 20px
|
93
|
+
line-height: 20px
|
94
|
+
margin-left: 10px
|
95
|
+
display: block
|
96
|
+
position: absolute
|
97
|
+
right: 10px
|
98
|
+
top: 50%
|
@@ -11,17 +11,21 @@ var _react = _interopRequireWildcard(require("react"));
|
|
11
11
|
|
12
12
|
var _mobxReactLite = require("mobx-react-lite");
|
13
13
|
|
14
|
-
var _store = _interopRequireDefault(require("
|
14
|
+
var _store = _interopRequireDefault(require("../store"));
|
15
15
|
|
16
|
-
var _TabPanes = _interopRequireDefault(require("./
|
16
|
+
var _TabPanes = _interopRequireDefault(require("./TabPanes"));
|
17
17
|
|
18
|
-
var _ImageTab = _interopRequireDefault(require("./
|
18
|
+
var _ImageTab = _interopRequireDefault(require("./ImageTab"));
|
19
19
|
|
20
|
-
var _RotationTab = _interopRequireDefault(require("./
|
20
|
+
var _RotationTab = _interopRequireDefault(require("./RotationTab"));
|
21
21
|
|
22
|
-
var
|
22
|
+
var _PanoramaTab = _interopRequireDefault(require("./PanoramaTab"));
|
23
23
|
|
24
|
-
var
|
24
|
+
var _ModelTab = _interopRequireDefault(require("./ModelTab"));
|
25
|
+
|
26
|
+
var _TabWrapper = _interopRequireDefault(require("./TabWrapper"));
|
27
|
+
|
28
|
+
var _D = _interopRequireDefault(require("../assets/img/3D.jpg"));
|
25
29
|
|
26
30
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
27
31
|
|
@@ -69,14 +73,20 @@ const Application = (0, _mobxReactLite.observer)(_ref => {
|
|
69
73
|
title: "Panoramic tour",
|
70
74
|
text: ['Use mouse to rotate', 'To move through the rooms, click on the layout thumbnail'],
|
71
75
|
onStart: hideTabPanes
|
72
|
-
}, /*#__PURE__*/_react.default.createElement(
|
76
|
+
}, /*#__PURE__*/_react.default.createElement(_PanoramaTab.default, {
|
77
|
+
json: config.json,
|
78
|
+
planImage: config.planImage,
|
79
|
+
images: config.panoramaImages
|
80
|
+
})),
|
73
81
|
'model': /*#__PURE__*/_react.default.createElement(_TabWrapper.default, {
|
74
82
|
isActive: !isTabPanesVisible,
|
75
83
|
image: _D.default,
|
76
84
|
title: "3D Model",
|
77
85
|
text: ['Use mouse to rotate', 'Use the right mouse button to move'],
|
78
86
|
onStart: hideTabPanes
|
79
|
-
}, /*#__PURE__*/_react.default.createElement(
|
87
|
+
}, /*#__PURE__*/_react.default.createElement(_ModelTab.default, {
|
88
|
+
json: config.json
|
89
|
+
}))
|
80
90
|
};
|
81
91
|
const appStyle = {
|
82
92
|
width,
|
@@ -0,0 +1,22 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
4
|
+
value: true
|
5
|
+
});
|
6
|
+
exports.default = void 0;
|
7
|
+
|
8
|
+
var _react = _interopRequireDefault(require("react"));
|
9
|
+
|
10
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
11
|
+
|
12
|
+
const Loader = _ref => {
|
13
|
+
let {
|
14
|
+
absolute
|
15
|
+
} = _ref;
|
16
|
+
return /*#__PURE__*/_react.default.createElement("div", {
|
17
|
+
className: "widget-loader ".concat(absolute ? 'widget-loader--absolute' : '')
|
18
|
+
}, /*#__PURE__*/_react.default.createElement("div", null), /*#__PURE__*/_react.default.createElement("div", null), /*#__PURE__*/_react.default.createElement("div", null), /*#__PURE__*/_react.default.createElement("div", null));
|
19
|
+
};
|
20
|
+
|
21
|
+
var _default = Loader;
|
22
|
+
exports.default = _default;
|
@@ -0,0 +1,115 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
4
|
+
value: true
|
5
|
+
});
|
6
|
+
exports.default = void 0;
|
7
|
+
|
8
|
+
require("core-js/modules/web.dom-collections.iterator.js");
|
9
|
+
|
10
|
+
var _react = _interopRequireWildcard(require("react"));
|
11
|
+
|
12
|
+
var THREE = _interopRequireWildcard(require("three"));
|
13
|
+
|
14
|
+
var _cameraControls = _interopRequireDefault(require("camera-controls"));
|
15
|
+
|
16
|
+
var _modelHelpers = require("../utils/modelHelpers");
|
17
|
+
|
18
|
+
var _grass = _interopRequireDefault(require("../assets/img/grass.png"));
|
19
|
+
|
20
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
21
|
+
|
22
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
23
|
+
|
24
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
25
|
+
|
26
|
+
_cameraControls.default.install({
|
27
|
+
THREE: THREE
|
28
|
+
});
|
29
|
+
|
30
|
+
const textureLoader = new THREE.TextureLoader();
|
31
|
+
|
32
|
+
const createScene = () => {
|
33
|
+
const scene = new THREE.Scene();
|
34
|
+
const light = new THREE.AmbientLight(0xffffff);
|
35
|
+
scene.background = new THREE.Color('#FAFAFA');
|
36
|
+
scene.add(light);
|
37
|
+
createGround(scene);
|
38
|
+
return scene;
|
39
|
+
};
|
40
|
+
|
41
|
+
const createCamera = renderer => {
|
42
|
+
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
|
43
|
+
camera.position.set(0, 0, 0);
|
44
|
+
window.addEventListener('resize', () => {
|
45
|
+
camera.aspect = window.innerWidth / window.innerHeight;
|
46
|
+
camera.updateProjectionMatrix();
|
47
|
+
renderer.setSize(window.innerWidth, window.innerHeight);
|
48
|
+
});
|
49
|
+
return camera;
|
50
|
+
};
|
51
|
+
|
52
|
+
const createRenderer = () => {
|
53
|
+
const renderer = new THREE.WebGLRenderer();
|
54
|
+
renderer.setPixelRatio(window.devicePixelRatio);
|
55
|
+
renderer.setSize(window.innerWidth, window.innerHeight);
|
56
|
+
renderer.localClippingEnabled = true;
|
57
|
+
return renderer;
|
58
|
+
};
|
59
|
+
|
60
|
+
const createControls = (clock, camera, scene, renderer) => {
|
61
|
+
const controls = new _cameraControls.default(camera, renderer.domElement);
|
62
|
+
controls.minDistance = 0.5;
|
63
|
+
controls.maxDistance = 180;
|
64
|
+
controls.maxPolarAngle = Math.PI / 2.1;
|
65
|
+
(0, _modelHelpers.setDefaultControls)(controls, Math.PI / 4);
|
66
|
+
controls.verticalDragToForward = true;
|
67
|
+
(0, _modelHelpers.addKeyboardControls)(controls);
|
68
|
+
|
69
|
+
const animate = () => {
|
70
|
+
controls.update(clock.getDelta());
|
71
|
+
window.requestAnimationFrame(animate);
|
72
|
+
renderer.render(scene, camera);
|
73
|
+
};
|
74
|
+
|
75
|
+
animate();
|
76
|
+
return controls;
|
77
|
+
};
|
78
|
+
|
79
|
+
const createGround = scene => {
|
80
|
+
textureLoader.load(_grass.default, grassTexture => {
|
81
|
+
grassTexture.wrapS = grassTexture.wrapT = THREE.RepeatWrapping;
|
82
|
+
grassTexture.repeat.set(70, 70);
|
83
|
+
let groundMaterial = new THREE.MeshBasicMaterial({
|
84
|
+
map: grassTexture,
|
85
|
+
color: 'rgb(255,255,255)'
|
86
|
+
});
|
87
|
+
let groundMesh = new THREE.Mesh(new THREE.PlaneBufferGeometry(500, 500), groundMaterial);
|
88
|
+
groundMesh.rotation.x = -Math.PI / 2;
|
89
|
+
scene.add(groundMesh);
|
90
|
+
});
|
91
|
+
};
|
92
|
+
|
93
|
+
const ModelTab = _ref => {
|
94
|
+
let {
|
95
|
+
json
|
96
|
+
} = _ref;
|
97
|
+
const [clock] = (0, _react.useState)(new THREE.Clock());
|
98
|
+
const [scene] = (0, _react.useState)(createScene());
|
99
|
+
const [renderer] = (0, _react.useState)(createRenderer());
|
100
|
+
const [camera] = (0, _react.useState)(createCamera(renderer));
|
101
|
+
const [controls] = (0, _react.useState)(createControls(clock, camera, scene, renderer));
|
102
|
+
(0, _react.useEffect)(() => {
|
103
|
+
const container = document.querySelector('.widget-tab__model-scene');
|
104
|
+
if (container.children.length !== 0) return;
|
105
|
+
container.appendChild(renderer.domElement);
|
106
|
+
}, [renderer]);
|
107
|
+
return /*#__PURE__*/_react.default.createElement("div", {
|
108
|
+
className: "widget-tab__model"
|
109
|
+
}, /*#__PURE__*/_react.default.createElement("div", {
|
110
|
+
className: "widget-tab__model-scene"
|
111
|
+
}));
|
112
|
+
};
|
113
|
+
|
114
|
+
var _default = ModelTab;
|
115
|
+
exports.default = _default;
|
@@ -0,0 +1,215 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
4
|
+
value: true
|
5
|
+
});
|
6
|
+
exports.default = void 0;
|
7
|
+
|
8
|
+
require("core-js/modules/es.array.reduce.js");
|
9
|
+
|
10
|
+
require("core-js/modules/es.string.includes.js");
|
11
|
+
|
12
|
+
require("core-js/modules/web.dom-collections.iterator.js");
|
13
|
+
|
14
|
+
var _react = _interopRequireWildcard(require("react"));
|
15
|
+
|
16
|
+
var THREE = _interopRequireWildcard(require("three"));
|
17
|
+
|
18
|
+
var PANOLENS = _interopRequireWildcard(require("panolens"));
|
19
|
+
|
20
|
+
var _threeDeviceOrientation = _interopRequireDefault(require("three-device-orientation"));
|
21
|
+
|
22
|
+
var _Loader = _interopRequireDefault(require("./Loader"));
|
23
|
+
|
24
|
+
var _panoramaHelpers = require("../utils/panoramaHelpers");
|
25
|
+
|
26
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
27
|
+
|
28
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
29
|
+
|
30
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
31
|
+
|
32
|
+
const {
|
33
|
+
DEVICEORIENTATION,
|
34
|
+
ORBIT
|
35
|
+
} = PANOLENS.CONTROLS;
|
36
|
+
const pathName = 'Panorama_0_0_';
|
37
|
+
|
38
|
+
const getPanoramas = (json, images, setLoadingState) => {
|
39
|
+
return json.Floors[0].Units[0].Rooms.reduce((acc, jsonRoom, index) => {
|
40
|
+
const image = images.find(img => img.includes(pathName + index));
|
41
|
+
if (!image) return acc;
|
42
|
+
const panorama = new PANOLENS.ImagePanorama(image);
|
43
|
+
panorama['panorama_id'] = index + 1;
|
44
|
+
panorama['room_id'] = jsonRoom.ID;
|
45
|
+
panorama.addEventListener('progress', event => {
|
46
|
+
setLoadingState(true);
|
47
|
+
|
48
|
+
if (event.progress.loaded / event.progress.total * 100 === 100) {
|
49
|
+
setLoadingState(false);
|
50
|
+
}
|
51
|
+
});
|
52
|
+
panorama.addEventListener('enter', () => setLoadingState(false));
|
53
|
+
acc.push(panorama);
|
54
|
+
return acc;
|
55
|
+
}, []);
|
56
|
+
};
|
57
|
+
|
58
|
+
const getPanoramaRooms = (json, panoramas) => {
|
59
|
+
const {
|
60
|
+
Vertices,
|
61
|
+
Floors
|
62
|
+
} = json;
|
63
|
+
const {
|
64
|
+
Walls
|
65
|
+
} = Floors[0];
|
66
|
+
return panoramas.map((panorama, index) => {
|
67
|
+
const currentRoom = Floors[0].Units[0].Rooms.find(room => room.ID === panorama['room_id']);
|
68
|
+
const {
|
69
|
+
left,
|
70
|
+
top
|
71
|
+
} = (0, _panoramaHelpers.findRoomCenter)(currentRoom, Walls, Vertices);
|
72
|
+
return {
|
73
|
+
type: currentRoom.Type,
|
74
|
+
id: index,
|
75
|
+
panorama,
|
76
|
+
left,
|
77
|
+
top
|
78
|
+
};
|
79
|
+
}, []);
|
80
|
+
};
|
81
|
+
|
82
|
+
const initPanorama = () => {
|
83
|
+
let camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1100);
|
84
|
+
let controls = new _threeDeviceOrientation.default(camera);
|
85
|
+
window.addEventListener('resize', () => {
|
86
|
+
camera.aspect = window.innerWidth / window.innerHeight;
|
87
|
+
camera.updateProjectionMatrix();
|
88
|
+
});
|
89
|
+
|
90
|
+
const animate = () => {
|
91
|
+
window.requestAnimationFrame(animate);
|
92
|
+
controls.update();
|
93
|
+
};
|
94
|
+
|
95
|
+
animate();
|
96
|
+
|
97
|
+
if (DeviceOrientationEvent.requestPermission) {
|
98
|
+
DeviceOrientationEvent.requestPermission().catch(() => console.log('Device motion not allowed'));
|
99
|
+
}
|
100
|
+
|
101
|
+
return {
|
102
|
+
camera,
|
103
|
+
controls
|
104
|
+
};
|
105
|
+
};
|
106
|
+
|
107
|
+
const PanoramaTab = _ref => {
|
108
|
+
let {
|
109
|
+
json,
|
110
|
+
planImage,
|
111
|
+
images
|
112
|
+
} = _ref;
|
113
|
+
const [menuState, setMenuState] = (0, _react.useState)(false);
|
114
|
+
const [loadingState, setLoadingState] = (0, _react.useState)(true);
|
115
|
+
const [isMapActive, setMapState] = (0, _react.useState)(false);
|
116
|
+
const [currentRoomIndex, setCurrentRoomIndex] = (0, _react.useState)(0);
|
117
|
+
const [panoramas] = (0, _react.useState)(getPanoramas(json, images, setLoadingState));
|
118
|
+
const [panoramaRooms] = (0, _react.useState)(getPanoramaRooms(json, panoramas));
|
119
|
+
const [viewer, setViewer] = (0, _react.useState)(null);
|
120
|
+
const [planScale, setPlanScale] = (0, _react.useState)({
|
121
|
+
X: 1,
|
122
|
+
Y: 1
|
123
|
+
});
|
124
|
+
|
125
|
+
const changePanorama = (panorama, index) => {
|
126
|
+
setCurrentRoomIndex(index);
|
127
|
+
viewer.setPanorama(panorama);
|
128
|
+
};
|
129
|
+
|
130
|
+
const toggleVrMode = () => {
|
131
|
+
if (viewer.mode === 3) {
|
132
|
+
viewer.disableEffect();
|
133
|
+
return;
|
134
|
+
}
|
135
|
+
|
136
|
+
viewer.enableEffect(PANOLENS.MODES.STEREO);
|
137
|
+
};
|
138
|
+
|
139
|
+
const toggleOrientationMode = () => {
|
140
|
+
if (viewer.control.id === 'orbit') {
|
141
|
+
viewer.enableControl(DEVICEORIENTATION);
|
142
|
+
return;
|
143
|
+
}
|
144
|
+
|
145
|
+
viewer.enableControl(ORBIT);
|
146
|
+
};
|
147
|
+
|
148
|
+
const toggleMap = () => setMapState(!isMapActive);
|
149
|
+
|
150
|
+
const setScale = () => {
|
151
|
+
const image = document.querySelector('.widget-tab__panorama-map img');
|
152
|
+
setPlanScale((0, _panoramaHelpers.getScale)(image, json));
|
153
|
+
};
|
154
|
+
|
155
|
+
const getDotClassName = index => {
|
156
|
+
let className = 'widget-tab__panorama-map__dot';
|
157
|
+
if (isMapActive) className += ' widget-tab__panorama-map__dot--big';
|
158
|
+
if (currentRoomIndex === index) className += ' widget-tab__panorama-map__dot--active';
|
159
|
+
return className;
|
160
|
+
};
|
161
|
+
|
162
|
+
(0, _react.useEffect)(() => {
|
163
|
+
const newViewer = new PANOLENS.Viewer({
|
164
|
+
container: document.querySelector('.widget-tab__panorama-overlay'),
|
165
|
+
autoHideInfospot: false,
|
166
|
+
controlButtons: [],
|
167
|
+
cameraFov: 90
|
168
|
+
});
|
169
|
+
panoramas.forEach(panorama => {
|
170
|
+
if (!panorama.panorama_id) return;
|
171
|
+
newViewer.add(panorama);
|
172
|
+
});
|
173
|
+
setViewer(newViewer);
|
174
|
+
initPanorama();
|
175
|
+
}, [panoramas]);
|
176
|
+
(0, _react.useEffect)(setScale, [json, isMapActive]);
|
177
|
+
return /*#__PURE__*/_react.default.createElement("div", {
|
178
|
+
className: "widget-tab__panorama"
|
179
|
+
}, /*#__PURE__*/_react.default.createElement("div", {
|
180
|
+
className: "widget-tab__panorama-overlay"
|
181
|
+
}), loadingState && /*#__PURE__*/_react.default.createElement(_Loader.default, {
|
182
|
+
absolute: true
|
183
|
+
}), /*#__PURE__*/_react.default.createElement("div", {
|
184
|
+
className: "widget-tab__panorama-menu"
|
185
|
+
}, /*#__PURE__*/_react.default.createElement("ul", null, /*#__PURE__*/_react.default.createElement("li", {
|
186
|
+
onClick: () => setMenuState(!menuState)
|
187
|
+
}, "Rooms"), menuState && panoramaRooms.map((room, index) => /*#__PURE__*/_react.default.createElement("li", {
|
188
|
+
key: index,
|
189
|
+
onClick: () => changePanorama(room.panorama, index)
|
190
|
+
}, currentRoomIndex === index && '• ', " ", room.type)))), /*#__PURE__*/_react.default.createElement("div", {
|
191
|
+
className: "widget-tab__panorama-map"
|
192
|
+
}, /*#__PURE__*/_react.default.createElement("img", {
|
193
|
+
src: planImage,
|
194
|
+
className: isMapActive ? 'active' : '',
|
195
|
+
onClick: toggleMap,
|
196
|
+
alt: "plan"
|
197
|
+
}), panoramaRooms.map((room, index) => /*#__PURE__*/_react.default.createElement("div", {
|
198
|
+
key: index,
|
199
|
+
style: {
|
200
|
+
left: "".concat(room.left * planScale.X, "px"),
|
201
|
+
top: "".concat(room.top * planScale.Y, "px")
|
202
|
+
},
|
203
|
+
className: getDotClassName(index),
|
204
|
+
onClick: () => changePanorama(room.panorama, index)
|
205
|
+
}))), /*#__PURE__*/_react.default.createElement("button", {
|
206
|
+
className: "widget-tab__panorama-mode",
|
207
|
+
onClick: toggleVrMode
|
208
|
+
}, "VR"), /*#__PURE__*/_react.default.createElement("button", {
|
209
|
+
className: "widget-tab__panorama-standart",
|
210
|
+
onClick: toggleOrientationMode
|
211
|
+
}, "Standart"));
|
212
|
+
};
|
213
|
+
|
214
|
+
var _default = PanoramaTab;
|
215
|
+
exports.default = _default;
|
@@ -11,7 +11,7 @@ var _react = _interopRequireWildcard(require("react"));
|
|
11
11
|
|
12
12
|
var _panzoom = _interopRequireDefault(require("panzoom"));
|
13
13
|
|
14
|
-
var _threesixty = _interopRequireDefault(require("../
|
14
|
+
var _threesixty = _interopRequireDefault(require("../threesixty"));
|
15
15
|
|
16
16
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
17
17
|
|