@react-native-community/art波浪動畫

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是進行數(shù)據(jù)范圍的一個限定
            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的數(shù)據(jù)一直在加
            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)
        //循環(huán)遍歷繪制點
        // 正弦曲線公式: y = A sin(Bx + C) + D
        // A 控制振幅,A 值越大,波峰和波谷越大,A 值越小,波峰和波谷越?。?        // B 值會影響周期,B 值越大,那么周期越短,B 值越小,周期越長。
        // C 值會影響圖像左右移動,C 值為正數(shù),圖像右移,C 值為負數(shù),圖像左移。
        // D 值控制上下移動。
        //w有幾個68,然后x持續(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({});

參考鏈接波浪動畫

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容