add input animation + input item rafctor

This commit is contained in:
riqo 2020-11-22 11:49:25 -06:00
commit 3cf07e2b45
7 changed files with 121 additions and 63 deletions

View file

@ -48,6 +48,7 @@ function createWindow() {
if (process.env.WEBPACK_DEV_SERVER_URL) {
// Load the url of the dev server if in development mode
win.loadURL(process.env.WEBPACK_DEV_SERVER_URL as string);
// NOTE uncomment for dev tools on app launch
// if (!process.env.IS_TEST) win.webContents.openDevTools();
} else {
createProtocol("app");

View file

@ -1,5 +1,5 @@
<template>
<foreignObject class="inputContainer" :x="x" y="450" width="55%" height="50%">
<foreignObject class="inputContainer" :x="inputXoffset" y="450" width="55%" height="50%">
<div xmlns="http://www.w3.org/1999/xhtml">
<div class="inputBubble" contenteditable v-show="input.length > 0">
<p>{{ input }}</p>
@ -9,72 +9,18 @@
</template>
<script lang="ts">
import useKeyDownHandler from "@/composables/keyDownHandler/useKeyDownHandler";
import AnimeFunc from "@/types/animejs/index";
import useInputRenderer from "@/composables/inputItem/useInputRenderer";
import {
defineComponent,
onUnmounted,
computed,
ref,
onMounted,
watch,
inject,
} from "vue";
export default defineComponent({
name: "InputItem",
setup() {
const emitter: any = inject("mitt");
emitter.on("newSelfMessage", (payload: any) => console.log("foo", payload));
const { keyDownHandler, input } = useKeyDownHandler();
const inputHeight = ref(42);
let inputBubble: HTMLElement;
const inputWidth = ref(0);
const { inputXoffset, input } = useInputRenderer();
// imports animejs safely
let anime: AnimeFunc;
const animeInject: AnimeFunc | undefined = inject("animejs");
if (animeInject) anime = animeInject;
// add window event listener
window.addEventListener("keydown", keyDownHandler);
// remove Event Listener on component unMount
onUnmounted(() => {
window.removeEventListener("keydown", keyDownHandler);
});
watch(input, async (input, prevInput) => {
const inputDivs = await document.getElementsByClassName("inputBubble");
const height = inputDivs[0].getBoundingClientRect().height;
inputWidth.value = inputDivs[0].getBoundingClientRect().width;
const foreignObjectDiv = document.getElementsByClassName(
"inputContainer"
);
if (height !== inputHeight.value) {
inputHeight.value = height;
}
const foreignEl = foreignObjectDiv[0] as HTMLElement;
if (inputHeight.value === 0) {
anime({
targets: foreignEl,
translateY: -10,
});
} else if (inputHeight.value > 36) {
anime({
targets: foreignEl,
translateY: -inputHeight.value + 30,
easing: "easeOutQuad",
duration: 150,
});
}
});
const x = computed(() => {
return `calc(50% - ${inputWidth.value / 2})`;
});
return {
return {
input,
x,
inputXoffset,
};
},
});

View file

@ -0,0 +1,53 @@
import AnimeFunc from "@/types/animejs/index";
import {inject} from "vue";
import {Ref} from "@/types/vueRef/index";
export default function useInputAnims() {
// imports animejs safely
let anime: AnimeFunc;
const animeInject: AnimeFunc | undefined = inject("animejs");
if (animeInject) anime = animeInject;
const animateSend = (el: HTMLElement, elHeight: number, input: Ref<string>) => {
anime({
targets: el,
translateY: -elHeight + 15,
duration: 200,
easing: "easeInQuad",
complete: function() {
anime({
targets: el,
translateY: 50,
duration: 200,
easing: "easeOutQuad",
complete: function () {
input.value = "";
}
})
}
})
}
const inputAppear = (el: HTMLElement) => {
anime({
targets: el,
translateY: -10,
});
}
const verticalShiftInput = (el: HTMLElement, yTrans: number) => {
anime({
targets: el,
translateY: yTrans,
easing: "easeOutQuad",
duration: 150,
});
}
return {
animateSend,
verticalShiftInput,
inputAppear
}
}

View file

@ -0,0 +1,58 @@
import {ref, computed, inject, watch, onUnmounted} from "vue";
import useInputAnims from "./useInputAnims";
import useKeyDownHandler from "@/composables/keyDownHandler/useKeyDownHandler";
export default function useInputRenderer() {
const { keyDownHandler, input } = useKeyDownHandler();
// add window event listener
window.addEventListener("keydown", keyDownHandler);
// remove Event Listener on component unMount
onUnmounted(() => {
window.removeEventListener("keydown", keyDownHandler);
});
const emitter: any = inject("mitt");
const {animateSend, verticalShiftInput, inputAppear} = useInputAnims();
const inputHeight = ref(42);
const inputWidth = ref(0);
const renderInput = async() => {
const inputDivs = await document.getElementsByClassName("inputBubble");
const height = inputDivs[0].getBoundingClientRect().height;
inputWidth.value = inputDivs[0].getBoundingClientRect().width;
const foreignObjectDiv = document.getElementsByClassName(
"inputContainer"
);
if (height !== inputHeight.value) {
inputHeight.value = height;
}
const foreignEl = foreignObjectDiv[0] as HTMLElement;
if (inputHeight.value === 0) {
inputAppear(foreignEl)
} else if (inputHeight.value > 36) {
const yTrans = -inputHeight.value + 30;
verticalShiftInput(foreignEl, yTrans);
}
}
watch(input, () => {
renderInput();
});
emitter.on("newSelfMessage", async (payload: any) => {
const inputEl = document.getElementsByClassName("inputContainer");
const foreignEl = inputEl[0] as HTMLElement;
animateSend(foreignEl, inputHeight.value, input);
});
const inputXoffset = computed(() => {
return `calc(50% - ${inputWidth.value / 2})`;
});
return {
inputXoffset,
input
}
}

View file

@ -28,7 +28,6 @@ export default function useKeyDownHandler() {
};
// fire event with message payload
emitter.emit("newSelfMessage", message);
input.value = "";
}
function keyDownHandler(e: KeyDownEvent) {

View file

@ -1,7 +1,5 @@
import { ref, onMounted } from "vue";
interface Ref<A> {
value: A;
}
import {Ref} from "@/types/vueRef/index";
export default function useMessageItemAnims({
mr,
tr,

View file

@ -0,0 +1,3 @@
export interface Ref<A> {
value: A;
}