I need to plot the sine function using html, css and javascript and be able to dynamically change its amplitude by sliding slider. So I made a slider that gives me a value and I plotted basic sine function. My biggest struggle is in replacing no. 5 in math expression in the first function by variable, that gets the value from slider. Any ideas how to make it work? Thanks for your responses.
<!DOCTYPE html>
<html>
<script type="text/javascript">
function fun1(x) {return Math.sin(x)*5;}
function draw() {
var canvas = document.getElementById("canvas");
if (null==canvas || !canvas.getContext) return;
var axes={}, ctx=canvas.getContext("2d");
axes.x0 = .5 + .5*canvas.width; // x0 pixels from left to x=0
axes.y0 = .5 + .5*canvas.height; // y0 pixels from top to y=0
axes.scale = 40; // 40 pixels from x=0 to x=1
axes.doNegativeX = true;
showAxes(ctx,axes);
funGraph(ctx,axes,fun1,"rgb(11,153,11)",1);
}
function funGraph (ctx,axes,func,color,thick) {
var xx, yy, dx=4, x0=axes.x0, y0=axes.y0, scale=axes.scale;
var iMax = Math.round((ctx.canvas.width-x0)/dx);
var iMin = axes.doNegativeX ? Math.round(-x0/dx) : 0;
ctx.beginPath();
ctx.lineWidth = thick;
ctx.strokeStyle = color;
for (var i=iMin;i<=iMax;i++) {
xx = dx*i; yy = scale*func(xx/scale);
if (i==iMin) ctx.moveTo(x0+xx,y0-yy);
else ctx.lineTo(x0+xx,y0-yy);
}
ctx.stroke();
}
function showAxes(ctx,axes) {
var x0=axes.x0, w=ctx.canvas.width;
var y0=axes.y0, h=ctx.canvas.height;
var xmin = axes.doNegativeX ? 0 : x0;
ctx.beginPath();
ctx.strokeStyle = "rgb(128,128,128)";
ctx.moveTo(xmin,y0); ctx.lineTo(w,y0); // X axis
ctx.moveTo(x0,0); ctx.lineTo(x0,h); // Y axis
ctx.stroke();
}
</script>
<style>
#slidecontainer {
width: 50%;
}
.slider {
-webkit-appearance: slider-vertical;
width: 100%;
height: 25px;
background: grey;
outline: none;
opacity: 0.7;
-webkit-transition: .2s;
transition: opacity .2s;
}
.slider:hover {
opacity: 1;
}
.slider::-webkit-slider-thumb {
-webkit-appearance: slider-vertical;
appearance: none;
width: 25px;
height: 25px;
background: blue;
cursor: pointer;
}
.slider::-moz-range-thumb {
width: 25px;
height: 25px;
background: #4CAF50;
cursor: pointer;
}
html{
margin-left: 25%;
margin-right: 25%;
}
</style>
<body onload="draw()">
<h2>Select your amplitude</h2>
<div id="slidecontainer">
<input type="range" min="-10" max="10" value="0" class="slider" id="myRange">
<p>Amplitude: <span id="demo"></span></p>
</div>
<canvas id="canvas" width="500%" height="200%"></canvas>
<script>
var slider = document.getElementById("myRange");
var a = document.getElementById("demo");
a.innerHTML = slider.value;
slider.oninput = function() {
a.innerHTML = this.value;
}
</script>
</body>
</html>
You use 5 as a fixed value, so I replaced it with a global variable named global_var. Every time the slider changes, this value is updated and your canvas is refreshed.
My two minor changes:
var global_var = 5;
function fun1(x) {return Math.sin(x)*global_var;}
and
slider.oninput = function() {
a.innerHTML = this.value;
global_var = this.value;
//reset canvas
document.getElementById("canvas").getContext("2d").clearRect(0, 0, canvas.width, canvas.height);
//draw again
draw();
}
Working example follows:
<!DOCTYPE html>
<html>
<script type="text/javascript">
var global_var = 5;
function fun1(x) {return Math.sin(x)*global_var;}
function draw() {
var canvas = document.getElementById("canvas");
if (null==canvas || !canvas.getContext) return;
var axes={}, ctx=canvas.getContext("2d");
axes.x0 = .5 + .5*canvas.width; // x0 pixels from left to x=0
axes.y0 = .5 + .5*canvas.height; // y0 pixels from top to y=0
axes.scale = 40; // 40 pixels from x=0 to x=1
axes.doNegativeX = true;
showAxes(ctx,axes);
funGraph(ctx,axes,fun1,"rgb(11,153,11)",1);
}
function funGraph (ctx,axes,func,color,thick) {
var xx, yy, dx=4, x0=axes.x0, y0=axes.y0, scale=axes.scale;
var iMax = Math.round((ctx.canvas.width-x0)/dx);
var iMin = axes.doNegativeX ? Math.round(-x0/dx) : 0;
ctx.beginPath();
ctx.lineWidth = thick;
ctx.strokeStyle = color;
for (var i=iMin;i<=iMax;i++) {
xx = dx*i; yy = scale*func(xx/scale);
if (i==iMin) ctx.moveTo(x0+xx,y0-yy);
else ctx.lineTo(x0+xx,y0-yy);
}
ctx.stroke();
}
function showAxes(ctx,axes) {
var x0=axes.x0, w=ctx.canvas.width;
var y0=axes.y0, h=ctx.canvas.height;
var xmin = axes.doNegativeX ? 0 : x0;
ctx.beginPath();
ctx.strokeStyle = "rgb(128,128,128)";
ctx.moveTo(xmin,y0); ctx.lineTo(w,y0); // X axis
ctx.moveTo(x0,0); ctx.lineTo(x0,h); // Y axis
ctx.stroke();
}
</script>
<style>
#slidecontainer {
width: 50%;
}
.slider {
-webkit-appearance: slider-vertical;
width: 100%;
height: 25px;
background: grey;
outline: none;
opacity: 0.7;
-webkit-transition: .2s;
transition: opacity .2s;
}
.slider:hover {
opacity: 1;
}
.slider::-webkit-slider-thumb {
-webkit-appearance: slider-vertical;
appearance: none;
width: 25px;
height: 25px;
background: blue;
cursor: pointer;
}
.slider::-moz-range-thumb {
width: 25px;
height: 25px;
background: #4CAF50;
cursor: pointer;
}
html{
margin-left: 25%;
margin-right: 25%;
}
</style>
<body onload="draw()">
<h2>Select your amplitude</h2>
<div id="slidecontainer">
<input type="range" min="-10" max="10" value="0" class="slider" id="myRange">
<p>Amplitude: <span id="demo"></span></p>
</div>
<canvas id="canvas" width="500%" height="500%"></canvas>
<script>
var slider = document.getElementById("myRange");
var a = document.getElementById("demo");
a.innerHTML = slider.value;
slider.oninput = function() {
a.innerHTML = this.value;
global_var = this.value;
//reset
document.getElementById("canvas").getContext("2d").clearRect(0, 0, canvas.width, canvas.height);
//draw again
draw();
}
</script>
</body>
</html>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With