react-native抽奖转盘制作




一的代码

import React, { Component } from 'react'
import { View, TouchableWithoutFeedback, Animated, Easing } from 'react-native'
import styled from 'styled-components'
import { pxw, pxh } from '../px'
import { Overlay } from 'react-native-elements'

export default class Turntable2 extends Component {
  state = {
    index: 0,
    span: 50,
    visible: false,
    rotate: new Animated.Value(0),
    inputRange: 1
  }

  render() {
    const { index, visible, rotate, inputRange } = this.state
    return (
      <Container>
        <Center style={{ elevation: 5 }}>
          <Card>
            <InnerCard bgc={index === 5 ? '#000' : '#faa'}>
              <Text bottom='45px' right='30px'>5</Text>
            </InnerCard>
            <InnerCard bgc={index === 6 ? '#000' : '#faa'} rotate='-40deg' lateX={pxw(8) + 'px'}>
              <Text rotate='45deg' bottom='100px' right='50px'>6</Text>
            </InnerCard>
          </Card>
          <Card>
            <InnerCard bgc={index === 7 ? '#000' : '#faa'}>
              <Text bottom='83px' right='40px'>7</Text>
            </InnerCard>
            <InnerCard bgc={index === 8 ? '#000' : '#faa'} rotate='40deg' lateX={pxw(9) + 'px'}>
              <Text rotate='-45deg' bottom='30px' right='60px'>8</Text>
            </InnerCard>
          </Card>
          <Card>
            <InnerCard bgc={index === 4 ? '#000' : '#faa'}>
              <Text bottom='90px' right='30px'>4</Text>
            </InnerCard>
            <InnerCard bgc={index === 3 ? '#000' : '#faa'} rotate='40deg' lateX={pxw(9) + 'px'}>
              <Text rotate='-45deg' bottom='40px' right='55px'>3</Text>
            </InnerCard>
          </Card>
          <Card>
            <InnerCard bgc={index === 2 ? '#000' : '#faa'}>
              <Text bottom='57px' right='30px'>2</Text>
            </InnerCard>
            <InnerCard bgc={index === 1 ? '#000' : '#faa'} rotate='-40deg' lateX={pxw(8) + 'px'}>
              <Text rotate='45deg' bottom='110px' right='50px'>1</Text>
            </InnerCard>
          </Card>
          <TouchableWithoutFeedback onPress={this.begin}>
            <ClickRound>
              <Text size='25px' position='relative'>CLICK</Text>
              <AnimatedZhenContainer style={{
                transform: [{
                  rotate: rotate.interpolate({
                    inputRange: [0, 1, 2, 3, 4, 5, 6, 7,8,16],
                    outputRange: ['0deg', '45deg', '90deg', '135deg', '180deg', '225deg', '270deg', '315deg','360deg', '720deg']
                  })
                }]
              }}>
                <Zhen bgc='transparent' />
                <Zhen />
              </AnimatedZhenContainer>
            </ClickRound>
          </TouchableWithoutFeedback>
        </Center>
        <Overlay
          onBackdropPress={() => {
            this.setState({ visible: !this.state.visible, index: 0 })}
            }
          backdropStyle={{ backgroundColor: 'transparent' }}
          overlayStyle={{ backgroundColor: 'rgba(0,0,0,0.6)', elevation: 0, width: pxw(90), height: pxw(50), justifyContent: 'center' }}
          isVisible={visible}>
          <View>
            <Text size='50px' position='relative'>恭喜</Text>
            <Text size='50px' position='relative'>{index}号奖励</Text>
          </View>
        </Overlay>
      </Container>
    )
  }
  begin = () => {
    const resultNum = Math.floor(1 + Math.random() * 8) - 0.3;
    Animated.timing(this.state.rotate,{
      toValue: 16,
      duration: 5000,
      easing: Easing.back(),
      useNativeDriver: false
    }).start(() => {
      Animated.timing(this.state.rotate,{
        toValue: 0,
        duration: 0,
        easing: Easing.linear(),
        useNativeDriver: false
      }).start()
      Animated.timing(this.state.rotate,{
        toValue: resultNum,
        duration: 3000,
        easing: Easing.linear(),
        useNativeDriver: false
      }).start(() => {
        this.setState({index: Math.floor(resultNum) + 1})
        setTimeout(()=>{
          this.setState({visible: true})
        },700)
      })
    })
  }
}
const ZhenContainer = styled.View`
  width: ${pxw(60)}px;
  height: 4px;
  flex-direction: row;
  position: absolute;
  /* transform: rotate(30deg) */
`
const AnimatedZhenContainer = Animated.createAnimatedComponent(ZhenContainer)
const Zhen = styled.View`
  flex: 1;
  background-color: ${props => props.bgc || '#9f9'};
`
const Text = styled.Text`
  font-weight: bold;
  font-size: ${props => props.size || '30px'};
  color: ${props => props.color || '#fff'};
  text-align: center;
  position: ${props => props.position || 'absolute'};
  bottom: ${props => props.bottom || '0px'};
  right: ${props => props.right || '0px'};
  transform: rotate(${props => props.rotate || '0deg'});
`

const ClickRound = styled.View`
  position: absolute;
  background-color: #000;
  width: ${pxw(30)}px;
  height: ${pxw(30)}px;
  border-radius: ${pxw(30)}px;
  top: ${pxw(30)}px;
  left: ${pxw(30)}px;
  justify-content: center;
  align-items: center
`

const Card = styled.View`
  width: 50%;
  height: 50%;
  background-color: ${props => props.bgc || '#faa'};
  flex-direction: row;
  overflow: hidden;
`
const InnerCard = styled(Card)`
  width: auto;
  height: auto;
  flex: 1;
  transform: rotate(${props => props.rotate || '0deg'}) translateX(${props => props.lateX || '0px'}) scale(2)
`

