繁体   English   中英

Javascript 旋转到一定程度后停止旋转 animation

[英]Javascript stop rotate animation after rotating to a certain degree

我想在按下按钮后使图像旋转到一定程度。 我遵循了一些互联网教程来实现我的代码基础。

我正在使用来自互联网的 arrow.png 图像,我希望它在每次按下按钮时以 +45 度的 animation 旋转。 例如,箭头默认指向右,按下按钮后我想让它顺时针旋转到右下角。 从那个 position 开始,再次按下应该使其旋转,尖端朝下等。

我的问题是,按下按钮后,我的 animation 卡在一个循环中,我不知道如何让它以 +45 度旋转,而不会每次都从 0 度开始旋转。

这是我的代码


class App extends Component {
  constructor() {
    super();
    this.RotateValueHolder = new Animated.Value(0);
  }

  StartImageRotateFunction() {
    this.RotateValueHolder.setValue(0);
    Animated.timing(this.RotateValueHolder, {
      toValue: 1,
      duration: 1000,
      easing: Easing.linear,
    }).start(() => this.StartImageRotateFunction());
  }

  state = {
    count: 0,
  };

  onPress = () => {
    this.setState({
      count: this.state.count + 1,
    });
    this.StartImageRotateFunction(0);
  };

  render() {
    const RotateData = this.RotateValueHolder.interpolate({
      inputRange: [0, 1],
      outputRange: ['0deg', '45deg'],
    });

    return (
      <View style={styles.container}>
        <Animated.Image
          source={{ uri: 'https://img.icons8.com/plasticine/2x/arrow.png' }}
          style={{
            width: 200,
            height: 200,
            transform: [{ rotate: RotateData }],
          }}
        />
        <TouchableOpacity style={styles.button} onPress={this.onPress}>
          <Text>Apasa aici</Text>
        </TouchableOpacity>
        <View style={styles.countContainer}>
          <Text>Ai apasat aici de {this.state.count} times</Text>
          <Text>{this.estedisperat()} </Text>
        </View>
      </View>
    );
  }



从您的示例中很难判断,因为您使用的Animated function 似乎没有被导入。 每当您要提出问题时,请始终尝试提供最小的工作示例。 它极大地帮助人们试图给你一个回应。

看起来可能存在问题的另一件事是您的transform: [{ rotate: RotateData }]行未连接到任何其他 state 这意味着未来的印刷机将无法告知需要旋转的次数发生。 我希望有一些像

const degrees = this.state.count * 45 表示每次单击后箭头需要旋转的度数。

此外,在提出问题时,请尝试将问题分成独立的部分。 你提到两件事:

  • 您的 animation 陷入循环
  • 你不知道如何旋转按钮

至于上面的第二个项目符号,请参见此示例

关于Animate function 需要注意的一点是它需要一个域和范围。 为了确保您的旋转和点击次数始终保持在指定范围内,您可以使用%取模运算符。 请参阅我在此处创建的简化示例。

https://codesandbox.io/s/lucid-bas-bs7fw

import React, { useState } from "react";

const App = () => {
  const [count, setCount] = useState(0);

  const increment = () => setCount(count + 1);
  return (
    <>
      <button onClick={increment}>Increment</button>
      <div>{count * 45}</div>
    </>
  );
};

export default App;

我在您的示例中看到了一些冗余片段,请参阅注释掉它们的解释。

这是一个工作示例

class App extends Component {
  constructor() {
    super();
    this.RotateValueHolder = new Animated.Value(0);

/*
  It seem that it could be defined only once, 
  recalculate the same transform on every render is not necessary  
*/
    this.RotateData = this.RotateValueHolder.interpolate({
      inputRange: [0, 1],
      outputRange: ['0deg', '45deg'],
    });
  }

  StartImageRotateFunction() {
   /*
Loop problem starts here, omit
This one set rotate value to 0 on very call 
    // this.RotateValueHolder.setValue(0);   
  */   
    Animated.timing(this.RotateValueHolder, {
      /*
      Next problem.
      instead times to times set target value to 1 you should use cuurent value from state 
      // toValue: 1,
      */
      toValue: this.state.count,
      duration: 1000,
      easing: Easing.linear,
    })
     /*
     call `.start()` is required, but when you pass callback into
     it will invoked just after animation ends,
     in your case it had start looping 
     // .start(() => this.StartImageRotateFunction());
     */
     .start();
  }

  state = {
    count: 0,
  };

  onPress = () => {
    this.setState({
      count: this.state.count + 1,
    }, () => this.StartImageRotateFunction());
    /*
     Last, bat not least, start animation after set new state
    // this.StartImageRotateFunction(0);
    */
  };

  render() {
    return (
      <View style={styles.container}>
        <Animated.Image
          source={{ uri: 'https://img.icons8.com/plasticine/2x/arrow.png' }}
          style={{
            width: 200,
            height: 200,
            transform: [{ rotate: this.RotateData /* `this`, due to moved in constructor */ }],
          }}
        />
        <TouchableOpacity style={styles.button} onPress={this.onPress}>
          <Text>Apasa aici</Text>
        </TouchableOpacity>
        <View style={styles.countContainer}>
          <Text>Ai apasat aici de {this.state.count} times</Text>
          <Text>{
/* just replace absent function with expected behavior */ 
`rotated ${(this.state.count * 45) % 360}`
}</Text>
        </View>
      </View>
    );
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM