@react-three/drei 9.116.2 → 9.116.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.
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@babel/runtime/helpers/extends"),r=require("react"),t=require("@react-three/fiber"),n=require("three"),u=require("./Instances.cjs.js"),a=require("./useSpriteLoader.cjs.js");function c(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function s(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)}require("react-composer"),require("../helpers/deprecated.cjs.js");var l=c(e),o=s(r),f=s(n);const i=o.createContext(null);const m=new f.PlaneGeometry(1,1),p=o.forwardRef((({startFrame:e,endFrame:r,fps:n,frameName:c,textureDataURL:s,textureImageURL:p,loop:d,numberOfFrames:h,autoPlay:y,animationNames:v,onStart:w,onEnd:E,onLoopEnd:g,onFrame:x,play:b,pause:F,flipX:S,alphaTest:j,children:R,asSprite:M,offset:A,playBackwards:O,resetOnEnd:z,maxItems:N,instanceItems:q,spriteDataset:L,canvasRenderingContext2DSettings:P,roundFramePosition:T=!1,meshProps:k={},...D},I)=>{var _;const C=o.useRef(),U=o.useRef(null),B=o.useRef(),G=o.useRef(),H=o.useRef(window.performance.now()),J=o.useRef(e||0),V=o.useRef(c||""),W=(null!=n?n:30)>0?1e3/(n||30):0,[X,K]=o.useState(new f.Texture),Q=o.useRef(0),[Y,Z]=o.useState([1,1,1]),$=S?-1:1,[ee,re]=o.useState(null==M||M),te=o.useRef(F),ne=o.useRef(A),ue=o.useRef(!1),ae=o.useRef([]),{spriteObj:ce,loadJsonAndTexture:se}=a.useSpriteLoader(null,null,v,h,void 0,P);function le(){}const oe=o.useMemo((()=>({current:ne.current,offset:ne.current,imageUrl:p,reset:le,hasEnded:!1,ref:I})),[p,L]);o.useImperativeHandle(I,(()=>C.current),[]),o.useLayoutEffect((()=>{ne.current=A}),[A]);const fe=(e,r)=>{const t=r/e;return G.current&&G.current.scale.set(1,t,1),[1,t,1]};o.useEffect((()=>{var e;L?ie(null==L||null==(e=L.spriteTexture)?void 0:e.clone(),L.spriteData):p&&s&&se(p,s)}),[L]),o.useEffect((()=>{var e;ce&&ie(null==ce||null==(e=ce.spriteTexture)?void 0:e.clone(),null==ce?void 0:ce.spriteData)}),[ce]),o.useEffect((()=>{re(null==M||M)}),[M]),o.useEffect((()=>{oe.hasEnded=!1,U.current&&!0===O?J.current=U.current.frames.length-1:J.current=0}),[O]),o.useLayoutEffect((()=>{me()}),[X,S]),o.useEffect((()=>{y&&(te.current=!1)}),[y]),o.useLayoutEffect((()=>{if(V.current!==c&&c&&(J.current=0,V.current=c,oe.hasEnded=!1,W<=0&&(J.current=r||e||0),U.current)){const{w:e,h:r}=de(U.current.frames).sourceSize,t=fe(e,r);Z(t)}}),[c,W]);const ie=(e,r=null)=>{if(null===r){if(h){const t=e.image.width,n=e.image.height;Q.current=h,O&&(J.current=h-1),U.current={frames:[],meta:{version:"1.0",size:{w:t,h:n},scale:"1"}},U.current.frames=r}}else{U.current=r,Q.current=U.current.frames.length,O&&(J.current=Q.current-1);const{w:t,h:n}=de(U.current.frames).sourceSize,u=fe(t,n);Z(u),B.current&&(B.current.map=e)}if(q)for(var t=0;t<q.length;t++){const e=Object.keys(U.current.frames),r=e[Math.floor(Math.random()*e.length)];ae.current.push({key:t,frames:U.current.frames,selectedFrame:r,offset:{x:0,y:0}})}K(e)},me=()=>{if(!U.current)return;const{meta:{size:e},frames:r}=U.current,{w:t,h:n}=Array.isArray(r)?r[0].sourceSize:c&&r[c]?r[c][0].sourceSize:{w:0,h:0};B.current.map.wrapS=B.current.map.wrapT=f.RepeatWrapping,B.current.map.center.set(0,0),B.current.map.repeat.set(1*$/(e.w/t),1/(e.h/n));const u=1/((e.h-1)/n);B.current.map.offset.x=0,B.current.map.offset.y=1-u,w&&w({currentFrameName:c,currentFrame:J.current})},pe=(e,r,t,n)=>{var u=void 0===A?oe.current:A;const a=J.current;let c=0,s=0;fe(e,r);const l=T?Math.round((t.w-1)/e):(t.w-1)/e,o=T?Math.round((t.h-1)/r):(t.h-1)/r;if(!n[a])return;const{frame:{x:f,y:i},sourceSize:{w:m,h:p}}=n[a],d=1/l,h=1/o;if(c=$>0?d*(f/m):d*(f/m)-B.current.map.repeat.x,s=Math.abs(1-h)-h*(i/p),B.current.map.offset.x=c,B.current.map.offset.y=s,null!=u){let e=Math.floor(u*n.length);e=Math.max(0,Math.min(e,n.length-1)),isNaN(e)&&(e=0),J.current=e}else O?J.current-=1:J.current+=1};t.useFrame(((t,n)=>{var u,a;null!=(u=U.current)&&u.frames&&null!=(a=B.current)&&a.map&&(te.current||oe.hasEnded||!y&&!b||((()=>{const{meta:{size:t},frames:n}=U.current,{w:u,h:a}=de(n).sourceSize,s=Array.isArray(n)?n:c?n[c]:[],l=r||s.length-1;var o=void 0===A?oe.current:A;if(W<=0)return J.current=r||e||0,void pe(u,a,t,s);const f=window.performance.now(),i=f-H.current;if(!(i<=W)){var m=O?J.current<0:J.current>l,p=O?J.current===l:0===J.current,h=O?J.current<0:J.current>=l;if(m){if(J.current=d&&null!=e?e:0,O&&(J.current=l),d?null==g||g({currentFrameName:c,currentFrame:J.current}):(null==E||E({currentFrameName:c,currentFrame:J.current}),oe.hasEnded=!z,z&&(te.current=!0)),!d)return}else p&&(null==w||w({currentFrameName:c,currentFrame:J.current}));void 0!==o&&h?!1===ue.current&&(null==E||E({currentFrameName:c,currentFrame:J.current}),ue.current=!0):ue.current=!1,i<=W||(H.current=f-i%W,pe(u,a,t,s))}})(),x&&x({currentFrameName:V.current,currentFrame:J.current})))}));const de=e=>{if(Array.isArray(e))return e[0];if("object"==typeof e&&null!==e){const r=Object.keys(e);return c?e[c][0]:e[r[0]][0]}return{w:0,h:0}};return o.createElement("group",l.default({},D,{ref:C,scale:function(e,r){let t=[];return"number"==typeof r?t=[r,r,r]:Array.isArray(r)?t=r:r instanceof f.Vector3&&(t=[r.x,r.y,r.z]),e.map(((e,r)=>e*t[r]))}(null!=Y?Y:[1,1,1],null!==(_=D.scale)&&void 0!==_?_:1)}),o.createElement(i.Provider,{value:oe},o.createElement(o.Suspense,{fallback:null},ee&&o.createElement("sprite",l.default({ref:G,scale:1,geometry:m},k),o.createElement("spriteMaterial",{premultipliedAlpha:!1,toneMapped:!1,ref:B,map:X,transparent:!0,alphaTest:null!=j?j:0})),!ee&&o.createElement(u.Instances,l.default({geometry:m,limit:null!=N?N:1},k),o.createElement("meshBasicMaterial",{premultipliedAlpha:!1,toneMapped:!1,side:f.DoubleSide,ref:B,map:X,transparent:!0,alphaTest:null!=j?j:0}),(null!=q?q:[0]).map(((e,r)=>o.createElement(u.Instance,l.default({key:r,ref:1===(null==q?void 0:q.length)?G:null,position:e,scale:1},k)))))),R))}));exports.SpriteAnimator=p,exports.useSpriteAnimator=function(){return o.useContext(i)};
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@babel/runtime/helpers/extends"),r=require("react"),t=require("@react-three/fiber"),n=require("three"),u=require("./Instances.cjs.js"),a=require("./Billboard.cjs.js"),c=require("./useSpriteLoader.cjs.js");function l(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function s(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)}require("react-composer"),require("../helpers/deprecated.cjs.js");var o=l(e),i=s(r),m=s(n);const f=i.createContext(null);const p=new m.PlaneGeometry(1,1),d=i.forwardRef((({startFrame:e=0,endFrame:r,fps:n=30,frameName:l="",textureDataURL:s,textureImageURL:d,loop:h=!1,numberOfFrames:v=1,autoPlay:y=!0,animationNames:w,onStart:E,onEnd:F,onLoopEnd:b,onFrame:g,play:x,pause:S=!1,flipX:j=!1,alphaTest:R=0,children:A,asSprite:M=!1,offset:N,playBackwards:O=!1,resetOnEnd:q=!1,maxItems:z=1,instanceItems:D=[[0,0,0]],spriteDataset:L,canvasRenderingContext2DSettings:P,roundFramePosition:T=!1,meshProps:I={},...k},B)=>{const C=i.useRef(new m.Group),V=i.useRef(null),_=i.useRef(null),U=i.useRef(null),G=i.useRef(window.performance.now()),H=i.useRef(e),J=i.useRef(l),W=n>0?1e3/n:0,[X,K]=i.useState(new m.Texture),Q=i.useRef(0),[Y,Z]=i.useState(new m.Vector3(1,1,1)),$=j?-1:1,ee=i.useRef(S),re=i.useRef(N),te=i.useRef(!1),{spriteObj:ne,loadJsonAndTexture:ue}=c.useSpriteLoader(null,null,w,v,void 0,P),ae=i.useRef(l),ce=i.useCallback(((e,r)=>{if(null===r)v&&(Q.current=v,O&&(H.current=v-1),V.current=r);else{var t,n;V.current=r,V.current&&Array.isArray(V.current.frames)?Q.current=V.current.frames.length:V.current&&"object"==typeof V.current&&ae.current?Q.current=V.current.frames[ae.current].length:Q.current=0,O&&(H.current=Q.current-1);const{w:u,h:a}=c.getFirstFrame(null!==(t=null==(n=V.current)?void 0:n.frames)&&void 0!==t?t:[],ae.current).sourceSize,l=oe(u,a);Z(l),_.current&&(_.current.map=e)}K(e)}),[v,O]),le=i.useCallback((()=>{if(!V.current)return;const{meta:{size:e},frames:r}=V.current,{w:t,h:n}=Array.isArray(r)?r[0].sourceSize:l&&r[l]?r[l][0].sourceSize:{w:0,h:0};_.current&&_.current.map&&(_.current.map.wrapS=_.current.map.wrapT=m.RepeatWrapping,_.current.map.center.set(0,0),_.current.map.repeat.set(1*$/(e.w/t),1/(e.h/n)));const u=1/((e.h-1)/n);_.current&&_.current.map&&(_.current.map.offset.x=0,_.current.map.offset.y=1-u),E&&E({currentFrameName:null!=l?l:"",currentFrame:H.current})}),[$,l,E]),se=i.useMemo((()=>({current:re.current,offset:re.current,imageUrl:d,hasEnded:!1,ref:B})),[d,B]);i.useImperativeHandle(B,(()=>C.current),[]),i.useLayoutEffect((()=>{re.current=N}),[N]);const oe=(e,r)=>{var t;const n=new m.Vector3,u=r/e;return n.set(1,u,1),null==(t=U.current)||t.scale.copy(n),n};i.useEffect((()=>{var e;L?ce(null==L||null==(e=L.spriteTexture)?void 0:e.clone(),L.spriteData):d&&s&&ue(d,s)}),[ue,L,s,d,ce]),i.useEffect((()=>{var e;ne&&ce(null==ne||null==(e=ne.spriteTexture)?void 0:e.clone(),null==ne?void 0:ne.spriteData)}),[ne,ce]),i.useEffect((()=>{var e;(se.hasEnded=!1,V.current&&!0===O)?H.current=(null!==(e=V.current.frames.length)&&void 0!==e?e:0)-1:H.current=0}),[O,se]),i.useLayoutEffect((()=>{le()}),[X,j,le]),i.useEffect((()=>{y&&(ee.current=!1)}),[y]),i.useLayoutEffect((()=>{if(J.current!==l&&l&&(H.current=0,J.current=l,se.hasEnded=!1,W<=0&&(H.current=r||e||0),V.current)){const{w:e,h:r}=c.getFirstFrame(V.current.frames,l).sourceSize,t=oe(e,r);Z(t)}}),[l,W,se,r,e]);const ie=(e,r,t,n)=>{var u=void 0===N?se.current:N;const a=H.current;let c=0,l=0;oe(e,r);const s=T?Math.round((t.w-1)/e):(t.w-1)/e,o=T?Math.round((t.h-1)/r):(t.h-1)/r;if(!n[a])return;const{frame:{x:i,y:m},sourceSize:{w:f,h:p}}=n[a],d=1/s,h=1/o;if(_.current&&_.current.map&&(c=$>0?d*(i/f):d*(i/f)-_.current.map.repeat.x,l=Math.abs(1-h)-h*(m/p),_.current.map.offset.x=c,_.current.map.offset.y=l),null!=u){let e=Math.floor(u*n.length);e=Math.max(0,Math.min(e,n.length-1)),isNaN(e)&&(e=0),H.current=e}else O?H.current-=1:H.current+=1};return t.useFrame(((t,n)=>{var u,a;null!=(u=V.current)&&u.frames&&null!=(a=_.current)&&a.map&&(ee.current||se.hasEnded||!y&&!x||((()=>{if(null===(t=V.current)||!("meta"in t)||!("frames"in t))return;var t;const{meta:{size:n},frames:u}=V.current,{w:a,h:s}=c.getFirstFrame(u,l).sourceSize,o=Array.isArray(u)?u:l?u[l]:[],i=r||o.length-1;var m=void 0===N?se.current:N;if(W<=0)return H.current=r||e||0,void ie(a,s,n,o);const f=window.performance.now(),p=f-G.current;if(!(p<=W)){var d=O?H.current<0:H.current>i,v=O?H.current===i:0===H.current,y=O?H.current<0:H.current>=i;if(d){if(H.current=h&&null!=e?e:0,O&&(H.current=i),h?null==b||b({currentFrameName:null!=l?l:"",currentFrame:H.current}):(null==F||F({currentFrameName:null!=l?l:"",currentFrame:H.current}),se.hasEnded=!q,q&&(ee.current=!0)),!h)return}else v&&(null==E||E({currentFrameName:null!=l?l:"",currentFrame:H.current}));void 0!==m&&y?!1===te.current&&(null==F||F({currentFrameName:null!=l?l:"",currentFrame:H.current}),te.current=!0):te.current=!1,p<=W||(G.current=f-p%W,ie(a,s,n,o))}})(),null==g||g({currentFrameName:J.current,currentFrame:H.current})))})),i.createElement("group",o.default({},k,{ref:C,scale:function(e=new m.Vector3(1,1,1),r=1){return"number"==typeof r?e.multiplyScalar(r):Array.isArray(r)?e.multiply(new m.Vector3(...r)):r instanceof m.Vector3?e.multiply(r):void 0}(Y,k.scale)}),i.createElement(f.Provider,{value:se},M&&i.createElement(a.Billboard,null,i.createElement("mesh",o.default({ref:U,scale:1,geometry:p},I),i.createElement("meshBasicMaterial",{premultipliedAlpha:!1,toneMapped:!1,side:m.DoubleSide,ref:_,map:X,transparent:!0,alphaTest:null!=R?R:0}))),!M&&i.createElement(u.Instances,o.default({geometry:p,limit:null!=z?z:1},I),i.createElement("meshBasicMaterial",{premultipliedAlpha:!1,toneMapped:!1,side:m.DoubleSide,ref:_,map:X,transparent:!0,alphaTest:null!=R?R:0}),(null!=D?D:[0]).map(((e,r)=>i.createElement(u.Instance,o.default({key:r,ref:1===(null==D?void 0:D.length)?U:null,position:e,scale:1},I))))),A))}));exports.SpriteAnimator=d,exports.useSpriteAnimator=function(){return i.useContext(f)};
@@ -1,11 +1,14 @@
1
1
  import * as React from 'react';
