</template>
<script lang="ts">
-import { defineComponent } from 'vue';
+import { defineComponent, computed, onMounted, ref } from 'vue';
export default defineComponent({
name: "MessageItem",
props: {
required: true
},
},
- data() {
- return {
- textArr: [],
- signature: ""
- };
- },
- computed: {
- textFill() {
- switch (this.item.modifier) {
- case "ai":
- return "#fff";
- default:
- return "#000";
+ setup(props) {
+ interface ProtectedRef {
+ readonly el: SVGElement | HTMLElement;
+ reference: any;
+ height: number | null;
}
- },
- bubbleFill() {
- switch (this.item.modifier) {
- case "sf":
- return "#61b4f4";
- case "ai":
- return "#585858";
- default:
- return "#fff";
+ 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,
}
- },
- startingOffset() {
- switch (this.item.modifier) {
- case "sf":
- return "translate(10, 600)";
- case "ai":
- return "translate(135, 600)";
- default:
- return "translate(20, 600)";
+
+ const textFill = computed(() => {
+ switch (props.item.modifier) {
+ case "ai":
+ return "#fff";
+ default:
+ return "#000";
+ }
+ });
+
+ const bubbleFill = computed(() => {
+ switch (props.item.modifier) {
+ case "sf":
+ return "#61b4f4";
+ case "ai":
+ return "#585858";
+ default:
+ return "#fff";
+ }
+ });
+
+ const startingOffset = computed(() => {
+ switch (props.item.modifier) {
+ case "sf":
+ return "translate(10, 600)";
+ case "ai":
+ return "translate(135, 600)";
+ default:
+ return "translate(20, 600)";
+ }
+ })
+
+ function signaturePosition(): void {
+ if (bubble.reference.value.getAttribute("height") !== null) {
+ const height = Number(bubble.reference.value.getAttribute("height"));
+ const p = -10;
+ signature = `translate(-10 ${height + p})`;
+ }
}
- }
- },
- async mounted() {
- await this.createTextBox(this.item.content, 32);
- await this.adjustRect();
- this.signaturePosition();
+
+ function createTextBox(s: string, w: number): void {
+ // return tspan elements for text with correct size
+ const wrap = (s: string, w: number) =>
+ s.replace(
+ new RegExp(`(?![^\\n]{1,${w}}$)([^\\n]{1,${w}})\\s`, "g"),
+ "$1\n"
+ );
+ textArr = wrap(s, w).split("\n");
+ }
+
+ 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);
+ }
+
+ onMounted(async () => {
+ await createTextBox(props.item.content, 32);
+ await adjustRect();
+ signaturePosition();
+ })
+
+ return {
+ bubble,
+ textFill,
+ bubbleFill,
+ startingOffset,
+ signaturePosition,
+ textArr,
+ signature
+ }
+
},
- 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>