/** * handles visualization of view messages through * vue transition callbacks and anime-js animations */ 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 { 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})` } 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; } const enter: VueTransitionCallback = (el) => { // query DOM for latest message as soon as it enters 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; } if (el) { if (shift) { shiftOffset -= el.getBBox().height + messagePadding; // if (messageOffset.y < 445) { // shiftOffset -= 15; // } else { // shiftOffset -= el.getBBox().height + messagePadding; // } } animateMessage(el); } } return { beforeEnter, enter, afterEnter }; }