正弦波代码的相位控制出了什么问题?

问题描述 投票:4回答:1

我创建了一个正弦波绘图网络应用程序。这是我的代码:

const canvas = document.getElementById("canvas"),
  amplitude_slider = document.getElementById("amplitude_control"),
  wavelength_slider = document.getElementById("wavelength_control"),
  phase_slider = document.getElementById("phase_control"),
  amplitude_output = document.getElementById("amplitude_value"),
  wavelength_output = document.getElementById("wavelength_value"),
  phase_output = document.getElementById("phase_value"),
  radian_factor = Math.PI / 180;

var width,
  height,
  canvas_middle,
  context,
  amplitude = 20,
  wavelength = 0,
  phase = 0;

function init() {
  width = window.innerWidth - 4; //exclude 4 pixels for the border
  height = window.innerHeight - 4;
  canvas.width = width;
  canvas.height = height / 2;
  canvas_middle = height / 4;
  context = canvas.getContext("2d");
}

function draw() {
  context.clearRect(0, 0, width, height);
  context.beginPath();
  var ampl = amplitude / 100 * canvas_middle;
  context.moveTo(0, canvas_middle + ampl * Math.sin(radian_factor * phase * Math.pow(2, wavelength)));
  for (i = 1; i < width; i++) {
    context.lineTo(i, canvas_middle + ampl * Math.sin(radian_factor * (i + phase) * Math.pow(2, wavelength)));
  }
  context.stroke();
}
init();
draw();
window.addEventListener("resize", () => {
  init();
  draw();
});

amplitude_slider.addEventListener("input", () => {
  amplitude = amplitude_slider.value;
  amplitude_output.innerHTML = amplitude;
  draw();
});
wavelength_slider.addEventListener("input", () => {
  wavelength = wavelength_slider.value;
  wavelength_output.innerHTML = Math.pow(2, wavelength).toFixed(2);
  draw();
});
phase_slider.addEventListener("input", () => {
  phase = phase_slider.value;
  phase_output.innerHTML = phase + "&deg; (" + (radian_factor * phase).toFixed(3) + "rad)";
  draw();
});
* {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
  padding: 0;
  margin: 0;
}

canvas {
  border: 2px solid green;
  width: 100%;
  height: 50%;
}

input {
  width: 100%;
  margin-top: 2em;
  padding: 0 10px 0 10px;
}
<canvas id="canvas"></canvas>
<input type="range" id="amplitude_control" value="20" min="0" max="100" step="0.1"> Amplitude <span id="amplitude_value">20</span><br>
<input type="range" id="wavelength_control" value="0" min="-5" max="5" step="0.01"> Wavelength <span id="wavelength_value">4.00</span><br>
<input type="range" id="phase_control" value="0" min="0" max="360" step="0.1"> Phase <span id="phase_value">0&deg; (0.000 rad)</span>

Amplitude控件和Wavelength控件可以正常工作,但Phase控件可以正常工作。我希望它是这样的:enter image description here180度相位enter image description here90度相位

但是,它表现得很怪异,您可以使用Phase滑块自己看到它。我犯了什么错误?

javascript html html5-canvas sign
1个回答
0
投票

借助于Temmu's>]评论,我能够解决我的问题。在我的代码中,问题是phase_slider.value返回的值为string类型。使用该string类型值进行计算会导致问题。

我只需要通过使用parseInt()方法或通过在变量之前放置+符号将phase_slider.value

转换为数字。

这里是我的代码的更正版本:

const canvas = document.getElementById("canvas"),
  amplitude_slider = document.getElementById("amplitude_control"),
  wavelength_slider = document.getElementById("wavelength_control"),
  phase_slider = document.getElementById("phase_control"),
  amplitude_output = document.getElementById("amplitude_value"),
  wavelength_output = document.getElementById("wavelength_value"),
  phase_output = document.getElementById("phase_value"),
  radian_factor = Math.PI / 180;

var width,
  height,
  canvas_middle,
  context,
  amplitude = 20,
  wavelength = 0,
  phase = 0;

function init() {
  width = window.innerWidth - 4; //exclude 4 pixels for the border
  height = window.innerHeight - 4;
  canvas.width = width;
  canvas.height = height / 2;
  canvas_middle = height / 4;
  context = canvas.getContext("2d");
}

function draw() {
  context.clearRect(0, 0, width, height);
  context.beginPath();
  var ampl = amplitude / 100 * canvas_middle;
  context.moveTo(0, canvas_middle + ampl * Math.sin(radian_factor * phase * Math.pow(2, wavelength)));
  for (i = 1; i < width; i++) {
    context.lineTo(i, canvas_middle + ampl * Math.sin(radian_factor * (i + phase) * Math.pow(2, wavelength)));
  }
  context.stroke();
}
init();
draw();
window.addEventListener("resize", () => {
  init();
  draw();
});

amplitude_slider.addEventListener("input", () => {
  amplitude = amplitude_slider.value;
  amplitude_output.innerHTML = amplitude;
  draw();
});
wavelength_slider.addEventListener("input", () => {
  wavelength = wavelength_slider.value;
  wavelength_output.innerHTML = Math.pow(2, wavelength).toFixed(2);
  draw();
});
phase_slider.addEventListener("input", () => {
  phase = parseInt(phase_slider.value); //This is the corrected line
  phase_output.innerHTML = phase + "&deg; (" + (radian_factor * phase).toFixed(3) + "rad)";
  draw();
});
* {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
  padding: 0;
  margin: 0;
}

canvas {
  border: 2px solid green;
  width: 100%;
  height: 50%;
}

input {
  width: 100%;
  margin-top: 2em;
  padding: 0 10px 0 10px;
}
<canvas id="canvas"></canvas>
<input type="range" id="amplitude_control" value="20" min="0" max="100" step="0.1"> Amplitude <span id="amplitude_value">20</span><br>
<input type="range" id="wavelength_control" value="0" min="-5" max="5" step="0.01"> Wavelength <span id="wavelength_value">4.00</span><br>
<input type="range" id="phase_control" value="0" min="0" max="360" step="0.1"> Phase <span id="phase_value">0&deg; (0.000 rad)</span>
© www.soinside.com 2019 - 2024. All rights reserved.