@react-three/drei 9.69.1 → 9.69.3
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 +9 -3
- package/core/SpriteAnimator.cjs.js +1 -1
- package/core/SpriteAnimator.d.ts +0 -2
- package/core/SpriteAnimator.js +7 -23
- package/index.cjs.js +1 -1
- package/package.json +2 -2
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
|
-
|
|
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:
|
|
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)};
|
package/core/SpriteAnimator.d.ts
CHANGED
package/core/SpriteAnimator.js
CHANGED
|
@@ -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
|
-
|
|
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
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
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
|
|
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
|
|
271
|
+
calculateAspectRatio(frameW, frameH);
|
|
288
272
|
const framesH = (metaInfo.w - 1) / frameW;
|
|
289
273
|
const framesV = (metaInfo.h - 1) / frameH;
|
|
290
274
|
const {
|