version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
+ @click="renderMessage"
>
<defs>
<linearGradient
<g
v-for="(item, index) in renderArr"
:key="index"
+ :id="index"
class="test"
transform="translate(0, 0)"
>
</template>
<script lang="ts">
-import { defineComponent, inject, onMounted, reactive } from "vue";
+import { defineComponent, ref, inject, onMounted, reactive } from "vue";
import MessageItem from './UIDetails/messageItem.vue';
import InputItem from "./UIDetails/inputItem.vue";
import Messages from "./UIDetails/messages";
setup() {
const renderArr: Message[] = reactive([])
const messages = Messages;
+ const count = ref(0);
const { beforeEnter, enter, msgOffset } = useUIindexAnims();
- function renderMsg(i: number): void {
- setTimeout(() => {
- renderArr.push(messages[i]);
- }, 2000);
- }
-
- function runAnim(): void {
- for (let i = 0; i < messages.length; i++) {
- renderMsg(i);
- }
- }
-
// TODO implemeant Undo animation
function leave() {
}
+ const renderMessage = () => {
+ if (count.value < messages.length) {
+ renderArr.push(messages[count.value])
+ count.value++;
+ return;
+ }
+ }
- onMounted(() => {
- runAnim();
- });
return {
+ renderMessage,
renderArr,
msgOffset,
beforeEnter,
-import { inject, onMounted } from "vue";
+import { inject, onMounted, ref } from "vue";
export default function useUIindexAnims() {
const anime: any = inject("animejs");
- const timeline = anime.timeline({ loop: true });
const msgOffset = {
x: 0,
y: 0
};
let winW: number;
let modifier: string;
- let msg: any;
- let cardsDiv: any;
+ let msg: HTMLElement | null;
let prevCardH = 0;
let totalHeight = 0;
- let messenger: any;
- let currentCard: Element;
+ let messenger: HTMLElement | null;
let renderList: NodeList;
+ let scrollAnim = false;
+ let scroll = 0;
onMounted(() => {
messenger = document.getElementById("messenger");
- winW = messenger.clientWidth;
+ if (messenger) {
+ winW = messenger.clientWidth;
+ }
});
- function getCardHeight(el: any) {
+ function getSVGElHeight(el: SVGGElement) {
const cardHeight = el.getBBox().height;
return cardHeight;
}
const cards = document.querySelectorAll(".test");
if (cards.length) {
renderList = cards;
- currentCard = cards.item(cards.length - 1);
for (const card of cards) {
- const height = getCardHeight(card);
+ const el = card as SVGGElement;
+ const height = getSVGElHeight(el);
totalHeight += height;
}
+ scrollAnim = totalHeight > 500 ? true : false;
}
}
async function beforeEnter(el: SVGGElement) {
modifier = el.className.baseVal.substring(0, 2);
- calculateAllCardsHeight();
+ if (!scrollAnim) calculateAllCardsHeight();
}
- async function stackAnimate(el: any, done: any) {
- const paddingLeft = 40;
- msg = await document.getElementById(el.id);
- const rect = msg.getBoundingClientRect();
- const msgW = rect.width;
- const msgH = rect.height;
- cardsDiv = document.getElementById("cardsDiv");
- const cdBox = cardsDiv.getBBox();
-
- if (prevCardH === 0) {
- msgOffset.y += cdBox.height;
- } else if (prevCardH > msgH) {
- // cardsDiv is offset by 17.5
- msgOffset.y += prevCardH + msgH / 2 + 17.5;
- } else {
- msgOffset.y += cdBox.height - 20;
+ function scrollOffset(l: NodeList, height: number) {
+ for (const card of l) {
+ const c = card.parentNode as HTMLElement;
+ anime({
+ targets: c,
+ transform: `translate(0 ${height})`,
+ easing: "easeInOutQuad",
+ duration: 500,
+ })
}
- prevCardH = msgH;
+ }
+
+ function scrollAnimate(el: SVGGElement) {
+ anime({
+ targets: el,
+ transform: `translate(${msgOffset.x} ${msgOffset.y})`,
+ easing: "easeInOutQuad",
+ duration: 500,
+ begin: function() {
+ scrollOffset(renderList, scroll);
+ },
+ complete: function() {
+ anime({
+ targets: el,
+ transform: `translate(${msgOffset.x} ${msgOffset.y + 5})`,
+ offset: 1000
+ });
+ }
+ });
+ }
+
+ function stackAnimate(el: SVGGElement) {
+ const translateUp = `translate(${msgOffset.x} ${msgOffset.y})`;
+ const translateDown = `translate(${msgOffset.x} ${msgOffset.y + 5})`;
+ anime({
+ targets: el,
+ transform: translateUp,
+ easing: "easeInOutQuad",
+ duration: 1000,
+ complete: function() {
+ anime({
+ targets: el,
+ transform: translateDown,
+ easing: "easeInOutQuad",
+ duration: 500,
+ offset: 1000
+ });
+ }
+ });
+ }
+
+ function addMessage(el: SVGGElement) {
+ scrollAnim ? scrollAnimate(el) : stackAnimate(el)
+ }
+ function setXoffset(messageWidth: number) {
+ const paddingLeft = 40;
switch (modifier) {
case "sf":
- msgOffset.x = winW - msgW;
+ msgOffset.x = winW - messageWidth;
break;
case "ai":
- msgOffset.x = (winW - msgW) / 2;
+ msgOffset.x = (winW - messageWidth) / 2;
break;
default:
msgOffset.x = paddingLeft;
}
-
- const translateUp = `translate(${msgOffset.x} ${msgOffset.y})`;
- const translateDown = `translate(${msgOffset.x} ${msgOffset.y + 5})`;
- timeline
- .add({
- targets: el,
- transform: translateUp,
- easing: "easeInOutQuad",
- duration: 1000
- })
- .add({
- targets: el,
- transform: translateDown,
- easing: "easeInOutQuad",
- duration: 500,
- offset: 1000
- });
- done;
-
}
- function OffsetMessage() {
- // TODO implement individual offset function
-
+ function setYoffset(messageHeight: number) {
+ if (prevCardH === 0) {
+ msgOffset.y += messageHeight;
+ } else {
+ msgOffset.y += prevCardH + messageHeight / 2 + 17.5;
+ }
+ prevCardH = messageHeight;
}
- function scrollOffset(l: NodeList) {
+ function calculateMessageOffsets(msg: any) {
+ const msgRect = msg.getBoundingClientRect();
+ if (scrollAnim) {
+ // update scroll
+ scroll -= msgRect.height + msgRect.height / 2;
+ }
+ setXoffset(msgRect.width)
+ setYoffset(msgRect.height)
}
- async function scrollAnimate(el: any, done: any) {
- // get incoming card height
- const height = getCardHeight(el);
- scrollOffset(renderList)
- }
- async function enter(el: SVGGElement, done: any) {
- if (totalHeight < 500) {
- stackAnimate(el, done)
- } else {
- scrollAnimate(el, done);
- }
+ async function enter(el: SVGGElement) {
+ msg = await document.getElementById(el.id);
+ calculateMessageOffsets(msg)
+ addMessage(el);
}
+
return {
beforeEnter,
enter,
- msgOffset
+ msgOffset,
+ addMessage
};
}