add bottom bound to message visualizer

This commit is contained in:
riqo 2021-02-15 16:24:33 -06:00
commit 2831c11de3
6 changed files with 66 additions and 106 deletions

View file

@ -19,8 +19,8 @@ export async function main() {
});
// Instantiate socket session with crimata-platorm.
// if (!socket) initSession();
// socket = true;
if (!socket) initSession();
socket = true;
// Begin audio stream.
// initRecorder();

View file

@ -4,13 +4,12 @@
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
:viewBox="scrollView"
id="test"
>
<g id="messageView" transform="translate(0, 5)">
<g id="messageView" transform="translate(0, 20)">
<g
v-for="(item, index) in renderArr"
:key="index"
class="messageList"
transform="translate(0, 25)"
preserverAspectRatio="none"
>
<transition
@ -31,7 +30,7 @@ import useMessageView from "./viewDetails/visualizer";
import useScrollView from "@/modules/scrollView";
import TextBubble from "@/components/textBubble/index.vue";
import { Message } from "@/types/message/index";
import { defineComponent, reactive, onMounted, onUnmounted } from "vue";
import { defineComponent, reactive, onMounted, onUnmounted, watch, ref, computed } from "vue";
import useMitt from "@/modules/mitt";
import { useIpc } from "@/modules/ipc";
@ -51,9 +50,9 @@ export default defineComponent({
emitter.on("animateSend", async (message) => {
try {
renderArr.push(message)
// await invoke(message);
// renderArr.push(data.value);
// renderArr.push(message)
await invoke(message);
renderArr.push(data.value);
} catch (e) {
console.log("No response. Do not render.");
}
@ -80,13 +79,3 @@ export default defineComponent({
},
});
</script>
<style lang="scss" scoped>
svg {
height: 1%;
overflow: hidden;
}
#messageRenderer {
margin: 0;
}
</style>

View file

@ -5,76 +5,47 @@ import { MessageAnimeFunc } from '@/types/message/index';
/**
* anime js animations used by message renderer
*/
export default function useMessageViewAnims(): {
shiftAnimate: MessageAnimeFunc;
stackAnimate: MessageAnimeFunc;
} {
export default function useMessageViewAnims() {
// imports animejs safely
let anime: AnimeFunc;
const animeInject: AnimeFunc | undefined = inject("animejs");
if (animeInject) anime = animeInject;
// shifts message list by a given value
function shiftList({ targetList, sv }: { targetList: NodeList | undefined; sv: number | undefined }) {
if (targetList) {
for (const element of targetList) {
const el = element.parentNode as HTMLElement;
anime({
targets: el,
transform: `translate(0 ${sv})`,
easing: "easeInOutQuad",
duration: 500,
});
}
}
}
// adds new message at the bottom of the list and shifts existing message list
const shiftAnimate: MessageAnimeFunc = (el, transform, shiftValue, targetList) => {
const shiftAnimate = (el: Element, transform: string, view: SVGGElement, viewTransform: string) => {
anime({
targets: el,
transform: transform.initialTranslate,
transform: transform,
easing: "easeInOutQuad",
duration: 500,
duration: 800,
begin: function() {
shiftList({
targetList,
sv: shiftValue
});
shiftView(view, viewTransform);
},
complete: function() {
anime({
targets: el,
transform: transform.finalTranslate,
easing: "easeInOutQuad",
duration: 500,
offset: 1000
});
}
});
}
// stacks message from top to bottom
const stackAnimate: MessageAnimeFunc = (el, transform) => {
const stackAnimate = (el: Element, transform: string) => {
anime({
targets: el,
transform: transform.initialTranslate,
transform: transform,
easing: "easeInOutQuad",
duration: 1000,
complete: function() {
anime({
targets: el,
transform: transform.finalTranslate,
easing: "easeInOutQuad",
duration: 500,
offset: 1000
});
}
});
}
// update message View bottom bound
const shiftView = (el: SVGGElement, transform: string) => {
anime({
targets: el,
transform: transform,
easing: "easeInOutQuad",
duration: 500,
});
}
return {
shiftAnimate,
stackAnimate
stackAnimate,
};
}

View file

@ -9,7 +9,7 @@ export default function useOffsetCalculator() {
let previousMessageHeight = 0;
const messagePadding = 15;
function calculateX(message: HTMLElement): void {
function calculateX(message: HTMLElement| SVGGElement): void {
const computedQuery = window.getComputedStyle(message);
const matrix = new WebKitCSSMatrix(computedQuery.webkitTransform);
xOffset.value = matrix.m41;

View file

@ -7,60 +7,62 @@ import { VueTransitionCallback } from '@/types/vue3/vueTransitionCallback/index'
import useMessageViewAnims from "./anime";
import useOffsetCalculator from './offsetCalculator';
export default function useMessageView(): {
beforeEnter: VueTransitionCallback;
enter: VueTransitionCallback;
afterEnter: VueTransitionCallback;
} {
// uses offsetCalculator logic and renderer animations
const wH = 500; // window Height
const vP = 10; // view padding
const mP = 15; // message padding
let mH: number; // message Height
let vH: number; // view Height
let vB: number; // view Bottom Bound
let message: HTMLElement | null;
let messageOffset = { x: 0, y: 0 };
let shift = false;
let beforeEnterVH: number;
let messageView: SVGGElement;
export default function useMessageView() {
const { calculateMessageOffsets } = useOffsetCalculator();
const { shiftAnimate, stackAnimate } = useMessageViewAnims();
const messagePadding = 15;
let messageList: NodeList;
let message: HTMLElement | null;
let messageOffset = { x: 0, y: 0 };
let shift = false;
let shiftOffset = 0;
// animates message item to 'enter' renderView
const animateMessage = (el: SVGGElement): void => {
const transform = {
initialTranslate: `translate(${messageOffset.x} ${messageOffset.y})`,
finalTranslate: `translate(${messageOffset.x} ${messageOffset.y})`
const elTransform = `translate(${messageOffset.x} ${messageOffset.y})`;
const viewTransform = `translate(0 ${-vB})`;
if (shift) {
shiftAnimate(el, elTransform, messageView, viewTransform);
} else {
stackAnimate(el, elTransform)
}
shift ? shiftAnimate(el, transform, shiftOffset, messageList) : stackAnimate(el, transform);
}
const beforeEnter: VueTransitionCallback = () => {
const queryResult = document.querySelectorAll(".messageList");
console.log(queryResult)
if (queryResult.length) messageList = queryResult;
// query DOM for messageView element
const messageViewQuery = document.querySelectorAll("#messageView");
messageView = messageViewQuery[0] as SVGGElement;
if (messageViewQuery){
beforeEnterVH = messageView.getBBox().height;
}
}
const enter: VueTransitionCallback = (el) => {
// query DOM for latest message as soon as it enters
// query DOM for latest message
if (el) {
message = document.getElementById(el.id);
}
}
const afterEnter: VueTransitionCallback = (el) => {
// get message positioning & shift state before animating
if (message) {
messageOffset = calculateMessageOffsets(message);
shift = messageOffset.y > 400 ? true : false;
}
const afterEnter: VueTransitionCallback = async (el) => {
if (message) messageOffset = calculateMessageOffsets(message);
if (el) {
if (shift) {
shiftOffset -= el.getBBox().height + messagePadding;
// if (messageOffset.y < 445) {
// shiftOffset -= 15;
// } else {
// shiftOffset -= el.getBBox().height + messagePadding;
// }
}
// calculate message & view heights, as well as view bottom bound
mH = el.getBoundingClientRect().height;
vH = mH + beforeEnterVH + mP;
vB = Math.abs(vH - wH) + vP;
shift = vH > wH ? true : false;
animateMessage(el);
}
}
@ -68,6 +70,6 @@ export default function useMessageView(): {
return {
beforeEnter,
enter,
afterEnter
afterEnter,
};
}

View file

@ -4,7 +4,6 @@
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
@click="emittMessage"
>
<MessageView />
<TextAudioInput />
@ -26,7 +25,6 @@ export default defineComponent({
const counter = ref(0);
const emittMessage = () => {
console.log('testing')
emitter.emit('animateSend', Messages[counter.value])
counter.value++;
}