繁体   English   中英

如何使我的 javascript 中的正弦波正常工作?

[英]How can I make my sine wave in javascript work properly?

我正在尝试在填充某种颜色的画布上制作正弦波 我成功地创建了波浪动画。 但是,我似乎无法正确填写。 您可以在下面的代码段中看到我的代码的工作方式

 const canvas = document.querySelector('canvas') const gui = new dat.GUI() const c = canvas.getContext('2d') canvas.width = innerWidth canvas.height = innerHeight const wave = { y: canvas.height / 2, length: 0.01, amplitude: 150, frequency: 0.01 } const strokeColor = { h: 200, s: 50, l: 50 } const backgroundColor = { r: 255, g: 50, b: 255, a: 1 } const waveFolder = gui.addFolder('wave') waveFolder.add(wave, 'y', 0, canvas.height) waveFolder.add(wave, 'length', -0.01, 0.01) waveFolder.add(wave, 'amplitude', -300, 300) waveFolder.add(wave, 'frequency', -0.01, 1) const strokeFolder = gui.addFolder('stroke') strokeFolder.add(strokeColor, 'h', 0, 255) strokeFolder.add(strokeColor, 's', 0, 100) strokeFolder.add(strokeColor, 'l', 0, 100) const backgroundFolder = gui.addFolder('background') backgroundFolder.add(backgroundColor, 'r', 0, 255) backgroundFolder.add(backgroundColor, 'g', 0, 255) backgroundFolder.add(backgroundColor, 'b', 0, 255) backgroundFolder.add(backgroundColor, 'a', 0, 1) let increment = 0 function drawSineWave() { c.fillStyle = `rgba(${backgroundColor.r},${backgroundColor.g},${backgroundColor.b},${backgroundColor.a})` c.clearRect(0, 0, canvas.width, canvas.height) increment++ c.beginPath() c.moveTo(0, canvas.height / 2) c.lineTo(0, canvas.height / 2) c.lineTo(0, canvas.height) c.lineTo(canvas.width, canvas.height) c.lineTo(canvas.width, canvas.height / 2) c.moveTo(0, canvas.height / 2) for (let i = 0; i < canvas.width; i++) { c.lineTo(i, wave.y + Math.sin(increment / 50) * wave.amplitude * Math.sin(i * wave.length + wave.frequency)) } c.lineTo(canvas.width, canvas.height / 2) c.strokeStyle = `hsl(${strokeColor.h},${strokeColor.s}%,${strokeColor.l}%)` c.fill() c.stroke() } function animate() { requestAnimationFrame(animate) drawSineWave() } animate()
 * { margin: 0; padding: 0; box-sizing: border-box; } canvas { width: 100%; height: 100%; }
 <head> <title>Waves</title> <link rel="stylesheet" href="index.css"> </head> <body> <canvas></canvas> <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.7/dat.gui.min.js"></script> <script src="index.js"></script> </body>

我希望波的外观是这样的:

适当的填充正弦波

有人可以帮我达到预期的结果吗? 谢谢!

你只需要按照正确的顺序绘制下半部分

结果是

function drawSineWave() {
  c.fillStyle = `rgba(${backgroundColor.r},${backgroundColor.g},${backgroundColor.b},${backgroundColor.a})`
  c.clearRect(0, 0, canvas.width, canvas.height)
  increment++
  c.beginPath()
  for (let i = 0; i < canvas.width; i++) {
    c.lineTo(i, wave.y + Math.sin(increment / 50) * wave.amplitude * Math.sin(i * wave.length + wave.frequency))
  }
  c.strokeStyle = `hsl(${strokeColor.h},${strokeColor.s}%,${strokeColor.l}%)`
  c.stroke();  // draw stroke along wave top only

  c.lineTo(canvas.width, canvas.height) // bottom right
  c.lineTo(0, canvas.height)            // bottom left
  c.fill()
}

例子

我玩了一下。

 const canvas = document.querySelector('canvas') const gui = new dat.GUI() const c = canvas.getContext('2d') canvas.width = innerWidth canvas.height = innerHeight const wave = { offset: canvas.height/2, speed: 1, amplitude:50, frequency: 1, } var disFreq = wave.frequency, disFreqChase = 0; var disAmp = wave.amplitude, disAmpChase = 0; var disY = wave.offset, disYChase = 0; var disSp = wave.speed, disSpChase = 0; const strokeColor = {width: 2, h:200,s:50, l:50 } const backgroundColor = { r:255, g:50, b:255, a:1 } const waveFolder = gui.addFolder('wave') waveFolder.add(wave,'speed',-1,1); // peeks per second waveFolder.add(wave,'offset',0,canvas.height); waveFolder.add(wave,'amplitude',-100,100) waveFolder.add(wave,'frequency',0.5,10); // frequency also defines wave length // Value is fraction of canvas width const strokeFolder = gui.addFolder('stroke') strokeFolder.add(strokeColor,'width',0,18) strokeFolder.add(strokeColor,'h',0,255) strokeFolder.add(strokeColor,'s',0,100) strokeFolder.add(strokeColor,'l',0,100) const backgroundFolder = gui.addFolder('background') backgroundFolder.add(backgroundColor,'r',0,255) backgroundFolder.add(backgroundColor,'g',0,255) backgroundFolder.add(backgroundColor,'b',0,255) backgroundFolder.add(backgroundColor,'a',0,1) let increment = 0 function drawSineWave() { // smooth out changes disFreq += disFreqChase = (disFreqChase += (wave.frequency - disFreq)*0.2)* 0.2; disAmp += disAmpChase = (disAmpChase += (wave.amplitude - disAmp) * 0.2) * 0.2; disY += disYChase = (disYChase += (wave.offset - disY) * 0.2) * 0.2; disSp += disSpChase = (disSpChase += (wave.speed - disSp) * 0.2) * 0.2; c.lineWidth = strokeColor.width; c.fillStyle = `rgba(${backgroundColor.r},${backgroundColor.g},${backgroundColor.b},${backgroundColor.a})` c.clearRect(0,0,canvas.width,canvas.height) //increment++ increment += (disSp / 60); c.beginPath() const h = canvas.height; for (let i=0;i<canvas.width;i++){ const a = (disAmp / 200) * h; const x = ((i / canvas.width) * disFreq) % 1 + increment; const p = x * Math.PI * 2; c.lineTo(i, disY + Math.sin(p)*a); } c.strokeStyle = `hsl(${strokeColor.h},${strokeColor.s}%,${strokeColor.l}%)` c.stroke() c.lineTo(canvas.width,canvas.height) c.lineTo(0, canvas.height) c.fill() } function animate(){ requestAnimationFrame(animate) drawSineWave() } animate()
 *{ margin: 0; padding: 0; box-sizing: border-box; } canvas{ width: 100%; height: 100%; }
 <canvas></canvas> <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.7/dat.gui.min.js"></script> <script src="index.js"></script> </body>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM