Note: This release is in preview. Features described here don’t become generally available until the latest general availability date that Salesforce announces for this release. Before then, and where features are noted as beta, pilot, or developer preview, we can’t guarantee general availability within any particular time frame or at all. Make your purchase decisions only on the basis of generally available products and features.

AR SpaceCapture Example

The component’s HTML template is minimal and includes a button that initiates the room scan.
1<template>
2  <div style="height: 100%; padding: 0px;margin: 0px;">
3    <table class="rootTable" style="width: 100%; height: 100%; padding: 0px; border-spacing: 5px">
4      <thead>
5        <tr>
6          <th colspan="3">
7            <h1>AR SpaceCapture Demo</h1>
8          </th>
9        </tr>
10      </thead>
11      <tbody>
12        <tr style="height: 1px;">
13          <td><input type="button" class="lightningButton" onclick={handleBeginScanRoomClick} value='Scan Room' style="width: 100%; height: 50px; border: none; color: white; background: #0072d9; border-radius: 6px; font-size: medium; white-space: normal; word-wrap: break-word;"/></td>
14        </tr>
15        <tr>
16          <td colspan="3">
17            <div lwc:ref="previewDivSummary" class="previewDivSummary" style="width: 100%; height: 100%; border: 1px solid #c3c3c3; border-radius: 6px;">
18              Summary: <br>
19              <div lwc:ref="outputDivSummary" id="outputDivSummary" style="margin: 10px;">Results will be shown here soon...</div>
20            </div>
21          </td>
22        </tr>
23        <tr>
24          <td colspan="3">
25            <div lwc:ref="previewDiv" class="previewDiv" style="width: 100%; height: 100%; border: 1px solid #c3c3c3; border-radius: 6px;">
26              Full JSON: <br>
27              <div lwc:ref="outputDiv" id="outputDiv" style="margin: 10px;">Results will be shown here soon...</div>
28            </div>
29          </td>
30        </tr>
31      </tbody>
32    </table>
33  </div>
34</template>

This example uses AR SpaceCapture to let the user scan a room.

