@react-three/drei 9.69.1 → 9.69.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2096,8 +2096,6 @@ type Props = {
2096
2096
  fps?: number
2097
2097
  /** The frame identifier to use, has to be one of animationNames */
2098
2098
  frameName?: string
2099
- /** The scale factor of the aspect ratio */
2100
- scaleFactor?: number
2101
2099
  /** The URL of the texture JSON (if using JSON-Array or JSON-Hash) */
2102
2100
  textureDataURL?: string
2103
2101
  /** The URL of the texture image */
@@ -2122,12 +2120,20 @@ type Props = {
2122
2120
  play?: boolean
2123
2121
  /** Control when the animation pauses */
2124
2122
  pause?: boolean
2123
+ /** Whether or not the Sprite should flip sides on the x-axis */
2124
+ flipX?: boolean
2125
+ /** Sets the alpha value to be used when running an alpha test. https://threejs.org/docs/#api/en/materials/Material.alphaTest */
2126
+ alphaTest?: number
2125
2127
  }
2126
2128
  ```
2127
2129
 
2128
2130
  The SpriteAnimator component provided by drei is a powerful tool for animating sprites in a simple and efficient manner. It allows you to create sprite animations by cycling through a sequence of frames from a sprite sheet image or JSON data.
2131
+
2129
2132
  Notes:
2130
- The SpriteAnimator component internally uses the useFrame hook from react-three-fiber (r3f) for efficient frame updates and rendering.
2133
+
2134
+ - The SpriteAnimator component internally uses the useFrame hook from react-three-fiber (r3f) for efficient frame updates and rendering.
2135
+ - The sprites should contain equal size frames
2136
+ - Trimming of spritesheet frames is not yet supported
2131
2137
 
2132
2138
  ```jsx
2133
2139
  <SpriteAnimator
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),r=require("@react-three/fiber"),t=require("three");function n(e){if(e&&e.__esModule)return e;var r=Object.create(null);return e&&Object.keys(e).forEach((function(t){if("default"!==t){var n=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(r,t,n.get?n:{enumerable:!0,get:function(){return e[t]}})}})),r.default=e,Object.freeze(r)}var a=n(e),u=n(t);exports.SpriteAnimator=({startFrame:e,endFrame:t,fps:n,frameName:c,scaleFactor:s,maxScale:o,textureDataURL:f,textureImageURL:i,loop:m,numberOfFrames:l,autoPlay:p,animationNames:h,onStart:w,onEnd:y,onLoopEnd:d,onFrame:S,play:g,pause:x,flipX:b,alphaTest:z,children:F,...A},E)=>{const O=r.useThree((e=>e.viewport)),R=a.useRef(null),[j,v]=a.useState(!1),L=a.useRef(),M=a.useRef(),P=a.useRef(window.performance.now()),T=a.useRef(),N=a.useRef(e||0),k=a.useRef(c||""),_=1e3/(n||30),[q,C]=a.useState(new u.Texture),D=a.useRef(0),[I,U]=a.useState([1,1,1]),W=s||.1,X=b?-1:1;const B=(e,r,t)=>{const n=r*(O.aspect>e/r?O.width/e:O.height/r),a=e*(O.aspect>e/r?O.width/e:O.height/r)*t,u=n*t,c=null!=o?o:1;let s=Math.min(c,a),f=Math.min(c,u);return a>c&&(s=c,f=u/a*c),M.current.scale.set(s,f,1),[s,f,1]};a.useEffect((()=>{if(f&&i)!function(e,r,t){const n=new u.TextureLoader,a=fetch(e).then((e=>e.json())),c=new Promise((e=>{n.load(r,e)}));Promise.all([a,c]).then((e=>{t(e[0],e[1])}))}(f,i,G);else if(i){const e=new u.TextureLoader;new Promise((r=>{e.load(i,r)})).then((e=>{G(null,e)}))}}),[]),a.useLayoutEffect((()=>{J()}),[q]),a.useEffect((()=>{}),[x]),a.useEffect((()=>{k.current!==c&&c&&(N.current=0,k.current=c)}),[c]);const G=(e,r)=>{if(null===e){if(r&&l){const e=r.image.width,t=r.image.height,n=e/l,a=t;if(T.current=r,D.current=l,R.current={frames:[],meta:{version:"1.0",size:{w:e,h:t},scale:"1"}},parseInt(n.toString(),10)===n)for(let e=0;e<l;e++)R.current.frames.push({frame:{x:e*n,y:0,w:n,h:a},rotated:!1,trimmed:!1,spriteSourceSize:{x:0,y:0,w:n,h:a},sourceSize:{w:n,h:t}})}}else if(r){R.current=e,R.current.frames=Array.isArray(e.frames)?e.frames:H(),D.current=Array.isArray(e.frames)?e.frames.length:Object.keys(e.frames).length,T.current=r;const{w:t,h:n}=K(e.frames).sourceSize,a=B(t,n,W);U(a),L.current&&(L.current.map=r)}r.premultiplyAlpha=!1,C(r)},H=()=>{const e={},r=R.current,t=h;if(t)for(let n=0;n<t.length;n++){e[t[n]]=[];for(let a in r.frames){const u=r.frames[a],c=u.frame,s=c.x,o=c.y,f=c.w,i=c.h,m=u.sourceSize.w,l=u.sourceSize.h;"string"==typeof a&&-1!==a.toLowerCase().indexOf(t[n].toLowerCase())&&e[t[n]].push({x:s,y:o,w:f,h:i,frame:c,sourceSize:{w:m,h:l}})}}return e},J=()=>{if(!R.current)return;const{meta:{size:e},frames:r}=R.current,{w:t,h:n}=Array.isArray(r)?r[0].sourceSize:c&&r[c]?r[c][0].sourceSize:{w:0,h:0};L.current.map.wrapS=L.current.map.wrapT=u.RepeatWrapping,L.current.map.center.set(0,0),L.current.map.repeat.set(1*X/(e.w/t),1/(e.h/n));const a=1/((e.h-1)/n);L.current.map.offset.x=0,L.current.map.offset.y=1-a,v(!0),w&&w({currentFrameName:c,currentFrame:N.current})};r.useFrame(((r,n)=>{var a,u;null!=(a=R.current)&&a.frames&&null!=(u=L.current)&&u.map&&(x||(p||g)&&((()=>{const r=window.performance.now(),n=r-P.current,{meta:{size:a},frames:u}=R.current,{w:s,h:o}=K(u).sourceSize,f=Array.isArray(u)?u:c?u[c]:[];let i=0,l=0;const p=t||f.length-1;if(N.current>p&&(N.current=m&&null!=e?e:0,m?null==d||d({currentFrameName:c,currentFrame:N.current}):null==y||y({currentFrameName:c,currentFrame:N.current}),!m))return;if(n<=_)return;P.current=r-n%_,B(s,o,W);const h=(a.w-1)/s,w=(a.h-1)/o,{frame:{x:S,y:g},sourceSize:{w:x,h:b}}=f[N.current],z=1/h,F=1/w;i=X>0?z*(S/x):z*(S/x)-L.current.map.repeat.x,l=Math.abs(1-F)-F*(g/b),L.current.map.offset.x=i,L.current.map.offset.y=l,N.current+=1})(),S&&S({currentFrameName:k.current,currentFrame:N.current})))}));const K=e=>{if(Array.isArray(e))return e[0];if("object"==typeof e&&null!==e){return e[Object.keys(e)[0]][0]}return{w:0,h:0}};return a.createElement("group",A,a.createElement(a.Suspense,{fallback:null},a.createElement("sprite",{ref:M,scale:I},a.createElement("spriteMaterial",{toneMapped:!1,ref:L,map:q,transparent:!0,alphaTest:null!=z?z:0}))),F)};
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),r=require("@react-three/fiber"),t=require("three");function n(e){if(e&&e.__esModule)return e;var r=Object.create(null);return e&&Object.keys(e).forEach((function(t){if("default"!==t){var n=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(r,t,n.get?n:{enumerable:!0,get:function(){return e[t]}})}})),r.default=e,Object.freeze(r)}var a=n(e),u=n(t);exports.SpriteAnimator=({startFrame:e,endFrame:t,fps:n,frameName:s,textureDataURL:c,textureImageURL:o,loop:f,numberOfFrames:i,autoPlay:m,animationNames:l,onStart:p,onEnd:h,onLoopEnd:w,onFrame:y,play:d,pause:S,flipX:x,alphaTest:g,children:b,...z},F)=>{r.useThree((e=>e.viewport));const A=a.useRef(null),[E,O]=a.useState(!1),R=a.useRef(),j=a.useRef(),v=a.useRef(window.performance.now()),L=a.useRef(),P=a.useRef(e||0),T=a.useRef(s||""),N=1e3/(n||30),[M,k]=a.useState(new u.Texture),_=a.useRef(0),[q,C]=a.useState([1,1,1]),D=x?-1:1;const I=(e,r)=>{const t=r/e;return j.current.scale.set(1,t,1),[1,t,1]};a.useEffect((()=>{if(c&&o)!function(e,r,t){const n=new u.TextureLoader,a=fetch(e).then((e=>e.json())),s=new Promise((e=>{n.load(r,e)}));Promise.all([a,s]).then((e=>{t(e[0],e[1])}))}(c,o,U);else if(o){const e=new u.TextureLoader;new Promise((r=>{e.load(o,r)})).then((e=>{U(null,e)}))}}),[]),a.useLayoutEffect((()=>{X()}),[M]),a.useEffect((()=>{}),[S]),a.useEffect((()=>{T.current!==s&&s&&(P.current=0,T.current=s)}),[s]);const U=(e,r)=>{if(null===e){if(r&&i){const e=r.image.width,t=r.image.height,n=e/i,a=t;if(L.current=r,_.current=i,A.current={frames:[],meta:{version:"1.0",size:{w:e,h:t},scale:"1"}},parseInt(n.toString(),10)===n)for(let e=0;e<i;e++)A.current.frames.push({frame:{x:e*n,y:0,w:n,h:a},rotated:!1,trimmed:!1,spriteSourceSize:{x:0,y:0,w:n,h:a},sourceSize:{w:n,h:t}})}}else if(r){A.current=e,A.current.frames=Array.isArray(e.frames)?e.frames:W(),_.current=Array.isArray(e.frames)?e.frames.length:Object.keys(e.frames).length,L.current=r;const{w:t,h:n}=B(e.frames).sourceSize,a=I(t,n);C(a),R.current&&(R.current.map=r)}r.premultiplyAlpha=!1,k(r)},W=()=>{const e={},r=A.current,t=l;if(t)for(let n=0;n<t.length;n++){e[t[n]]=[];for(let a in r.frames){const u=r.frames[a],s=u.frame,c=s.x,o=s.y,f=s.w,i=s.h,m=u.sourceSize.w,l=u.sourceSize.h;"string"==typeof a&&-1!==a.toLowerCase().indexOf(t[n].toLowerCase())&&e[t[n]].push({x:c,y:o,w:f,h:i,frame:s,sourceSize:{w:m,h:l}})}}return e},X=()=>{if(!A.current)return;const{meta:{size:e},frames:r}=A.current,{w:t,h:n}=Array.isArray(r)?r[0].sourceSize:s&&r[s]?r[s][0].sourceSize:{w:0,h:0};R.current.map.wrapS=R.current.map.wrapT=u.RepeatWrapping,R.current.map.center.set(0,0),R.current.map.repeat.set(1*D/(e.w/t),1/(e.h/n));const a=1/((e.h-1)/n);R.current.map.offset.x=0,R.current.map.offset.y=1-a,O(!0),p&&p({currentFrameName:s,currentFrame:P.current})};r.useFrame(((r,n)=>{var a,u;null!=(a=A.current)&&a.frames&&null!=(u=R.current)&&u.map&&(S||(m||d)&&((()=>{const r=window.performance.now(),n=r-v.current,{meta:{size:a},frames:u}=A.current,{w:c,h:o}=B(u).sourceSize,i=Array.isArray(u)?u:s?u[s]:[];let m=0,l=0;const p=t||i.length-1;if(P.current>p&&(P.current=f&&null!=e?e:0,f?null==w||w({currentFrameName:s,currentFrame:P.current}):null==h||h({currentFrameName:s,currentFrame:P.current}),!f))return;if(n<=N)return;v.current=r-n%N,I(c,o);const y=(a.w-1)/c,d=(a.h-1)/o,{frame:{x:S,y:x},sourceSize:{w:g,h:b}}=i[P.current],z=1/y,F=1/d;m=D>0?z*(S/g):z*(S/g)-R.current.map.repeat.x,l=Math.abs(1-F)-F*(x/b),R.current.map.offset.x=m,R.current.map.offset.y=l,P.current+=1})(),y&&y({currentFrameName:T.current,currentFrame:P.current})))}));const B=e=>{if(Array.isArray(e))return e[0];if("object"==typeof e&&null!==e){return e[Object.keys(e)[0]][0]}return{w:0,h:0}};return a.createElement("group",z,a.createElement(a.Suspense,{fallback:null},a.createElement("sprite",{ref:j,scale:q},a.createElement("spriteMaterial",{toneMapped:!1,ref:R,map:M,transparent:!0,alphaTest:null!=g?g:0}))),b)};
@@ -4,8 +4,6 @@ export declare type SpriteAnimatorProps = {
4
4
  endFrame?: number;
5
5
  fps?: number;
6
6
  frameName?: string;
7
- scaleFactor?: number;
8
- maxScale?: number;
9
7
  textureDataURL?: string;
10
8
  textureImageURL: string;
11
9
  loop?: boolean;
@@ -7,8 +7,6 @@ const SpriteAnimator = ({
7
7
  endFrame,
8
8
  fps,
9
9
  frameName,
10
- scaleFactor,
11
- maxScale,
12
10
  textureDataURL,
13
11
  textureImageURL,
14
12
  loop,
@@ -26,7 +24,7 @@ const SpriteAnimator = ({
26
24
  children,
27
25
  ...props
28
26
  }, fref) => {
29
- const v = useThree(state => state.viewport);
27
+ useThree(state => state.viewport);
30
28
  const spriteData = React.useRef(null);
31
29
  const [isJsonReady, setJsonReady] = React.useState(false);
32
30
  const matRef = React.useRef();
@@ -39,7 +37,6 @@ const SpriteAnimator = ({
39
37
  const [spriteTexture, setSpriteTexture] = React.useState(new THREE.Texture());
40
38
  const totalFrames = React.useRef(0);
41
39
  const [aspect, setAspect] = React.useState([1, 1, 1]);
42
- const aspectFactor = scaleFactor || 0.1;
43
40
  const flipOffset = flipX ? -1 : 1;
44
41
 
45
42
  function loadJsonAndTextureAndExecuteCallback(jsonUrl, textureUrl, callback) {
@@ -53,23 +50,10 @@ const SpriteAnimator = ({
53
50
  });
54
51
  }
55
52
 
56
- const calculateAspectRatio = (width, height, factor) => {
57
- const adaptedHeight = height * (v.aspect > width / height ? v.width / width : v.height / height);
58
- const adaptedWidth = width * (v.aspect > width / height ? v.width / width : v.height / height);
59
- const scaleX = adaptedWidth * factor;
60
- const scaleY = adaptedHeight * factor;
61
- const currentMaxScale = maxScale !== null && maxScale !== void 0 ? maxScale : 1; // Calculate the maximum scale based on the aspect ratio and max scale limit
62
-
63
- let finalMaxScaleW = Math.min(currentMaxScale, scaleX);
64
- let finalMaxScaleH = Math.min(currentMaxScale, scaleY); // Ensure that scaleX and scaleY do not exceed the max scale while maintaining aspect ratio
65
-
66
- if (scaleX > currentMaxScale) {
67
- finalMaxScaleW = currentMaxScale;
68
- finalMaxScaleH = scaleY / scaleX * currentMaxScale;
69
- }
70
-
71
- spriteRef.current.scale.set(finalMaxScaleW, finalMaxScaleH, 1);
72
- return [finalMaxScaleW, finalMaxScaleH, 1];
53
+ const calculateAspectRatio = (width, height) => {
54
+ const aspectRatio = height / width;
55
+ spriteRef.current.scale.set(1, aspectRatio, 1);
56
+ return [1, aspectRatio, 1];
73
57
  }; // initial loads
74
58
 
75
59
 
@@ -156,7 +140,7 @@ const SpriteAnimator = ({
156
140
  w,
157
141
  h
158
142
  } = getFirstItem(json.frames).sourceSize;
159
- const aspect = calculateAspectRatio(w, h, aspectFactor);
143
+ const aspect = calculateAspectRatio(w, h);
160
144
  setAspect(aspect);
161
145
 
162
146
  if (matRef.current) {
@@ -284,7 +268,7 @@ const SpriteAnimator = ({
284
268
 
285
269
  if (diff <= fpsInterval) return;
286
270
  timerOffset.current = now - diff % fpsInterval;
287
- calculateAspectRatio(frameW, frameH, aspectFactor);
271
+ calculateAspectRatio(frameW, frameH);
288
272
  const framesH = (metaInfo.w - 1) / frameW;
289
273
  const framesV = (metaInfo.h - 1) / frameH;
290
274
  const {