rn自定义精美动画按钮组件

本文介绍了一个自定义动画按钮的实现,按钮的大小、文字、背景颜色及动画效果均可配置。使用React Native和styled-components,实现了两个小球在按钮上随机移动的动画效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

效果
在这里插入图片描述
在这里插入图片描述
所谓的自定义指的是自定义按钮的大小,文字内容,背景颜色,两个小球的颜色小球的大小根据按钮的宽高变化,小球运动的终点是一个随机数的一个区间
代码 用了styled-component (尝试在函数式组件里写动画,果然很勉强)

import React, { useState, useEffect } from 'react'
import { Animated, TouchableNativeFeedback } from 'react-native'
import styled from 'styled-components'
import { Title } from './index'

const AnimatedButton = ({ title, width, height, bgc, bigColor, smColor, onPress, size }) => {
  const [BigRoundX, setBigRoundX] = useState(new Animated.Value(0))
  const [BigRoundY, setBigRoundY] = useState(new Animated.Value(0))
  const [SmRoundX, setSmRoundX] = useState(new Animated.Value(-(100 + Math.random() * 200)))
  const [SmRoundY, setSmRoundY] = useState(new Animated.Value(-(Math.random() * 150)))

  function add () {
    const randomX = -(250 + (Math.random() * 100))
    const randomY = -(100 + (Math.random() * 100))
    const randomSmX = -(Math.random() * 50)
    const randomSmY = -(Math.random() * 50)
    Animated.timing(BigRoundX, { toValue: randomX, duration: 20000, useNativeDriver: false }).start()
    Animated.timing(BigRoundY, { toValue: randomY, duration: 20000, useNativeDriver: false }).start()
    Animated.timing(SmRoundX, { toValue: randomSmX, duration: 20000, useNativeDriver: false }).start()
    Animated.timing(SmRoundY, { toValue: randomSmY, duration: 20000, useNativeDriver: false }).start(() => reduce())
  }
  function reduce () {
    const randomX = (Math.random() * 50)
    const randomY = (Math.random() * 50)
    const randomSmX = -(200 + (Math.random() * 100))
    const randomSmY = -(100 + (Math.random() * 100))
    Animated.timing(BigRoundX, { toValue: randomX, duration: 20000, useNativeDriver: false }).start()
    Animated.timing(BigRoundY, { toValue: randomY, duration: 20000, useNativeDriver: false }).start()
    Animated.timing(SmRoundX, { toValue: randomSmX, duration: 20000, useNativeDriver: false }).start()
    Animated.timing(SmRoundY, { toValue: randomSmY, duration: 20000, useNativeDriver: false }).start(() => add())
  }
  useEffect(() => {
    add()
  })
  return (
    <TouchableNativeFeedback onPress={() => {
      if (!onPress) return
      onPress()
    }}>
      <Container bgc={bgc} width={width} height={height}>
        <Title shadow size={size || '40px'} style={{ elevation: 50 }}>{title}</Title>
        <AnimatedRound
          bgc={bigColor}
          style={{
            elevation: 10,
            transform: [
              { translateX: BigRoundX },
              { translateY: BigRoundY }
            ]
          }} />
        <AnimatedRound
          bgc={smColor || '#a5f'}
          style={{
            elevation: 40,
            transform: [
              { translateX: SmRoundX },
              { translateY: SmRoundY }
            ]
          }}
          width='20%' height='40%' />
      </Container>
    </TouchableNativeFeedback>
  )
}

export default AnimatedButton

const Round = styled.View`
  position: absolute;
  width: ${props => props.width || '60%'};
  height: ${props => props.height || '120%'};
  background-color: ${props => props.bgc || '#f77'};
  border-radius: 1000px;
  right: ${props => props.right || '-30%'};
  bottom: ${props => props.bottom || '-50%'};
  z-index: -1;
`
const AnimatedRound = Animated.createAnimatedComponent(Round)

const Container = styled.View`
  width: ${props => props.width || '300px'};
  height: ${props => props.height || '150px'};
  background-color: ${props => props.bgc || '#7f7'};
  border-radius: 10px;
  justify-content: center;
  align-items: center;
  overflow: hidden;
`

Title样式

export const Title = styled.Text`
  color: ${props => props.color || '#fffae5'};
  font-weight: bold;
  text-align: center;
  font-size: ${props => props.size || '25px'};
  text-shadow: ${props => props.shadow ? '0 0 2px #00f' : '0 0 0 #000'};
  text-transform: ${props => props.textT || 'uppercase'};
`

使用

<AnimatedButton title='default' />

<AnimatedButton
	title='Custom Title'
	width='200px'
	height='100px'
	bgc='#fffaaa'
	bigColor='#afa'
	smColor='#aaa'
/>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值