add animejs + wasm to vue

This commit is contained in:
Enrique Hernandez 2020-10-08 23:17:47 -05:00
commit c3562172c4
14 changed files with 483 additions and 131 deletions

View file

@ -1,64 +0,0 @@
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<p>
For a guide and recipes on how to configure / customize this project,<br>
check out the
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
</p>
<h3>Installed CLI Plugins</h3>
<ul>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router" target="_blank" rel="noopener">router</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-vuex" target="_blank" rel="noopener">vuex</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-unit-jest" target="_blank" rel="noopener">unit-jest</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-typescript" target="_blank" rel="noopener">typescript</a></li>
</ul>
<h3>Essential Links</h3>
<ul>
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
</ul>
<h3>Ecosystem</h3>
<ul>
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
</ul>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
name: 'HelloWorld',
props: {
msg: String,
},
});
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>

View file

@ -0,0 +1,136 @@
<template>
<g
:id="item.id"
:class="item.modifier"
:transform="startingOffset"
>
<rect
ref="bubble"
id="#bubble"
x="30"
y="10"
width="196"
height="63"
rx="20"
:fill="bubbleFill"
/>
<text
font-size="14"
font-family="SF Pro"
id="#message"
ref="content"
:fill="textFill"
>
<tspan
dy="16"
x="0"
v-for="(item, index) in textArr"
:key="index"
>
{{ item }}
</tspan>
</text>
<g :transform="signature">
<image
xlink:href="profile.png"
width="29"
height="29"
fill="#b5b5b5"
clip-path="url(#clip)"
/>
<text
transform="translate(36, 17)"
fill="#888"
font-size="10"
font-family="SFCompactDisplay-Bold, SF Compact Display"
font-weight="700"
>
<tspan v-if="item.outgoing">You to</tspan>
<tspan v-else>From</tspan>
<tspan xml:space="preserve" fill="#000"> {{ item.signature }}</tspan>
</text>
</g>
</g>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
name: "MessageItem",
props: {
item: {
type: Object,
required: true
},
},
data() {
return {
textArr: [],
signature: ""
};
},
computed: {
textFill() {
switch (this.item.modifier) {
case "ai":
return "#fff";
default:
return "#000";
}
},
bubbleFill() {
switch (this.item.modifier) {
case "sf":
return "#61b4f4";
case "ai":
return "#585858";
default:
return "#fff";
}
},
startingOffset() {
switch (this.item.modifier) {
case "sf":
return "translate(10, 600)";
case "ai":
return "translate(135, 600)";
default:
return "translate(20, 600)";
}
}
},
async mounted() {
await this.createTextBox(this.item.content, 32);
await this.adjustRect();
this.signaturePosition();
},
methods: {
signaturePosition() {
const height = Number(this.$refs.bubble.getAttribute("height"));
const p = -10;
this.signature = `translate(-10 ${height + p})`;
},
createTextBox(s, w) {
// return tspan elements for text with correct size
const wrap = (s, w) =>
s.replace(
new RegExp(`(?![^\\n]{1,${w}}$)([^\\n]{1,${w}})\\s`, "g"),
"$1\n"
);
this.textArr = wrap(s, w).split("\n");
},
adjustRect() {
// must get dimensions of text box to fit bubble around
const padding = 20;
const bbox = this.$refs.content.getBBox();
const bubble = this.$refs.bubble;
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);
}
}
});
</script>
<style></style>

View file

@ -0,0 +1,52 @@
const Messages = [
{
content:
"I can be there at 5 pm tomorrow to greet you at a Chick file with my almond and chive salad.",
signature: "Tommy McConville",
outgoing: true,
modifier: "sf",
imgURL: "../assets/logo.png",
id: "1"
},
{
content: "Sounds good, see you Thursday.",
signature: "Josie Wright",
outgoing: false,
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"
}
];
export default Messages;

205
src/components/UI/index.vue Normal file
View file

