hart-estate-widget 0.0.40 → 0.0.43

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.
Files changed (74) hide show
  1. package/README.md +16 -4
  2. package/build/assets/fonts/RobotoMono/RobotoMono-Bold.eot +0 -0
  3. package/build/assets/fonts/RobotoMono/RobotoMono-Bold.ttf +0 -0
  4. package/build/assets/fonts/RobotoMono/RobotoMono-Bold.woff +0 -0
  5. package/build/assets/fonts/RobotoMono/RobotoMono-Bold.woff2 +0 -0
  6. package/build/assets/fonts/RobotoMono/RobotoMono-BoldItalic.eot +0 -0
  7. package/build/assets/fonts/RobotoMono/RobotoMono-BoldItalic.ttf +0 -0
  8. package/build/assets/fonts/RobotoMono/RobotoMono-BoldItalic.woff +0 -0
  9. package/build/assets/fonts/RobotoMono/RobotoMono-BoldItalic.woff2 +0 -0
  10. package/build/assets/fonts/RobotoMono/RobotoMono-Italic.eot +0 -0
  11. package/build/assets/fonts/RobotoMono/RobotoMono-Italic.ttf +0 -0
  12. package/build/assets/fonts/RobotoMono/RobotoMono-Italic.woff +0 -0
  13. package/build/assets/fonts/RobotoMono/RobotoMono-Italic.woff2 +0 -0
  14. package/build/assets/fonts/RobotoMono/RobotoMono-Light.eot +0 -0
  15. package/build/assets/fonts/RobotoMono/RobotoMono-Light.ttf +0 -0
  16. package/build/assets/fonts/RobotoMono/RobotoMono-Light.woff +0 -0
  17. package/build/assets/fonts/RobotoMono/RobotoMono-Light.woff2 +0 -0
  18. package/build/assets/fonts/RobotoMono/RobotoMono-LightItalic.eot +0 -0
  19. package/build/assets/fonts/RobotoMono/RobotoMono-LightItalic.ttf +0 -0
  20. package/build/assets/fonts/RobotoMono/RobotoMono-LightItalic.woff +0 -0
  21. package/build/assets/fonts/RobotoMono/RobotoMono-LightItalic.woff2 +0 -0
  22. package/build/assets/fonts/RobotoMono/RobotoMono-Medium.eot +0 -0
  23. package/build/assets/fonts/RobotoMono/RobotoMono-Medium.ttf +0 -0
  24. package/build/assets/fonts/RobotoMono/RobotoMono-Medium.woff +0 -0
  25. package/build/assets/fonts/RobotoMono/RobotoMono-Medium.woff2 +0 -0
  26. package/build/assets/fonts/RobotoMono/RobotoMono-MediumItalic.eot +0 -0
  27. package/build/assets/fonts/RobotoMono/RobotoMono-MediumItalic.ttf +0 -0
  28. package/build/assets/fonts/RobotoMono/RobotoMono-MediumItalic.woff +0 -0
  29. package/build/assets/fonts/RobotoMono/RobotoMono-MediumItalic.woff2 +0 -0
  30. package/build/assets/fonts/RobotoMono/RobotoMono-Regular.eot +0 -0
  31. package/build/assets/fonts/RobotoMono/RobotoMono-Regular.ttf +0 -0
  32. package/build/assets/fonts/RobotoMono/RobotoMono-Regular.woff +0 -0
  33. package/build/assets/fonts/RobotoMono/RobotoMono-Regular.woff2 +0 -0
  34. package/build/assets/fonts/RobotoMono/RobotoMono-Thin.eot +0 -0
  35. package/build/assets/fonts/RobotoMono/RobotoMono-Thin.ttf +0 -0
  36. package/build/assets/fonts/RobotoMono/RobotoMono-Thin.woff +0 -0
  37. package/build/assets/fonts/RobotoMono/RobotoMono-Thin.woff2 +0 -0
  38. package/build/assets/fonts/RobotoMono/RobotoMono.css +108 -0
  39. package/build/assets/icons/1x.svg +4 -0
  40. package/build/assets/icons/2x.svg +4 -0
  41. package/build/assets/icons/bullet.png +0 -0
  42. package/build/assets/icons/close.svg +4 -0
  43. package/build/assets/icons/enter-fullscreen.svg +6 -0
  44. package/build/assets/icons/hand-move.svg +15 -0
  45. package/build/assets/icons/hand-research.svg +12 -0
  46. package/build/assets/icons/rotation-close.svg +6 -0
  47. package/build/assets/icons/rotation.svg +4 -0
  48. package/build/assets/img/logo.svg +11 -0
  49. package/build/assets/sass/components/instructions.sass +51 -33
  50. package/build/assets/sass/components/model.sass +1 -0
  51. package/build/assets/sass/components/panorama.sass +95 -31
  52. package/build/assets/sass/components/tabs.sass +90 -91
  53. package/build/assets/sass/index.sass +45 -2
  54. package/build/assets/sass/mixin.sass +12 -0
  55. package/build/assets/sass/vars.sass +4 -1
  56. package/build/components/Application.js +48 -71
  57. package/build/components/Buttons/FullScreenButton.js +46 -0
  58. package/build/components/Buttons/TabButton.js +26 -0
  59. package/build/components/Instructions.js +26 -15
  60. package/build/components/ModelTab.js +62 -39
  61. package/build/components/PanoramaTab.js +268 -159
  62. package/build/components/RotationTab.js +40 -10
  63. package/build/config/defaultConfig.js +5 -2
  64. package/build/enums/deviceOrientationStatus.js +11 -0
  65. package/build/enums/imageExtentions.js +21 -0
  66. package/build/index.js +6 -12
  67. package/build/store/fullScreenStore.js +54 -0
  68. package/build/store/index.js +17 -29
  69. package/build/utils/panoramaHelpers.js +45 -2
  70. package/package.json +6 -4
  71. package/build/components/TabPanes.js +0 -96
  72. package/build/components/TabWrapper.js +0 -42
  73. package/build/index.css +0 -1
  74. package/build/index.css.map +0 -1
