lightswind
Version:
A collection of beautifully crafted React Components, Blocks & Templates for Modern Developers. Create stunning web applications effortlessly by using our 160+ professional and animated react components.
148 lines • 7.38 kB
JavaScript
;
// @ts-nocheck
"use client";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const fiber_1 = require("@react-three/fiber");
const drei_1 = require("@react-three/drei");
const OBJLoader_1 = require("three/examples/jsm/loaders/OBJLoader");
const THREE = __importStar(require("three"));
const isTouch = typeof window !== "undefined" &&
("ontouchstart" in window || navigator.maxTouchPoints > 0);
const deg2rad = (d) => (d * Math.PI) / 180;
// ---
// Reusable Components
// ---
const Loader = () => {
const { progress } = (0, drei_1.useProgress)();
return ((0, jsx_runtime_1.jsx)(drei_1.Html, { center: true, children: (0, jsx_runtime_1.jsx)("div", { className: "text-gray-400 text-lg", children: `${Math.round(progress)} %` }) }));
};
// Component for handling GLTF/GLB models
const GltfContent = ({ url, onLoaded, }) => {
const { scene } = (0, drei_1.useGLTF)(url);
(0, react_1.useLayoutEffect)(() => {
if (scene) {
scene.traverse((o) => {
if (o.isMesh) {
o.castShadow = true;
o.receiveShadow = true;
}
});
onLoaded();
}
}, [scene, onLoaded]);
return (0, jsx_runtime_1.jsx)("primitive", { object: scene.clone() });
};
// Component for handling FBX models
const FbxContent = ({ url, onLoaded, }) => {
const fbx = (0, drei_1.useFBX)(url);
(0, react_1.useLayoutEffect)(() => {
if (fbx) {
fbx.traverse((o) => {
if (o.isMesh) {
o.castShadow = true;
o.receiveShadow = true;
}
});
onLoaded();
}
}, [fbx, onLoaded]);
return (0, jsx_runtime_1.jsx)("primitive", { object: fbx.clone() });
};
// Component for handling OBJ models
const ObjContent = ({ url, onLoaded, }) => {
const obj = (0, fiber_1.useLoader)(OBJLoader_1.OBJLoader, url);
(0, react_1.useLayoutEffect)(() => {
if (obj) {
obj.traverse((o) => {
if (o.isMesh) {
o.castShadow = true;
o.receiveShadow = true;
}
});
onLoaded();
}
}, [obj, onLoaded]);
return (0, jsx_runtime_1.jsx)("primitive", { object: obj.clone() });
};
const SceneContent = ({ url, autoRotate, autoRotateSpeed, onLoaded }) => {
const modelRef = (0, react_1.useRef)(null);
const ext = url.split(".").pop()?.toLowerCase();
(0, fiber_1.useFrame)((state, delta) => {
if (autoRotate && modelRef.current) {
modelRef.current.rotation.y += (autoRotateSpeed || 1) * delta;
}
});
const onLoadedHandler = () => {
onLoaded?.();
};
const ModelComponent = () => {
switch (ext) {
case "glb":
case "gltf":
return (0, jsx_runtime_1.jsx)(GltfContent, { url: url, onLoaded: onLoadedHandler });
case "fbx":
return (0, jsx_runtime_1.jsx)(FbxContent, { url: url, onLoaded: onLoadedHandler });
case "obj":
return (0, jsx_runtime_1.jsx)(ObjContent, { url: url, onLoaded: onLoadedHandler });
default:
return null;
}
};
return ((0, jsx_runtime_1.jsx)(drei_1.Center, { children: (0, jsx_runtime_1.jsx)("group", { ref: modelRef, children: (0, jsx_runtime_1.jsx)(ModelComponent, {}) }) }));
};
// ---
// Main Viewer Component
// ---
const ModelViewer = ({ url, width = "100%", height = "100%", defaultZoom = 2, minZoomDistance = 0.5, maxZoomDistance = 10, enableManualRotation = true, enableManualZoom = true, ambientIntensity = 0.3, keyLightIntensity = 1, fillLightIntensity = 0.5, rimLightIntensity = 0.8, environmentPreset = "forest", autoRotate = false, autoRotateSpeed = 0.35, onModelLoaded, }) => {
// Preload hook calls should also be unconditional.
// The 'useGLTF.preload' hook is called here, but if you had other preloaders,
// they would need to be handled similarly.
// We'll call useGLTF.preload unconditionally, but it's only effective for gltf/glb files.
(0, react_1.useEffect)(() => void drei_1.useGLTF.preload(url), [url]);
return ((0, jsx_runtime_1.jsx)("div", { style: { width, height }, className: "relative", children: (0, jsx_runtime_1.jsxs)(fiber_1.Canvas, { shadows: true, camera: {
fov: 50,
position: [0, 0, defaultZoom],
near: 0.01,
far: 100,
}, gl: {
toneMapping: THREE.ACESFilmicToneMapping,
outputColorSpace: THREE.SRGBColorSpace,
}, frameloop: "demand", children: [(0, jsx_runtime_1.jsx)(react_1.Suspense, { fallback: (0, jsx_runtime_1.jsx)(Loader, {}), children: (0, jsx_runtime_1.jsx)(SceneContent, { url: url, autoRotate: autoRotate, autoRotateSpeed: deg2rad(autoRotateSpeed), onLoaded: onModelLoaded }) }), environmentPreset !== "none" && ((0, jsx_runtime_1.jsx)(drei_1.Environment, { preset: environmentPreset })), (0, jsx_runtime_1.jsx)("ambientLight", { intensity: ambientIntensity }), (0, jsx_runtime_1.jsx)("directionalLight", { position: [5, 5, 5], intensity: keyLightIntensity, castShadow: true }), (0, jsx_runtime_1.jsx)("directionalLight", { position: [-5, 2, 5], intensity: fillLightIntensity }), (0, jsx_runtime_1.jsx)("directionalLight", { position: [0, 4, -5], intensity: rimLightIntensity }), (0, jsx_runtime_1.jsx)(drei_1.ContactShadows, { position: [0, -0.5, 0], opacity: 0.35, scale: 10, blur: 2 }), (0, jsx_runtime_1.jsx)(drei_1.OrbitControls, { makeDefault: true, enablePan: false, enableRotate: enableManualRotation, enableZoom: enableManualZoom, minDistance: minZoomDistance, maxDistance: maxZoomDistance, autoRotate: isTouch ? false : autoRotate, autoRotateSpeed: autoRotateSpeed })] }) }));
};
exports.default = ModelViewer;
//# sourceMappingURL=3d-model-viewer.js.map