UNPKG

@react-three/drei

Version:

useful add-ons for react-three-fiber

2 lines (1 loc) 4.98 kB
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("three"),r=require("@react-three/fiber"),t=require("react");function a(e){if(e&&e.__esModule)return e;var r=Object.create(null);return e&&Object.keys(e).forEach((function(t){if("default"!==t){var a=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(r,t,a.get?a:{enumerable:!0,get:function(){return e[t]}})}})),r.default=e,Object.freeze(r)}var n=a(e),s=a(t);const o=(e,r)=>{if(Array.isArray(e))return e[0];return e[null!=r?r:Object.keys(e)[0]][0]},u=e=>{for(let r=3;r<e.length;r+=4)if(0!==e[r])return!1;return!0};function c(a,c,i,f,l,m){const h=s.useRef(r.useThree((e=>e.viewport))),d=s.useRef(null),w=s.useRef(0),p=s.useRef(a),y=s.useRef(c),g=s.useRef(i),[b,x]=t.useState(null),[A,S]=s.useState(new n.Texture),L=s.useMemo((()=>new n.TextureLoader),[]),[C,O]=t.useState(null),j=s.useCallback(((e,r,t)=>{const a=r*(h.current.aspect>e/r?h.current.width/e:h.current.height/r),s=e*(h.current.aspect>e/r?h.current.width/e:h.current.height/r)*t,o=a*t;let u=Math.min(1,s),c=Math.min(1,o);return s>1&&(u=1,c=o/s*1),new n.Vector3(u,c,1)}),[]),k=s.useCallback(((e,r)=>{if(e.image){const t=document.createElement("canvas"),a=t.getContext("2d",m);if(!a)throw new Error("Failed to get 2d context");t.width=e.image.width,t.height=e.image.height,a.drawImage(e.image,0,0);const n=e.image.width,s=e.image.height,o=Math.round(Math.sqrt(r*(n/s))),c=Math.round(r/o),i=n/o,f=s/c,l=[];for(let e=0;e<c;e++)for(let t=0;t<o;t++){if(e*o+t>=r){l.push({row:e,col:t});continue}const n=a.getImageData(t*i,e*f,i,f).data;u(n)&&l.push({row:e,col:t})}return{rows:c,columns:o,frameWidth:i,frameHeight:f,emptyFrames:l}}return{rows:0,columns:0,frameWidth:0,frameHeight:0,emptyFrames:[]}}),[m]),v=s.useCallback((e=>{const r=e=>{let r=null;for(const t of e){const{w:e,h:a}=t.frame,n=e*a;(!r||n>r.area)&&(r={w:e,h:a,area:n})}return e.map((e=>{const{w:t,h:a}=e.frame,n=t*a,s=r?n===r.area?1:Math.sqrt(n/r.area):1;return{...e,scaleRatio:s}}))};if(Array.isArray(e))return r(e);{const t={};for(const a in e)t[a]=r(e[a]);return t}}),[]),z=s.useCallback((()=>{const e={},r=d.current,t=g.current;if(r){if(t&&Array.isArray(r.frames)){for(let a=0;a<t.length;a++){e[t[a]]=[];for(const n of r.frames){const r=n.frame,s=n.sourceSize.w,o=n.sourceSize.h;"string"==typeof n.filename&&-1!==n.filename.toLowerCase().indexOf(t[a].toLowerCase())&&e[t[a]].push({...n,frame:r,sourceSize:{w:s,h:o}})}}for(const r in e){const t=v(e[r]);Array.isArray(t)&&(e[r]=t)}return e}if(t&&"object"==typeof r.frames){for(let a=0;a<t.length;a++){e[t[a]]=[];for(const n in r.frames){const s=r.frames[n],o=s.frame,u=s.sourceSize.w,c=s.sourceSize.h;"string"==typeof n&&-1!==n.toLowerCase().indexOf(t[a].toLowerCase())&&e[t[a]].push({...s,frame:o,sourceSize:{w:u,h:c}})}}for(const r in e){const t=v(e[r]);Array.isArray(t)&&(e[r]=t)}return e}{let e=[];return null!=r&&r.frames&&(e=Array.isArray(r.frames)?r.frames.map((e=>({...e,x:e.frame.x,y:e.frame.y,w:e.frame.w,h:e.frame.h}))):Object.values(r.frames).flat().map((e=>({...e,x:e.frame.x,y:e.frame.y,w:e.frame.w,h:e.frame.h})))),v(e)}}return[]}),[v,d]),R=s.useCallback(((e,r)=>{let t=new n.Vector3(1,1,1);if(null===e){if(r&&f){const e=r.image.width,a=r.image.height;w.current=f;const{rows:n,columns:s,frameWidth:o,frameHeight:u,emptyFrames:c}=k(r,f),i={frames:[],meta:{version:"1.0",size:{w:e,h:a},rows:n,columns:s,frameWidth:o,frameHeight:u,scale:"1"}};for(let e=0;e<n;e++)for(let r=0;r<s;r++){(null!=c?c:[]).some((t=>t.row===e&&t.col===r))||Array.isArray(i.frames)&&i.frames.push({frame:{x:r*o,y:e*u,w:o,h:u},scaleRatio:1,rotated:!1,trimmed:!1,spriteSourceSize:{x:0,y:0,w:o,h:u},sourceSize:{w:o,h:u}})}t=j(o,u,.1),d.current=i}d.current&&d.current.frames&&(d.current.frames=v(d.current.frames))}else if(r){d.current=e,d.current.frames=z(),w.current=Array.isArray(e.frames)?e.frames.length:Object.keys(e.frames).length;const{w:r,h:a}=o(e.frames).sourceSize;t=j(r,a,.1)}x(d.current),"encoding"in r?r.encoding=3001:"colorSpace"in r&&(r.colorSpace=n.SRGBColorSpace),S(r),O({spriteTexture:r,spriteData:d.current,aspect:t})}),[k,f,z,j,v]),E=s.useCallback(((e,r,t)=>{const a=fetch(e).then((e=>e.json())),n=new Promise((e=>{L.load(r,e)}));Promise.all([a,n]).then((e=>{t(e[0],e[1])}))}),[L]),M=s.useCallback((e=>{if(!e&&!p.current)throw new Error("Either textureUrl or input must be provided");const r=null!=e?e:p.current;if(!r)throw new Error("A valid texture URL must be provided");L.load(r,(e=>R(null,e)))}),[L,R]),T=s.useCallback(((e,r)=>{r&&e?E(r,e,R):M(e)}),[E,M,R]);return s.useLayoutEffect((()=>{y.current&&p.current?E(y.current,p.current,R):p.current&&M();const t=p.current;return()=>{t&&r.useLoader.clear(e.TextureLoader,t)}}),[E,M,R]),s.useLayoutEffect((()=>{null==l||l(A,null!=b?b:null)}),[A,b,l]),{spriteObj:C,loadJsonAndTexture:T}}c.preload=t=>r.useLoader.preload(e.TextureLoader,t),c.clear=t=>r.useLoader.clear(e.TextureLoader,t),exports.checkIfFrameIsEmpty=u,exports.getFirstFrame=o,exports.useSpriteLoader=c;