Last active
December 20, 2020 16:32
-
-
Save highfiiv/e968afe54bc96c3a3e309a88b88153c6 to your computer and use it in GitHub Desktop.
Frequency eq band component for visualizing audio stream band data
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<p class="score"><span title="range">{{percent}}</span> / <span title="peaking">{{score}}</span></p> | |
<form class="range-form" [formGroup]="form" (keydown.enter)="$event.preventDefault()"> | |
<input-range formControlName="range"></input-range> | |
</form> | |
<div class="eqband" [ngStyle]="{'padding-top': peak+'px'}"></div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
:host { | |
position:relative; | |
min-width: 25px; | |
height: 255px; // frequencyBinCount is 0 - 255 | |
align-items: flex-end; | |
background-color: #868686; | |
// range defined gradient to define sensitivity zone | |
background: linear-gradient(rgba(253,92,99,1), rgba(144,255,0,1) 50%); | |
} | |
.eqband{ | |
position: relative; | |
width:calc(1vw); | |
height: 0px; | |
background: rgb(255, 255, 255); | |
} | |
.range-form{ | |
position:relative; | |
width:10px; | |
height: 255px; | |
} | |
input-range{ | |
position:absolute; | |
height: 255px; | |
} | |
.score{ | |
position:absolute; | |
top: -34px; | |
width:100%; | |
justify-content: center; | |
margin:0; | |
font-size: 12px; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Component, ElementRef, EventEmitter, forwardRef, Input, OnDestroy, OnInit, Output, Renderer2 } from '@angular/core'; | |
import { FormBuilder, FormGroup, NG_VALUE_ACCESSOR } from '@angular/forms'; | |
import { Subject } from 'rxjs'; | |
import { takeUntil } from 'rxjs/operators'; | |
import { BaseControlValueAccessor } from '@shared/utilities/BaseControlValueAccessor'; | |
@Component({ | |
selector: 'band', | |
templateUrl: './band.component.html', | |
styleUrls: ['./band.component.scss'], | |
providers: [{ | |
provide: NG_VALUE_ACCESSOR, | |
useExisting: forwardRef(() => BandComponent), | |
multi: true | |
}] | |
}) | |
export class BandComponent extends BaseControlValueAccessor<any> implements OnInit, OnDestroy { | |
private _ngUnsubscribe: Subject<void> = new Subject<void>(); | |
@Input() set dB(value: number) { | |
this.peak = value; | |
this.score = this.form.controls.range.value < value ? value - this.form.controls.range.value : 0; | |
} | |
@Input() id: number = 0; | |
@Output() senseVal = new EventEmitter<number>(); | |
public peak: number = 0; // public dB level | |
public percent: number = 50; // range value is what percentage of 0 - 255 | |
public score: number = 0; // dB peaks into the range value this much | |
public form = <FormGroup>this.fb.group({ | |
range: this.fb.control(null) | |
}); | |
constructor( | |
private fb: FormBuilder, | |
private renderer: Renderer2, | |
private elementRef: ElementRef | |
) { super(); } // required methods are within BaseControlValueAccessor | |
public ngOnInit(): void { | |
this.form.patchValue({ | |
range: 50 | |
}, | |
{ | |
emitEvent: false, | |
onlySelf: true | |
}); | |
this.form.controls['range'].valueChanges | |
.pipe( | |
takeUntil(this._ngUnsubscribe) | |
).subscribe((val: any) => { | |
this.percent = parseInt(((val / 255) * 100).toFixed()); | |
this.renderer.setStyle(this.elementRef.nativeElement, 'background-image', `linear-gradient(rgba(253,92,99,1), rgba(144,255,0,1) ${this.percent}%)`); | |
this.senseVal.emit(val); | |
}); | |
} | |
// init value | |
public writeValue(val: string): void { | |
this.value = val; | |
this.onChange(+this.value); // set the control/form value | |
} | |
public onInput(val: string): void { | |
this.value = val; | |
this.onChange(+this.value); // set the control/form value | |
} | |
public ngOnDestroy(): void { | |
this._ngUnsubscribe.next(); | |
this._ngUnsubscribe.complete(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { ControlValueAccessor } from '@angular/forms'; | |
export class BaseControlValueAccessor<T> implements ControlValueAccessor { | |
public disabled = false; | |
/** | |
* Call when value has changed programmatically | |
*/ | |
public onChange(newVal: T) { } | |
public onTouched(_?: any) { } | |
public value: T; | |
/** | |
* Model -> View changes | |
*/ | |
public writeValue(obj: T): void { this.value = obj; } | |
public registerOnChange(fn: any): void { this.onChange = fn; } | |
public registerOnTouched(fn: any): void { this.onTouched = fn; } | |
public setDisabledState?(isDisabled: boolean): void { this.disabled = isDisabled; } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment