UNPKG

@darrench3140/react-native-sprite-sheet

Version:

An up to date react native sprite sheet for use in animations.

89 lines (87 loc) 2.95 kB
"use strict"; import { forwardRef, useCallback, useEffect, useImperativeHandle, useState } from 'react'; import { Platform, StyleSheet, View, Image } from 'react-native'; import { Image as ExpoImage } from 'expo-image'; import Animated, { useAnimatedStyle, useSharedValue } from 'react-native-reanimated'; import { jsx as _jsx } from "react/jsx-runtime"; const AnimatedImage = Platform.OS === 'android' ? Animated.createAnimatedComponent(ExpoImage) : Animated.createAnimatedComponent(Image); const Sprite = /*#__PURE__*/forwardRef((props, ref) => { const { source, spriteSheetSize, size, offset = { x: 0, y: 1 }, columnRowMapping, frameSize, frames, defaultFrame, styles } = props; const [allFrames, setAllFrames] = useState(frames ?? []); const currentFrameIndex = useSharedValue(defaultFrame); const setCurrentFrameIndex = useCallback(frameIndex => { if (frameIndex < 0 || frameIndex >= allFrames.length) { console.warn(`Invalid frame index: ${frameIndex}`); return; } currentFrameIndex.value = frameIndex; }, [currentFrameIndex, allFrames.length]); useImperativeHandle(ref, () => ({ setCurrentFrameIndex }), [setCurrentFrameIndex]); const animatedStyle = useAnimatedStyle(() => { const frame = allFrames[currentFrameIndex.value]?.frame; if (!frame) return {}; const scaleX = size.width / frame.w; const scaleY = size.height / frame.h; return { width: spriteSheetSize.width * scaleX, height: spriteSheetSize.height * scaleY, transform: [{ translateX: -(frame.x + (offset?.x ?? 0)) * scaleX }, { translateY: -(frame.y + (offset?.y ?? 0)) * scaleY }] }; }); useEffect(() => { if (!frames) { if (!columnRowMapping || columnRowMapping.length === 0) throw new Error('columnRowMapping is not set.'); const w = frameSize?.width ?? spriteSheetSize.width / Math.max(...columnRowMapping); const h = frameSize?.height ?? spriteSheetSize.height / columnRowMapping.length; const calcFrames = columnRowMapping.flatMap((noOfColumn, rowIndex) => { return Array.from({ length: noOfColumn }, (_, colIndex) => ({ frame: { h: h, w: w, x: colIndex * w, y: rowIndex * h } })); }); setAllFrames(calcFrames); } }, []); // eslint-disable-line react-hooks/exhaustive-deps const containerStyle = StyleSheet.compose(StyleSheet.compose(defaultStyles.container, size), styles); return /*#__PURE__*/_jsx(View, { style: containerStyle, children: /*#__PURE__*/_jsx(AnimatedImage, { source: source, style: animatedStyle, contentFit: "contain", resizeMode: 'contain' }) }); }); const defaultStyles = StyleSheet.create({ container: { overflow: 'hidden' } }); export default Sprite; //# sourceMappingURL=Sprite.js.map