React-Native使用react-native-community/art实现水波纹、音频波动效果_星三火的博客-程序员宝宝

技术标签: 音频动效  波形图  react native  typescript  javascript  RN开发  

 效果如下,可以通过改变volume值实现动态效果

效果展示

 

贴组件代码,复制就能用:

【依赖package.json】 

"@react-native-community/art": "^1.1.2",
"react-native": "0.61.4",

【组件代码DancingLine.tsx】 

import React, { PureComponent, } from 'react';

import {
  StyleSheet,
  View,
  Dimensions,
} from 'react-native';
import style from '../../constants/style';
import { Surface, Shape, Path } from '@react-native-community/art'
import _ from 'lodash';
import { observer } from 'mobx-react';
import { observable } from 'mobx';
const ScreenWidth = Dimensions.get('window').width;

const styles = StyleSheet.create({

})


interface IProps {
  volume: number,
  numberOfWaves?: number,
  waveColor?: string,
  waveWidth: number,
  waveHeight: number,
}


@observer
class DancingLine extends PureComponent<IProps> {

  // 传入波动值[0, 0.5]
  private volume: any = 0
  // 条数
  private numberOfWaves = 5
  // 颜色
  private waveColor: any = '#ff0000'
  // 主波线宽
  private mainWaveWidth: any = 2.0
  // 辅波线宽
  private decorativeWavesWidth: any = 1.0
  // 闲置时即最小振幅
  private idleAmplitude: any = 0.02

  private frequency: any = 1.2
  private density: any = 1.0

  private phaseShift: any = -0.25

  private phase: any = 0

  private amplitude: any = 1.0

  private waveHeight: any = 200
  private waveWidth: any = ScreenWidth
  private waveMid: any = this.waveWidth / 2.0
  private maxAmplitude: any = this.waveHeight - 4.0

  @observable
  private paths: any = []

  constructor(props: IProps) {
    super(props)
    const { numberOfWaves, waveColor, waveWidth, waveHeight } = this.props
    numberOfWaves && (this.numberOfWaves = numberOfWaves)
    waveColor && (this.waveColor = waveColor)
    waveWidth && (this.waveWidth = waveWidth)
    waveHeight && (this.waveHeight = waveHeight)
  }


  _updateVolume = () => {
    this.volume = this.props.volume
    this.phase += this.phaseShift;
    this.amplitude = Math.max(this.volume, this.idleAmplitude);

    // 绘制线条
    var paths = []
    for (let i = 0; i < this.numberOfWaves; i++) {

      let progress = 1.0 - i / this.numberOfWaves
      let normedAmplitude = (1.5 * progress - 0.5) * this.amplitude

      var speedStr = ''
      for (let x = 0; x < this.waveWidth + this.density; x += this.density) {
        // 使顶峰保持在视图中央
        let scaling = - Math.pow(x / this.waveMid - 1, 2) + 1
        let y = scaling * this.maxAmplitude * normedAmplitude * Math.sin(2 * Math.PI * (x / this.waveWidth) * this.frequency + this.phase) + (this.waveHeight * 0.5)

        if (x == 0) {
          speedStr += `M${x} ${y}`
        } else {
          speedStr += `L${x} ${y}`
        }
      }
      const path = new Path(speedStr);
      paths.push(path)
    }
    this.paths = paths
  }

  componentDidMount = () => {
    this._updateVolume()
  }

  shouldComponentUpdate(nextProps: IProps): boolean {
    if (this.props.volume == nextProps.volume) {
      return false
    }
    this._updateVolume()
    return true
  }

  render() {
    return <View style={
   { width: this.waveWidth, height: this.waveHeight }}>
      {_.map(this.paths, (path, index: number) => {
        let strokeColor = ''
        if (index == 0) {
          strokeColor = this.waveColor
        } else {
          // 渐变浅色
          let progress = 1.0 - index / this.numberOfWaves
          let multiplier = Math.min(1.0, (progress / 3.0 * 2.0) + (1.0 / 3.0))
          if (multiplier == 0) {
            multiplier = 1
          }
          let num = parseInt(255 * multiplier + '')
          strokeColor = this.waveColor + num.toString(16)
        }

        let strokeWidth = index == 0 ? this.mainWaveWidth : this.decorativeWavesWidth;

        return <View style={
   { height: this.waveHeight, width: this.waveWidth, position: 'absolute', }}>
          <Surface height={this.waveHeight} width={this.waveWidth}>
            <Shape d={path} stroke={strokeColor} strokeWidth={strokeWidth} />
          </Surface>
        </View>
      })
      }
    </View >
  }
}

export default DancingLine

【使用】

import DancingLine from "../../../components/view/DancingLine";
@observable
volume: number = 0
componentDidMount(): void {
   setInterval(() => {
       this.volume = Math.random() * 0.5
   }, 100)
}
<DancingLine volume={this.volume} waveWidth={Dimensions.get('window').width} waveHeight={300}/>

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/NB_Token/article/details/110121673

智能推荐

Python pika, TypeError: exchange_declare() got an unexpected keyword argument 'type' 问题修复_weixin_30621919的博客-程序员宝宝

