美文网首页
react-native使用transfrom旋转动画,如何设置

react-native使用transfrom旋转动画,如何设置

作者: sunny635533 | 来源:发表于2022-06-28 14:47 被阅读0次

引用库:https://github.com/sueLan/react-native-anchor-point
参考代码:

import React from "react";
import { Animated, Easing, View } from "react-native";

export class LoadingView extends React.Component {

    _rotateAnimatedValue = new Animated.Value(0);
    _animation;

    componentDidMount() {
        this.startAnimation()
    }

    startAnimation = () => {
        this._animation = Animated.loop(
            Animated.timing(this._rotateAnimatedValue, {
                toValue: 1,
                duration: 1000,
                useNativeDriver: true,
                easing: Easing.ease,
                delay: 200
            }),
            { iterations: 1000 },
        ).start();

    }

    componentWillUnmount() {
        if (this._animation) {
            this._animation.stop();
            this._animation = null
        }
    }


    render() {
        const { source, imgWidth = 24, imgHeight = 24, resizeMode, style } = this.props;
        const rotateValue = this._rotateAnimatedValue.interpolate({
            inputRange: [0, 1],
            outputRange: ['0deg', '360deg'],
        })
        return <View>
            <Animated.Image
                style={{
                    width: imgWidth,
                    height: imgHeight,
                    transform: [{ rotate: rotateValue }],
                    ...style
                }}
                resizeMode={resizeMode}
                source={source} />
        </View>
    }
}

动画组合代码

startAnimation = () => {
    this._animation = Animated.loop(
      Animated.sequence([
        Animated.timing(this._rotateAnimatedValue, {
          toValue: 1,
          duration: 1500,
          useNativeDriver: true,
          easing: Easing.ease,
          delay: 200
        }),
        Animated.timing(this._rotateAnimatedValue, {
          toValue: 0,
          duration: 1500,
          useNativeDriver: true,
          easing: Easing.ease
        }),
      ]),
      { iterations: 1000 },
    );
    this._animation.start();
  }

getTransform = () => {
    const rotateValue = this._rotateAnimatedValue.interpolate({
      inputRange: [0, 1],
      outputRange: ['0deg', '24deg'],
    })
    let transform = {
      transform: [{ perspective: 400 }, { rotateZ: rotateValue }],
    };
    return withAnchorPoint(transform, { x: 0, y: 1 }, { width: 46, height: 37 });
  };

<Animated.Image
                  style={[{
                    width: 46,
                    height: 37,
                    position: 'absolute',
                    right: 8,
                    bottom: 1
                  },
                  this.getTransform()
                  ]}
                  resizeMode={"stretch"}
                  source={require("@assets/home/diagnos_search.png")} />

该库的核心代码index.ts 如下:

import type { TransformsStyle } from "react-native";

export interface Point {
    x: number;
    y: number;
}

export interface Size {
    width: number;
    height: number;
}

const isValidSize = (size: Size): boolean => {
    return size && size.width > 0 && size.height > 0;
}; 

const defaultAnchorPoint = { x: 0.5, y: 0.5 };

export const withAnchorPoint = (transform: TransformsStyle, anchorPoint: Point, size: Size) => {
    if(!isValidSize(size)) {
        return transform;
    }

    let injectedTransform = transform.transform;
    if (!injectedTransform) {
        return transform;
    }

    if (anchorPoint.x !== defaultAnchorPoint.x && size.width) {
        const shiftTranslateX = [];

        // shift before rotation
        shiftTranslateX.push({
            translateX: size.width * (anchorPoint.x - defaultAnchorPoint.x),
        });
        injectedTransform = [...shiftTranslateX, ...injectedTransform];
        // shift after rotation
        injectedTransform.push({
            translateX: size.width * (defaultAnchorPoint.x - anchorPoint.x),
        });
    }

    if (!Array.isArray(injectedTransform)) {
        return { transform: injectedTransform };
    }

    if (anchorPoint.y !== defaultAnchorPoint.y && size.height) {
        let shiftTranslateY = [];
        // shift before rotation
        shiftTranslateY.push({
            translateY: size.height * (anchorPoint.y - defaultAnchorPoint.y),
        });
        injectedTransform = [...shiftTranslateY, ...injectedTransform];
        // shift after rotation
        injectedTransform.push({
            translateY: size.height * (defaultAnchorPoint.y - anchorPoint.y),
        });
    }

    return { transform: injectedTransform };
};

相关文章

网友评论

      本文标题:react-native使用transfrom旋转动画,如何设置

      本文链接:https://www.haomeiwen.com/subject/kigavrtx.html