room-craft
Version:
A lightweight React component for displaying products in both Augmented Reality (AR) and 3D. Perfect for eCommerce applications where you want to showcase your products in an immersive and interactive way.
147 lines (143 loc) • 7.54 kB
JavaScript
;
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _react = _interopRequireWildcard(require("react"));
require("@google/model-viewer");
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; }
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; } // import React, { useRef, useState } from "react";
// import "@google/model-viewer";
// import PropTypes from "prop-types";
// const XrHitModelContainer = ({ gltfPath }) => {
// const modelViewerRef = useRef(null);
// const [isPlaced, setIsPlaced] = useState(false);
// const [scale, setScale] = useState(1); // Default scale
// const handleARPlacement = (event) => {
// const modelViewer = modelViewerRef.current;
// if (modelViewer?.scene) {
// const hitTest = event.detail?.hitTestResults?.[0];
// if (hitTest) {
// const { x, y, z } = hitTest.transform.position;
// // Set position and scale
// modelViewer.scene.position.set(x, y, z);
// modelViewer.scene.scale.set(scale, scale, scale);
// setIsPlaced(true);
// }
// }
// };
// const increaseScale = () => setScale((prev) => prev + 0.1);
// const decreaseScale = () => setScale((prev) => Math.max(prev - 0.1, 0.1));
// return (
// <div style={{ width: "100%", height: "90%" }}>
// <model-viewer
// ref={modelViewerRef}
// src={gltfPath}
// ar
// ar-hit-test
// camera-controls
// style={{ width: "100%", height: "100%" }}
// onArHitTest={handleARPlacement}
// />
// {isPlaced && (
// <div style={{ position: "absolute", bottom: "10px", left: "10px" }}>
// <button onClick={increaseScale} style={{ marginRight: "10px" }}>
// Increase Scale
// </button>
// <button onClick={decreaseScale}>Decrease Scale</button>
// </div>
// )}
// </div>
// );
// };
// XrHitModelContainer.propTypes = {
// gltfPath: PropTypes.string.isRequired,
// };
// export default XrHitModelContainer;
var XrHitModelContainer = function XrHitModelContainer() {
var modelViewerRef = (0, _react.useRef)(null);
var _useState = (0, _react.useState)(false),
_useState2 = _slicedToArray(_useState, 2),
isPlaced = _useState2[0],
setIsPlaced = _useState2[1];
var _useState3 = (0, _react.useState)(1),
_useState4 = _slicedToArray(_useState3, 2),
scale = _useState4[0],
setScale = _useState4[1];
var _useState5 = (0, _react.useState)(""),
_useState6 = _slicedToArray(_useState5, 2),
gltfPath = _useState6[0],
setGltfPath = _useState6[1];
// Extract gltfPath from URL parameters
(0, _react.useEffect)(function () {
var params = new URLSearchParams(window.location.search);
var path = params.get("gltfPath");
if (path) setGltfPath(path);
}, []);
// Handle AR placement logic
var handleARPlacement = function handleARPlacement(event) {
var _event$detail;
var modelViewer = modelViewerRef.current;
if (!modelViewer) return;
var hitTest = (_event$detail = event.detail) === null || _event$detail === void 0 || (_event$detail = _event$detail.hitTestResults) === null || _event$detail === void 0 ? void 0 : _event$detail[0]; // Get first hit test result
if (hitTest) {
var _hitTest$transform$po = hitTest.transform.position,
x = _hitTest$transform$po.x,
y = _hitTest$transform$po.y,
z = _hitTest$transform$po.z;
modelViewer.setAttribute("position", "".concat(x, " ").concat(y, " ").concat(z));
modelViewer.setAttribute("scale", "".concat(scale, " ").concat(scale, " ").concat(scale));
setIsPlaced(true);
}
};
// Increase and decrease scale
var increaseScale = function increaseScale() {
return setScale(function (prev) {
return prev + 0.1;
});
};
var decreaseScale = function decreaseScale() {
return setScale(function (prev) {
return Math.max(prev - 0.1, 0.1);
});
};
return /*#__PURE__*/_react["default"].createElement("div", {
style: {
width: "100%",
height: "100vh",
position: "relative"
}
}, gltfPath ? /*#__PURE__*/_react["default"].createElement("model-viewer", {
ref: modelViewerRef,
src: gltfPath,
ar: true,
"ar-hit-test": true,
"camera-controls": true,
"auto-rotate": true,
style: {
width: "100%",
height: "90%"
},
onArHitTest: handleARPlacement
}) : /*#__PURE__*/_react["default"].createElement("p", null, "Loading AR Viewer..."), isPlaced && /*#__PURE__*/_react["default"].createElement("div", {
style: {
position: "absolute",
bottom: "10px",
left: "10px",
display: "flex",
gap: "10px"
}
}, /*#__PURE__*/_react["default"].createElement("button", {
onClick: increaseScale
}, "Increase Scale"), /*#__PURE__*/_react["default"].createElement("button", {
onClick: decreaseScale
}, "Decrease Scale")));
};
var _default = exports["default"] = XrHitModelContainer;