UNPKG

@react-three/drei

Version:

useful add-ons for react-three-fiber

2 lines (1 loc) 5.23 kB
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),t=require("three"),r=require("@react-three/fiber");function n(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach((function(r){if("default"!==r){var n=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,n.get?n:{enumerable:!0,get:function(){return e[r]}})}})),t.default=e,Object.freeze(t)}var o=n(e),c=n(t),a=function(e){return e[e.NONE=0]="NONE",e[e.START=1]="START",e[e.ACTIVE=2]="ACTIVE",e}(a||{});const u=e=>e&&e.isOrthographicCamera,i=e=>1-Math.exp(-5*e)+.007*e,s=o.createContext(null);exports.Bounds=function({children:e,maxDuration:t=1,margin:n=1.2,observe:m,fit:p,clip:l,interpolateFunc:x=i,onFit:d}){const f=o.useRef(null),{camera:y,size:h,invalidate:g}=r.useThree(),v=r.useThree((e=>e.controls)),R=o.useRef(d);R.current=d;const M=o.useRef({camPos:new c.Vector3,camRot:new c.Quaternion,camZoom:1}),P=o.useRef({camPos:void 0,camRot:void 0,camZoom:void 0,camUp:void 0,target:void 0}),w=o.useRef(a.NONE),T=o.useRef(0),[V]=o.useState((()=>new c.Box3)),A=o.useMemo((()=>{function e(){const e=V.getSize(new c.Vector3),t=V.getCenter(new c.Vector3),r=Math.max(e.x,e.y,e.z),o=u(y)?4*r:r/(2*Math.atan(Math.PI*y.fov/360)),a=u(y)?4*r:o/y.aspect,i=n*Math.max(o,a);return{box:V,size:e,center:t,distance:i}}return{getSize:e,refresh(e){if((t=e)&&t.isBox3)V.copy(e);else{const t=e||f.current;if(!t)return this;t.updateWorldMatrix(!0,!0),V.setFromObject(t)}var t;if(V.isEmpty()){const e=y.position.length()||10;V.setFromCenterAndSize(new c.Vector3,new c.Vector3(e,e,e))}return M.current.camPos.copy(y.position),M.current.camRot.copy(y.quaternion),u(y)&&(M.current.camZoom=y.zoom),P.current.camPos=void 0,P.current.camRot=void 0,P.current.camZoom=void 0,P.current.camUp=void 0,P.current.target=void 0,this},reset(){const{center:t,distance:r}=e(),n=y.position.clone().sub(t).normalize();P.current.camPos=t.clone().addScaledVector(n,r),P.current.target=t.clone();const o=(new c.Matrix4).lookAt(P.current.camPos,P.current.target,y.up);return P.current.camRot=(new c.Quaternion).setFromRotationMatrix(o),w.current=a.START,T.current=0,this},moveTo(e){return P.current.camPos=Array.isArray(e)?new c.Vector3(...e):e.clone(),w.current=a.START,T.current=0,this},lookAt({target:e,up:t}){P.current.target=Array.isArray(e)?new c.Vector3(...e):e.clone(),P.current.camUp=t?Array.isArray(t)?new c.Vector3(...t):t.clone():y.up.clone();const r=(new c.Matrix4).lookAt(P.current.camPos||y.position,P.current.target,P.current.camUp);return P.current.camRot=(new c.Quaternion).setFromRotationMatrix(r),w.current=a.START,T.current=0,this},to({position:e,target:t}){return this.moveTo(e).lookAt({target:t})},fit(){if(!u(y))return this.reset();let e=0,t=0;const r=[new c.Vector3(V.min.x,V.min.y,V.min.z),new c.Vector3(V.min.x,V.max.y,V.min.z),new c.Vector3(V.min.x,V.min.y,V.max.z),new c.Vector3(V.min.x,V.max.y,V.max.z),new c.Vector3(V.max.x,V.max.y,V.max.z),new c.Vector3(V.max.x,V.max.y,V.min.z),new c.Vector3(V.max.x,V.min.y,V.max.z),new c.Vector3(V.max.x,V.min.y,V.min.z)],o=P.current.camPos||y.position,i=P.current.target||(null==v?void 0:v.target),s=P.current.camUp||y.up,m=i?(new c.Matrix4).lookAt(o,i,s).setPosition(o).invert():y.matrixWorldInverse;for(const n of r)n.applyMatrix4(m),e=Math.max(e,Math.abs(n.y)),t=Math.max(t,Math.abs(n.x));e*=2,t*=2;const p=(y.top-y.bottom)/e,l=(y.right-y.left)/t;return P.current.camZoom=Math.min(p,l)/n,w.current=a.START,T.current=0,R.current&&R.current(this.getSize()),this},clip(){const{distance:t}=e();return y.near=t/100,y.far=100*t,y.updateProjectionMatrix(),v&&(v.maxDistance=10*t,v.update()),g(),this}}}),[V,y,v,n,g]);o.useLayoutEffect((()=>{if(v){const e=()=>{if(v&&P.current.target&&w.current!==a.NONE){const e=(new c.Vector3).setFromMatrixColumn(y.matrix,2),t=M.current.camPos.distanceTo(v.target),r=(P.current.camPos||M.current.camPos).distanceTo(P.current.target),n=(1-T.current)*t+T.current*r;v.target.copy(y.position).addScaledVector(e,-n),v.update()}w.current=a.NONE};return v.addEventListener("start",e),()=>v.removeEventListener("start",e)}}),[v]);const z=o.useRef(0);return o.useLayoutEffect((()=>{(m||0==z.current++)&&(A.refresh(),p&&A.reset().fit(),l&&A.clip())}),[h,l,p,m,y,v]),r.useFrame(((e,r)=>{if(w.current===a.START)w.current=a.ACTIVE,g();else if(w.current===a.ACTIVE){if(T.current+=r/t,T.current>=1)P.current.camPos&&y.position.copy(P.current.camPos),P.current.camRot&&y.quaternion.copy(P.current.camRot),P.current.camUp&&y.up.copy(P.current.camUp),P.current.camZoom&&u(y)&&(y.zoom=P.current.camZoom),y.updateMatrixWorld(),y.updateProjectionMatrix(),v&&P.current.target&&(v.target.copy(P.current.target),v.update()),w.current=a.NONE;else{const e=x(T.current);P.current.camPos&&y.position.lerpVectors(M.current.camPos,P.current.camPos,e),P.current.camRot&&y.quaternion.slerpQuaternions(M.current.camRot,P.current.camRot,e),P.current.camUp&&y.up.set(0,1,0).applyQuaternion(y.quaternion),P.current.camZoom&&u(y)&&(y.zoom=(1-e)*M.current.camZoom+e*P.current.camZoom),y.updateMatrixWorld(),y.updateProjectionMatrix()}g()}})),o.createElement("group",{ref:f},o.createElement(s.Provider,{value:A},e))},exports.useBounds=function(){return o.useContext(s)};