@@ -9,11 +9,17 @@ require("core-js/modules/es.array.reduce.js");
9
9
 
10
10
  require("core-js/modules/es.regexp.exec.js");
11
11
 
12
- require("core-js/modules/es.string.replace.js");
12
+ require("core-js/modules/es.string.split.js");
13
+
14
+ require("core-js/modules/es.string.includes.js");
13
15
 
14
16
  require("core-js/modules/web.dom-collections.iterator.js");
15
17
 
16
- require("core-js/modules/es.string.includes.js");
18
+ require("core-js/modules/es.regexp.to-string.js");
19
+
20
+ require("core-js/modules/es.array.flat.js");
21
+
22
+ require("core-js/modules/es.array.unscopables.flat.js");
17
23
 
18
24
  var _react = _interopRequireWildcard(require("react"));
19
25
 
@@ -25,50 +31,66 @@ var PANOLENS = _interopRequireWildcard(require("panolens"));
25
31
 
26
32
  var _threeDeviceOrientation = _interopRequireDefault(require("three-device-orientation"));
27
33
 
28
- var _Loader = _interopRequireDefault(require("./Loader"));
34
+ var _geometric = require("geometric");
35
+
36
+ var _deviceOrientationStatus = require("../enums/deviceOrientationStatus");
37
+
38
+ var _imageExtentions = require("../enums/imageExtentions");
29
39
 
30
40
  var _panoramaHelpers = require("../utils/panoramaHelpers");
31
41
 
32
- var _geometric = require("geometric");
42
+ var _Loader = _interopRequireDefault(require("./Loader"));
43
+
44
+ var _Instructions = _interopRequireDefault(require("./Instructions"));
33
45
 
34
46
  var _spotIcon = _interopRequireDefault(require("../assets/img/spot-icon.png"));
35
47
 
36
48
  var _doorIcon = _interopRequireDefault(require("../assets/img/door-icon.png"));
37
49
 
50
+ var _handMove = _interopRequireDefault(require("../assets/icons/hand-move.svg"));
51
+
52
+ var _handResearch = _interopRequireDefault(require("../assets/icons/hand-research.svg"));
53
+
54
+ var _rotationClose = _interopRequireDefault(require("../assets/icons/rotation-close.svg"));
55
+
56
+ var _rotation = _interopRequireDefault(require("../assets/icons/rotation.svg"));
57
+
58
+ var _x = _interopRequireDefault(require("../assets/icons/1x.svg"));
59
+
60
+ var _x2 = _interopRequireDefault(require("../assets/icons/2x.svg"));
61
+
38
62
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
39
63
 
40
64
  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); }
41
65
 
42
66
  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; }
43
67
 
68
+ const instructionSteps = [{
69
+ icon: _handMove.default,
70
+ text: 'Вращать планировку'
71
+ }, {
72
+ icon: _handResearch.default,
73
+ text: 'Исследовать планировку'
74
+ }];
44
75
  const {
45
76
  DEVICEORIENTATION,
46
77
  ORBIT
47
78
  } = PANOLENS.CONTROLS;
48
- const imgExtentions = ['.png', '.PNG', '.jpg', '.JPG'];
49
79
  const pathName = 'Panorama_0_0_';
