2017-07-10 15 views
-1

私はカスタム画像付きのスライダーを作成するために使っているreact-native-sliderの非常に編集されたバージョンを持っています。これまでのところ、スライダの親指として機能する2つのイメージを持つ背景イメージがありますが、イメージの1つにアニメーション 'onSlidingComplete'を適用したいと考えています。反応ネイティブスライダー内で私自身のアニメーションを作成するにはどうすればいいですか

私は希望の効果を得るためにnode_modules内のslider.jsファイルを編集しましたが、私は今までにすべてのことをやっていましたが、私の人生ではアニメーションを動作させることはできません。

スライダー宣言:

   <Slider 

       style={styles.slider} 

       trackStyle={styles.trackStyle} 

       maximumValue={this.props.max} 

       minimumValue={this.props.min} 

       step={this.props.step} 

       value={this.state.value} 

       thumbTouchSize={this.props.thumbTouchSize} 

       sliderBg={require('../../images/tank_bg.png')} 

       thumbImage={require('../../images/thumb_slider.png')} 

       thumbImageBg={require('../../images/thumb_slider_whitebg_line.png')} 

       onSlidingComplete={(value) => this.onSlidingComplete(value)} 

       onValueChange={(value) => this.onValueChange(value)} 

       orientation={'horizontal'} 

       sliderAnim={this.state.sliderAnim} 

      /> 

これは私が私のslider.jsを設定している方法です。私はすでにアニメーションを実装しようとしていることに注意することが

場所は私が何を探しています何240

ラインにライン577と_animateSlider機能上の_setCurrentValueAnimated機能していることは、そのを通じてスライダーにブール値を渡すことです宣言をthis.state.sliderAnim:proptypes.boolとして宣言し、コードでスクリプト化されたアニメーションを実行させます。

私がしようとしているのは、onSlidingCompleteが呼び出されるたびにthumbImageBgの高さを0から100%にアニメートさせることです。

