add animation loop [messageItem render bug]

This commit is contained in:
riqo 2020-10-10 15:40:52 -05:00
commit 1646eca195
3 changed files with 161 additions and 95 deletions

View file

@ -2,7 +2,7 @@
<g
:id="item.id"
:class="item.modifier"
:transform="startingOffset"
:transform = "startingOffset"
>
<rect
ref="bubble"
@ -54,7 +54,7 @@
</template>
<script lang="ts">
import { defineComponent, computed, onMounted, ref } from 'vue';
import { defineComponent, computed, onMounted, ref, reactive, onBeforeMount } from 'vue';
export default defineComponent({
name: "MessageItem",
props: {
@ -64,23 +64,12 @@ import { defineComponent, computed, onMounted, ref } from 'vue';
},
},
setup(props) {
interface ProtectedRef {
readonly el: SVGElement | HTMLElement;
reference: any;
height: number | null;
}
let textArr: string[] = [];
let signature = "";
const bubble: ProtectedRef = {
el: document.createElement("rect"),
reference: ref(null),
height: 0,
};
const content: ProtectedRef = {
el: document.createElement("text"),
reference: ref(null),
height: 0,
}
let textArr: string[] = reactive([]);
const signature = ref("");
let bubble: any;
let content: any;
const textFill = computed(() => {
switch (props.item.modifier) {
@ -114,10 +103,10 @@ import { defineComponent, computed, onMounted, ref } from 'vue';
})
function signaturePosition(): void {
if (bubble.reference.value.getAttribute("height") !== null) {
const height = Number(bubble.reference.value.getAttribute("height"));
if (bubble.getAttribute("height") !== null) {
const height = Number(bubble.getAttribute("height"));
const p = -10;
signature = `translate(-10 ${height + p})`;
signature.value = `translate(-10 ${height + p})`;
}
}
@ -134,19 +123,20 @@ import { defineComponent, computed, onMounted, ref } from 'vue';
function adjustRect(): void {
// must get dimensions of text box to fit bubble around
const padding = 20;
const bbox = content.reference.value.getBBox();
bubble.reference.value.setAttribute("x", bbox.x - padding);
bubble.reference.value.setAttribute("y", bbox.y - padding);
bubble.reference.value.setAttribute("width", bbox.width + 2 * padding);
bubble.reference.value.setAttribute("height", bbox.height + 2 * padding);
const bbox = content.getBBox();
bubble.setAttribute("x", bbox.x - padding);
bubble.setAttribute("y", bbox.y - padding);
bubble.setAttribute("width", bbox.width + 2 * padding);
bubble.setAttribute("height", bbox.height + 2 * padding);
}
createTextBox(props.item.content, 32);
onMounted(async () => {
await createTextBox(props.item.content, 32);
await adjustRect();
signaturePosition();
})
bubble = document.getElementById("#bubble");
content = document.getElementById("#message");
await adjustRect();
signaturePosition();
})
return {
bubble,
textFill,
@ -154,7 +144,8 @@ import { defineComponent, computed, onMounted, ref } from 'vue';
startingOffset,
signaturePosition,
textArr,
signature
signature,
content
}
},

View file

@ -23,38 +23,38 @@ const Messages: Message[] = [
modifier: "fr",
imgURL: "@/assets/logo.png",
id: "2"
},
{
content: "Hey Anna, did you get the paper done?",
signature: "Tommy McConville",
outgoing: false,
modifier: "fr",
imgURL: "@/assets/logo.png",
id: "3"
},
{
content: "Yes posting it online soon.",
signature: "Tommy McConville",
outgoing: true,
modifier: "sf",
imgURL: "../../assets/logo.png",
id: "4"
},
{
content: "Sweet, thanks!",
signature: "Tommy McConville",
outgoing: false,
modifier: "fr",
imgURL: "../../assets/logo.png",
id: "5"
},
{
content: "Hey do you know Enrique Hernandez?",
signature: "Crimata AI",
outgoing: false,
modifier: "ai",
imgURL: "../../assets/logo.png",
id: "6"
}
// {
// content: "Hey Anna, did you get the paper done?",
// signature: "Tommy McConville",
// outgoing: false,
// modifier: "fr",
// imgURL: "@/assets/logo.png",
// id: "3"
// },
// {
// content: "Yes posting it online soon.",
// signature: "Tommy McConville",
// outgoing: true,
// modifier: "sf",
// imgURL: "../../assets/logo.png",
// id: "4"
// },
// {
// content: "Sweet, thanks!",
// signature: "Tommy McConville",
// outgoing: false,
// modifier: "fr",
// imgURL: "../../assets/logo.png",
// id: "5"
// }
// {
// content: "Hey do you know Enrique Hernandez?",
// signature: "Crimata AI",
// outgoing: false,
// modifier: "ai",
// imgURL: "../../assets/logo.png",
// id: "6"
// }
];
export default Messages;

