• Vue3.0+TSX+TS尝试绘制音乐频谱


    import { defineComponent, ref, reactive, onMounted } from 'vue'
    import './index.scss'
    export default defineComponent({
        name: 'Music',
        setup(props:Props, context) {
            const musicConfig:State = reactive({
                src: '/src/assets/tokyo.mp3'
            })
            const isPlay:Ref<boolean> = ref(true)
            const audioRef:Ref<any> = ref(null)
            const canvasRef:Ref<any> = ref(null)
            class Audio {
                constructor(audio,fftSize) {
                    this.audioCtx = new AudioContext()
                    this.analyser = this.audioCtx.createAnalyser()
                    this.audio = audio
                    this.audio.crossOrigin = 'anonymous'
                    this.audioSrc = this.audioCtx.createMediaElementSource(this.audio)
                    this.analyser.fftSize = fftSize
                    this.audioSrc.connect(this.analyser)
                    this.analyser.connect(this.audioCtx.destination)
                    this.freqArr = new Uint8Array(this.analyser.frequencyBinCount)
                }
            }
            class Canvas {
                constructor(canvas,audio,options={}) {
                    this.canvas = canvas
                    this.analyser = audio.analyser
                    this.freqArr = audio.freqArr
                    this.ctx = canvas.getContext('2d')
                    //方块的宽度
                    this.meterWidth = options.meterWidth || 5
                    //方块的间距
                    this.gap = options.gap || 2
                    //方块最小高度
                    this.minHeight = options.minHeight || 2
                    this.cwidth = this.canvas.width
                    this.cheight = this.canvas.height - 2
                    this.capHeight = 0
                    //根据宽度和间距计算出可以放多少个方块
                    this.meterNum = this.cwidth / (this.meterWidth + this.gap)
                }
                draw() {
                    let gradient = this.ctx.createLinearGradient(0, 0, 0, 300)
                    gradient.addColorStop(1, '#0f00f0')
                    gradient.addColorStop(0.5, '#ff0ff0')
                    gradient.addColorStop(0, '#f00f00')
                    this.ctx.fillStyle = gradient
                }
                render() {
                    const freqArr = new Uint8Array(this.analyser.frequencyBinCount)
                    this.analyser.getByteFrequencyData(freqArr)
                    //从频谱数据中每隔step均匀取出meterNum个数据.
                    const step = Math.round(freqArr.length / this.meterNum)
                    this.ctx.clearRect(0, 0, this.cwidth, this.cheight)
                    for (var i = 0; i < this.meterNum; i++) {
                        const value = freqArr[i * step]
                        //绘制
                        this.ctx.fillRect(i * (this.meterWidth + this.gap), this.cheight - value + this.capHeight, this.meterWidth, this.cheight || this.minHeight)
                    }
                    requestAnimationFrame(()=>{
                        this.render()
                    })
                }
            }
    
            onMounted(() => {
                const audio = audioRef.value
                const canvas = canvasRef.value
                //音频获取频谱部分
                const audioExp = new Audio(audio,512)
                const canvasExp = new Canvas(canvas,audioExp)
                canvasExp.draw()
                canvasExp.render()
            })
            return()=>(
                <>
                    <canvas id='canvas' ref={canvasRef} width="375" height="300"></canvas>
                    <audio id="audio" ref={audioRef} src={musicConfig.src} autoplay controls loop></audio>
                </>
            )
        }
    })
    

      

  • 相关阅读:
    HTML多媒体标记之字幕标记
    认识JS的基础对象,定义对象的方法
    JDBC-ODBC桥接器连接Access数据库
    使用JQuery制作幻灯片(轮播图)
    开博11天后的第一次随笔!
    Springboot配置MongoDB连接增加mongoplus支持
    云服务器部署集锦 阿里ESC+docker+mysql+Portainer+rabbitmq+mongo
    centos8安装docker
    vue cli的使用
    MyBatis Plus数组list存入数据库之TypeHanlder类转换器
  • 原文地址:https://www.cnblogs.com/BlueCc/p/14285681.html
Copyright © 2020-2023  润新知