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.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>