dev-audioprocessing/components/VueMeter.vue

95 lines
2.3 KiB
Vue
Executable File

<template>
<canvas
:width="width"
:height="height"
v-draw-meter="{ amp: dBVal, peak: dBPeakVal, clipSize: clipSize, showPeaks: showPeaks }"
/>
</template>
<script>
export default {
props: {
val: {
type: Number,
default: 0
},
peakVal: {
type: Number,
default: 0
},
refreshRate: {
type: Number,
default: 0.1
},
clipSize: {
type: Number,
default: 10
},
width: {
type: Number,
default: 20
},
height: {
type: Number,
default: 128
},
showPeaks: {
type: Boolean,
default: false
}
},
computed: {
dBVal: function () {
return 40 * Math.log10(this.val)+20;
},
dBPeakVal: function () {
return 40 * Math.log10(this.peakVal)+20;
}
},
watch: {
val: function (newVal, oldVal) {
if (this.showPeaks) {
var smoothingFactor = 50;
if (newVal > this.peakVal) {
this.peakVal = newVal;
} else {
this.peakVal =
newVal * (1 / smoothingFactor) +
this.peakVal * ((smoothingFactor - 1) / smoothingFactor);
}
}
}
},
directives: {
drawMeter: function (canvas, binding) {
var clipSize = binding.value.clipSize;
var showPeaks = binding.value.showPeaks;
var amp = binding.value.amp / 76 + 1;
var peak = binding.value.peak / 76 + 1;
var w = canvas.width;
var h = canvas.height;
var hInRange = h - clipSize;
var ctx = canvas.getContext("2d");
var gradient = ctx.createLinearGradient(0, 0, 0, h);
gradient.addColorStop(0, "red");
gradient.addColorStop(clipSize / h, "orange");
gradient.addColorStop(clipSize / h, "greenyellow");
gradient.addColorStop(1, "#009374");
ctx.clearRect(0, 0, w, h);
ctx.fillStyle = gradient;
ctx.fillRect(0, h - hInRange * amp, w, hInRange * amp);
if (showPeaks) {
if (peak >= 1) {
ctx.fillStyle = "red";
} else {
ctx.fillStyle = "greenyellow";
}
ctx.fillRect(0, Math.round(h - hInRange * peak), w, 1);
}
ctx.fillStyle = "white";
ctx.fillRect(0, clipSize, w, 1);
}
}
}
</script>