217 lines
4.1 KiB
Vue
217 lines
4.1 KiB
Vue
<template>
|
|
<div
|
|
id="inputItem"
|
|
class="input-item"
|
|
:class="{ playing: isRecording }"
|
|
:style="{ top: `${position.y}px`, left: `${position.x}px` }"
|
|
>
|
|
|
|
<!-- animations for recording and on-standby -->
|
|
<span v-if="isRecording" class="play"></span>
|
|
<span v-if="isRecording" class="pause">
|
|
<div class="rec-icon"></div>
|
|
</span>
|
|
|
|
<!-- Show text input on key-down -->
|
|
<input id="textInput" type="text" />
|
|
|
|
<div @mousedown.prevent="toggleMenu" id="helpMenu" v-if="!isDragging"></div>
|
|
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import { defineComponent, watch, ref } from "vue";
|
|
import draggify from "@/modules/draggify";
|
|
import useInputController from "./inputController";
|
|
|
|
export default defineComponent({
|
|
name: "InputItem",
|
|
setup() {
|
|
|
|
// Calculate position of inputItem on drag.
|
|
const { position, isDragging } = draggify({ elementId: "inputItem" });
|
|
|
|
// determine whether the user is typing or recording.
|
|
const { isRecording, isTyping } = useInputController();
|
|
|
|
const canOpen = ref(true);
|
|
|
|
const toggleMenu = (e: any) => {
|
|
if(isDragging.value === false) {
|
|
setImmediate(() => {
|
|
console.log('yuh yeet')
|
|
})
|
|
return;
|
|
}
|
|
}
|
|
|
|
watch(isDragging, (current, prev) => {
|
|
if (current) {
|
|
console.log('is dragging')
|
|
canOpen.value = false;
|
|
} else {
|
|
console.log('not dragging')
|
|
canOpen.value = true;
|
|
}
|
|
})
|
|
|
|
|
|
return {
|
|
position,
|
|
isRecording,
|
|
isTyping,
|
|
toggleMenu,
|
|
isDragging,
|
|
canOpen
|
|
};
|
|
},
|
|
});
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
#helpMenu {
|
|
width: 150px;
|
|
height: 150px;
|
|
border: 1px solid red;
|
|
background-color: transparent;
|
|
position: absolute;
|
|
bottom: 0;
|
|
left: 0;
|
|
|
|
border-radius: 18px;
|
|
}
|
|
|
|
#textInput {
|
|
width: 0px;
|
|
height: 36px;
|
|
|
|
border-top-right-radius: 18px;
|
|
border-bottom-right-radius: 18px;
|
|
|
|
padding: 0;
|
|
margin-left: 18px;
|
|
|
|
outline: none;
|
|
border: none;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.rec-icon {
|
|
width: 8px;
|
|
height: 8px;
|
|
border-radius: 50%;
|
|
background-color: red;
|
|
transform: translate(14px);
|
|
|
|
animation-name: rec;
|
|
animation-duration: 0.5s;
|
|
}
|
|
|
|
@keyframes rec {
|
|
from {
|
|
transform: translate(14px) scale(0.3);
|
|
}
|
|
to {
|
|
transform: translate(14px) scale(1.0);
|
|
}
|
|
}
|
|
|
|
.input-item {
|
|
position: absolute;
|
|
|
|
display: flex;
|
|
align-items: center;
|
|
|
|
padding: 0;
|
|
|
|
width: 36px;
|
|
height: 36px;
|
|
|
|
border-radius: 18px;
|
|
|
|
z-index: 3;
|
|
|
|
background-color: white;
|
|
|
|
cursor: pointer;
|
|
|
|
.play,
|
|
.pause {
|
|
z-index: 5;
|
|
&::before,
|
|
&::after {
|
|
-webkit-border-radius: 1000px;
|
|
-moz-border-radius: 1000px;
|
|
border-radius: 1000px;
|
|
content: "";
|
|
position: absolute;
|
|
height: 2.35em;
|
|
width: 2.35em;
|
|
left: 50%;
|
|
transform: translate(-50%, -50%);
|
|
top: 50%;
|
|
z-index: 0;
|
|
}
|
|
}
|
|
.play::before {
|
|
box-shadow: 0 0 0 rgba(195, 195, 195, 0);
|
|
}
|
|
.pause {
|
|
opacity: 0;
|
|
}
|
|
&.playing {
|
|
.play {
|
|
opacity: 0;
|
|
}
|
|
.pause {
|
|
opacity: 1;
|
|
&::before {
|
|
-moz-animation: circle1 1.5s infinite ease-in-out;
|
|
-o-animation: circle1 1.5s infinite ease-in-out;
|
|
-webkit-animation: circle1 1.5s infinite ease-in-out;
|
|
animation: circle1 1.5s infinite ease-in-out;
|
|
}
|
|
&::after {
|
|
-moz-animation: circle2 2.2s infinite ease-in-out;
|
|
-o-animation: circle2 2.2s infinite ease-in-out;
|
|
-webkit-animation: circle2 2.2s infinite ease-in-out;
|
|
animation: circle2 2.2s infinite ease-in-out;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@keyframes circle1 {
|
|
0%,
|
|
100% {
|
|
box-shadow: 0 0 0 0.4em rgba(195, 195, 195, 0.4);
|
|
}
|
|
25% {
|
|
box-shadow: 0 0 0 0.15em rgba(195, 195, 195, 0.15);
|
|
}
|
|
50% {
|
|
box-shadow: 0 0 0 0.55em rgba(195, 195, 195, 0.55);
|
|
}
|
|
75% {
|
|
box-shadow: 0 0 0 0.25em rgba(195, 195, 195, 0.25);
|
|
}
|
|
}
|
|
|
|
@keyframes circle2 {
|
|
0%,
|
|
100% {
|
|
box-shadow: 0 0 0 0.25em rgba(195, 195, 195, 0.15);
|
|
}
|
|
25% {
|
|
box-shadow: 0 0 0 0.4em rgba(195, 195, 195, 0.3);
|
|
}
|
|
50% {
|
|
box-shadow: 0 0 0 0.15em rgba(195, 195, 195, 0.05);
|
|
}
|
|
75% {
|
|
box-shadow: 0 0 0 0.55em rgba(195, 195, 195, 0.45);
|
|
}
|
|
}
|
|
|
|
</style>
|