Skip to content

Instantly share code, notes, and snippets.

@creimers
Created February 4, 2026 11:40
Show Gist options
  • Select an option

  • Save creimers/99ab74e896f29d38709ab32db9a4fb83 to your computer and use it in GitHub Desktop.

Select an option

Save creimers/99ab74e896f29d38709ab32db9a4fb83 to your computer and use it in GitHub Desktop.
viro-ar-examp.e
import * as React from "react";
import { ImageSourcePropType, View } from "react-native";
import {
ViroARScene,
ViroAmbientLight,
Viro3DObject,
ViroARSceneNavigator,
ViroARImageMarker,
ViroNode,
} from "@reactvision/react-viro";
import { useAppStore } from "@/lib/store";
import { AR_DEFAULT_IMAGE_MARKER_NAME } from "./../constants";
import { AR3DObjectFeature } from "./../interfaces";
import ARWarningModal from "./../ARWarningModal";
import Scanner from "../Scanner";
import { Viro3DPoint } from "@reactvision/react-viro/dist/components/Types/ViroUtils";
type Props = {
config: AR3DObjectFeature;
};
const Scene = ({ config }: Props) => {
const showScanner = useAppStore((state) => state.showScanner);
const hideScanner = useAppStore((state) => state.hideScanner);
const activeFeature = config;
const scale = activeFeature?.scale || 1;
const sceneRotationX =
activeFeature.sceneRotationX !== undefined
? activeFeature.sceneRotationX
: 0;
const sceneRotationY =
activeFeature.sceneRotationY !== undefined
? activeFeature.sceneRotationY
: 0;
const sceneRotationZ =
activeFeature.sceneRotationZ !== undefined
? activeFeature.sceneRotationZ
: 0;
return (
<ViroARScene>
<ViroAmbientLight color="#ffffff" />
<ViroARImageMarker
target={activeFeature?.imageMarkerName || AR_DEFAULT_IMAGE_MARKER_NAME}
onAnchorFound={hideScanner}
>
<ViroNode
position={[0, 0, 0]}
scale={[1, 1, 1]}
rotation={[sceneRotationX, 0, 0]}
>
<ViroNode
position={[0, 0, 0]}
scale={[1, 1, 1]}
rotation={[0, sceneRotationY, 0]}
>
<ViroNode
position={[0, 0, 0]}
scale={[1, 1, 1]}
rotation={[0, 0, sceneRotationZ]}
>
{!showScanner ? (
<Viro3DObject
source={activeFeature.source as ImageSourcePropType}
lightReceivingBitMask={3}
position={activeFeature.position as Viro3DPoint} // x, y, z
scale={[scale, scale, scale]}
onError={(error: any) => console.log(error)}
resources={activeFeature.resources as ImageSourcePropType[]}
type={
(activeFeature.sourceType || "OBJ") as
| "OBJ"
| "VRX"
| "GLTF"
| "GLB"
}
materials={activeFeature.material}
/>
) : null}
</ViroNode>
</ViroNode>
</ViroNode>
</ViroARImageMarker>
</ViroARScene>
);
};
export default function AR3DObjectScene({ config }: Props) {
const [isARWarned, setIsARWarned] = React.useState(false);
const { showScanner, setShowScanner } = useAppStore((state) => state);
React.useEffect(() => {
return () => {
setShowScanner(true);
};
}, []);
return (
<View className="flex-1 relative">
{showScanner && <Scanner />}
<ARWarningModal visible={!isARWarned} hide={() => setIsARWarned(true)} />
<ViroARSceneNavigator
autofocus={true}
initialScene={{ scene: () => <Scene config={config} /> }}
style={{ flex: 1 }}
/>
</View>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment