3d-scene-creator
Version:
A simple utility to create and manage 3D scenes
2 lines (1 loc) • 5.51 kB
JavaScript
(function(a,c){typeof exports=="object"&&typeof module<"u"?c(exports,require("three"),require("gsap"),require("three/examples/jsm/controls/OrbitControls")):typeof define=="function"&&define.amd?define(["exports","three","gsap","three/examples/jsm/controls/OrbitControls"],c):(a=typeof globalThis<"u"?globalThis:a||self,c(a["3d-scene-creator"]={},a.THREE,a.gsap,a.OrbitControls))})(this,function(a,c,d,m){"use strict";var b=Object.defineProperty;var y=(a,c,d)=>c in a?b(a,c,{enumerable:!0,configurable:!0,writable:!0,value:d}):a[c]=d;var h=(a,c,d)=>(y(a,typeof c!="symbol"?c+"":c,d),d);const u=o=>o&&typeof o=="object"&&"default"in o?o:{default:o};function f(o){if(o&&o.__esModule)return o;const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(o){for(const t in o)if(t!=="default"){const i=Object.getOwnPropertyDescriptor(o,t);Object.defineProperty(e,t,i.get?i:{enumerable:!0,get:()=>o[t]})}}return e.default=o,Object.freeze(e)}const s=f(c),l=u(d);class g{constructor(e,t,i,r){h(this,"scene");h(this,"renderer");h(this,"container");h(this,"cWidth");h(this,"cHeight");h(this,"camera");h(this,"initialCamPos");h(this,"initialTargetPos");h(this,"prevCamPos");h(this,"controls");h(this,"additionalRenderFn");h(this,"stopLoop",!1);h(this,"scale",1);h(this,"animating",0);this.scene=new s.Scene,this.renderer=new s.WebGLRenderer({antialias:!0,alpha:!0}),t&&(this.scale=t),this.cWidth=0,this.cHeight=0,this.camera=new s.PerspectiveCamera(50,this.cWidth/this.cHeight,.1*this.scale,2e3*this.scale),i?this.initialCamPos=i:this.initialCamPos=new s.Vector3(10*this.scale,10*this.scale,10*this.scale),this.prevCamPos=new s.Vector3(this.initialCamPos.x+1,1,1),r?this.initialTargetPos=r:this.initialTargetPos=new s.Vector3(0,0,0),this.camera.position.set(this.initialCamPos.x,this.initialCamPos.y,this.initialCamPos.z);var n=this.initialTargetPos;this.camera.lookAt(n),this.resizeListener(),e&&this.attachRenderer(e)}addControls(e={}){this.controls=new m.OrbitControls(this.camera,this.renderer.domElement);const t={enabled:!0,enableDamping:!0,dampingFactor:.25,maxPolarAngle:Math.PI/2,maxDistance:100*this.scale,minDistance:0,rotateSpeed:1,enableZoom:!0,enablePan:!0},i=Object.assign(t,e);return Object.assign(this.controls,i),this.controls.target.set(this.initialTargetPos.x,this.initialTargetPos.y,this.initialTargetPos.z),this}setAdditionalRenderFn(e){this.additionalRenderFn=e}resetSizes(){this.container&&(this.cWidth=this.container.clientWidth,this.cHeight=this.container.clientHeight)}animateModelColor(e,t,i=2){const r=this.scene.getObjectByName(e);if(r){let n=new s.Color(t);r.traverse(p=>{p instanceof s.Mesh&&(this.animating++,l.default.to(p.material.color,{duration:i,r:n.r,b:n.b,g:n.g,onComplete:()=>{this.animating--}}))})}return this}animateModelOpacity(e,t,i=2){const r=this.scene.getObjectByName(e);return r&&r.traverse(n=>{n instanceof s.Mesh&&(n.material.transparent=!0,n.material.needsUpdate=!0,this.animating++,l.default.to(n.material,{duration:i,opacity:t,onComplete:()=>{this.animating++,n.material.needsUpdate=!0}}),n.material.needsUpdate=!0)}),this}animateModelPosition(e,t,i=2){const r=this.scene.getObjectByName(e);return r&&l.default.to(r.position,{duration:i,x:t.x,y:t.y,z:t.z}),this}attachRenderer(e){return this.container=e,this.resetSizes(),this.camera.aspect=this.cWidth/this.cHeight,this.camera.updateProjectionMatrix(),this.renderer.setSize(this.cWidth,this.cHeight),this.container.appendChild(this.renderer.domElement),this.scene.updateMatrixWorld(!0),this.startRenderLoop(),this}addLighting(){const e=new s.AmbientLight(16777215,.4);this.scene.add(e);const t=new s.DirectionalLight(16777215,.3);t.position.set(1,1,0),this.scene.add(t);const i=new s.DirectionalLight(16777215,.2);return i.position.set(-1,1,-1),this.scene.add(i),this}addSkybox(e,t="#B2FFFF",i){const r=new s.SphereGeometry(100*this.scale,60,60);r.scale(-1,1,1);let n;e?(s.TextureLoader.prototype.crossOrigin="anonymous",n=new s.MeshBasicMaterial({map:new s.TextureLoader().load(e)})):n=new s.MeshStandardMaterial({color:t});const p=new s.Mesh(r,n);return p.name=i||"skybox",this.scene.add(p),this}resizeListener(){this.resetSizes(),window.addEventListener("resize",()=>{this.resetSizes();const e=this.camera,t=this.renderer;e.aspect=this.cWidth/this.cHeight,e.updateProjectionMatrix(),t.setSize(this.cWidth*1,this.cHeight*1),e.position.x=e.position.x+.001},!1)}stopRenderLoop(){return this.stopLoop=!0,this}startRenderLoop(){return this.stopLoop=!1,this.renderLoop(),this}renderLoop(){if(this.stopLoop)return;requestAnimationFrame(this.renderLoop.bind(this));const e=this.scene,t=this.renderer,i=this.camera;(i.position.x!==this.prevCamPos.x||i.position.y!==this.prevCamPos.y||i.position.z!==this.prevCamPos.z||this.animating)&&t.render(e,i),this.prevCamPos=this.camera.position.clone(),this.additionalRenderFn&&this.additionalRenderFn(),this.controls&&this.controls.update()}resetCameraPosition(){this.moveCamera(this.initialCamPos,this.initialTargetPos)}moveCamera(e,t,i){const r=this.camera;let n;return this.controls&&(n=this.controls.enabled,this.controls.enabled=!1),l.default.to(r.position,{duration:3,x:e.x,y:e.y,z:e.z,onComplete:()=>{this.controls&&(this.controls.enabled=n),typeof i=="function"&&i()}}),t&&this.controls&&l.default.to(this.controls.target,{duration:3,x:t.x,y:t.y,z:t.z}),this}loadModel(e,t){return t||(t=new s.ObjectLoader),t.loadAsync(e).then(i=>(this.scene.add(i),i))}}a.SceneCreator=g,Object.defineProperties(a,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});