React-Native使用react-native-community/art实现水波纹、音频波动效果

2023-11-19

 效果如下,可以通过改变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}/>

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

React-Native使用react-native-community/art实现水波纹、音频波动效果 的相关文章

随机推荐

  • PE文件结构详解(完整篇)

    一 基本概念 PE Portable Execute 文件是Windows下可执行文件的总称 常见的有DLL EXE OCX SYS等 事实上 一个文件是否是PE文件与其扩展名无关 PE文件可以是任何扩展名 那Windows是怎么区分可执行
  • Vue 中使用 Echarts5.0 的一些问题(vue-cli 下开发)

    问题 最新版的 Echarts5 0 使用 import echarts from echarts 导入 会发现导出的 echarts 是 undefined 的情况 无法正常使用 解决方案一 新版本有问题就用旧版本咯 卸载 Echarts
  • Python采集股票行情排行榜数据~帮帮友善的朋友

    嗨害大家好鸭 我是爱摸鱼的芝士 开发环境 解释器版本 python 3 8 代码编辑器 pycharm 2021 2 股票涨幅缩略界面 导入模块 import requests import json import csv python学习
  • Gparted的安装使用,

    安装的方法 在Ubuntu下 sudo apt get install gparted 或者进入ubutun系统商店搜索parted 进行安装 菜单上的位置是 系统 gt 系统管理 gt Gnome分区管理器 Gparted支持动态分区 不
  • 构建前端之光:JavaScript插件的研发艺术

    前言 在前端开发的宇宙中 星星是网页 而照亮这个宇宙的 是我们前端开发者手中的JavaScript插件 插件就像乐高积木 可以将我们的代码块组装成复杂而精美的页面 本文将引导你走进JavaScript插件的世界 探讨如何开发 测试和发布你的
  • cmd 激活anaconda的python运行环境

    cmd 激活anaconda的python运行环境 使用cmd 打开Anaconda 的python环境 输入activate 环境名 弹出activate不是内部或外部命令 解决办法 1 将Anaconda下的路径添加到系统变量 比如我的
  • 高通平台Linux kernel死机解题心得

    1 前言 1 1 目的 能够结合知识背景 借助相关调试工具 使用一般分析手段分析 定位解决项目过程中遇到的死机类系统稳定性问题 提升工作效率 持续积累 拓宽知识深度和广度 1 2 死机 指系统发生致命性异常导致主动或者被动进入系统完全不可用
  • UML类图小结

    类与类之间的关系 1 关联关系 关联 Association 关系是类与类之间最常用的一种关系 它是一种结构化关系 用于表示一类对象与另一类对象之间有联系 如汽车和轮胎 师傅和徒弟 班级和学生等等 图1 关联关系实例 1 双向关联 默认情况
  • auto_ptr 代码及缺陷

    uto ptr是C 标准库里的类 它接受一个类型形参的模板 为动态分配的对象提供异常安全 其实 它的核心思想是 用一个对象存储需要被自动释放的资源 然后依靠对象的析构函数来释放资源 这是 More Effective C 中的解释 下面给出
  • 《机器学习实战》第四章 Python3代码-(亲自修改测试可成功运行)

    由于Peter Harrington所著的这本 机器学习实战 中的官方代码是Python2版本的且有一些勘误 使用Python3的朋友运行起来会有很多问题 所以我将自己在学习过程中修改好的Python3版本代码分享给大家 以供大家交流学习
  • 统计学三大分布(卡方、t、F)即相应概率密度图的R语言实现

    三大统计分布 1 2 chi 2 2分布 设随机变量 X 1
  • Thinking in Java

    Thinking in Java Java编程思想 学习总结心得 一 前序 学习java也已经有大约两年时间 但大多数断断续续 零散没有系统学习 这次经多方推荐购买了一本java学习必读书籍 Thinking in Java 学习之余将书中
  • python3 [入门基础实战] 爬虫入门之智联招聘的学习(一)

    老实说 懵逼啊 这次爬取的是智联招聘上的求职数据 虽然没有仔细正确核对一下数据是否具有重复性 随机抽查了些 数据大部分还是能对上来的 这次爬取的智联招聘上的数据90页 每页60条 主要抓取的是android开发工程的数据 抓取的数据为全国的
  • 行业权威来揭秘,商用PC为什么首选12代酷睿

    第12代酷睿处理器可以提供更卓越的性能 凭借架构先进性让商用台式机和笔记本电脑为用户带来更好的体验 帮助企业和员工效率倍增 作者 九月 来源 PConline 想要让办公效率进一步提升 一台强大的PC设备是必不可少的生产力和内容创作工具 而
  • SQL Server如何建立表关系

    SQL Server怎么建立关系表 用教师表和学生表举例 两表建立关系之前 要检查连接的条件满足否 比如学生表里的外键 教师ID 要和教师表里的主键 教师ID 的数据类型相同 也就是建立关系的条件数据类型要相同 确认条件满足之后开始建立关系
  • 对象式单片机外部模块驱动编写详解——DAC8552为例

    对象式单片机外部模块驱动编写详解 DAC8552为例 对象式驱动原理 DAC8552基本介绍 DAC8552驱动抽象 源码文件及其解释 参考资料 具体的代码和例程请参照以下GitHub仓库 记得给我star哦 https github co
  • 区块链能提供有效的身份管理?

    随着身份盗窃和数据泄露在世界各地越来越多的情况下 身份验证是一个主要问题 对访问数据的人进行身份验证实际上是他们要求的 每天 数以百万计的人在网上进行不同的活动 从研究一个学术话题 到购买新的项目 到在社交媒体平台上发表评论 甚至进行不同的
  • /etc/init.d

    etc init d目录在Linux系统中可是大名鼎鼎 它只负责一件事情 但却涉及到全系统 它包含系统中各种服务的start stop脚本 从acpid到x11 common 其重要性可见一斑 init d 初始化脚本称之为System V
  • 如何生成序号_合并单元格自动添加序号,还在手动输入就out了,学会三组函数公式一秒搞定...

    相信许多同学在用Excel表格登记各类数据的时候 为了规范表格我们经常会用到序号来进行数据标记 许多朋友在更新序号的时候 基本都是手动输入1 2 3等等 然后手动往下拖动 但是这样数据量比较大的时候 就会比较麻烦 而且如果数据是有合并单元格
  • React-Native使用react-native-community/art实现水波纹、音频波动效果

    效果如下 可以通过改变volume值实现动态效果 贴组件代码 复制就能用 依赖package json react native community art 1 1 2 react native 0 61 4 组件代码DancingLine