1import { LightningElement } from 'lwc';
2import { ShowToastEvent } from 'lightning/platformShowToastEvent';
3import { getARSpaceCapture } from 'lightning/mobileCapabilities';
4
5
6export default class ArSpaceCaptureNew extends LightningElement {
7	myARSpaceCaptureScanner;
8	scanRoomDisabled = false;
9	capturedRoomsData = '';
10
11
12	// When the component is initialized, determine whether to enable the Scan Room button
13	connectedCallback() {
14		this.myARSpaceCaptureScanner = getARSpaceCapture();
15		if (this.myARSpaceCaptureScanner?.isAvailable() != true) {
16			this.scanRoomDisabled = true;
17		}
18	}
19
20
21	handleBeginScanRoomClick() {
22		// Reset capturedRoomsData to empty string before starting a new scan
23		this.capturedRoomsData = '';
24
25
26		// Make sure AR SpaceCapture is available before trying to use it.
27		// Scan Room button also disabled when scanner unavailable
28		if (this.myARSpaceCaptureScanner?.isAvailable()) {
29			let options = {};
30
31
32			// Starting the scanning process
33			this.myARSpaceCaptureScanner.scanRoom(options)
34				.then((results) => {
35					try {
36						this.refs.outputDiv.innerHTML = "";
37					} catch (ex) {
38
39
40					}
41
42
43					const capturedRooms = results.capturedRooms ?? [];
44					if (capturedRooms) {
45						// Array of Rooms
46						let summary = {};
47
48
49						try {
50							summary.isSuccess = results.isSuccess;
51							summary.wallsCount = results.capturedRooms[0].walls.length;
52							summary.floorsCount = results.capturedRooms[0].floors.length;
53							summary.openingsCount = results.capturedRooms[0].openings.length;
54							summary.doorsCount = results.capturedRooms[0].doors.length;
55							summary.windowsCount = results.capturedRooms[0].windows.length;
56
57
58							if (results.capturedRooms[0].floors.length > 0) {
59								summary.roomSizeWidth = results.capturedRooms[0].floors[0].dimensions[0];
60								summary.roomSizeHeight = results.capturedRooms[0].floors[0].dimensions[1];
61								summary.roomVolume = summary.roomSizeWidth * summary.roomSizeHeight;
62							}
63
64
65							if (results.capturedRooms[0].openings.length > 0) {
66								summary.openingSizeWidth = results.capturedRooms[0].openings[0].dimensions[0];
67								summary.openingSizeHeight = results.capturedRooms[0].openings[0].dimensions[1];
68								summary.openingVolume = summary.openingSizeWidth * summary.openingSizeHeight;
69							}
70
71
72							if (results.capturedRooms[0].doors.length > 0) {
73								summary.doorSizeWidth = results.capturedRooms[0].doors[0].dimensions[0];
74								summary.doorSizeHeight = results.capturedRooms[0].doors[0].dimensions[1];
75								summary.openingVolume = summary.doorSizeWidth * summary.doorSizeHeight;
76							}
77
78
79							this.refs.outputDivSummary.innerHTML = "<pre><code>" + JSON.stringify(summary, undefined, 2) + "</code></pre>";
80							this.refs.outputDiv.innerHTML = "<pre><code>" + JSON.stringify(results, undefined, 2) + "</code></pre>";
81						} catch (ex) {
82							this.refs.outputDivSummary.innerHTML = ex.code + "<br>" + ex.message;
83						}
84					} else {
85// Single Room
86
87
88					try {
89							let summary = {};
90
91
92							summary.isSuccess = results.isSuccess;
93							summary.wallsCount = results.capturedRoom.walls.length;
94							summary.floorsCount = results.capturedRoom.floors.length;
95							summary.openingsCount = results.capturedRoom.openings.length;
96							summary.doorsCount = results.capturedRoom.doors.length;
97							summary.windowsCount = results.capturedRoom.windows.length;
98
99
100							if (results.capturedRoom.floors.length > 0) {
101								summary.roomSizeWidth = results.capturedRoom.floors[0].dimensions[0];
102								summary.roomSizeHeight = results.capturedRoom.floors[0].dimensions[1];
103								summary.roomVolume = summary.roomSizeWidth * summary.roomSizeHeight;
104							}
105
106
107
108
109							if (results.capturedRoom.openings.length > 0) {
110								summary.openingSizeWidth = results.capturedRoom.openings[0].dimensions[0];
111								summary.openingSizeHeight = results.capturedRoom.openings[0].dimensions[1];
112								summary.openingVolume = summary.openingSizeWidth * summary.openingSizeHeight;
113							}
114
115
116							if (results.capturedRoom.doors.length > 0) {
117								summary.doorSizeWidth = results.capturedRoom.doors[0].dimensions[0];
118								summary.doorSizeHeight = results.capturedRoom.doors[0].dimensions[1];
119								summary.doorVolume = summary.doorSizeWidth * summary.doorSizeHeight;
120							}
121
122
123							this.refs.outputDivSummary.innerHTML = "<pre><code>" + JSON.stringify(summary, undefined, 2) + "</code></pre>";
124							this.refs.outputDiv.innerHTML = "<pre><code>" + JSON.stringify(results, undefined, 2) + "</code></pre>";
125						} catch (ex) {
126							this.refs.outputDivSummary.innerHTML = ex.code + "<br>" + ex.message;
127						}
128					}
129				})
130				.catch((error) => {
131					// There was an error while scanning
132					this.refs.outputDivSummary.innerHTML = error.code + "<br>" + error.message;
133				})
134				.finally({
135					// Close capture process regardless of whether we completed successfully or had an error
136					// this.myARSpaceCaptureScanner.dismiss();
137				});
138		} else {
139			this.refs.outputDivSummary.innerHTML = 'AR SpaceCapture is not available on your device.';
140		}
141	}
142}