stream path animation v4
update input items styling add ipc event handler for message add send-message ipc handler add audio to send-message ipc remove extra JSON stringify statement for audio message add render bug fix for add contacts
This commit is contained in:
parent
52f6893c50
commit
1627e07964
23 changed files with 450 additions and 295 deletions
148
src/core/UI/input/audio/useStreamVisualizer.ts
Normal file
148
src/core/UI/input/audio/useStreamVisualizer.ts
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
import { Ref } from '@/types/vueRef/index';
|
||||
import AnimeFunc from "@/types/animejs/index";
|
||||
import { inject, ref } from "vue";
|
||||
|
||||
interface AudioPath {
|
||||
identifier: string;
|
||||
d: string;
|
||||
offset: number;
|
||||
color: string;
|
||||
draw: boolean;
|
||||
}
|
||||
export default function useStreamVisualizer(draw: Ref<boolean>) {
|
||||
const audioContext = new AudioContext();
|
||||
console.log('audi sample rate', audioContext.sampleRate)
|
||||
const analyzer = audioContext.createAnalyser();
|
||||
analyzer.fftSize = 128;
|
||||
const bufferLength = analyzer.frequencyBinCount;
|
||||
const dataArray = new Uint8Array(bufferLength);
|
||||
|
||||
// imports animejs safely
|
||||
let anime: AnimeFunc;
|
||||
const animeInject: AnimeFunc | undefined = inject("animejs");
|
||||
if (animeInject) anime = animeInject;
|
||||
|
||||
/*
|
||||
* Draws MediaStream audioTrack as 'AudioPath' objects
|
||||
*/
|
||||
function drawStreamAs(paths: Ref<any>, bubbleWidth: Ref<number>): void {
|
||||
const xInitial = ref(10);
|
||||
const maxAmplitude = 15;
|
||||
const maxBubbleWidth = 300;
|
||||
|
||||
function shiftPathStream(pathList: NodeList): void {
|
||||
for (let i = 0; i < pathList.length; i++) {
|
||||
const stick = pathList[i] as HTMLElement;
|
||||
const computedQuery = window.getComputedStyle(stick);
|
||||
const matrix = new WebKitCSSMatrix(computedQuery.webkitTransform);
|
||||
anime({
|
||||
targets: stick,
|
||||
translateX: [matrix.m41, matrix.m41 - 6],
|
||||
})
|
||||
}
|
||||
}
|
||||
function filterPathList(pathList: NodeList) {
|
||||
for (let i = 0; i < pathList.length; i++) {
|
||||
const stick = pathList[i] as HTMLElement;
|
||||
const computedQuery = window.getComputedStyle(stick);
|
||||
const matrix = new WebKitCSSMatrix(computedQuery.webkitTransform);
|
||||
if (matrix.m41 < 10) {
|
||||
anime({
|
||||
targets: stick,
|
||||
opacity: 0,
|
||||
duration: 0
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function drawNewPath(): void {
|
||||
|
||||
const calculateAmplitude = (): number => (
|
||||
Math.min(Math.max(
|
||||
(dataArray.reduce((a, b) => a + b) / bufferLength) * 0.45,
|
||||
0), maxAmplitude)
|
||||
)
|
||||
|
||||
const createAudioPath = (a: number, o: number): AudioPath => ({
|
||||
identifier: `path_${o}`,
|
||||
d: `M0,25v${-a}`,
|
||||
offset: o,
|
||||
color: '#000',
|
||||
draw: true
|
||||
})
|
||||
|
||||
const amplitude = calculateAmplitude();
|
||||
const p: AudioPath = createAudioPath(amplitude, xInitial.value);
|
||||
paths.value.push(p);
|
||||
}
|
||||
|
||||
paths.value = [];
|
||||
function drawPathStream(): void {
|
||||
|
||||
let streamPath;
|
||||
if (!draw.value) {
|
||||
window.clearTimeout(streamPath)
|
||||
return;
|
||||
}
|
||||
setTimeout(() => {
|
||||
requestAnimationFrame(drawPathStream);
|
||||
analyzer.getByteFrequencyData(dataArray);
|
||||
}, 1000 / 10)
|
||||
|
||||
/*
|
||||
* To Draw pathStream
|
||||
*/
|
||||
if (bubbleWidth.value === 300) {
|
||||
xInitial.value = bubbleWidth.value - 10;
|
||||
} else if (bubbleWidth.value > 20) {
|
||||
xInitial.value = bubbleWidth.value;
|
||||
} else {
|
||||
xInitial.value +=3;
|
||||
}
|
||||
streamPath = setTimeout(async () => {
|
||||
const pathList = document.querySelectorAll('path');
|
||||
filterPathList(pathList);
|
||||
drawNewPath();
|
||||
if (bubbleWidth.value === maxBubbleWidth) {
|
||||
shiftPathStream(pathList);
|
||||
}
|
||||
}, 200)
|
||||
}
|
||||
drawPathStream();
|
||||
}
|
||||
|
||||
function increaseBubbleWidth(bubbleRef: Ref<number>) {
|
||||
const increase = () => {
|
||||
|
||||
let animation;
|
||||
if (!draw.value) {
|
||||
if (animation) {
|
||||
cancelAnimationFrame(animation)
|
||||
}
|
||||
return;
|
||||
}
|
||||
animation = requestAnimationFrame(increase);
|
||||
if (bubbleRef.value < 300) {
|
||||
bubbleRef.value++;
|
||||
}
|
||||
}
|
||||
increase();
|
||||
}
|
||||
|
||||
function expandBubble(bubbleWidth: Ref<number>) {
|
||||
increaseBubbleWidth(bubbleWidth);
|
||||
}
|
||||
|
||||
function visualizeStreamAsPaths(s: MediaStream, paths: Ref<any>, bubbleWidth: Ref<number>): void {
|
||||
const source = audioContext.createMediaStreamSource(s);
|
||||
source.connect(analyzer);
|
||||
drawStreamAs(paths, bubbleWidth);
|
||||
}
|
||||
|
||||
return {
|
||||
visualizeStreamAsPaths,
|
||||
expandBubble
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue