react-native-导航

@react-native-community/art波浪动画

2020-09-01  本文已影响0人  蒲小帅丶

yarn add @react-native-community/art


GIF.gif
/**
  * desc:
  * author:
  * date: 
  */
import React, {PropTypes} from 'react';
import {
    StyleSheet,
    View,
    Text,
    Image,Dimensions
} from 'react-native';
import {Surface, Path, LinearGradient,Shape} from '@react-native-community/art'
import {commonStyle} from "../styles/commonStyle";
const {width,height}=Dimensions.get("window")

export default class WaveView extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            surfaceWidth:this.props.surfaceWidth,
            surfaceHeight:this.props.surfaceHeight,
            //a,b是进行数据范围的一个限定
            a:1.5,
            b:0,
            increase:false
        }
    }

    shouldComponentUpdate() {
        return true
    }
   componentDidMount() {
        this.intervalTimer=setInterval(()=>{
            let a=this.state.a
            let b=this.state.b
            let increase=this.state.increase
            if(increase){
                a+=0.01
            }else {
                a-=0.01
            }
            if(a<=1){
                increase=true
            }
            if(a>=1.5){
                increase=false
            }
            //b的数据一直在加
            b+=0.1
            this.setState({
                a:a,
                b:b,
                increase:increase
            })
        },80)
   }
   componentWillUnmount() {
        this.intervalTimer&&clearInterval(this.intervalTimer)
   }
   //绘制渐变的背景
    artBackGround(){
        const w=this.state.surfaceWidth
        const h=this.state.surfaceHeight
        const pathBase=new Path()
            .moveTo(0,0) // 改变起点为 0,5 。默认为0,0
            .lineTo(w,0) // 目标点
            .lineTo(w,h) // 目标点
            .lineTo(0,h) // 目标点
            .close();
        let colors = [ commonStyle.white,commonStyle.white ];
        let linerarGradient=new LinearGradient(colors,0,0,90,280)
        return <View style={{ backgroundColor: 'argb(0,0,0,0.0)' }}>
            <Surface width={this.state.surfaceWidth} height={this.state.surfaceHeight} >
                <Shape d={pathBase} fill={linerarGradient}/>
                {this.wave(this.state.surfaceHeight-20,'rgba(123,174,255,0.4)')}
                {this.wave1(this.state.surfaceHeight-20,'rgba(123,174,255,0.5)')}
                {this.wave2(this.state.surfaceHeight-20,'rgba(123,174,255,0.6)')}
                {this.wave3(this.state.surfaceHeight-20,'rgba(123,174,255,0.7)')}
            </Surface>
        </View>

    }
    wave(startY,f1){
        //获取a,b值
        const a=this.state.a
        const b = this.state.b
        const w = this.state.surfaceWidth
        const h = this.state.surfaceHeight
        //定义起点
        const pathBase=new Path()
            .moveTo(0,startY)
        //循环遍历绘制点
        // 正弦曲线公式: y = A sin(Bx + C) + D
        // A 控制振幅,A 值越大,波峰和波谷越大,A 值越小,波峰和波谷越小;
        // B 值会影响周期,B 值越大,那么周期越短,B 值越小,周期越长。
        // C 值会影响图像左右移动,C 值为正数,图像右移,C 值为负数,图像左移。
        // D 值控制上下移动。
        //w有几个68,然后x持续增大
        for (let i = 0; i < w/68; i+=0.1) {
            let x=i*70
            //a控制增幅,限定在了10到15   乘了10之间
            let y=a*Math.sin(i+b)*10+startY
            pathBase.lineTo(x,y)
        }
        //最后封闭起来
        pathBase.lineTo(w,h-36)
        pathBase.lineTo(0,h-36)
        pathBase.close()
        return <Shape d={pathBase} fill={f1}/>
    }
    wave1(startY,fl){
        const a = this.state.a
        const b = this.state.b
        const w = this.state.surfaceWidth
        const h = this.state.surfaceHeight
        const pathBase = new Path()
            .moveTo(0,startY) // 改变起点为 0,5 。默认为0,0
        for( let i = 0; i <= w/68; i += 0.2 ){
            let x = i * 70;
            let y = a * Math.cos( i*1.3 + b ) * 10 + startY;
            pathBase.lineTo( x, y );
        }
        pathBase.lineTo(w,h-36) // 目标点
        pathBase.lineTo(0, h-36);
        pathBase.close();
        return <Shape d={pathBase} fill={fl}/>
    }
    wave2(startY,fl){
        const a = this.state.a
        const b = this.state.b
        const w = this.state.surfaceWidth
        const h = this.state.surfaceHeight
        const pathBase = new Path()
            .moveTo(0,startY) // 改变起点为 0,5 。默认为0,0
        for( let i = 0; i <= w/78; i += 0.2){
            let x = i * 80;
            let y = a * Math.sin( i*1.5 + b ) * 10 + startY;
            pathBase.lineTo( x, y );
        }
        pathBase.lineTo(w,h-36) // 目标点
        pathBase.lineTo(0, h-36);
        pathBase.close();
        return <Shape d={pathBase} fill={fl}/>
    }
    wave3(startY,fl){
        const a = this.state.a
        const b = this.state.b
        const w = this.state.surfaceWidth
        const h = this.state.surfaceHeight
        const pathBase = new Path()
            .moveTo(0,startY) // 改变起点为 0,5 。默认为0,0
        for( let i = 0; i <= w/88; i += 0.2){
            let x = i * 90;
            let y = a * Math.sin( i*1.6 + b ) * 10 + startY;
            pathBase.lineTo( x, y );
        }
        pathBase.lineTo(w,h-36) // 目标点
        pathBase.lineTo(0, h-36);
        pathBase.close();
        return <Shape d={pathBase} fill={fl}/>
    }

    render() {
        return (
            <View>
                {this.artBackGround()}

            </View>
        );
    }
}
WaveView.defaultProps={
    surfaceWidth:width,
    surfaceHeight:100,
}

const styles = StyleSheet.create({});

参考链接波浪动画

上一篇下一篇

猜你喜欢

热点阅读