yarn add @react-native-community/art
/**
* 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({});
参考链接波浪动画