<g
:id="item.id"
:class="item.modifier"
- :transform="startingOffset"
+ :transform = "startingOffset"
>
<rect
ref="bubble"
</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: {
},
},
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) {
})
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})`;
}
}
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,
startingOffset,
signaturePosition,
textArr,
- signature
+ signature,
+ content
}
},
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;
<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
</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
}
},
});