104 lines
2.6 KiB
Vue
104 lines
2.6 KiB
Vue
<template>
|
|
<foreignObject class="inputContainer" :x="x" 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>
|
|
</div>
|
|
</div>
|
|
</foreignObject>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import useKeyDownHandler from "@/composables/keyDownHandler/useKeyDownHandler";
|
|
import AnimeFunc from "@/types/animejs/index";
|
|
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);
|
|
|
|
// 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 {
|
|
input,
|
|
x,
|
|
};
|
|
},
|
|
});
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
div[contenteditable] {
|
|
width: auto;
|
|
max-width: 180px;
|
|
height: auto;
|
|
min-height: 36px;
|
|
display: table;
|
|
justify-items: center;
|
|
border: 0;
|
|
border-radius: 20px;
|
|
color: #fff;
|
|
background-color: #585858;
|
|
font-size: 14;
|
|
text-align: left;
|
|
p {
|
|
max-width: 150px;
|
|
overflow-wrap: break-word;
|
|
padding: 10px 15px 10px 15px;
|
|
margin: 0;
|
|
}
|
|
}
|
|
</style>
|