const Center = styled.View`
  background-color: #fff;
  width: ${pxw(90)}px;
  height: ${pxw(90)}px;
  flex-direction: row;
  flex-wrap: wrap;
  border-radius: ${pxw(90)}px;
  overflow: hidden
`

const Container = styled.View`
  justify-content: center;
  align-items: center;
  min-height: 100%;
  background-color: #fffae5
`

二,代码

import React, { Component } from 'react'
import { View, TouchableWithoutFeedback, Modal } from 'react-native'
import styled from 'styled-components'
import { pxw, pxh } from '../px'
import {Overlay } from 'react-native-elements'

export default class Turntable extends Component {
  state = {
    index: 0,
    span: 50,
    visible: false
  }

  render () {
    const { index, visible } = this.state
    return (
      <Container>
        <Center style={{ elevation: 5 }}>
          <Card>
            <InnerCard bgc={index === 1 ? '#000' : '#faa'}>
              <Text bottom='45px' right='30px'>1</Text>
            </InnerCard>
            <InnerCard bgc={index === 2 ? '#000' : '#00f'} rotate='-40deg' lateX={pxw(8) + 'px'}>
              <Text rotate='45deg' bottom='100px' right='50px'>2</Text>
            </InnerCard>
          </Card>
          <Card>
            <InnerCard bgc={index === 3 ? '#000' : '#f00'}>
              <Text bottom='83px' right='40px'>3</Text>
            </InnerCard>
            <InnerCard bgc={index === 4 ? '#000' : '#0ff'} rotate='40deg' lateX={pxw(9) + 'px'}>
              <Text rotate='-45deg' bottom='30px' right='60px'>4</Text>
            </InnerCard>
          </Card>
          <Card>
            <InnerCard bgc={index === 8 ? '#000' : '#0fa'}>
              <Text bottom='90px' right='30px'>8</Text>
            </InnerCard>
            <InnerCard bgc={index === 7 ? '#000' : '#a5f'} rotate='40deg' lateX={pxw(9) + 'px'}>
              <Text rotate='-45deg' bottom='40px' right='55px'>7</Text>
            </InnerCard>
          </Card>
          <Card>
            <InnerCard bgc={index === 6 ? '#000' : '#971'}>
              <Text bottom='57px' right='30px'>6</Text>
            </InnerCard>
            <InnerCard bgc={index === 5 ? '#000' : '#f0f'} rotate='-40deg' lateX={pxw(8) + 'px'}>
              <Text rotate='45deg' bottom='110px' right='50px'>5</Text>
            </InnerCard>
          </Card>
          <TouchableWithoutFeedback onPress={this.begin}>
            <ClickRound>
              <Text position='relative'>CLICK</Text>
            </ClickRound>
          </TouchableWithoutFeedback>
        </Center>
        <Overlay
          onBackdropPress={()=>this.setState({visible: !this.state.visible})}
          backdropStyle={{ backgroundColor: 'transparent' }}
          overlayStyle={{ backgroundColor: 'rgba(0,0,0,0.6)', elevation: 0,width: pxw(90),height: pxw(50),justifyContent: 'center' }}
          isVisible={visible}>
          <View>
            <Text size='50px' position='relative'>恭喜</Text>
            <Text size='50px' position='relative'>{index}号奖励</Text>
          </View>
        </Overlay>
      </Container>
    )
  }
  begin = () => {
    const resultNum = parseInt(30 + Math.random() * 10);
    let temp = 0;
    let that = this;
    let time;
    setTimeout(function innerFn () {
      that.setState({index: that.state.index >7 ? 1 : that.state.index + 1 })
      temp++
      time = setTimeout(innerFn,that.state.span)
      if(temp === resultNum) {
        clearTimeout(time)
        time = null
        that.setState({span: 100},()=>{
          setTimeout(()=>{
            that.setState({visible: true})
          },1000)
        })
      }
      if(resultNum - temp < 10){
        that.addSpan()
      }
    },that.state.span)
  }
  addSpan = () => {
    this.setState({span: this.state.span + 100})
  }
}

const Text = styled.Text`
  font-weight: bold;
  font-size: ${props => props.size || '30px'};
  color: ${props => props.color || '#fff'};
  text-align: center;
  position: ${props => props.position || 'absolute'};
  bottom: ${props => props.bottom || '0px'};
  right: ${props => props.right || '0px'};
  transform: rotate(${props => props.rotate || '0deg'});
`

const ClickRound = styled.View`
  position: absolute;
  background-color: #000;
  width: ${pxw(30)}px;
  height: ${pxw(30)}px;
  border-radius: ${pxw(30)}px;
  top: ${pxw(30)}px;
  left: ${pxw(30)}px;
  justify-content: center
`

const Card = styled.View`
  width: 50%;
  height: 50%;
  background-color: ${props => props.bgc || '#faa'};
  flex-direction: row;
  overflow: hidden;
`
const InnerCard = styled(Card)`
  width: auto;
  height: auto;
  flex: 1;
  transform: rotate(${props => props.rotate || '0deg'}) translateX(${props => props.lateX || '0px'}) scale(2)
`

const Center = styled.View`
  background-color: #fff;
  width: ${pxw(90)}px;
  height: ${pxw(90)}px;
  flex-direction: row;
  flex-wrap: wrap;
  border-radius: ${pxw(90)}px;
  overflow: hidden
`

const Container = styled.View`
  justify-content: center;
  align-items: center;
  min-height: 100%;
  background-color: #fffae5
`

你可能感兴趣的:(react-native,react,native)