2
- type CommonMeshProps = {
3
- frustumCulled?: boolean;
4
- renderOrder?: number;
5
- visible?: boolean;
6
- userData?: any;
7
- matrixAutoUpdate?: boolean;
2
+ import { Vector3 } from '@react-three/fiber';
3
+ import * as THREE from 'three';
4
+ import { Instances, Instance } from './Instances';
5
+ import { SpriteData } from './useSpriteLoader';
6
+ type AnimationEventData = {
7
+ currentFrameName: string;
8
+ currentFrame: number;
8
9
  };
10
+ type CommonProps<T, U, V> = Pick<T & U & V, keyof T & keyof U & keyof V>;
11
+ type CommonMeshProps = CommonProps<React.ComponentProps<'mesh'>, React.ComponentProps<typeof Instance>, React.ComponentProps<typeof Instances>>;
9
12
  export type SpriteAnimatorProps = {
10
13
  startFrame?: number;
11
14
  endFrame?: number;
@@ -17,32 +20,36 @@ export type SpriteAnimatorProps = {
17
20
  numberOfFrames?: number;
18
21
  autoPlay?: boolean;
19
22
  animationNames?: Array<string>;
20
- onStart?: Function;
21
- onEnd?: Function;
22
- onLoopEnd?: Function;
23
- onFrame?: Function;
23
+ onStart?: (data: AnimationEventData) => void;
24
+ onEnd?: (data: AnimationEventData) => void;
25
+ onLoopEnd?: (data: AnimationEventData) => void;
26
+ onFrame?: (data: AnimationEventData) => void;
24
27
  play?: boolean;
25
28
  pause?: boolean;
26
29
  flipX?: boolean;
27
- position?: Array<number>;
28
30
  alphaTest?: number;
29
31
  asSprite?: boolean;
30
32
  offset?: number;
31
33
  playBackwards?: boolean;
32
34
  resetOnEnd?: boolean;
35
+ instanceItems?: Vector3[];
33
36
  maxItems?: number;
34
- instanceItems?: any[];
35
- spriteDataset?: any;
37
+ spriteDataset?: {
38
+ spriteTexture: THREE.Texture;
39
+ spriteData: SpriteData | null;
40
+ aspect: Vector3;
41
+ } | null;
36
42
  canvasRenderingContext2DSettings?: CanvasRenderingContext2DSettings;
37
43
  roundFramePosition?: boolean;
38
44
  meshProps?: CommonMeshProps;
39
45
  } & JSX.IntrinsicElements['group'];
40
46
  type SpriteAnimatorState = {
41
- current: number | undefined;
42
- offset: number | undefined;
43
- hasEnded: boolean | undefined;
44
- ref: React.MutableRefObject<any> | undefined | null | ((instance: any) => void);
47
+ current?: number;
48
+ offset?: number;
49
+ imageUrl?: string;
50
+ hasEnded: boolean;
51
+ ref: React.Ref<THREE.Group>;
45
52
  };
46
53
  export declare function useSpriteAnimator(): SpriteAnimatorState | null;
47
- export declare const SpriteAnimator: React.FC<SpriteAnimatorProps>;
54
+ export declare const SpriteAnimator: React.ForwardRefExoticComponent<Omit<SpriteAnimatorProps, "ref"> & React.RefAttributes<THREE.Group>>;
48
55
  export {};
@@ -3,88 +3,168 @@ import * as React from 'react';
3
3
  import { useFrame } from '@react-three/fiber';
4
4
  import * as THREE from 'three';
5
5
  import { Instances, Instance } from './Instances.js';
6
- import { useSpriteLoader } from './useSpriteLoader.js';
6
+ import { Billboard } from './Billboard.js';
7
+ import { useSpriteLoader, getFirstFrame } from './useSpriteLoader.js';
8
+
9
+ // Frame-related types
7
10
 
8
11
  const context = /*#__PURE__*/React.createContext(null);
9
12
  function useSpriteAnimator() {
10
13
  return React.useContext(context);
11
14
  }
15
+
16
+ // Type guard for SpriteData
17
+ function isSpriteData(data) {
18
+ return data !== null && 'meta' in data && 'frames' in data;
19
+ }
12
20
  const geometry = new THREE.PlaneGeometry(1, 1);
13
21
  const SpriteAnimator = /* @__PURE__ */React.forwardRef(({
14
- startFrame,
22
+ startFrame = 0,
15
23
  endFrame,
16
- fps,
17
- frameName,
24
+ fps = 30,
25
+ frameName = '',
18
26
  textureDataURL,
19
27
  textureImageURL,
20
- loop,
21
- numberOfFrames,
22
- autoPlay,
28
+ loop = false,
29
+ numberOfFrames = 1,
30
+ autoPlay = true,
23
31
  animationNames,
24
32
  onStart,
25
33
  onEnd,
26
34
  onLoopEnd,
27
35
  onFrame,
28
36
  play,
29
- pause,
30
- flipX,
31
- alphaTest,
37
+ pause = false,
38
+ flipX = false,
39
+ alphaTest = 0.0,
32
40
  children,
33
- asSprite,
41
+ asSprite = false,
34
42
  offset,
35
- playBackwards,
36
- resetOnEnd,
37
- maxItems,
38
- instanceItems,
43
+ playBackwards = false,
44
+ resetOnEnd = false,
45
+ maxItems = 1,
46
+ instanceItems = [[0, 0, 0]],
39
47
  spriteDataset,
40
48
  canvasRenderingContext2DSettings,
41
49
  roundFramePosition = false,
42
50
  meshProps = {},
43
51
  ...props
44
52
  }, fref) => {
45
- var _props$scale;
46
- const ref = React.useRef();
53
+ const ref = React.useRef(new THREE.Group());
47
54
  const spriteData = React.useRef(null);
48
- const matRef = React.useRef();
49
- const spriteRef = React.useRef();
55
+ const matRef = React.useRef(null);
56
+ const spriteRef = React.useRef(null);
50
57
  const timerOffset = React.useRef(window.performance.now());
51
- const currentFrame = React.useRef(startFrame || 0);
52
- const currentFrameName = React.useRef(frameName || '');
53
- const fpsInterval = (fps !== null && fps !== void 0 ? fps : 30) > 0 ? 1000 / (fps || 30) : 0;
58
+ const currentFrame = React.useRef(startFrame);
59
+ const currentFrameName = React.useRef(frameName);
60
+ const fpsInterval = fps > 0 ? 1000 / fps : 0;
54
61
  const [spriteTexture, setSpriteTexture] = React.useState(new THREE.Texture());
55
62
  const totalFrames = React.useRef(0);
56
- const [aspect, setAspect] = React.useState([1, 1, 1]);
63
+ const [aspect, setAspect] = React.useState(new THREE.Vector3(1, 1, 1));
57
64
  const flipOffset = flipX ? -1 : 1;
58
- const [displayAsSprite, setDisplayAsSprite] = React.useState(asSprite !== null && asSprite !== void 0 ? asSprite : true);
59
65
  const pauseRef = React.useRef(pause);
60
66
  const pos = React.useRef(offset);
61
67
  const softEnd = React.useRef(false);
62
- const frameBuffer = React.useRef([]);
63
68
  const {
64
69
  spriteObj,
65
70
  loadJsonAndTexture
66
71
  } = useSpriteLoader(null, null, animationNames, numberOfFrames, undefined, canvasRenderingContext2DSettings);
67
- //
72
+ const frameNameRef = React.useRef(frameName);
73
+
74
+ // lite version for pre-loaded assets
75
+ const parseSpriteDataLite = React.useCallback((textureData, data) => {
76
+ if (data === null) {
77
+ if (numberOfFrames) {
78
+ //get size from texture
79
+
80
+ totalFrames.current = numberOfFrames;
81
+ if (playBackwards) {
82
+ currentFrame.current = numberOfFrames - 1;
83
+ }
84
+ spriteData.current = data;
85
+ }
86
+ } else {
87
+ var _spriteData$current$f, _spriteData$current;
88
+ spriteData.current = data;
89
+ if (spriteData.current && Array.isArray(spriteData.current.frames)) {
90
+ totalFrames.current = spriteData.current.frames.length;
91
+ } else if (spriteData.current && typeof spriteData.current === 'object' && frameNameRef.current) {
92
+ totalFrames.current = spriteData.current.frames[frameNameRef.current].length;
93
+ } else {
94
+ totalFrames.current = 0;
95
+ }
96
+ if (playBackwards) {
97
+ currentFrame.current = totalFrames.current - 1;
98
+ }
99
+ const {
100
+ w,
101
+ h
102
+ } = getFirstFrame((_spriteData$current$f = (_spriteData$current = spriteData.current) == null ? void 0 : _spriteData$current.frames) !== null && _spriteData$current$f !== void 0 ? _spriteData$current$f : [], frameNameRef.current).sourceSize;
103
+ const aspect = calculateAspectRatio(w, h);
104
+ setAspect(aspect);
105
+ if (matRef.current) {
106
+ matRef.current.map = textureData;
107
+ }
108
+ }
109
+ setSpriteTexture(textureData);
110
+ }, [numberOfFrames, playBackwards]);
68
111
 
69
- function reset() {}
112
+ // modify the sprite material after json is parsed and state updated
113
+ const modifySpritePosition = React.useCallback(() => {
114
+ if (!spriteData.current) return;
115
+ const {
116
+ meta: {
117
+ size: metaInfo
118
+ },
119
+ frames
120
+ } = spriteData.current;
121
+ const {
122
+ w: frameW,
123
+ h: frameH
124
+ } = Array.isArray(frames) ? frames[0].sourceSize : frameName ? frames[frameName] ? frames[frameName][0].sourceSize : {
125
+ w: 0,
126
+ h: 0
127
+ } : {
128
+ w: 0,
129
+ h: 0
130
+ };
131
+ if (matRef.current && matRef.current.map) {
132
+ matRef.current.map.wrapS = matRef.current.map.wrapT = THREE.RepeatWrapping;
133
+ matRef.current.map.center.set(0, 0);
134
+ matRef.current.map.repeat.set(1 * flipOffset / (metaInfo.w / frameW), 1 / (metaInfo.h / frameH));
135
+ }
136
+ //const framesH = (metaInfo.w - 1) / frameW
137
+ const framesV = (metaInfo.h - 1) / frameH;
138
+ const frameOffsetY = 1 / framesV;
139
+ if (matRef.current && matRef.current.map) {
140
+ matRef.current.map.offset.x = 0.0; //-matRef.current.map.repeat.x
141
+ matRef.current.map.offset.y = 1 - frameOffsetY;
142
+ }
143
+ if (onStart) {
144
+ onStart({
145
+ currentFrameName: frameName !== null && frameName !== void 0 ? frameName : '',
146
+ currentFrame: currentFrame.current
147
+ });
148
+ }
149
+ }, [flipOffset, frameName, onStart]);
70
150
  const state = React.useMemo(() => ({
71
151
  current: pos.current,
72
152
  offset: pos.current,
73
153
  imageUrl: textureImageURL,
74
- reset: reset,
75
154
  hasEnded: false,
76
155
  ref: fref
77
- }), [textureImageURL, spriteDataset]);
156
+ }), [textureImageURL, fref]);
78
157
  React.useImperativeHandle(fref, () => ref.current, []);
79
158
  React.useLayoutEffect(() => {
80
159
  pos.current = offset;
81
160
  }, [offset]);
82
161
  const calculateAspectRatio = (width, height) => {
162
+ var _spriteRef$current;
163
+ const ret = new THREE.Vector3();
83
164
  const aspectRatio = height / width;
84
- if (spriteRef.current) {
85
- spriteRef.current.scale.set(1, aspectRatio, 1);
86
- }
87
- return [1, aspectRatio, 1];
165
+ ret.set(1, aspectRatio, 1);
166
+ (_spriteRef$current = spriteRef.current) == null || _spriteRef$current.scale.copy(ret);
167
+ return ret;
88
168
  };
89
169
 
90
170
  // initial loads
@@ -97,29 +177,27 @@ const SpriteAnimator = /* @__PURE__ */React.forwardRef(({
97
177
  loadJsonAndTexture(textureImageURL, textureDataURL);
98
178
  }
99
179
  }
100
- }, [spriteDataset]);
180
+ }, [loadJsonAndTexture, spriteDataset, textureDataURL, textureImageURL, parseSpriteDataLite]);
101
181
  React.useEffect(() => {
102
182
  if (spriteObj) {
103
183
  var _spriteObj$spriteText;
104
184
  parseSpriteDataLite(spriteObj == null || (_spriteObj$spriteText = spriteObj.spriteTexture) == null ? void 0 : _spriteObj$spriteText.clone(), spriteObj == null ? void 0 : spriteObj.spriteData);
105
185
  }
106
- }, [spriteObj]);
107
- React.useEffect(() => {
108
- setDisplayAsSprite(asSprite !== null && asSprite !== void 0 ? asSprite : true);
109
- }, [asSprite]);
186
+ }, [spriteObj, parseSpriteDataLite]);
110
187
 