50
- const cameraIdBeginning = 'CameraId';
51
-
52
- const removeExtention = str => imgExtentions.reduce((acc, extention) => {
53
- return acc.replace(extention, '');
54
- }, str);
55
-
56
- const getCameraFromSrc = (json, src) => {
57
- var _json$Floors$0$Camera;
58
-
59
- const cameraIdIndex = src.indexOf(cameraIdBeginning);
60
- if (cameraIdIndex === -1) return null;
61
- const cameraId = removeExtention(src.substring(cameraIdIndex));
62
- return ((_json$Floors$0$Camera = json.Floors[0].CameraPoints) === null || _json$Floors$0$Camera === void 0 ? void 0 : _json$Floors$0$Camera.find(_ref => {
63
- let {
64
- ID
65
- } = _ref;
66
- return ID === cameraId;
67
- })) || null;
80
+ const cameraFovValues = {
81
+ x1: 90,
82
+ x2: 60
68
83
  };
69
84
 
85
+ const getDefaultUserData = () => ({
86
+ left: 0,
87
+ top: 0,
88
+ points: []
89
+ });
90
+
70
91
  const createPanorama = (image, index, setLoadingState) => {
71
92
  const panorama = new PANOLENS.ImagePanorama(image);
93
+ panorama.userData = getDefaultUserData();
72
94
  panorama['panorama_id'] = index + 1;
73
95
  panorama.addEventListener('progress', event => {
74
96
  setLoadingState(true);
@@ -83,12 +105,18 @@ const createPanorama = (image, index, setLoadingState) => {
83
105
 
84
106
  const getPanoramas = (json, images, setLoadingState) => {
85
107
  if (!json) return images.map((image, index) => createPanorama(image, index, setLoadingState));
86
- return json.Floors[0].Units[0].Rooms.reduce((acc, jsonRoom, index) => {
108
+ const panoramas = json.Floors[0].Units[0].Rooms.reduce((acc, jsonRoom, index) => {
87
109
  const roomImages = images.filter(img => {
88
110
  const panoramaIdIndex = img.indexOf(pathName) + pathName.length;
89
111
  if (panoramaIdIndex < pathName.length) return false;
90
112
  const indexAsString = String(index);
91
- const panoramaId = String(removeExtention(img.substring(panoramaIdIndex)));
113
+ let panoramaId = String((0, _imageExtentions.removeExtention)(img.substring(panoramaIdIndex))).split('.')[0];
114
+
115
+ if (panoramaId.includes(_panoramaHelpers.cameraIdBeginning)) {
116
+ const cameraIdIndex = panoramaId.indexOf(_panoramaHelpers.cameraIdBeginning) - 1;
117
+ panoramaId = panoramaId.slice(0, cameraIdIndex);
118
+ }
119
+
92
120
  const maxIndexLength = Math.max(indexAsString.length, panoramaId.length);
93
121
  const imageInRoom = (0, _panoramaHelpers.getArrayFromNumber)(maxIndexLength).every(i => {
94
122
  return panoramaId[i] === indexAsString[i];
@@ -100,8 +128,24 @@ const getPanoramas = (json, images, setLoadingState) => {
100
128
  const panorama = createPanorama(image, index, setLoadingState);
101
129
  panorama['room_images'] = roomImages;
102
130
  panorama['room_id'] = jsonRoom.ID;
131
+ const roomPoints = (0, _panoramaHelpers.getRoomCoordinates)(jsonRoom, json.Floors[0].Walls, json.Vertices);
132
+ let [left, top] = (0, _geometric.polygonMean)(roomPoints);
133
+
134
+ if (!panorama.linkedSpots.length) {
135
+ if (panorama.src.includes('_CameraId')) {
136
+ const currentCamera = (0, _panoramaHelpers.getCameraFromSrc)(json, panorama.src);
137
+ left = currentCamera.Location.X;
138
+ top = currentCamera.Location.Y;
139
+ }
140
+
141
+ panorama.userData = {
142
+ left,
143
+ top,
144
+ points: roomPoints
145
+ };
146
+ }
103
147
 
104
- if (panorama['room_id'] === _store.default.hallRoomId) {
148
+ if (panorama['room_id'] === _store.default.initialPanoramaRoomId) {
105
149
  acc.unshift(panorama);
106
150
  } else {
107
151
  acc.push(panorama);
@@ -109,64 +153,37 @@ const getPanoramas = (json, images, setLoadingState) => {
109
153
  });
110
154
  return acc;
111
155
  }, []);
112
- };
113
-
114
- const getPanoramaRooms = (json, panoramas) => {
115
156
  return panoramas.map((panorama, index) => {
116
157
  panorama['panorama_index'] = index;
117
- const type = "Room - ".concat(panorama['panorama_id']);
118
- if (!json) return {
119
- type,
120
- id: index,
121
- panorama,
122
- left: 0,
123
- top: 0
124
- };
125
158
  const currentRoom = json.Floors[0].Units[0].Rooms.find(room => room.ID === panorama['room_id']);
126
- let [left, top] = (0, _geometric.polygonMean)((0, _panoramaHelpers.getRoomCoordinates)(currentRoom, json.Floors[0].Walls, json.Vertices));
127
- panorama['roomType'] = currentRoom.Type;
128
159
 
129
160
  if (!panorama.linkedSpots.length) {
130
- if (panorama.src.includes('_CameraId')) {
131
- const currentCamera = getCameraFromSrc(json, panorama.src);
132
- const {
133
- Location
134
- } = currentCamera;
135
- left = Location.X;
136
- top = Location.Y;
137
- }
138
-
139
- setPanoramaLinks(json, currentRoom, [left, top], panorama, panoramas);
161
+ return setPanoramaLinks(json, currentRoom, panorama, panoramas);
140
162
  }
141
163
 
142
- return {
143
- type: currentRoom.Type,
144
- id: index,
145
- panorama,
146
- left,
147
- top
148
- };
149
- }, []);
164
+ return panorama;
165
+ });
150
166
  };
151
167
 
152
- const setPanoramaLinks = (json, currentRoom, center, panorama, panoramas) => {
168
+ const setPanoramaLinks = (json, currentRoom, panorama, panoramas) => {
169
+ const center = [panorama.userData.left, panorama.userData.top];
153
170
  panorama['room_images'].forEach(image => {
154
171
  if (image === panorama.src) return;
155
- const connectedPanorama = panoramas.find(_ref2 => {
172
+ const connectedPanorama = panoramas.find(_ref => {
156
173
  let {
157
174
  src
158
- } = _ref2;
175
+ } = _ref;
159
176
  return src === image;
160
177
  });
161
- const currentCamera = getCameraFromSrc(json, connectedPanorama.src);
178
+ const currentCamera = (0, _panoramaHelpers.getCameraFromSrc)(json, connectedPanorama.src);
162
179
  if (!currentCamera) return;
163
180
  connectPanorama(panorama, connectedPanorama, currentCamera.Location, center, false);
164
181
  });
165
- json.Floors[0].Doors.forEach(_ref3 => {
182
+ json.Floors[0].Doors.forEach(_ref2 => {
166
183
  let {
167
184
  Location,
168
185
  Walls
169
- } = _ref3;
186
+ } = _ref2;
170
187
  if (!Walls.some(doorWallId => currentRoom.Walls.some(roomWallId => roomWallId === doorWallId))) return;
171
188
  const connectedRoom = json.Floors[0].Units[0].Rooms.find(room => {
172
189
  const roomHasSameWall = room.Walls.some(roomWallId => Walls.some(doorWallId => roomWallId === doorWallId));
@@ -174,15 +191,19 @@ const setPanoramaLinks = (json, currentRoom, center, panorama, panoramas) => {
174
191
  return roomHasSameWall && !isSameRoom;
175
192
  });
176
193
  if (!connectedRoom) return;
177
- const connectedPanorama = panoramas.find(_ref4 => {
194
+ const availablePanoramas = panoramas.filter(_ref3 => {
178
195
  let {
179
196
  room_id
180
- } = _ref4;
197
+ } = _ref3;
181
198
  return room_id === connectedRoom.ID;
182
199
  });
200
+ const {
201
+ panorama: connectedPanorama
202
+ } = (0, _panoramaHelpers.getClosestPanorama)([Location.X, Location.Y], availablePanoramas);
183
203
  if (!connectedPanorama) return;
184
204
  connectPanorama(panorama, connectedPanorama, Location, center, true);
185
205
  });
206
+ return panorama;
186
207
  };
187
208
 
188
209
  const connectPanorama = function connectPanorama(panorama, connectedPanorama, location, center) {
@@ -203,107 +224,117 @@ const connectPanorama = function connectPanorama(panorama, connectedPanorama, lo
203
224
  panorama.link(connectedPanorama, position, resultScale, iconUrl);
204
225
  };
205
226
 
206
- const initPanorama = () => {
207
- let camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1100);
208
- let controls = new _threeDeviceOrientation.default(camera);
209
- window.addEventListener('resize', () => {
210
- camera.aspect = window.innerWidth / window.innerHeight;
211
- camera.updateProjectionMatrix();
212
- });
227
+ const PanoramaTab = _ref4 => {
228
+ var _panoramas$currentRoo;
213
229
 
214
- const animate = () => {
215
- window.requestAnimationFrame(animate);
216
- controls.update();
217
- };
218
-
219
- animate();
220
- return {
221
- camera,
222
- controls
223
- };
224
- };
225
-
226
- const PanoramaTab = _ref5 => {
227
230
  let {
228
231
  json,
229
232
  planImage,
230
- images
231
- } = _ref5;
232
- const [menuState, setMenuState] = (0, _react.useState)(false);
233
+ images,
234
+ disabled
235
+ } = _ref4;
236
+ const [showInstructions, setInstructionsState] = (0, _react.useState)(true);
233
237
  const [loadingState, setLoadingState] = (0, _react.useState)(true);
234
- const [isMapActive, setMapState] = (0, _react.useState)(false);
235
- const [currentRoomIndex, setCurrentRoomIndex] = (0, _react.useState)(0);
236
- const [panoramas] = (0, _react.useState)(getPanoramas(json, images, setLoadingState));
237
- const [panoramaRooms] = (0, _react.useState)(getPanoramaRooms(json, panoramas));
238
- const [viewer, setViewer] = (0, _react.useState)(null);
238
+ const [windowWidth, setWindowWidth] = (0, _react.useState)(0);
239
+ const [isMapDisabled, setMapDisabledState] = (0, _react.useState)(true);
239
240
  const [planScale, setPlanScale] = (0, _react.useState)({
240
241
  X: 1,
241
242
  Y: 1
242
243
  });
243
- const isMapDisabled = !json;
244
+ const [autoplayEnabled, setAutoplayState] = (0, _react.useState)(false);
245
+ const [cameraFov, setCameraFov] = (0, _react.useState)(cameraFovValues.x1);
246
+ const [currentRoomIndex, setCurrentRoomIndex] = (0, _react.useState)(0);
247
+ const [panoramas, setPanoramas] = (0, _react.useState)([]);
248
+ const [viewer, setViewer] = (0, _react.useState)(null);
244
249
 
245
- const changePanorama = (panorama, index) => {
246
- setCurrentRoomIndex(index);
250
+ const changePanorama = panorama => {
251
+ setCurrentRoomIndex(panorama['panorama_index']);
247
252
  viewer.setPanorama(panorama);
248
253
  };
249
254
 
250
- const toggleVrMode = () => {
251
- if (viewer.mode === 3) {
252
- viewer.disableEffect();
253
- return;
254
- }
255
+ const setScale = () => {
256
+ const image = document.querySelector('.widget-tab__panorama-map img');
257
+ setPlanScale((0, _panoramaHelpers.getScale)(image, json));
258
+ };
259
+
260
+ const onImageLoaded = () => {
261
+ setScale();
262
+ setMapDisabledState(!json);
263
+ };
264
+
265
+ const getDotClassName = index => {
266
+ let className = 'widget-tab__panorama-map__dot widget-tab__panorama-map__dot--big';
267
+ if (currentRoomIndex === index) className += ' widget-tab__panorama-map__dot--active';
268
+ return className;
269
+ };
255
270
 
256
- viewer.enableEffect(PANOLENS.MODES.STEREO);
271
+ const getDotPosition = _ref5 => {
272
+ let {
273
+ left,
274
+ top
275
+ } = _ref5;
276
+ return {
277
+ left: "".concat(left * planScale.X, "px"),
278
+ top: "".concat(top * planScale.Y, "px")
279
+ };
257
280
  };
258
281
 
259
- const toggleOrientationMode = () => {
260
- if (viewer.control.id === 'orbit') {
261
- viewer.enableControl(DEVICEORIENTATION);
282
+ const updateCameraFov = fov => {
283
+ setCameraFov(fov);
284
+ viewer.camera.fov = fov;
285
+ viewer.camera.currentFov = fov;
286
+ viewer.camera.updateProjectionMatrix();
287
+ };
288
+
289
+ const toggleFov = () => {
290
+ if (viewer.camera.fov === cameraFovValues.x1) {
291
+ updateCameraFov(cameraFovValues.x2);
262
292
  return;
263
293
  }
264
294
 
265
- viewer.enableControl(ORBIT);
295
+ updateCameraFov(cameraFovValues.x1);
266
296
  };
267
297
 
268
- const toggleMap = () => setMapState(!isMapActive);
298
+ const toggleAutoplay = () => {
299
+ setAutoplayState(!autoplayEnabled);
269
300
 
270
- const setScale = () => {
271
- const image = document.querySelector('.widget-tab__panorama-map img');
272
- setPlanScale((0, _panoramaHelpers.getScale)(image, json));
273
- };
301
+ if (autoplayEnabled) {
302
+ viewer.disableAutoRate();
303
+ return;
304
+ }
274
305
 
275
- const getDotClassName = index => {
276
- let className = 'widget-tab__panorama-map__dot';
277
- if (isMapActive) className += ' widget-tab__panorama-map__dot--big';
278
- if (currentRoomIndex === index) className += ' widget-tab__panorama-map__dot--active';
279
- return className;
306
+ viewer.enableAutoRate();
280
307
  };
281
308
 
309
+ const updateWindowWidth = () => setWindowWidth(window.innerWidth);
310
+
311
+ (0, _react.useEffect)(() => {
312
+ window.addEventListener('resize', updateWindowWidth);
313
+ return function cleanup() {
314
+ window.removeEventListener('resize', updateWindowWidth);
315
+ };
316
+ }, []);
282
317
  (0, _react.useEffect)(() => {
318
+ if (!panoramas.length) return;
283
319
  const container = document.querySelector('.widget-tab__panorama-overlay');
284
320
  const newViewer = new PANOLENS.Viewer({
285
- container,
321
+ autoRotateActivationDuration: 1,
286
322
  autoHideInfospot: false,
287
323
  controlButtons: [],
288
- cameraFov: 90
324
+ controlBar: false,
325
+ cameraFov: cameraFovValues.x1,
326
+ container
289
327
  });
290
- container.addEventListener('mousewheel', e => {
328
+
329
+ const preventCameraFovChange = e => {
291
330
  e.preventDefault();
292
331
  e.stopPropagation();
293
- const scope = newViewer.getControl();
294
- const fovStep = 2;
295
-
296
- if (e.deltaY > 0) {
297
- const newFov = scope.object.fov + fovStep;
298
- scope.object.fov = newFov < scope.maxFov ? newFov : scope.maxFov;
299
- scope.object.updateProjectionMatrix();
300
- return;
301
- }
332
+ newViewer.camera.fov = newViewer.camera.currentFov;
333
+ newViewer.camera.updateProjectionMatrix();
334
+ };
302
335
 
303
- const newFov = scope.object.fov - fovStep;
304
- scope.object.fov = newFov > scope.minFov ? newFov : scope.minFov;
305
- scope.object.updateProjectionMatrix();
306
- });
336
+ container.addEventListener('mousewheel', preventCameraFovChange);
337
+ container.addEventListener('touchmove', preventCameraFovChange);
307
338
  panoramas.forEach(panorama => {
308
339
  if (!panorama.panorama_id) return;
309
340
  panorama.addEventListener('enter', _ref6 => {
@@ -315,46 +346,124 @@ const PanoramaTab = _ref5 => {
315
346
  newViewer.add(panorama);
316
347
  });
317
348
  newViewer.scene.rotation.y = Math.PI / 2;
349
+ newViewer.camera.currentFov = cameraFovValues.x1;
318
350
  setViewer(newViewer);
319
- initPanorama();
351
+ const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1000);
352
+ const orientationControls = new _threeDeviceOrientation.default(camera);
353
+
354
+ const animate = () => {
355
+ window.requestAnimationFrame(animate);
356
+ camera.aspect = window.innerWidth / window.innerHeight;
357
+ camera.updateProjectionMatrix();
358
+ orientationControls.update();
359
+ const fovElement = document.querySelector('.widget-tab__panorama-map__fov');
360
+ if (!fovElement) return;
361
+ const control = newViewer.getControl();
362
+ const angle = -(control.alpha || control.getAzimuthalAngle());
363
+ fovElement.style.transform = "translate(-50%, -50%) rotate(".concat(angle, "rad)");
364
+ };
365
+
366
+ animate();
320
367
  }, [panoramas]);
321
- (0, _react.useEffect)(setScale, [json, isMapActive]);
322
- return /*#__PURE__*/_react.default.createElement("div", {
368
+ (0, _react.useEffect)(setScale, [json, windowWidth]);
369
+ (0, _react.useEffect)(() => setPanoramas(getPanoramas(json, images, setLoadingState)), [json, images]);
370
+
371
+ const onStart = () => {
372
+ setInstructionsState(false);
373
+
374
+ try {
375
+ if (!DeviceOrientationEvent.requestPermission) return;
376
+ return DeviceOrientationEvent.requestPermission().then(status => {
377
+ if (status !== _deviceOrientationStatus.deviceOrientationStatus.GRANTED) {
378
+ setTimeout(() => viewer.enableControl(ORBIT), 100);
379
+ return;
380
+ }
381
+
382
+ setTimeout(() => viewer.enableControl(DEVICEORIENTATION), 100);
383
+ });
384
+ } catch (error) {
385
+ console.error(error.message);
386
+ }
387
+ };
388
+
389
+ const getRoomPointsAsString = points => {
390
+ return points.map(_ref7 => {
391
+ let [x, y] = _ref7;
392
+ return [x * planScale.X, y * planScale.Y];
393
+ }).flat().filter(num => !isNaN(num)).toString();
394
+ };
395
+
396
+ const onMapClick = event => {
397
+ const image = document.querySelector('.widget-tab__panorama-map img');
398
+ const {
399
+ clientX,
400
+ clientY
401
+ } = event;
402
+ const x = (clientX - image.x) / planScale.X;
403
+ const y = (clientY - image.y) / planScale.Y;
404
+ const availablePanoramas = panoramas.filter(_ref8 => {
405
+ let {
406
+ userData
407
+ } = _ref8;
408
+ return (0, _geometric.pointInPolygon)([x, y], userData.points);
409
+ });
410
+ const {
411
+ panorama
412
+ } = (0, _panoramaHelpers.getClosestPanorama)([x, y], availablePanoramas);
413
+ if (!panorama) return;
414
+ changePanorama(panorama);
415
+ };
416
+
417
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
323
418
  className: "widget-tab__panorama"
324
419
  }, /*#__PURE__*/_react.default.createElement("div", {
325
420
  className: "widget-tab__panorama-overlay"
326
421
  }), loadingState && /*#__PURE__*/_react.default.createElement(_Loader.default, {
327
422
  absolute: true
328
423
  }), /*#__PURE__*/_react.default.createElement("div", {
329
- className: "widget-tab-menu"
330
- }, /*#__PURE__*/_react.default.createElement("ul", null, /*#__PURE__*/_react.default.createElement("li", {
331
- onClick: () => setMenuState(!menuState)
332
- }, "Rooms"), menuState && panoramaRooms.map((room, index) => /*#__PURE__*/_react.default.createElement("li", {
333
- key: index,
334
- onClick: () => changePanorama(room.panorama, index)
335
- }, currentRoomIndex === index && '• ', " ", room.type)))), /*#__PURE__*/_react.default.createElement("div", {
336
- className: "widget-tab__panorama-map ".concat(planImage ? '' : 'widget-tab__panorama-map--hidden')
424
+ className: "widget-tab__panorama-map ".concat(isMapDisabled ? 'widget-tab__panorama-map--hidden' : '')
337
425
  }, /*#__PURE__*/_react.default.createElement("img", {
338
426
  src: planImage,
339
- className: isMapActive ? 'active' : '',
340
- onClick: toggleMap,
341
- onLoad: setScale,
427
+ onLoad: onImageLoaded,
342
428
  alt: "plan"
343
- }), !isMapDisabled && panoramaRooms.map((room, index) => /*#__PURE__*/_react.default.createElement("div", {
429
+ }), !isMapDisabled && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, panoramas.map((panorama, index) => /*#__PURE__*/_react.default.createElement("button", {
344
430
  key: index,
345
- style: {
346
- left: "".concat(room.left * planScale.X, "px"),
347
- top: "".concat(room.top * planScale.Y, "px")
348
- },
349
431
  className: getDotClassName(index),
350
- onClick: () => changePanorama(room.panorama, index)
351
- }))), /*#__PURE__*/_react.default.createElement("button", {
352
- className: "widget-tab__panorama-mode",
353
- onClick: toggleVrMode
354
- }, "VR"), /*#__PURE__*/_react.default.createElement("button", {
355
- className: "widget-tab__panorama-standart",
356
- onClick: toggleOrientationMode
357
- }, "Standart"));
432
+ style: getDotPosition(panorama.userData),
433
+ onClick: () => changePanorama(panorama)
434
+ })), /*#__PURE__*/_react.default.createElement("div", {
435
+ className: "widget-tab__panorama-map__fov",
436
+ style: getDotPosition(((_panoramas$currentRoo = panoramas[currentRoomIndex]) === null || _panoramas$currentRoo === void 0 ? void 0 : _panoramas$currentRoo.userData) || getDefaultUserData())
437
+ }), /*#__PURE__*/_react.default.createElement("svg", {
438
+ key: "X-".concat(planScale.X, "-Y-").concat(planScale.Y),
439
+ onClick: onMapClick
440
+ }, panoramas.map((_ref9, index) => {
441
+ let {
442
+ userData
443
+ } = _ref9;
444
+ return /*#__PURE__*/_react.default.createElement("polygon", {
445
+ key: index,
446
+ points: getRoomPointsAsString(userData.points)
447
+ });
448
+ })))), /*#__PURE__*/_react.default.createElement("div", {
449
+ className: "widget-tab__panorama-controls"
450
+ }, /*#__PURE__*/_react.default.createElement("button", {
451
+ className: "widget-tab__panorama-controls-button",
452
+ onClick: toggleFov
453
+ }, /*#__PURE__*/_react.default.createElement("img", {
454
+ src: cameraFov === cameraFovValues.x1 ? _x.default : _x2.default,
455
+ alt: "scale-icon"
456
+ })), /*#__PURE__*/_react.default.createElement("button", {
457
+ className: "widget-tab__panorama-controls-button",
458
+ onClick: toggleAutoplay
459
+ }, /*#__PURE__*/_react.default.createElement("img", {
460
+ src: autoplayEnabled ? _rotationClose.default : _rotation.default,
461
+ alt: "rotation-icon"
462
+ })))), showInstructions && /*#__PURE__*/_react.default.createElement(_Instructions.default, {
463
+ disabled: disabled,
464
+ steps: instructionSteps,
465
+ onClick: onStart
466
+ }));
358
467
  };
359
468
 
360
469
  var _default = PanoramaTab;
@@ -13,22 +13,38 @@ var _panzoom = _interopRequireDefault(require("panzoom"));
13
13
 
14
14
  var _threesixty = _interopRequireDefault(require("../threesixty"));
15
15
 
16
+ var _Instructions = _interopRequireDefault(require("./Instructions"));
17
+
18
+ var _handMove = _interopRequireDefault(require("../assets/icons/hand-move.svg"));
19
+
20
+ var _rotation = _interopRequireDefault(require("../assets/icons/rotation.svg"));
21
+
16
22
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
17
23
 
18
24
  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); }
19
25
 
20
26
  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; }
21
27
 
28
+ const instructionSteps = [{
29
+ icon: _handMove.default,
30
+ text: 'Вращать планировку'
31
+ }];
32
+
22
33
  const RotationTab = _ref => {
23
34
  let {
24
- images
35
+ images,
36
+ disabled = false
25
37
  } = _ref;
38
+ const [showInstructions, setInstructionsState] = (0, _react.useState)(false);
26
39
  const [activeIndex, setActiveIndex] = (0, _react.useState)(0);
27
- (0, _react.useEffect)(() => {
40
+ const [active, setActiveState] = (0, _react.useState)(false);
41
+
42
+ const onStart = () => {
43
+ setInstructionsState(false);
28
44
  const container = document.querySelector('.widget-tab__threesixty-container');
29
45
  const widgetTab = document.querySelector('.widget-tab');
30
46
  const rotation = new _threesixty.default(container, {
31
- image: images.map(img => img),
47
+ image: [...images],
32
48
  parentElement: widgetTab,
33
49
  inverted: true
34
50
  });
@@ -51,19 +67,33 @@ const RotationTab = _ref => {
51
67
 
52
68
  rotation._update = () => setActiveIndex(rotation.index);
53
69
  });
54
- }, [images]);
55
- return /*#__PURE__*/_react.default.createElement("div", {
56
- className: "widget-tab__threesixty"
70
+ };
71
+
72
+ const openInstructions = () => {
73
+ setInstructionsState(true);
74
+ setActiveState(true);
75
+ };
76
+
77
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
78
+ className: "widget-tab__threesixty ".concat(active ? 'widget-tab__threesixty--active' : '')
57
79
  }, /*#__PURE__*/_react.default.createElement("div", {
58
80
  className: "widget-tab__threesixty-container"
59
81
  }, images.map((img, index) => /*#__PURE__*/_react.default.createElement("img", {
60
82
  src: img,
61
83
  key: index,
62
84
  alt: "rotation-view-".concat(index),
63
- style: {
64
- opacity: activeIndex === index ? 1 : 0
65
- }
66
- }))));
85
+ className: activeIndex === index ? 'active' : ''
86
+ })))), !active && !showInstructions && /*#__PURE__*/_react.default.createElement("button", {
87
+ className: "widget-tab__threesixty-start",
88
+ onClick: openInstructions
89
+ }, /*#__PURE__*/_react.default.createElement("img", {
90
+ src: _rotation.default,
91
+ alt: "start-icon"
92
+ }), /*#__PURE__*/_react.default.createElement("span", null, "\u0412\u0440\u0430\u0449\u0430\u0442\u044C")), showInstructions && /*#__PURE__*/_react.default.createElement(_Instructions.default, {
93
+ disabled: disabled,
94
+ steps: instructionSteps,
95
+ onClick: onStart
96
+ }));
67
97
  };
68
98
 
69
99
  var _default = RotationTab;