@ -0,0 +1,205 @@
<template>
<svg
id="messenger"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<defs>
<linearGradient
id="linear-gradient"
x1="0.5"
y1="-1.438"
x2="0.5"
y2="0.633"
gradientUnits="objectBoundingBox"
>
<stop offset="0" stop-color="#fff33b" stop-opacity="0" />
<stop offset="0.152" stop-color="#ffde46" stop-opacity="0.141" />
<stop offset="0.467" stop-color="#ffa764" stop-opacity="0.435" />
<stop offset="0.581" stop-color="#ff916f" stop-opacity="0.541" />
<stop offset="1" stop-color="#ff5782" />
</linearGradient>
<linearGradient
id="linear-gradient-2"
x1="0.498"
y1="0.728"
x2="0.498"
y2="-0.433"
gradientUnits="objectBoundingBox"
>
<stop offset="0" stop-color="#f7cf83" />
<stop offset="1" stop-color="#fff" />
</linearGradient>
<rect id="rect" width="29" height="29" rx="10" />
<clipPath id="clip">
<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="titlebar" transform="translate(0, 0)">
<g data-name="Group 73" transform="translate(20 20)">
<ellipse
id="Oval"
cx="8.134"
cy="8.134"
rx="8.134"
ry="8.134"
transform="translate(0 0)"
fill="url(#linear-gradient)"
/>
<ellipse
id="Oval-2"
data-name="Oval"
cx="8.134"
cy="8.134"
rx="8.134"
ry="8.134"
transform="translate(27 0)"
fill="url(#linear-gradient-2)"
/>
</g>
</g>
</svg>
</template>
<script lang="ts">
import { defineComponent, inject } from "vue";
import MessageItem from './UIDetails/messageItem.vue';
// @ts-ignore
import {Messages} from "./UIDetails/messages.js";
export default defineComponent({
name: 'UIindex',
components: { MessageItem },
setup() {
const anime = inject('animejs');
let timeline;
console.log(Messages);
const setTimeLine = () => {
timeline = anime.timeline({ loop: true });
}
setTimeLine();
return {
timeline
}
},
// data() {
// return {
// renderArr: [],
// messages: [],
// timeline: null,
// msgOffset: {
// x: null,
// y: null
// },
// prevCardH: 0
// };
// },
// mounted() {
// this.setTimeLine();
// this.runAnim();
// },
// methods: {
// setTimeLine() {
// this.timeline = this.anime.timeline({ loop: true });
// },
// runAnim() {
// this.messages = Messages;
// for (let i = 0; i < this.messages.length; i++) {
// this.renderMsg(i);
// }
// },
// renderMsg(i) {
// setTimeout(() => {
// this.renderArr.push(this.messages[i]);
// }, 2000);
// },
// async beforeEnter(el) {},
// async enter(el, done) {
// const winW = document.getElementById("messenger").clientWidth;
// const modifier = el.className.baseVal.substring(0, 2);
// const msg = await document.getElementById(el.id);
// const rect = msg.getBoundingClientRect();
// const msgW = rect.width;
// const msgH = rect.height;
// const paddingLeft = 40;
// const cardsDiv = await document.getElementById("cardsDiv");
// const cdBox = cardsDiv.getBBox();
//
// if (this.prevCardH === 0) {
// this.msgOffset.y += cdBox.height;
// } else if (this.prevCardH > msgH) {
// // cardsDiv is offset by 17.5
// this.msgOffset.y += this.prevCardH + msgH / 2 + 17.5;
// } else {
// this.msgOffset.y += cdBox.height - 20;
// }
// this.prevCardH = msgH;
//
// switch (modifier) {
// case "sf":
// this.msgOffset.x = winW - msgW;
// break;
// case "ai":
// this.msgOffset.x = (winW - msgW) / 2;
// break;
// default:
// this.msgOffset.x = paddingLeft;
// }
//
// const translateUp = `translate(${this.msgOffset.x} ${this.msgOffset.y})`;
// const translateDown = `translate(${this.msgOffset.x} ${this.msgOffset.y +
// 5})`;
// this.timeline
// .add({
// targets: el,
// transform: translateUp,
// easing: "easeInOutQuad",
// duration: 1000
// })
// .add({
// targets: el,
// transform: translateDown,
// easing: "easeInOutQuad",
// duration: 500,
// offset: 1000
// });
// done();
// },
// leave(el, done) {
// console.log("leaving");
// }
// }
});
</script>
<style lang="scss" scoped>
#messenger {
width: 350px;
height: 500px;
background-color: #E6E6E6;
box-shadow: 0px 3px 10px 0px rgba(0, 0, 0, 0.3);
border-radius: 20px;
}
</style>