111
188
  // support backwards play
112
189
  React.useEffect(() => {
113
190
  state.hasEnded = false;
114
191
  if (spriteData.current && playBackwards === true) {
115
- currentFrame.current = spriteData.current.frames.length - 1;
192
+ var _ref;
193
+ currentFrame.current = ((_ref = spriteData.current.frames.length) !== null && _ref !== void 0 ? _ref : 0) - 1;
116
194
  } else {
117
195
  currentFrame.current = 0;
118
196
  }
119
- }, [playBackwards]);
197
+ }, [playBackwards, state]);
120
198
  React.useLayoutEffect(() => {
121
199
  modifySpritePosition();
122
- }, [spriteTexture, flipX]);
200
+ }, [spriteTexture, flipX, modifySpritePosition]);
123
201
  React.useEffect(() => {
124
202
  if (autoPlay) {
125
203
  pauseRef.current = false;
@@ -138,113 +216,16 @@ const SpriteAnimator = /* @__PURE__ */React.forwardRef(({
138
216
  const {
139
217
  w,
140
218
  h
141
- } = getFirstItem(spriteData.current.frames).sourceSize;
219
+ } = getFirstFrame(spriteData.current.frames, frameName).sourceSize;
142
220
  const _aspect = calculateAspectRatio(w, h);
143
221
  setAspect(_aspect);
144
222
  }
145
223
  }
146
- }, [frameName, fpsInterval]);
147
-
148
- // lite version for pre-loaded assets
149
- const parseSpriteDataLite = (textureData, frameData = null) => {
150
- if (frameData === null) {
151
- if (numberOfFrames) {
152
- //get size from texture
153
- const width = textureData.image.width;
154
- const height = textureData.image.height;
155
- totalFrames.current = numberOfFrames;
156
- if (playBackwards) {
157
- currentFrame.current = numberOfFrames - 1;
158
- }
159
- spriteData.current = {
160
- frames: [],
161
- meta: {
162
- version: '1.0',
163
- size: {
164
- w: width,
165
- h: height
166
- },
167
- scale: '1'
168
- }
169
- };
170
- spriteData.current.frames = frameData;
171
- }
172
- } else {
173
- spriteData.current = frameData;
174
- totalFrames.current = spriteData.current.frames.length;
175
- if (playBackwards) {
176
- currentFrame.current = totalFrames.current - 1;
177
- }
178
- const {
179
- w,
180
- h
181
- } = getFirstItem(spriteData.current.frames).sourceSize;
182
- const aspect = calculateAspectRatio(w, h);
183
- setAspect(aspect);
184
- if (matRef.current) {
185
- matRef.current.map = textureData;
186
- }
187
- }
188
-
189
- // buffer for instanced
190
- if (instanceItems) {
191
- for (var i = 0; i < instanceItems.length; i++) {
192
- const keys = Object.keys(spriteData.current.frames);
193
- const randomKey = keys[Math.floor(Math.random() * keys.length)];
194
- frameBuffer.current.push({
195
- key: i,
196
- frames: spriteData.current.frames,
197
- selectedFrame: randomKey,
198
- offset: {
199
- x: 0,
200
- y: 0
201
- }
202
- });
203
- }
204
- }
205
- setSpriteTexture(textureData);
206
- };
207
-
208
- // modify the sprite material after json is parsed and state updated
209
- const modifySpritePosition = () => {
210
- if (!spriteData.current) return;
211
- const {
212
- meta: {
213
- size: metaInfo
214
- },
215
- frames
216
- } = spriteData.current;
217
- const {
218
- w: frameW,
219
- h: frameH
220
- } = Array.isArray(frames) ? frames[0].sourceSize : frameName ? frames[frameName] ? frames[frameName][0].sourceSize : {
221
- w: 0,
222
- h: 0
223
- } : {
224
- w: 0,
225
- h: 0
226
- };
227
- matRef.current.map.wrapS = matRef.current.map.wrapT = THREE.RepeatWrapping;
228
- matRef.current.map.center.set(0, 0);
229
- matRef.current.map.repeat.set(1 * flipOffset / (metaInfo.w / frameW), 1 / (metaInfo.h / frameH));
230
-
231
- //const framesH = (metaInfo.w - 1) / frameW
232
- const framesV = (metaInfo.h - 1) / frameH;
233
- const frameOffsetY = 1 / framesV;
234
- matRef.current.map.offset.x = 0.0; //-matRef.current.map.repeat.x
235
- matRef.current.map.offset.y = 1 - frameOffsetY;
236
- if (onStart) {
237
- onStart({
238
- currentFrameName: frameName,
239
- currentFrame: currentFrame.current
240
- });
241
- }
242
- };
224
+ }, [frameName, fpsInterval, state, endFrame, startFrame]);
243
225
 
