I’m in the process of building a nice javascript class to display, play, and download audio files created dynamically from scripts on the page.
Javascript Class
class WaveDisplay {
constructor(width,height,name,caption,data) {
this.width = width;
this.height = height;
this.imageheight=height*.8*.98;
this.imagewidth=width*.98;
this.name=name;
this.caption = caption;
this.data = data;
}
update(data,caption) {
this.data=data;
this.caption=caption
}
draw(){
var last=0;
var c=document.getElementById("WD"+this.name);
var ctx=c.getContext("2d");
var hh=c.height*.45;
ctx.strokeStyle="#FFFFFF";
var yval=hh;
ctx.beginPath();
ctx.moveTo(0,hh);
ctx.stroke();
var pos=0;
var len=this.data.count;
for (var i=0;i<c.width;i++)
{
pos=i/c.width*this.data.count;
yval=hh-this.data[i]*hh;
ctx.beginPath();
ctx.moveTo(i-1,last);
ctx.lineTo(i,yval);
ctx.stroke();
last=yval;
}
ctx.lineTo(this.width,hh);
ctx.stroke();
}
html() {
var htmlstring="<div class=WDouter style=\"height:"+this.height+"px; width:"+this.width+"px;\">"+
"<div class=WDheader>"+
"<div class=WDheaderLeft>"+this.caption+"</div> <div class=WDheaderMid></div> <div class=WDheaderRight><img src='Play.png'><img src='Save.png'></div></div>"+
"<div class=WDbody>"+
"<div class=WDbodyInner> <canvas style=\"height:"+this.imageheight+"px; width:"+this.imagewidth+"px;\" id='WD"+this.name+"' src='Line.png' class=WDmain></canvas></div>"+
"</div>"+
"</div>";
return htmlstring;
}
}
Usage
To create a new wave display instance you must provide a length and width in pixels, the caption, name (used for the classes), and the initial data, which can be an empty list as long as you don’t draw it before calling update.
If you want width or height as percentage you’ll have to change the css yourself, it wouldn’t be hard, just set WDouter{width:100%;}
let demo = new WaveDisplay(600,200,"test","test",SineWave);
document.write(demo.html());
demo.draw();
To update the contents of the display at any point after initialisation simply call update with an array and new caption and then draw it.
demo.update(data,caption);
demo.draw();
<style>
.WDouter{
}
.WDheader{
width:100%;
height:64px;
}
.WDheaderLeft{
width:30%;
height:100%;
display:inline-block;
border:2px #A7C solid;
box-shadow:2px -2px 2px #A7C8, -2px -2px 2px #A7C8;
background:#555;
border-bottom:None;
vertical-align:top;
font-size:32px;
color:#000;
text-shadow:
1px -1px 2px #F9F,
-1px 1px 2px #C8D;
}
.WDheaderMid{
width:30%;
height:100%;
display:inline-block;
}
.WDheaderRight{
background:#555;
width:132px;
height:100%;
float:right;
display:inline-block;
vertical-align:top;
border:2px #A7C solid;
box-shadow:2px -2px 2px #A7C8;
border-bottom:None;
}
.WDmain{}
.WDbody{
width:100%;
height:80%;
background:#555;
border:2px #A7C solid;
padding:1%;
box-shadow:-2px -2px 6px #A7C8,
2px -2px 6px #A7C8,
-2px 2px 6px #A7C8,
2px 2px 6px #A7C8;
}
.WDbodyInner{
width:97.9%;
height:97.9%;
background:#000;
</style>
<script>
class WaveDisplay {
constructor(width,height,name,caption,data) {
this.width = width;
this.height = height;
this.imageheight=height*.8*.98;
this.imagewidth=width*.98;
this.name=name;
this.caption = caption;
this.data = data;
}
update(data,caption) {
this.data=data;
this.caption=caption
}
draw(){
var last=0;
var c=document.getElementById("WD"+this.name);
var ctx=c.getContext("2d");
var hh=c.height*.45;
ctx.strokeStyle="#FFFFFF";
var yval=hh;
ctx.beginPath();
ctx.moveTo(0,hh);
ctx.stroke();
var pos=0;
var len=this.data.count;
for (var i=0;i<c.width;i++)
{
pos=i/c.width*this.data.count;
yval=hh-this.data[i]*hh;
ctx.beginPath();
ctx.moveTo(i-1,last);
ctx.lineTo(i,yval);
ctx.stroke();
last=yval;
}
ctx.lineTo(this.width,hh);
ctx.stroke();
}
html() {
var htmlstring="<div class=WDouter style=\"height:"+this.height+"px; width:"+this.width+"px;\">"+
"<div class=WDheader>"+
"<div class=WDheaderLeft>"+this.caption+"</div> <div class=WDheaderMid></div> <div class=WDheaderRight><img src='Play.png'><img src='Save.png'></div></div>"+
"<div class=WDbody>"+
"<div class=WDbodyInner> <canvas style=\"height:"+this.imageheight+"px; width:"+this.imagewidth+"px;\" id='WD"+this.name+"' src='Line.png' class=WDmain></canvas></div>"+
"</div>"+
"</div>";
return htmlstring;
}
}
var SineWave=[];
for (var i=0;i<500;i++){
SineWave.push(Math.sin(i*Math.PI/50));
}
var SineWaveCubed=[];
for (var i=0;i<500;i++){
SineWaveCubed.push(Math.sin(i*Math.PI/50)**3);
}
var SineWaveTriple=[];
for (var i=0;i<500;i++){
SineWaveTriple.push((Math.sin(i*Math.PI/50)+Math.sin(.9+i*Math.PI/50)**5+Math.sin(.7+i*Math.PI/50)**3)*.3);
}
let test = new WaveDisplay(600,200,"sine","sine",SineWave);
let test2 = new WaveDisplay(600,200,"cubed","cubed",SineWaveCubed);
let test3 = new WaveDisplay(600,200,"triple","triple",SineWaveTriple);
document.write(test.html()+"<br><br><br>"+test2.html()+"<br><br><br>"+test3.html());
test.draw();
test2.draw();
test3.draw();
</script>
One thought on “Wave Display”