网上很多写法都是 type='fanout' 这样的。(这里是基于python=3.6版本, pika=0.13.0 版本)credentials = pika.PlainCredentials('guest', 'guest')connection = pika.BlockingConnection(pika.ConnectionParameters('127.0.0.1',567...

JS -- 如何判断数组中是否有重复的元素_仁王_雅治的博客-程序员宝宝

var sfIds = [];for(var i=0;i&lt;softwareInfo.length;i++){ sfIds.push(softwareInfo[i].softwareName[2]);}var repeatSfIdFlag = _self.isRepeat(sfIds);if(repeatSfIdFlag){ _self.$message({ s...

java8之Optional(六)_闻道☞的博客-程序员宝宝

Optional 类Optional&amp;lt;T&amp;gt; 类(java.util.Optional) 是一个容器类,代表一个值存在或不存在,原来用 null 表示一个值不存在,现在 Optional 可以更好的表达这个概念。并且可以避免空指针异常。常用方法:Optional.of(T t) : 创建一个 Optional 实例Optional.empty() : 创建一个空的 Optional 实...

(step8.2.9)hdu 2147(kiki's game)_黄俊东的博客-程序员宝宝

题目大意:输入2个整数n,m。分别表示棋盘的高和宽。首先将棋子放置在(1,m)这个位置上。每次只能往左 或者 下 或者左下方向移动一个。。。当移动到左下角的时候,对方就输了解题思路:1)档当n 和 m都为奇数的时候,kiki就输了。否则kiki都能赢代码如下:/* * 2147_1.cpp * * Created on: 2013年9月1日 *

asp.net mvc 各版本区别_ailiao3220的博客-程序员宝宝

MVC 6ASP.NET MVC and Web API has been merged in to one.Dependency injection is inbuilt and part of MVC.Side by side - deploy the runtime and framework with your applicationEverything pack...

随便推点

BZOJ1861 [Zjoi2006]Book 书架_weixin_30505225的博客-程序员宝宝

Splay维护操作。学习了一个很好的remove操作。 1 #include&lt;bits/stdc++.h&gt; 2 using namespace std; 3 const int N=8e4+5; 4 const int inf=1e9; 5 int fa[N],c[N][2],size[N],pos[N],a[N],v[N],n,m,rt; ...

GIS及空间统计相关基础整理【持续整理中】_待鸣的博客-程序员宝宝

前言这几天有幸结识到了一位专家,沟通的过程中学习到了一些新的方向,今天专家提供了一些论文,大部分都是GIS相关的,GIS的话以前就了解过,不过一直处于很模糊的认知,把所有论文都看完之后深感自己才学疏浅,为后期更好地沟通和交流,特意将空间统计学相关的理论和知识学了一遍,给自己加强印象的同时,也为后续项目参与人员提供一点帮助。东西写的比较碎,本文目的主要是帮助了解概念,深入的话有很多资料,一起学习吧!GIS先了解一下 GIS (Geographic Information System)是什么:地理

mysql数据库,使用substring函数截取字符串返回空问题_半糖少冰九九的博客-程序员宝宝_mysql substr 返回空

在MySql中使用substring(字段名,起始位置,字符串长度)函数时需要注意, 起始位置必须从1开始,如果0开始不能获取到数据。如果是oracle中起始位置从0或1开始都可,函数:substr(字段名,起始位置,字符串长度)...

【经典】进化树问题_a710128的博客-程序员宝宝

这个问题很经典啊。。想了我一下午题目描述树可以用来表示物种之间的进化关系。一棵“进化树”是一个带边权的树,其叶节点表示一个物种,两个叶节点之间的距离表示两个物种的差异。现在,一个重要的问题是,根据物种之间的距离,重构相应的“进化树”。    令N={1..n},用一个N上的矩阵M来定义树T。其中,矩阵M满足:对于任意的i,j,k,有M[i,j]+M[j,k]    1.叶节

在nginx上简单部署flask项目_Little Prince的博客-程序员宝宝

1、将项目写好,cmd模式进入项目目录,将所需的依赖导入requirements.txt文件,用于在linux中进行依赖安装命令:导出所有的依赖$ pip freeze &gt; requirements.txt恢复$ pip install -r requirements.txt将项目通过winscp传入linux下的nginx的www下回复依赖$ pip install -...

什么是数据资产?_许胜棋的博客-程序员宝宝_数据资产

在说什么是数据资产之前,我们需要先明确什么是数据?数据就是数值,可以是信息在某个时点的结果值,如数字、文本、图像、声音等都可以是数据,那么数据就是信息的载体,以数据库、文档、图形、视频等形式存在,这些都是企业的资源,数据类型的资源。资产是可以带来收益的那部分资源,那么数据资产就是企业拥有能给企业带来收益的数据资源,那么数据资产的属性特征有:数据资产是具有价值的,也就是有价值的数据资源才可以是数据资产。没价值的数据资源,通过数据采集、整理、汇总等加工处理后形成具有可以为企业带来直接或间接经济价值的数据

推荐文章

热门文章

相关标签