hart-estate-widget 3.9.15 → 4.0.0
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 +197 -341
- package/build/api.js +1 -0
- package/build/createWidget.js +2 -0
- package/build/{widget.module.js.LICENSE.txt → createWidget.js.LICENSE.txt} +34 -21
- package/build/plugins/DebugPlugin.js +2 -0
- package/build/{widget.bundle.js.LICENSE.txt → plugins/DebugPlugin.js.LICENSE.txt} +28 -28
- package/build/plugins/DefaultMapPlugin.js +2 -0
- package/build/plugins/DefaultMapPlugin.js.LICENSE.txt +49 -0
- package/build/plugins/FovPlugin.js +1 -0
- package/package.json +29 -38
- package/build/widget.bundle.js +0 -2
- package/build/widget.module.js +0 -2
- package/build/widget.module.worker.js.LICENSE.txt +0 -12
- /package/build/{widget.bundle.worker.js.LICENSE.txt → createWidget.worker.js.LICENSE.txt} +0 -0
package/README.md
CHANGED
@@ -3,16 +3,16 @@
|
|
3
3
|
The package is designed to present 2D and 3D floor plans generated by the AI service [getfloorplan.com](https://getfloorplan.com).
|
4
4
|
|
5
5
|
# Table of Contents
|
6
|
-
-
|
7
|
-
-
|
8
|
-
-
|
9
|
-
-
|
10
|
-
-
|
11
|
-
-
|
12
|
-
-
|
13
|
-
-
|
14
|
-
-
|
15
|
-
-
|
6
|
+
- [Quick Start](#quick-start)
|
7
|
+
- [Example vite.config.ts](#vite)
|
8
|
+
- [Example index.html](#html)
|
9
|
+
- [Example index.js](#javascript)
|
10
|
+
- [Example index.sass](#sass)
|
11
|
+
- [Docs](#docs)
|
12
|
+
- [Parameters](#parameters)
|
13
|
+
- [REST API Object](#widget-object-from-the-rest-api)
|
14
|
+
- [Versioning](#versioning)
|
15
|
+
- [Copyright and License](#copyright-and-license)
|
16
16
|
|
17
17
|
# Quick Start
|
18
18
|
|
@@ -20,34 +20,32 @@ As a result, you will receive a website that can display various floor plans.
|
|
20
20
|
|
21
21
|

|
22
22
|
|
23
|
-
- Download NodeJS 18
|
24
|
-
- Create a new project
|
25
|
-
|
23
|
+
- Download NodeJS 18+
|
24
|
+
- Create a new project
|
25
|
+
```shell
|
26
|
+
npm init
|
26
27
|
```
|
27
|
-
|
28
|
-
|
29
|
-
npm install
|
30
|
-
npm install
|
28
|
+
- Download the required packages
|
29
|
+
```shell
|
30
|
+
npm install -S hart-estate-widget@4.0.0 # GFP Widget package
|
31
|
+
npm install -S -D vite # Vite bundler
|
32
|
+
npm install -S -D sass-embedded # Sass style compiler
|
31
33
|
```
|
32
|
-
- Example structure of project
|
34
|
+
- Example structure of project
|
33
35
|
```
|
34
36
|
.
|
35
|
-
├── package-lock.json
|
36
|
-
├── package.json
|
37
37
|
├── src
|
38
|
-
│ ├──
|
39
|
-
│
|
40
|
-
│
|
41
|
-
│
|
42
|
-
|
43
|
-
|
44
|
-
│ └── js
|
45
|
-
└ └── index.tsx
|
38
|
+
│ ├── index.html
|
39
|
+
│ ├── index.js
|
40
|
+
│ ├── index.sass
|
41
|
+
│ └── logo.png
|
42
|
+
├── package.json
|
43
|
+
└── package-lock.json
|
46
44
|
```
|
47
45
|
- Copy-paste sample assets from below.
|
48
|
-
- Run with `rm -rf dist && npx
|
46
|
+
- Run with `rm -rf dist && npx vite`
|
49
47
|
- Open browser at:
|
50
|
-
http://localhost:1234/?id=
|
48
|
+
http://localhost:1234/?id=73b833c3-072a-4ac2-9f5d-7f7ac3d1fc9c
|
51
49
|
|
52
50
|
> The query `id` parameter accepts the UUID4 received from [getfloorplan.com](https://getfloorplan.com)
|
53
51
|
> You can use these UUID4 for test purposes:
|
@@ -57,68 +55,94 @@ http://localhost:1234/?id=228ba1dd-64d3-4d33-bcd7-b4c670bed40e
|
|
57
55
|
> - Neutral style: `e8553134-0457-488c-8d3e-611b0e2be4d4`
|
58
56
|
> - Modern style: `73b833c3-072a-4ac2-9f5d-7f7ac3d1fc9c`
|
59
57
|
|
58
|
+
## VITE
|
59
|
+
Insert the example into a file `vite.config.ts`
|
60
|
+
|
61
|
+
```ts
|
62
|
+
import { defineConfig } from 'vite';
|
63
|
+
|
64
|
+
export default defineConfig({
|
65
|
+
root: 'src',
|
66
|
+
build: { outDir: '../dist' },
|
67
|
+
server: { port: 1234, open: true },
|
68
|
+
});
|
69
|
+
```
|
70
|
+
|
60
71
|
## HTML
|
61
72
|
Insert the example into a file `src/index.html`
|
62
73
|
|
63
74
|
```html
|
75
|
+
<!DOCTYPE html>
|
64
76
|
<html lang="en">
|
65
77
|
<head>
|
66
78
|
<meta charset="utf-8">
|
67
79
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0" />
|
68
|
-
<title>
|
69
|
-
|
70
|
-
<script src="./
|
80
|
+
<title>HART Estate Widget</title>
|
81
|
+
|
82
|
+
<script type="module" src="./index.js"></script>
|
83
|
+
<link rel="icon" href="./logo.png">
|
71
84
|
</head>
|
72
85
|
|
73
86
|
<body>
|
74
|
-
<
|
75
|
-
<div class="widget" id="widget"></div> <!--must match the first attribute in 'new Widget('#widget', options);' -->
|
76
|
-
</section>
|
87
|
+
<div id="widget"></div>
|
77
88
|
</body>
|
78
89
|
</html>
|
79
90
|
```
|
80
91
|
|
81
92
|
## JavaScript
|
82
|
-
Insert the example into a file `src/
|
93
|
+
Insert the example into a file `src/index.js`
|
83
94
|
|
84
95
|
```js
|
85
|
-
import {
|
86
|
-
import '../assets/sass/index.sass'; // style
|
87
|
-
import logo from '../assets/img/logo.png'; // logo
|
96
|
+
import { Api } from 'hart-estate-widget/build/api.js'
|
88
97
|
|
89
|
-
const
|
98
|
+
const searchParams = new URLSearchParams(document.location.search);
|
99
|
+
const planId = searchParams.get('id');
|
100
|
+
const crmPlanId = searchParams.get('crmPlanId');
|
90
101
|
|
91
|
-
const
|
92
|
-
const widgetApiHandler = new ApiStore(WIDGET_API_URL)
|
102
|
+
const baseUrl = 'https://backend.estate.hart-digital.com';
|
93
103
|
|
94
|
-
|
95
|
-
const
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
+
const loadData = async () => {
|
105
|
+
const {loadCrmWidgetData, loadWidgetData} = new Api(baseUrl);
|
106
|
+
return crmPlanId ? loadCrmWidgetData(crmPlanId) : loadWidgetData(planId);
|
107
|
+
};
|
108
|
+
const loadCreateWidget = async () => (await import('hart-estate-widget/build/createWidget.js')).createWidget;
|
109
|
+
const loadFovPlugin = async () => (await import('hart-estate-widget/build/plugins/FovPlugin.js')).FovPlugin;
|
110
|
+
const loadLogoUrl = async () => (await import('./logo.png')).default;
|
111
|
+
const loadStyle = async () => (await import('./index.sass')).default;
|
112
|
+
const loadDocument = async () => new Promise((resolve) => (window.onload = resolve));
|
113
|
+
|
114
|
+
const queue = [
|
115
|
+
loadData(),
|
116
|
+
loadCreateWidget(),
|
117
|
+
loadFovPlugin(),
|
118
|
+
loadLogoUrl(),
|
119
|
+
loadStyle(),
|
120
|
+
loadDocument(),
|
121
|
+
];
|
122
|
+
|
123
|
+
Promise.all(queue).then(([data, createWidget, FovPlugin, logoUrl]) => {
|
124
|
+
const options = {
|
125
|
+
baseUrl,
|
104
126
|
logoUrl,
|
105
|
-
|
106
|
-
}
|
127
|
+
logoLinkUrl: 'https://getfloorplan.com',
|
128
|
+
};
|
107
129
|
|
108
|
-
|
109
|
-
|
130
|
+
const plugins = [
|
131
|
+
new FovPlugin(2),
|
132
|
+
];
|
110
133
|
|
111
|
-
createWidget('
|
134
|
+
createWidget('#widget', data, options, plugins);
|
135
|
+
});
|
112
136
|
```
|
113
137
|
|
114
138
|
## SASS
|
115
|
-
Insert the example into a file `src/
|
139
|
+
Insert the example into a file `src/index.sass`
|
116
140
|
|
117
141
|
```sass
|
118
142
|
*, *:before, *:after
|
119
143
|
-webkit-font-smoothing: antialiased
|
120
144
|
-moz-osx-font-smoothing: grayscale
|
121
|
-
font-family: 'Proxima Nova'
|
145
|
+
font-family: 'Proxima Nova', sans-serif
|
122
146
|
text-decoration: none
|
123
147
|
font-weight: 400
|
124
148
|
color: #fff
|
@@ -128,325 +152,157 @@ Insert the example into a file `src/sass/index.sass`
|
|
128
152
|
box-sizing: border-box
|
129
153
|
-webkit-box-sizing: border-box
|
130
154
|
|
131
|
-
body
|
155
|
+
html, body
|
132
156
|
width: 100%
|
133
157
|
height: 100%
|
134
|
-
overflow: hidden
|
135
158
|
|
136
|
-
|
159
|
+
#widget
|
137
160
|
width: 100%
|
138
161
|
height: 100%
|
139
|
-
|
140
|
-
width: 100%
|
141
|
-
height: 100%
|
162
|
+
overflow: hidden
|
142
163
|
```
|
143
164
|
|
144
|
-
|
145
165
|
# Docs
|
146
166
|
## Parameters:
|
147
167
|
Here you can see a list of accessible options and examples of usage. There are accessible values for each option below in the block "Types of Elements".
|
148
168
|
|
149
169
|
```ts
|
150
|
-
type
|
151
|
-
|
152
|
-
|
170
|
+
type TWidgetTab =
|
171
|
+
'rotation' | // circular view images (order is mandatory)
|
172
|
+
'plan' | // original plan image
|
173
|
+
'panorama' ; // 360° images
|
174
|
+
|
175
|
+
type TPanoramaControlType =
|
176
|
+
'ruler' | // Ruler button
|
177
|
+
'scale' | // Scale 1x, 2x, 0.5x button
|
178
|
+
'autoRotate' ; // Auto rotation button
|
179
|
+
|
180
|
+
type TAppColor =
|
181
|
+
'main' | // Widget fill color
|
182
|
+
'mainText' ; // Widget text color
|
183
|
+
|
184
|
+
type TWidgetLocale =
|
185
|
+
'en' | // English language
|
186
|
+
'ru' | // Russian language
|
187
|
+
'de' | // German language
|
188
|
+
'es' | // Spanish language
|
189
|
+
'ja' ; // Japanese language
|
190
|
+
|
191
|
+
export type TConfig = {
|
192
|
+
/** Widget API base URL */
|
193
|
+
baseUrl: string;
|
194
|
+
|
195
|
+
/** Widget locale */
|
196
|
+
locale: TWidgetLocale;
|
197
|
+
/** Overrides locale keys with custom text or translation */
|
198
|
+
localeOverrides: Record<string, string>;
|
153
199
|
|
154
200
|
/** Path/link to the logo */
|
155
|
-
|
201
|
+
logoUrl: string;
|
156
202
|
/** Link opened when logo is clicked */
|
157
|
-
|
158
|
-
|
159
|
-
/** Widget container offsetWidth */
|
160
|
-
width: 1920,
|
161
|
-
/** Widget container offsetHeight */
|
162
|
-
height: 1080,
|
163
|
-
/** Automatically resize the widget to the size of the container when the window is resized */
|
164
|
-
resizable: true;
|
165
|
-
|
166
|
-
/** Widget localization language (default: en) */
|
167
|
-
locale: 'en'
|
168
|
-
|
169
|
-
/** Use door proactive rectangle instead of door icon. */
|
170
|
-
enableDoorVisibility: false;
|
171
|
-
/** Type of images that will present in rotation tab, used as whitelist filter, defaults ['carousel', 'plan', 'topView'] */
|
172
|
-
availableRotationSteps: ['carousel', 'plan', 'topView'];
|
173
|
-
|
174
|
-
/** Available widget tabs, defaults ['rotation', 'plan', 'panorama'] */
|
175
|
-
tabs: ['rotation', 'plan', 'panorama'];
|
176
|
-
|
177
|
-
/**
|
178
|
-
* Mode of operation for plan images
|
179
|
-
* - `rotationModes.DEFAULT` - top view mode (multiple perspectives) and stylized plan view
|
180
|
-
* - `rotationModes.THREESIXTY` - image scrolling mode for circular view
|
181
|
-
* */
|
182
|
-
rotationMode: rotationModes.DEFAULT;
|
183
|
-
/** Camera persective FOV */
|
184
|
-
panoramaFov: 75;
|
185
|
-
/** Enable/disable camera rotation between panoramas (if CameraPoint.Rotation.Yaw is defined in JSON) */
|
186
|
-
enableCameraRotationBetweenPanoramas: true;
|
187
|
-
/** Enable/disable transition for camera rotation between panoramas (if CameraPoint.Rotation.Yaw is defined in JSON and enableCameraRotationBetweenPanoramas enabled) */
|
188
|
-
enableCameraTransitionBetweenPanoramas: false;
|
189
|
-
/** Override primary camera point ID over JSON */
|
190
|
-
primaryCameraPointId: 'CameraPointId12345678-12345678-12345678';
|
191
|
-
|
203
|
+
logoLinkUrl: string;
|
192
204
|
/**
|
193
205
|
* Widget color settings
|
194
206
|
* - `main`: main color of buttons, elements
|
195
207
|
* - `mainText`: text color for buttons, elements contrasting with the main color
|
196
208
|
* */
|
197
|
-
colors:
|
198
|
-
main: '#FFA900',
|
199
|
-
mainText: '#413E3E',
|
200
|
-
};
|
201
|
-
|
202
|
-
/** Panorama icons */
|
203
|
-
panoramaIcons: {
|
204
|
-
/** Icon for camera point links in one room */
|
205
|
-
spot: 'https://images.com/image-spot.svg';
|
206
|
-
/** Icon for proactive camera point links in one room */
|
207
|
-
interactiveSpot: 'https://images.com/image-interactive-spot.svg';
|
208
|
-
/** Icon for door link */
|
209
|
-
door: 'https://images.com/image-door.png';
|
210
|
-
};
|
209
|
+
colors: Record<TAppColor, string>;
|
211
210
|
|
212
|
-
/**
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
'made-by-link': 'https://getfloorplan.com/', // watermark link
|
220
|
-
'made-by-text': 'getfloorplan.com', // watermark text
|
221
|
-
'instructions-hint-text': '', // additional text on the bottom of instruction modal
|
222
|
-
'floor': '$0 floor' // floor text
|
223
|
-
};
|
211
|
+
/** First opened tab */
|
212
|
+
primaryTab: TWidgetTab;
|
213
|
+
/** Available widget tabs, defaults ['plan', 'rotation', 'panorama'] */
|
214
|
+
tabs: TWidgetTab[];
|
215
|
+
/** Path/link to the logo */
|
216
|
+
/** Controls can be: ruler, autoRotate or scale */
|
217
|
+
controls: TPanoramaControlType[];
|
224
218
|
|
225
219
|
/** Enable/disable modal of instruction in 3D tour */
|
226
|
-
|
220
|
+
isInstructionsVisible: boolean;
|
227
221
|
/** Enable/disable auto rotation in 3D tour */
|
228
|
-
|
229
|
-
/** Array of scale keys used as filter, can be x05, x1, ... */
|
230
|
-
scales: ['x05', 'x1'];
|
222
|
+
isAutoRotate: boolean;
|
231
223
|
/** Enable/disable device gyroscope for AR */
|
232
|
-
|
224
|
+
isGyroscopeEnabled: boolean;
|
225
|
+
/** Show/hide fullscreen button */
|
226
|
+
isFullscreenButtonVisible: boolean;
|
227
|
+
/** Show/hide current room type top label */
|
228
|
+
isRoomLabelVisible?: boolean;
|
233
229
|
|
234
|
-
/**
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
scaleButtonType: 'img';
|
240
|
-
/** Show floor number endings in floors locale translation */
|
241
|
-
floorNumberEndingsVisible: false;
|
230
|
+
/** Camera persective FOV */
|
231
|
+
cameraFov: number;
|
232
|
+
|
233
|
+
/** Time for fade in (seconds) */
|
234
|
+
panoramaFadeTime: number;
|
242
235
|
|
243
|
-
/**
|
244
|
-
* Design type
|
245
|
-
* - `standard`: bottom panel without sidebar, external floors select
|
246
|
-
* - `sidebar`: all buttons in sidebar, also floors select in sidebar
|
247
|
-
* - `custom`: use `bottombarContent` and `sidebarContent` to select required buttons manually
|
248
|
-
*/
|
249
|
-
designType: 'sidebar';
|
250
|
-
/** Bottom container button types to show */
|
251
|
-
bottombarContent: [];
|
252
|
-
/** Sidebar button types to show */
|
253
|
-
sidebarContent: ['floors', 'ruler', 'scale', 'rotation', 'furniture'];
|
254
|
-
/**
|
255
|
-
* Buttons design version
|
256
|
-
* - `two`: buttons design v2.0
|
257
|
-
* - `three`: buttons design v3.0
|
258
|
-
*/
|
259
|
-
tabsButtonsDesign: 'three';
|
260
|
-
/** Proactive cursor type: 'pointer' or 'circle' */
|
261
|
-
cursor: 'pointer';
|
262
|
-
/** Enable/disable proactive cursor pulse */
|
263
|
-
enableCursorPulse: true;
|
264
|
-
|
265
236
|
/** Widget external integrations */
|
266
237
|
integrations: {
|
267
|
-
/** Configuration options for the Sentry Browser SDK.
|
268
|
-
sentry
|
269
|
-
};
|
270
|
-
|
271
|
-
/** Allows movement only within a room or between rooms, can be interroom or intraroom */
|
272
|
-
movementType: 'interroom';
|
273
|
-
|
274
|
-
/** Options for DefaultLink graphics */
|
275
|
-
default_link_options: {
|
276
|
-
/** Use perspective size for DefaultLink sprite */
|
277
|
-
use_real_size: false;
|
278
|
-
/** Perspective size */
|
279
|
-
real_size: 300;
|
280
|
-
/** Perspective size scale on mobile devices */
|
281
|
-
real_size_mobile_scale: 1;
|
282
|
-
/** Minimal distance to prevent overscale in near distances */
|
283
|
-
real_size_min_distance: 100;
|
284
|
-
/** Minimal distance scale clamp on near distances */
|
285
|
-
real_size_distance_min_scale: 0.1;
|
286
|
-
/** Enable/disable scale on hover */
|
287
|
-
hover_scale: 1.2;
|
288
|
-
};
|
289
|
-
|
290
|
-
/** Panorama fading options */
|
291
|
-
fade_options: {
|
292
|
-
/** Time for fade in (seconds) */
|
293
|
-
fade_in_time: 0.5;
|
294
|
-
/** Time for fade out (seconds) */
|
295
|
-
fade_out_time: 0.5;
|
296
|
-
};
|
297
|
-
|
298
|
-
/** Options for DefaultLink graphics */
|
299
|
-
ruler_options: {
|
300
|
-
/** Font size for ruler text */
|
301
|
-
font_size: 38;
|
302
|
-
};
|
303
|
-
|
304
|
-
/** Options for DefaultLink graphics */
|
305
|
-
link_options: {
|
306
|
-
/** Enable/disable link pulse on hover */
|
307
|
-
enable_pulse: false;
|
308
|
-
/** Pulse scale from */
|
309
|
-
pulse_from_scale: 1;
|
310
|
-
/** Pulse scale to */
|
311
|
-
pulse_to_scale: 2;
|
312
|
-
/** Pulse speed */
|
313
|
-
pulse_speed: 1;
|
314
|
-
|
315
|
-
/** Enable/disable scale on hover */
|
316
|
-
enable_point_hover_scale: false;
|
317
|
-
/** Hover scale */
|
318
|
-
point_hover_scale: 1;
|
238
|
+
/** Configuration options for the Sentry Browser SDK. */
|
239
|
+
sentry?: BrowserOptions; // See https://docs.sentry.io/platforms/javascript/configuration/options/
|
319
240
|
};
|
320
|
-
|
321
|
-
/** Options for DefaultLink graphics */
|
322
|
-
map_options: {
|
323
|
-
/** Map type, should be 'default', 'top_view' or 'multi_floor' */
|
324
|
-
type: 'default';
|
325
|
-
/** Upscale top view resolution for better rendering */
|
326
|
-
top_view_upscale: 2;
|
327
|
-
/** Crop transparent bounds in multimap */
|
328
|
-
crop_transparent?: true;
|
329
|
-
};
|
330
|
-
|
331
|
-
/** Options for Scene camera */
|
332
|
-
camera_options: {
|
333
|
-
/** Speed of fov changing per deltaTime */
|
334
|
-
fov_change_speed?: 0;
|
335
|
-
};
|
336
|
-
|
337
|
-
/** Options for Portal link graphics */
|
338
|
-
portal_options?: {
|
339
|
-
/** Use overlay div elements instead of three.js graphics */
|
340
|
-
use_overlay?: true;
|
341
|
-
/** Generate portals from stairs */
|
342
|
-
generate_from_stairs?: true;
|
343
|
-
};
|
344
|
-
|
345
|
-
/** Options for DefaultLink graphics */
|
346
|
-
lazy_load_options: {
|
347
|
-
/** Count panoramas to lazy load after move to another panorama */
|
348
|
-
preload_count: 3;
|
349
|
-
/** Force lazy load another non-loaded panoramas instead of skipping near cached panoramas */
|
350
|
-
force_preload_non_cached: true;
|
351
|
-
/** Preload depth maps */
|
352
|
-
use_masks_preload: true;
|
353
|
-
};
|
354
|
-
|
355
|
-
/** Widget branding data */
|
356
|
-
widget_branding: {
|
357
|
-
/** Branded logo path */
|
358
|
-
logo_path: 'https://es-logos.com/logo.png';
|
359
|
-
/** Branded company name */
|
360
|
-
company_name: 'ES Company';
|
361
|
-
/** Branded company url */
|
362
|
-
company_url: 'https://es.company.com';
|
363
|
-
/** Branded widget language (See locale/*) */
|
364
|
-
widget_language: 'es';
|
365
|
-
}
|
366
|
-
|
367
|
-
/** Show/hide fullscreen button */
|
368
|
-
fullscreen_button_visible: false;
|
369
|
-
/** Show/hide room type label */
|
370
|
-
room_label_visible: false;
|
371
241
|
};
|
372
242
|
```
|
373
243
|
|
374
|
-
## Types of elements
|
375
|
-
```js
|
376
|
-
tabs: [
|
377
|
-
'rotation', // circular view images (order is mandatory)
|
378
|
-
'panorama', // 360° images
|
379
|
-
],
|
380
|
-
rotationMode: [
|
381
|
-
rotationModes.DEFAULT, // top view mode (multiple perspectives) and stylized plan view
|
382
|
-
rotationModes.THREESIXTY, // image scrolling mode for circular view
|
383
|
-
],
|
384
|
-
floors[0].rotate.type: [
|
385
|
-
'top_down', // full model
|
386
|
-
'middle_cut', // model with cut in the middle
|
387
|
-
],
|
388
|
-
floors[0].panorama.type: [
|
389
|
-
'sphere', // 360° panorama
|
390
|
-
'cube', // panorama with 6 images (top, down, left, right, front, back)
|
391
|
-
],
|
392
|
-
locale: [
|
393
|
-
'ru', // Russian language
|
394
|
-
'en', // English language
|
395
|
-
'es', // Spanish language
|
396
|
-
'de', // German language
|
397
|
-
'ja', // Japanese language
|
398
|
-
],
|
399
|
-
scales: [
|
400
|
-
'x05',
|
401
|
-
'x075',
|
402
|
-
'x1',
|
403
|
-
'x125',
|
404
|
-
'x2',
|
405
|
-
],
|
406
|
-
```
|
407
|
-
|
408
244
|
## Widget object from the REST API
|
409
245
|
|
410
246
|
JSON object returned from backend
|
411
247
|
|
412
248
|
```js
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
}
|
249
|
+
export default {
|
250
|
+
primary_variant: "<id>", // primary variant to open
|
251
|
+
variants: [ // all plan variants
|
252
|
+
{
|
253
|
+
variant_info: {
|
254
|
+
style_name: "<name>", // the name of the variant style
|
255
|
+
is_renovation: true, // is there a renovation in the plan
|
256
|
+
},
|
257
|
+
plan_id: "<uuid>", // variant service plan uuid
|
258
|
+
json: "<url>", // json url for additional plan data
|
259
|
+
assets_path: "<path>", // plan assets base url
|
260
|
+
capabilities: { /*...*/ }, // plan capabilities
|
261
|
+
rendering_settings: { /*...*/ }, // plan rendering settings
|
262
|
+
|
263
|
+
primary_floor: 0, // primary plan floor index
|
264
|
+
floors: [ // plan floors
|
265
|
+
{
|
266
|
+
original_plan_img: "<url>", // absolute path to original plan image
|
267
|
+
miniplan_img: "<url>", // absolute path to miniplan image
|
268
|
+
|
269
|
+
top_view: {
|
270
|
+
image_template: "<template>", // template for top view decoding
|
271
|
+
room_ids_template: "<template>", // template for top view mask decoding
|
272
|
+
items: ["<filename>"], // top view image names
|
273
|
+
},
|
274
|
+
isometric_view: {
|
275
|
+
image_template: "<template>", // template for isometric images decoding
|
276
|
+
room_ids_template: "<template>", // template for isometric images masks decoding
|
277
|
+
items: ["<filename>"], // isometric images names
|
278
|
+
},
|
279
|
+
panorama_view: {
|
280
|
+
template: "<template>", // template for panorama image decoding
|
281
|
+
scene_depth_template: "<template>", // template for panorama depth image decoding
|
282
|
+
primary_camera_point_id: "<id>", // primary plan camera id
|
283
|
+
},
|
284
|
+
|
285
|
+
location: { X: 0, Y: 0, Z: 0 }, // floor location
|
286
|
+
height: 280, // floor height
|
287
|
+
|
288
|
+
vertices: [ /*...*/ ], // plan vertices data
|
289
|
+
rooms: [ /*...*/ ], // plan rooms data
|
290
|
+
camera_points: [ /*...*/ ], // plan camera points data
|
291
|
+
walls: [ /*...*/ ], // plan walls data
|
292
|
+
doors: [ /*...*/ ], // plan doors data
|
293
|
+
stairs: [ /*...*/ ], // plan stairs data
|
294
|
+
portals: [ /*...*/ ], // plan portals data
|
295
|
+
apertures: [ /*...*/ ], // plan apertures data
|
296
|
+
decors: [ /*...*/ ], // plan decors data
|
297
|
+
|
298
|
+
object_pairs: [], // color pairs for furniture data
|
299
|
+
room_pairs: [], // color pairs for room data
|
300
|
+
plan_meta: { /*...*/ }, // plan metadata
|
301
|
+
},
|
302
|
+
],
|
303
|
+
},
|
304
|
+
],
|
305
|
+
};
|
450
306
|
```
|
451
307
|
|
452
308
|
# Versioning
|
package/build/api.js
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
var r={d:(e,t)=>{for(var a in t)r.o(t,a)&&!r.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:t[a]})},o:(r,e)=>Object.prototype.hasOwnProperty.call(r,e)},e={};r.d(e,{j:()=>t});class t{baseUrl;constructor(r){this.baseUrl=r}get headers(){return{Accept:"application/json;widget-version=4.0.0"}}loadCrmWidgetData=async r=>{if(!r)return this.makeError(404,"No crmPlanId!");try{const e=await this.fetch(`/api/crm/plans/${r}/v4/widget`);return e.ok?e.json():this.makeErrorFromResponse(e,"Failed to get CRM Plan widget data!")}catch(r){return this.makeError(520,r.message)}};loadWidgetData=async r=>{if(!r)return this.makeError(404,"No planId!");try{const e=await this.fetch(`/api/plans/${r}/v4/widget`);return e.ok?e.json():this.makeErrorFromResponse(e,"Failed to get Plan widget data!")}catch(r){return this.makeError(520,r.message)}};loadJson=async r=>{try{return(await fetch(r)).json()}catch(r){return this.makeError(500,r.message)}};makeError(r,e="Unknown error"){return{error:{status:r,message:e}}}async makeErrorFromResponse(r,e){if("application/json"===r.headers.get("Content-Type")){const e=await r.json();if("message"in e&&"string"==typeof e.message)return this.makeError(r.status,e.message)}return this.makeError(r.status,e)}fetch(r,e={headers:this.headers}){return fetch(`${this.baseUrl}${r}`,e)}}var a=e.j;export{a as Api};
|