我创建了一个正弦波绘图网络应用程序。这是我的代码:
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 + "° (" + (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° (0.000 rad)</span>
Amplitude控件和Wavelength控件可以正常工作,但Phase控件可以正常工作。我希望它是这样的:180度相位90度相位
但是,它表现得很怪异,您可以使用Phase滑块自己看到它。我犯了什么错误?
借助于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 + "° (" + (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° (0.000 rad)</span>