-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathar-button.js
156 lines (143 loc) · 5.49 KB
/
ar-button.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// constants to check for various platforms / AR subsytems support
// @see https://github.com/google/model-viewer/blob/master/packages/model-viewer/src/features/ar.ts
const IS_ANDROID = /android/i.test(navigator.userAgent);
const IS_IOS =
(/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream) ||
(navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1);
const IS_SAFARI = /Safari\//.test(navigator.userAgent);
const IS_FIREFOX = /firefox/i.test(navigator.userAgent);
const IS_OCULUS = /OculusBrowser/.test(navigator.userAgent);
const IS_IOS_CHROME = IS_IOS && /CriOS\//.test(navigator.userAgent);
const IS_IOS_SAFARI = IS_IOS && IS_SAFARI;
const SUPPORTS_SCENEVIEWER = IS_ANDROID && !IS_FIREFOX && !IS_OCULUS;
const SUPPORTS_QUICKLOOK = (() => {
const anchor = document.createElement("a");
return anchor.relList && anchor.relList.supports && anchor.relList.supports("ar");
})();
const activateAR = (href, button, isQuickLook) => {
const anchor = document.createElement("a");
if (isQuickLook) {
// quick look needs a <img> child to go directly to AR view
anchor.appendChild(document.createElement("img"));
anchor.rel = "ar";
}
anchor.setAttribute("href", href);
anchor.click();
if (button && isQuickLook) {
anchor.addEventListener(
"message",
(event) => {
if (event.data == "_apple_ar_quicklook_button_tapped") {
button.dispatchEvent(new CustomEvent("quick-look-button-tapped"));
}
},
false
);
}
};
const initializeArButton = (button) => {
// skip button if it was already initialized beforehand
if (button.getAttribute("ar") != null) {
return;
}
if ((IS_IOS_CHROME || IS_IOS_SAFARI) && SUPPORTS_QUICKLOOK) {
// system supports AR via quick look (on ios this takes precedence on scene viewer)
button.setAttribute("ar", "quick-look");
button.dispatchEvent(new CustomEvent("initialized", { detail: "quick-look" }));
button.addEventListener("click", () => {
const iosSrc = button.getAttribute("ios-src");
if (!iosSrc) {
console.error("Invalid ios-src in <ar-button>: " + button);
return;
}
const applePayButtonType = button.getAttribute("applepay-button-type");
const checkoutTitle = button.getAttribute("checkout-title");
const checkoutSubtitle = button.getAttribute("checkout-subtitle");
const price = button.getAttribute("price");
const callToAction = button.getAttribute("call-to-action");
const customBanner = button.getAttribute("custom-banner");
const customHeight = button.getAttribute("custom-height");
const noScale = button.getAttribute("no-scale");
let href = `${iosSrc}#`;
if (applePayButtonType) {
href += `&applePayButtonType=${encodeURIComponent(applePayButtonType)}`;
}
if (checkoutTitle) {
href += `&checkoutTitle=${encodeURIComponent(checkoutTitle)}`;
}
if (checkoutSubtitle) {
href += `&checkoutSubtitle=${encodeURIComponent(checkoutSubtitle)}`;
}
if (price) {
href += `&price=${encodeURIComponent(price)}`;
}
if (callToAction) {
href += `&callToAction=${encodeURIComponent(callToAction)}`;
}
if (customBanner) {
href += `&custom=${encodeURIComponent(customBanner)}`;
}
if (customHeight) {
href += `&customHeight=${encodeURIComponent(customHeight)}`;
}
if (noScale != null) {
href += `&allowsContentScaling=0`;
}
activateAR(href, button, true);
});
} else if (SUPPORTS_SCENEVIEWER) {
// system supports AR via scene viewer
button.setAttribute("ar", "scene-viewer");
button.dispatchEvent(new CustomEvent("initialized", { detail: "scene-viewer" }));
button.addEventListener("click", () => {
const src = button.getAttribute("src");
if (!src) {
console.error("Invalid src in <ar-button>: " + button);
return;
}
const title = button.getAttribute("title");
const fallbackUrl = button.getAttribute("fallback-url");
const link = button.getAttribute("link");
const noScale = button.getAttribute("no-scale");
let href = `intent://arvr.google.com/scene-viewer/1.0?file=${src}&mode=ar_only`;
if (title) {
href += `&title=${encodeURIComponent(title)}`;
}
if (link) {
href += `&link=${encodeURIComponent(link)}`;
}
if (noScale != null) {
href += `&resizable=false`;
}
href +=
`#Intent;scheme=https;` +
`package=com.google.ar.core;` +
`action=android.intent.action.VIEW;`;
if (fallbackUrl) {
href += `S.browser_fallback_url=${encodeURIComponent(fallbackUrl)};`;
}
href += `end;`;
activateAR(href);
});
} else {
// No AR supported on current system, hide the button or sets a fallback url
button.setAttribute("ar", "unsupported");
button.dispatchEvent(new CustomEvent("initialized", { detail: "unsupported" }));
if (button.getAttribute("show-if-unsupported") != null) {
button.addEventListener("click", () => {
const fallbackUrl = button.getAttribute("fallback-url");
if (fallbackUrl) {
activateAR(encodeURIComponent(fallbackUrl));
}
});
} else {
button.style.display = "none";
}
}
};
// go through all ar-button tags on the page and initialize them
const buttons = document.querySelectorAll("ar-button");
for (let i = 0; i < buttons.length; i++) {
const button = buttons.item(i);
initializeArButton(button);
}