canvas与傅里叶变换

    xiaoxiao2022-07-07  160

    canvas与傅里叶变换

    如果看了此文你还不懂傅里叶变换,那就过来掐死我吧【完整版】

    看到下面这幅图,我就想着用canvas来将它画出来。

    画圆

    function createDisc(r,color,x,y){ ctx.beginPath() ctx.arc(x||0,y||0,r,0,Math.PI*2,true) ctx.strokeStyle = color || '#00bcd4' ctx.stroke() }

    画线

    function createLine(d,rotate){ ctx.beginPath() ctx.moveTo(0,0) ctx.lineTo(d,0) ctx.stroke() }

    动画

    动画就是一直清空画布,然后重新绘制下一次的图像,不停的循环,就显示成了一个平面

    清空canavs

    canvas.width = 1000 canvas.height = 400 ctx.clearRect(0,0,canvas.width,canvas.height)

    调用window.requestAnimationFrame()来渲染动画,使用interval性能不好

    window.requestAnimationFrame(draw)

    dat.gui来调整圆的个数

    1、引入dat.gui

    <script type="text/javascript" src="https://cdn.bootcss.com/dat-gui/0.7.6/dat.gui.min.js"></script>

    2、定义controls参数

    var controls = new function () { this.discNum = 2; } var gui = new dat.GUI(); gui.add(controls, 'discNum', 1,4).step(1);

    完整代码

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>傅里叶变换</title> <script type="text/javascript" src="https://cdn.bootcss.com/dat-gui/0.7.6/dat.gui.min.js"></script> </head> <body> <canvas id="canvas"></canvas> <script type="text/javascript"> var canvas = document.getElementById('canvas') var ctx = canvas.getContext('2d') var raf; var running = false; var time = 0; var arr = [] var colorArr = ['#00bcd4', '#dd5866', '#335678', '#28a745'] var controls = new function () { this.discNum = 2; } var gui = new dat.GUI(); gui.add(controls, 'discNum', 1,4).step(1); function createDisc(r,color,x,y){ ctx.beginPath() ctx.arc(x||0,y||0,r,0,Math.PI*2,true) ctx.strokeStyle = color || '#00bcd4' ctx.stroke() } function createLine(d,rotate){ ctx.beginPath() ctx.moveTo(0,0) ctx.lineTo(d,0) ctx.stroke() } function draw(){ time -= Math.PI / 180 // 设置canvas大小 canvas.width = 1000 canvas.height = 400 ctx.clearRect(0,0,canvas.width,canvas.height) // 绘制左侧的圆 ctx.save() ctx.translate(150,150) var lastR = 50; for(var i=0;i< controls.discNum;i++){ if(i===0){ ctx.rotate( time ) }else{ ctx.translate(50 - (i-1)*15, 0) ctx.rotate( time*2 ) lastR = 50 - i*15 } createDisc(50 - i*15, colorArr[i]) createLine(50 - i*15, 2*time) } // 绘制圆上的线 ctx.translate(lastR,0) ctx.rotate( -( controls.discNum*2 - 1)*time ) ctx.beginPath() ctx.moveTo(0,0) var x = 150 for(var i=0;i< controls.discNum;i++){ x -= Math.cos((i*2+1)*time) * (50 - i*15) } ctx.lineTo(x,0) ctx.stroke() //绘制箭头 ctx.translate(x,0) ctx.save() ctx.rotate(-2.5) ctx.lineTo(5,0) ctx.stroke() ctx.restore() ctx.save() ctx.moveTo(0,0) ctx.rotate(2.5) ctx.lineTo(5,0) ctx.stroke() ctx.restore() // 记录频域 var arrY = 150 for(var i=0;i< controls.discNum;i++){ arrY += Math.sin((i*2+1)*time) * (50 - i*15) } arr.unshift(arrY) if(arr.length > 500) arr.pop() ctx.restore() ctx.strokeStyle = 'red' ctx.beginPath() ctx.moveTo(300,arrY) var arrX = 0; arr.forEach(v=>{ ctx.lineTo(300+arrX++, v) }) ctx.stroke() raf = window.requestAnimationFrame(draw) } raf = window.requestAnimationFrame(draw) canvas.addEventListener('click', function(){ running = !running running ? window.cancelAnimationFrame(raf) : raf = window.requestAnimationFrame(draw) }) </script> </body> </html>
    最新回复(0)