244
226
  // run the animation on each frame
245
227
  const runAnimation = () => {
246
- //if (!frameName) return
247
-
228
+ if (!isSpriteData(spriteData.current)) return;
248
229
  const {
249
230
  meta: {
250
231
  size: metaInfo
@@ -254,7 +235,7 @@ const SpriteAnimator = /* @__PURE__ */React.forwardRef(({
254
235
  const {
255
236
  w: frameW,
256
237
  h: frameH
257
- } = getFirstItem(frames).sourceSize;
238
+ } = getFirstFrame(frames, frameName).sourceSize;
258
239
  const spriteFrames = Array.isArray(frames) ? frames : frameName ? frames[frameName] : [];
259
240
  const _endFrame = endFrame || spriteFrames.length - 1;
260
241
  var _offset = offset === undefined ? state.current : offset;
@@ -278,15 +259,15 @@ const SpriteAnimator = /* @__PURE__ */React.forwardRef(({
278
259
  }
279
260
  if (loop) {
280
261
  onLoopEnd == null || onLoopEnd({
281
- currentFrameName: frameName,
262
+ currentFrameName: frameName !== null && frameName !== void 0 ? frameName : '',
282
263
  currentFrame: currentFrame.current
283
264
  });
284
265
  } else {
285
266
  onEnd == null || onEnd({
286
- currentFrameName: frameName,
267
+ currentFrameName: frameName !== null && frameName !== void 0 ? frameName : '',
287
268
  currentFrame: currentFrame.current
288
269
  });
289
- state.hasEnded = resetOnEnd ? false : true;
270
+ state.hasEnded = !resetOnEnd;
290
271
  if (resetOnEnd) {
291
272
  pauseRef.current = true;
292
273
  //calculateFinalPosition(frameW, frameH, metaInfo, spriteFrames)
@@ -295,7 +276,7 @@ const SpriteAnimator = /* @__PURE__ */React.forwardRef(({
295
276
  if (!loop) return;
296
277
  } else if (onStartCondition) {
297
278
  onStart == null || onStart({
298
- currentFrameName: frameName,
279
+ currentFrameName: frameName !== null && frameName !== void 0 ? frameName : '',
299
280
  currentFrame: currentFrame.current
300
281
  });
301
282
  }
@@ -304,7 +285,7 @@ const SpriteAnimator = /* @__PURE__ */React.forwardRef(({
304
285
  if (_offset !== undefined && manualProgressEndCondition) {
305
286
  if (softEnd.current === false) {
306
287
  onEnd == null || onEnd({
307
- currentFrameName: frameName,
288
+ currentFrameName: frameName !== null && frameName !== void 0 ? frameName : '',
308
289
  currentFrame: currentFrame.current
309
290
  });
310
291
  softEnd.current = true;
@@ -343,10 +324,12 @@ const SpriteAnimator = /* @__PURE__ */React.forwardRef(({
343
324
  } = spriteFrames[targetFrame];
344
325
  const frameOffsetX = 1 / framesH;
345
326
  const frameOffsetY = 1 / framesV;
346
- finalValX = flipOffset > 0 ? frameOffsetX * (frameX / originalSizeX) : frameOffsetX * (frameX / originalSizeX) - matRef.current.map.repeat.x;
347
- finalValY = Math.abs(1 - frameOffsetY) - frameOffsetY * (frameY / originalSizeY);
348
- matRef.current.map.offset.x = finalValX;
349
- matRef.current.map.offset.y = finalValY;
327
+ if (matRef.current && matRef.current.map) {
328
+ finalValX = flipOffset > 0 ? frameOffsetX * (frameX / originalSizeX) : frameOffsetX * (frameX / originalSizeX) - matRef.current.map.repeat.x;
329
+ finalValY = Math.abs(1 - frameOffsetY) - frameOffsetY * (frameY / originalSizeY);
330
+ matRef.current.map.offset.x = finalValX;
331
+ matRef.current.map.offset.y = finalValY;
332
+ }
350
333
 
351
334
  // if manual update is active
352
335
  if (_offset !== undefined && _offset !== null) {
@@ -371,8 +354,8 @@ const SpriteAnimator = /* @__PURE__ */React.forwardRef(({
371
354
 
372
355
  // *** Warning! It runs on every frame! ***
373
356
  useFrame((_state, _delta) => {
374
- var _spriteData$current, _matRef$current;
375
- if (!((_spriteData$current = spriteData.current) != null && _spriteData$current.frames) || !((_matRef$current = matRef.current) != null && _matRef$current.map)) {
357
+ var _spriteData$current2, _matRef$current;
358
+ if (!((_spriteData$current2 = spriteData.current) != null && _spriteData$current2.frames) || !((_matRef$current = matRef.current) != null && _matRef$current.map)) {
376
359
  return;
377
360
  }
378
361
  if (pauseRef.current) {
@@ -380,64 +363,35 @@ const SpriteAnimator = /* @__PURE__ */React.forwardRef(({
380
363
  }
381
364
  if (!state.hasEnded && (autoPlay || play)) {
382
365
  runAnimation();
383
- onFrame && onFrame({
366
+ onFrame == null || onFrame({
384
367
  currentFrameName: currentFrameName.current,
385
368
  currentFrame: currentFrame.current
386
369
  });
387
370
  }
388
371
  });
389
-
390
- // utils
391
- const getFirstItem = param => {
392
- if (Array.isArray(param)) {
393
- return param[0];
394
- } else if (typeof param === 'object' && param !== null) {
395
- const keys = Object.keys(param);
396
- return frameName ? param[frameName][0] : param[keys[0]][0];
397
- } else {
398
- return {
399
- w: 0,
400
- h: 0
401
- };
402
- }
403
- };
404
- function multiplyScale(initialScale, newScale) {
405
- let _newScale = [];
406
-
407
- // If newScale is a single number, convert it to a Vector3
408
- if (typeof newScale === 'number') {
409
- _newScale = [newScale, newScale, newScale];
410
- } else if (Array.isArray(newScale)) {
411
- // If newScale is an array, convert it to a Vector3
412
- _newScale = newScale;
413
- } else if (newScale instanceof THREE.Vector3) {
414
- _newScale = [newScale.x, newScale.y, newScale.z];
415
- }
416
-
417
- // Multiply the scale values element-wise
418
- const result = initialScale.map((value, index) => value * _newScale[index]);
419
- // Convert the result to an array of numbers
420
- return result;
372
+ function multiplyScale(initialScale = new THREE.Vector3(1, 1, 1), newScale = 1) {
373
+ if (typeof newScale === 'number') return initialScale.multiplyScalar(newScale);
374
+ if (Array.isArray(newScale)) return initialScale.multiply(new THREE.Vector3(...newScale));
375
+ if (newScale instanceof THREE.Vector3) return initialScale.multiply(newScale);
421
376
  }
422
377
  return /*#__PURE__*/React.createElement("group", _extends({}, props, {
423
378
  ref: ref,
424
- scale: multiplyScale(aspect !== null && aspect !== void 0 ? aspect : [1, 1, 1], (_props$scale = props.scale) !== null && _props$scale !== void 0 ? _props$scale : 1.0)
379
+ scale: multiplyScale(aspect, props.scale)
425
380
  }), /*#__PURE__*/React.createElement(context.Provider, {
426
381
  value: state
427
- }, /*#__PURE__*/React.createElement(React.Suspense, {
428
- fallback: null
429
- }, displayAsSprite && /*#__PURE__*/React.createElement("sprite", _extends({
382
+ }, asSprite && /*#__PURE__*/React.createElement(Billboard, null, /*#__PURE__*/React.createElement("mesh", _extends({
430
383
  ref: spriteRef,
431
384
  scale: 1.0,
432
385
  geometry: geometry
433
- }, meshProps), /*#__PURE__*/React.createElement("spriteMaterial", {
386
+ }, meshProps), /*#__PURE__*/React.createElement("meshBasicMaterial", {
434
387
  premultipliedAlpha: false,
435
388
  toneMapped: false,
389
+ side: THREE.DoubleSide,
436
390
  ref: matRef,
437
391
  map: spriteTexture,
438
392
  transparent: true,
439
393
  alphaTest: alphaTest !== null && alphaTest !== void 0 ? alphaTest : 0.0
440
- })), !displayAsSprite && /*#__PURE__*/React.createElement(Instances, _extends({
394
+ }))), !asSprite && /*#__PURE__*/React.createElement(Instances, _extends({
441
395
  geometry: geometry,
442
396
  limit: maxItems !== null && maxItems !== void 0 ? maxItems : 1
443
397
  }, meshProps), /*#__PURE__*/React.createElement("meshBasicMaterial", {
@@ -453,7 +407,7 @@ const SpriteAnimator = /* @__PURE__ */React.forwardRef(({
453
407
  ref: (instanceItems == null ? void 0 : instanceItems.length) === 1 ? spriteRef : null,
454
408
  position: item,
455
409
  scale: 1.0
456
- }, meshProps))))), children));
410
+ }, meshProps)))), children));
457
411
  });
458
412
 
459
413
  export { SpriteAnimator, useSpriteAnimator };