UNPKG

@niobrix/solidjs-skinview3d

Version:
244 lines (238 loc) 7.45 kB
import { use, insert, memo, effect, className, template } from 'solid-js/web'; import { SkinViewer, WalkingAnimation } from 'skinview3d'; import { createSignal, onMount, createEffect, onCleanup } from 'solid-js'; // src/SolidSkinView3D.tsx // src/SolidSkinView3D.module.css var SolidSkinView3D_default = {}; // src/SolidSkinView3D.tsx var _tmpl$ = /* @__PURE__ */ template(`<div><div><canvas>`); var _tmpl$2 = /* @__PURE__ */ template(`<div><div>`); var SolidSkinView3D = (props) => { const [viewer, setViewer] = createSignal(null); const [isLoading, setIsLoading] = createSignal(true); let canvasRef; let animationId = null; let animation = null; onMount(() => { if (!canvasRef) return; const skinViewerOptions = { canvas: canvasRef, alpha: true, width: props.width || 300, height: props.height || 400, fov: props.fov || 70 }; if (props.background) { skinViewerOptions.background = props.background; } const skinViewer = new SkinViewer(skinViewerOptions); setViewer(skinViewer); const orbitControls = skinViewer.controls; orbitControls.enableRotate = true; orbitControls.enableZoom = true; orbitControls.enablePan = false; if (props.zoom !== void 0) { skinViewer.camera.position.z = props.zoom; } if (props.autoRotate) { const rotateSpeed = props.rotateSpeed || 5e-3; const animate = () => { skinViewer.playerObject.rotation.y += rotateSpeed; animationId = requestAnimationFrame(animate); }; animate(); } const handleSkinLoaded = () => { setIsLoading(false); if (props.onSkinLoaded) { props.onSkinLoaded(); } }; const handleSkinError = (error) => { setIsLoading(false); if (props.onSkinError) { props.onSkinError(error); } }; if (props.skinUrl) { setIsLoading(true); const skinOptions = {}; if (typeof props.ears === "boolean") { skinOptions.ears = props.ears; } else if (props.ears) { skinOptions.ears = false; } skinViewer.loadSkin(props.skinUrl, skinOptions).then(() => { if (props.ears && typeof props.ears !== "boolean") { skinViewer.loadEars(props.ears.source, { textureType: props.ears.textureType }); } handleSkinLoaded(); }).catch(handleSkinError); } else { setIsLoading(false); } if (props.capeUrl) { skinViewer.loadCape(props.capeUrl, { backEquipment: props.backEquipment || "cape" }); } animation = new WalkingAnimation(); skinViewer.animation = animation; if (props.onReady) { props.onReady(skinViewer); } const handleResize = () => { if (props.autoResize) { const parent = canvasRef.parentElement; if (parent) { skinViewer.setSize(parent.clientWidth, parent.clientHeight); } } }; if (props.autoResize) { window.addEventListener("resize", handleResize); handleResize(); } onCleanup(() => { if (props.autoResize) { window.removeEventListener("resize", handleResize); } if (animationId !== null) { cancelAnimationFrame(animationId); } if (viewer()) { viewer()?.dispose(); } }); }); createEffect(() => { const currentViewer = viewer(); if (currentViewer && props.skinUrl) { setIsLoading(true); const skinOptions = {}; if (typeof props.ears === "boolean") { skinOptions.ears = props.ears; } else if (props.ears) { skinOptions.ears = false; } currentViewer.loadSkin(props.skinUrl, skinOptions).then(() => { if (props.ears && typeof props.ears !== "boolean") { currentViewer.loadEars(props.ears.source, { textureType: props.ears.textureType }); } setIsLoading(false); if (props.onSkinLoaded) { props.onSkinLoaded(); } }).catch((error) => { setIsLoading(false); if (props.onSkinError) { props.onSkinError(error); } }); } }); createEffect(() => { const currentViewer = viewer(); if (currentViewer && props.capeUrl !== void 0) { if (props.capeUrl) { currentViewer.loadCape(props.capeUrl, { backEquipment: props.backEquipment || "cape" }); } else { currentViewer.loadCape(null); } } }); createEffect(() => { const currentViewer = viewer(); if (currentViewer && props.backEquipment && props.capeUrl) { currentViewer.loadCape(props.capeUrl, { backEquipment: props.backEquipment }); } }); createEffect(() => { const currentViewer = viewer(); if (currentViewer && (props.width || props.height)) { currentViewer.setSize(props.width || currentViewer.width, props.height || currentViewer.height); } }); createEffect(() => { const currentViewer = viewer(); if (currentViewer && props.background !== void 0) { currentViewer.background = props.background; } }); createEffect(() => { const currentViewer = viewer(); if (currentViewer && props.zoom !== void 0) { currentViewer.camera.position.z = props.zoom; } }); createEffect(() => { const currentViewer = viewer(); if (currentViewer && props.fov !== void 0) { currentViewer.fov = props.fov; } }); createEffect(() => { if (props.autoRotate) { if (animationId === null && viewer()) { const rotateSpeed = props.rotateSpeed || 5e-3; const animate = () => { const currentViewer = viewer(); if (currentViewer) { currentViewer.playerObject.rotation.y += rotateSpeed; } animationId = requestAnimationFrame(animate); }; animate(); } } else if (animationId !== null) { cancelAnimationFrame(animationId); animationId = null; } }); return (() => { var _el$ = _tmpl$(), _el$2 = _el$.firstChild, _el$3 = _el$2.firstChild; var _ref$ = canvasRef; typeof _ref$ === "function" ? use(_ref$, _el$3) : canvasRef = _el$3; insert(_el$2, (() => { var _c$ = memo(() => !!(props.showLoader !== false && isLoading())); return () => _c$() && (() => { var _el$4 = _tmpl$2(), _el$5 = _el$4.firstChild; effect((_p$) => { var _v$4 = SolidSkinView3D_default.loader, _v$5 = SolidSkinView3D_default.spinner; _v$4 !== _p$.e && className(_el$4, _p$.e = _v$4); _v$5 !== _p$.t && className(_el$5, _p$.t = _v$5); return _p$; }, { e: void 0, t: void 0 }); return _el$4; })(); })(), null); effect((_p$) => { var _v$ = SolidSkinView3D_default.container, _v$2 = SolidSkinView3D_default.wrapper, _v$3 = `${SolidSkinView3D_default.canvas} ${props.className || ""}`; _v$ !== _p$.e && className(_el$, _p$.e = _v$); _v$2 !== _p$.t && className(_el$2, _p$.t = _v$2); _v$3 !== _p$.a && className(_el$3, _p$.a = _v$3); return _p$; }, { e: void 0, t: void 0, a: void 0 }); return _el$; })(); }; var SolidSkinView3D_default2 = SolidSkinView3D; // src/index.tsx var src_default = SolidSkinView3D_default2; export { SolidSkinView3D_default2 as SolidSkinView3D, src_default as default };