すべてのヘルプはたくさん

    ` 
     import React, { 
      Component, 
     } from "react"; 
     import { 
      Animated, 
      StyleSheet, 
      Image, 
      PanResponder, 
      View, 
      Easing, 
      Dimensions, 
      LayoutAnimation, 
      TouchableWithoutFeedback, 
      TouchableOpacity, 
      Platform, 
      UIManager 
     } from "react-native"; 

     import PropTypes from 'prop-types'; 

     if (Platform.OS === 'android') { 
      UIManager.setLayoutAnimationEnabledExperimental(true); 
     }; 

高く評価され~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

30k max charに合うように不要なコードが多数削除されましたサイズ。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~

  state = { 
      containerSize: {width: 0, height: 0}, 
      trackSize: {width: 0, height: 0}, 
      thumbSize: {width: 0, height: 0}, 
      allMeasured: false, 
      value: new Animated.Value(this.props.value), 
      imageBGStyle: { 
       height: this.props.thumbImageBg.height, 
      } 
      }; 

      static defaultProps = { 
      value: 0, 
      minimumValue: 0, 
      maximumValue: 1, 
      step: 0, 
      minimumTrackTintColor: '#3f3f3f', 
      maximumTrackTintColor: '#b3b3b3', 
      thumbTintColor: '#343434', 
      thumbTouchSize: {width: 80, height: 80}, 
      debugTouchArea: true, 
      animationType: 'timing', 
      orientation: 'horizontal', 
      sliderAnim: true, 
      }; 

      _animateSlider() { // ################################################################# 
      // I USED THIS METHOD TO TRY CREATE AN ANIMATION USING LAYOUTANIMATION 
      LayoutAnimation.configureNext(LayoutAnimation.Presets.spring); 
      this.setState({ 
       imageBGStyle: { 
       height: '100%', 
       } 
      }) 
      LayoutAnimation.configureNext(LayoutAnimation.Presets.spring); 
      setInterval(function() {this.setState({ 
       imageBGStyle: { 
       height: '0%', 
       } 
      })}.bind(this),5000) 
      } 

      componentWillMount() { 
      this._panResponder = PanResponder.create({ 
       onStartShouldSetPanResponder: this._handleStartShouldSetPanResponder, 
       onMoveShouldSetPanResponder: this._handleMoveShouldSetPanResponder, 
       onPanResponderGrant: this._handlePanResponderGrant, 
       onPanResponderMove: this._handlePanResponderMove, 
       onPanResponderRelease: this._handlePanResponderEnd, 
       onPanResponderTerminationRequest: this._handlePanResponderRequestEnd, 
       onPanResponderTerminate: this._handlePanResponderEnd, 
      }); 

      if(this.sliderAnim == true) 
      { 
       this.animatedValue = new Animated.Value(100); 
       alert('sliderAnim is true and runs'); 
       console.log('sliderAnim is true and runs'); 
      } 
      }; 

      componentWillReceiveProps(nextProps) { 
      var newValue = nextProps.value; 

      if (this.props.value !== newValue) { 
       if (this.props.animateTransitions) { 
       this._setCurrentValueAnimated(newValue); 
       } 
       else { 
       this._setCurrentValue(newValue); 
       } 
      } 
      }; 

      render() { 
      var { 
       minimumValue, 
       maximumValue, 
       minimumTrackTintColor, 
       maximumTrackTintColor, 
       thumbTintColor, 
       thumbImage, 
       styles, 
       style, 
       trackStyle, 
       thumbStyle, 
       debugTouchArea, 
       orientation, 
       sliderBg, 
       thumbImageBg, 
       sliderAnim, 
       ...other 
      } = this.props; 
      var {value, containerSize, trackSize, thumbSize, allMeasured} = this.state; 
      var mainStyles = styles || defaultStyles; 
      var outputRange; 
      if (orientation === 'horizontal') { 
       outputRange = [0, containerSize.width - thumbSize.width]; 
      } else { 
       outputRange = [containerSize.height - thumbSize.height, 0]; 
      } 
      var thumbStart = value.interpolate({ 
       inputRange: [minimumValue, maximumValue], 
       outputRange: outputRange, 
       //extrapolate: 'clamp', 
       }); 
      var valueVisibleStyle = {}; 
      if (!allMeasured) { 
       valueVisibleStyle.opacity = 0; 
      } 

      var minimumTrackStyle = { 
       position: 'absolute', 
       // width: Animated.add(thumbStart, thumbSize.width/2), 
       backgroundColor: minimumTrackTintColor, 
       ...valueVisibleStyle 
      }; 

      if (orientation === 'horizontal') { 
       minimumTrackStyle.width = Animated.add(thumbStart, thumbSize.width/2); 
       minimumTrackStyle.marginTop = -trackSize.height; 
      } else { 
       minimumTrackStyle.marginLeft = -trackSize.width; 
       minimumTrackStyle.top = thumbStart; 
       minimumTrackStyle.height = Animated.add(thumbStart, -trackSize.height); 
       minimumTrackStyle.height = Animated.multiply(minimumTrackStyle.height, -1); 
      } 

      var touchOverflowStyle = this._getTouchOverflowStyle(); 

      let imageBGStyle = [defaultStyles.thumbImgStyleBg, this.state.imageBGStyle]; 

      return (
       <View {...other} style={[mainStyles.container, style]} onLayout={this._measureContainer}> 
       <Image style={defaultStyles.trackImgStyle} source={this.props.sliderBg}> 
        <View 
        style={[{backgroundColor: maximumTrackTintColor,}, mainStyles.track, trackStyle]} 
        renderToHardwareTextureAndroid={true} 
        onLayout={this._measureTrack} /> 

        {/*LayoutAnimation.configureNext(LayoutAnimation.Presets.spring);*/} 

        {/*<Animated.View 
        renderToHardwareTextureAndroid={true} 
        style={[mainStyles.track, trackStyle, minimumTrackStyle]} > 
        </Animated.View>*/} 

        {/*<TouchableOpacity 
         style={[defaultStyles.touchArea, {zIndex: 100}]} 
         onPress={this.animateSlider.bind(this)}>*/} 

        <Animated.View 
        onLayout={this._measureThumb} 
        renderToHardwareTextureAndroid={true} 
        style={[ 

         mainStyles.thumb, thumbStyle, 
         { 
         transform: [ 
          { translateX: thumbStart }, 
          { translateY: 0 } 
         ], 
         ...valueVisibleStyle 
         } 
        ]} 
        > 


         <Animated.Image 
         style={imageBGStyle} 
         source={this.props.thumbImageBg} > 
         <Animated.Image 
         style={defaultStyles.thumbImgStyle} 
         source={this.props.thumbImage}/> 
         </Animated.Image> 
        </Animated.View> 
        {/*</TouchableOpacity>*/} 


        <View 
        renderToHardwareTextureAndroid={true} 
        style={[defaultStyles.touchArea, touchOverflowStyle]} 
        {...this._panResponder.panHandlers}> 
        {debugTouchArea == true && this._renderDebugThumbTouchRect(thumbStart)} 
        </View> 
       </Image> 
       </View> 
      ); 
      }; 

      _animate() { 
      Animated.timing(this.animatedValue, 
      { 
       toValue: 50, 
       duration: 5000, 
       easing: Easing.bounce 
      }).start() 
      }; 

      _getPropsForComponentUpdate(props) { 
      var { 
       value, 
       onValueChange, 
       onSlidingStart, 
       onSlidingComplete, 
       style, 
       trackStyle, 
       thumbStyle, 
       ...otherProps, 
      } = props; 

      return otherProps; 
      }; 

      _handleStartShouldSetPanResponder = (e: Object, /*gestureState: Object*/): boolean => { 
      // Should we become active when the user presses down on the thumb? 
      return this._thumbHitTest(e); 
      }; 

      _handleMoveShouldSetPanResponder(/*e: Object, gestureState: Object*/): boolean { 
      // Should we become active when the user moves a touch over the thumb? 
      return false; 
      }; 

      _handlePanResponderGrant = (/*e: Object, gestureState: Object*/) => { 
      this._previousStart = this._getThumbStart(this._getCurrentValue()); 
      this._fireChangeEvent('onSlidingStart'); 
      }; 
      _handlePanResponderMove = (e: Object, gestureState: Object) => { 
      if (this.props.disabled) { 
       return; 
      } 

      this._setCurrentValue(this._getValue(gestureState)); 
      this._fireChangeEvent('onValueChange'); 
      }; 
      _handlePanResponderRequestEnd(e: Object, gestureState: Object) { 
      // Should we allow another component to take over this pan? 
      return false; 
      }; 
      _handlePanResponderEnd = (e: Object, gestureState: Object) => { 
      if (this.props.disabled) { 
       return; 
      } 


      console.log("holy fuck"); 

      this._setCurrentValue(this._getValue(gestureState)); 
      this._fireChangeEvent('onSlidingComplete'); 
      if(this.sliderAnim === true) 
      { 
       this._animateSlider(); 
      } 
      }; 

      onSlidingComplete() { 
      alert("nah this works!"); 
      } 

      _measureContainer = (x: Object) => { 
      this._handleMeasure('containerSize', x); 
      }; 

      _measureTrack = (x: Object) => { 
      this._handleMeasure('trackSize', x); 
      }; 

      _measureThumb = (x: Object) => { 
      this._handleMeasure('thumbSize', x); 
      }; 

      _handleMeasure = (name: string, x: Object) => { 
      var {width, height} = x.nativeEvent.layout; 
      var size = {width: width, height: height}; 

      var storeName = `_${name}`; 
      var currentSize = this[storeName]; 
      if (currentSize && width === currentSize.width && height === currentSize.height) { 
       return; 
      } 
      this[storeName] = size; 

      if (this._containerSize && this._trackSize && this._thumbSize) { 
       this.setState({ 
       containerSize: this._containerSize, 
       trackSize: this._trackSize, 
       thumbSize: this._thumbSize, 
       allMeasured: true, 
       }) 
      } 
      }; 

      _getRatio = (value: number) => { 
      return (value - this.props.minimumValue)/(this.props.maximumValue - this.props.minimumValue); 
      }; 

      _getThumbStart = (value: number) => { 
      var ratio = this._getRatio(value); 

      var start = 0; 

      if (this.props.orientation === 'horizontal') { 
       var length = this.state.containerSize.width - this.state.thumbSize.width; 
       start = ratio * length; 
      } else { 
       var length = this.state.containerSize.height - this.state.thumbSize.height; 
       start = length - (ratio * length); 
      } 

      return start; 
      }; 

      _getValue = (gestureState: Object) => { 
      var length = 0; 

      if (this.props.orientation === 'horizontal') { 
       length = this.state.containerSize.width - this.state.thumbSize.width; 
      } else { 
       length = this.state.containerSize.height - this.state.thumbSize.height; 
      } 

      var thumbStart = this._previousStart; 

      var ratio; 
      /* 
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 

       THE NEXT STATEMENT IS EDITED TO AUTOMATICALLY TAKE ROTATED INPUTS FROM THE USER. EDIT IF "ORIENTATION" WORKS! 

       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
      */ 
      if (this.props.orientation === 'horizontal') { 
       thumbStart += -gestureState.dy; 
       ratio = (thumbStart/length); 
      } else { 
       thumbStart += gestureState.dy; 
       ratio = 1 - (thumbStart/length); 
      } 

      if (this.props.step) { 
       return Math.max(this.props.minimumValue, 
       Math.min(this.props.maximumValue, 
        this.props.minimumValue + Math.round(ratio * (this.props.maximumValue - this.props.minimumValue)/this.props.step) * this.props.step 
       ) 
      ); 
      } else { 
       return Math.max(this.props.minimumValue, 
       Math.min(this.props.maximumValue, 
        ratio * (this.props.maximumValue - this.props.minimumValue) + this.props.minimumValue 
       ) 
      ); 
      } 
      }; 

      _getCurrentValue =() => { 
      return this.state.value.__getValue(); 
      }; 

      _setCurrentValue = (value: Number) => { 
      this.state.value.setValue(value); 
      }; 

      _setCurrentValueAnimated = (value: Number) => { 
      var animationType = this.props.animationType; 
      var animationConfig = Object.assign(
        {}, 
        DEFAULT_ANIMATION_CONFIGS[animationType], 
        this.props.animationConfig, 
        {toValue : value} 
       ); 
       // ####################################################################################################################### 
       // I CHANGED THIS THIS.STATE IN THE NEXT LINE SO THAT IT WOULD CHANGE THE HEIGHT OF MY IMAGES STYLE IN AN ANIMATION BUT IT DID NOT WORK 
      Animated[animationType](this.state.imageBGStyle.height, animationConfig).start(); 
      }; 

      _fireChangeEvent = (event) => { 
      if (this.props[event]) { 
       this.props[event](this._getCurrentValue()); 
      } 
      }; 

      _getTouchOverflowSize =() => { 
      var state = this.state; 
      var props = this.props; 

      var size = {}; 
      if (state.allMeasured === true) { 

       if (props.orientation === 'horizontal') { 
       size.width = Math.max(0, props.thumbTouchSize.width - state.thumbSize.width); 
       size.height = Math.max(0, props.thumbTouchSize.height - state.containerSize.height); 
       } else { 
       size.width = Math.max(0, props.thumbTouchSize.width - state.containerSize.width); 
       size.height = Math.max(0, props.thumbTouchSize.height - state.thumbSize.height); 
       } 
      } 

      return size; 
      }; 

      _getTouchOverflowStyle =() => { 
      var {width, height} = this._getTouchOverflowSize(); 

      var touchOverflowStyle = {}; 
      if (width !== undefined && height !== undefined) { 
       var verticalMargin = -height/2; 
       touchOverflowStyle.marginTop = verticalMargin; 
       touchOverflowStyle.marginBottom = verticalMargin; 

       var horizontalMargin = -width/2; 
       touchOverflowStyle.marginLeft = horizontalMargin; 
       touchOverflowStyle.marginRight = horizontalMargin; 
      } 

      if (this.props.debugTouchArea === true) { 
       touchOverflowStyle.backgroundColor = 'orange'; 
       touchOverflowStyle.opacity = 0.5; 
      } 

      return touchOverflowStyle; 
      }; 

      _thumbHitTest = (e: Object) => { 
      var nativeEvent = e.nativeEvent; 
      var thumbTouchRect = this._getThumbTouchRect(); 

      return thumbTouchRect.containsPoint(nativeEvent.locationX, nativeEvent.locationY); 
      }; 

      _getThumbTouchRect =() => { 
      var state = this.state; 
      var props = this.props; 
      var touchOverflowSize = this._getTouchOverflowSize(); 

      var rect = new Rect(
       0, 
       0, 
       props.thumbTouchSize.width, 
       state.containerSize.height 
      ); 

      if (this.props.orientation === 'horizontal') { 
       rect.x = touchOverflowSize.width/2 + this._getThumbStart(this._getCurrentValue()) + (state.thumbSize.width - props.thumbTouchSize.width)/2; 
       rect.y = touchOverflowSize.height/2 + (state.containerSize.height - props.thumbTouchSize.height)/2; 
      } else { 
       rect.x = touchOverflowSize.width/2 + (state.containerSize.width - props.thumbTouchSize.width)/2; 
       rect.y = touchOverflowSize.height/2 + this._getThumbStart(this._getCurrentValue()) + (state.thumbSize.height - props.thumbTouchSize.height)/2; 
      } 

      return rect; 
      }; 

      _renderDebugThumbTouchRect = (thumbStart) => { 
      var thumbTouchRect = this._getThumbTouchRect(); 

      var positionStyle = { 
       left: thumbTouchRect.x, 
       top: thumbTouchRect.y, 
       width: thumbTouchRect.width, 
       height: thumbTouchRect.height, 
       flex: 1, 
       flexDirection: 'column', 
       justifyContent: 'center' 
      }; 

      if (this.props.orientation === 'horizontal') { 
       positionStyle.left = thumbStart; 
      } else { 
       positionStyle.top = thumbStart; 
      } 
      return (
       <Animated.View 
       style={[defaultStyles.debugThumbTouchArea, positionStyle]} 
       pointerEvents='none' 
       /> 
      ); 
      }; 

      _renderThumbImage =() => { 
      var {thumbImage} = this.props; 

      if (!thumbImage) return; 


      return {thumbImage}; 
      }; 
     }; 


     var defaultStyles = StyleSheet.create({ 
      container: { 
      // height: 440, 
      justifyContent: 'center', 

      }, 
      track: { 
      height: TRACK_SIZE, 
      borderRadius: TRACK_SIZE/2, 

      }, 
      thumb: { 
      position: 'absolute', 
      width: THUMB_SIZE, 
      height: '100%', 
      borderRadius: THUMB_SIZE/2, 

      }, 
      thumbImgStyle: { 
      resizeMode: 'contain', 
      width: '100%', 
      height: '100%', 
      backgroundColor:'transparent' 
      }, 
      thumbImgStyleBg: { 
      resizeMode: 'contain', 
      width: '100%', 
      height: '100%', 
      backgroundColor:'transparent' 
      }, 
      trackImgStyle: { 
      resizeMode: 'contain', 
      flex: 1, 
      width: '100%', 
      height: '100%', 
      }, 
      touchArea: { 
      position: 'absolute', 
      backgroundColor: 'transparent', 
      top: '-40%', 
      left: 0, 
      right: 0, 
      bottom: '-40%', 
      }, 
      debugThumbTouchArea: { 
      position: 'absolute', 
      backgroundColor: 'green', 
      opacity: 0.5, 

      } 
     });` 

答えて

0
私は答えを見つけた

私は渡されたカスタムアニメーションでLayoutAnimationを使用して終了しかし、私が持っていた問題は、アニメーションとまったく関係がありませんでしたが、this.setState()をどのように扱うかということでした。私はちょうどsetStateを使用し、setTimeout()を使用して、アニメーションが実行されたときに状態が更新されたことを確認しました.100%から100%にアニメーション化されていました。幅を0%に設定し、アニメーション中は100%で0%ではなく100%に戻すことはできません。なぜ私はそれがthis.setStateとはるかに後に私のアニメーションのコードを実行しているとは何の効果もないとしていることを理解していないネイティブに反応するために十分な新しいです。

私はこれがあまりにも漠然としていたので、私の今後の質問にもっと明確にしてください。

関連する問題