View file

@ -36,27 +36,26 @@
<use xlink:href="#rect" />
</clipPath>
</defs>
<!-- <g id="cardsDiv"> -->
<!-- <g
v-for="(item, index) in renderArr"
:key="index"
id="cards"
transform="translate(0, 0)"
>
<transition
appear
v-on:before-appear="beforeEnter"
v-on:appear="enter"
v-on:appear-cancelled="leave"
>
<MessageItem
:v-if="item"
:item="item"
:key="index"
/>
</transition>
</g> -->
<!-- </g> -->
<g id="cardsDiv">
<g
v-for="(item, index) in renderArr"
:key="index"
id="cards"
transform="translate(0, 0)"
>
<transition
appear
v-on:before-appear="beforeEnter"
v-on:appear="enter"
v-on:appear-cancelled="leave"
>
<MessageItem
:item="item"
:key="index"
/>
</transition>
</g>
</g>
<g id="titlebar" transform="translate(0, 0)">
<g data-name="Group 73" transform="translate(20 20)">
<ellipse
@ -84,39 +83,115 @@
</template>
<script lang="ts">
import { defineComponent, inject, onMounted } from "vue";
// import MessageItem from './UIDetails/messageItem.vue';
import Messages from "./UIDetails/messages";
import { defineComponent, inject, onMounted, reactive } from "vue";
import MessageItem from './UIDetails/messageItem.vue';
import Messages from "./UIDetails/messages";
export default defineComponent({
name: 'UIindex',
// components: { MessageItem },
components: { MessageItem },
setup() {
interface ProtectedRef {
readonly el: SVGElement | HTMLElement;
reference: any;
height: number | null;
}
const anime: object | any = inject('animejs');
const timeline: typeof anime = anime.timeline({ loop: true });
const renderArr: Message[] = [];
const renderArr: Message[] = reactive([])
const messages = Messages;
const messageOffset = {
x: null,
y: null
const msgOffset = {
x: 0 ,
y: 0
}
let messenger: any;
let winW: number;
let modifier: string;
let msg: any;
let cardsDiv: any;
let prevCardH = 0;
function renderMsg(i: number): void {
setTimeout(() => {
renderArr.push(messages[i]);
}, 2000);
}
function runAnim(): void {
for (let i = 0; i < messages.length; i++) {
renderMsg(i);
}
}
async function beforeEnter(el: any) {
modifier = el.className.baseVal.substring(0, 2);
}
async function enter(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 = await 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;
}
prevCardH = msgH;
switch (modifier) {
case "sf":
msgOffset.x = winW - msgW;
break;
case "ai":
msgOffset.x = (winW - msgW) / 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 leave() {
}
onMounted(() => {
messenger = document.getElementById('messenger');
winW = messenger.clientWidth;
runAnim();
});
return {
// timeline,
renderArr,
messageOffset
msgOffset,
beforeEnter,
enter,
leave
}
},
});