UNPKG

@niobrix/solidjs-skinview3d

Version:
209 lines (205 loc) 6.37 kB
// src/SolidSkinView3D.tsx import { SkinViewer, WalkingAnimation } from "skinview3d"; import { createEffect, createSignal, onCleanup, onMount } from "solid-js"; // src/SolidSkinView3D.module.css var SolidSkinView3D_default = {}; // src/SolidSkinView3D.tsx 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 <div class={SolidSkinView3D_default.container}><div class={SolidSkinView3D_default.wrapper}><canvas ref={canvasRef} class={`${SolidSkinView3D_default.canvas} ${props.className || ""}`} />{props.showLoader !== false && isLoading() && <div class={SolidSkinView3D_default.loader}><div class={SolidSkinView3D_default.spinner} /></div>}</div></div>; }; var SolidSkinView3D_default2 = SolidSkinView3D; // src/index.tsx var src_default = SolidSkinView3D_default2; export { SolidSkinView3D_default2 as SolidSkinView3D, src_default as default };