Skip to content

Commit ff51cd7

Browse files
committed
update to vue2-text-annotation
1 parent 10e202b commit ff51cd7

File tree

4 files changed

+527
-0
lines changed

4 files changed

+527
-0
lines changed

logo.png

24.8 KB
Loading

src/components/InputDialog.vue

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
<template>
2+
<div
3+
class="input-dialog__box"
4+
:class="{ 'align-right': align == 'right', 'align-left': align == 'left' }"
5+
:style="{ left: posX, top: posY, width: `${inputDialogWidth}px` }"
6+
>
7+
<div class="input-dialog__box_left">
8+
<input
9+
id="input-dialog"
10+
class="input-dialog"
11+
autocomplete="off"
12+
v-model="category"
13+
ref="input"
14+
type="text"
15+
v-on:mouseup.stop
16+
@keyup.enter="addAnnotation"
17+
/>
18+
<div class="underline" :style="{ borderColor: annotationBgColor }"></div>
19+
</div>
20+
<button
21+
class="add-annotation-button"
22+
@click="addAnnotation"
23+
:style="{
24+
backgroundColor: annotationBgColor,
25+
color: annotationTextColor,
26+
}"
27+
>
28+
ok
29+
</button>
30+
</div>
31+
</template>
32+
33+
<script lang="ts">
34+
import { Component, Vue, Emit, Prop } from "vue-property-decorator";
35+
@Component
36+
export default class InputDialog extends Vue {
37+
@Prop({ required: true }) posX!: string;
38+
@Prop({ required: true }) posY!: string;
39+
@Prop({ required: true }) annotationTextColor!: string;
40+
@Prop({ required: true }) annotationBgColor!: string;
41+
@Prop({ required: true }) align!: string;
42+
@Prop({ required: true }) inputDialogWidth!: number;
43+
44+
category = "";
45+
46+
@Emit()
47+
addAnnotation(): string {
48+
return this.category;
49+
}
50+
}
51+
</script>
52+
<style lang="scss" scoped>
53+
.input-dialog__box {
54+
position: fixed;
55+
background-color: #fff;
56+
border: 1px solid #e6e6e6;
57+
display: flex;
58+
padding: 10px;
59+
line-height: 1;
60+
justify-content: center;
61+
box-sizing: border-box;
62+
&_left {
63+
flex-grow: 1;
64+
}
65+
&.align-right {
66+
&::before {
67+
right: 10px;
68+
}
69+
}
70+
&.align-left {
71+
&::before {
72+
left: 10px;
73+
}
74+
}
75+
&::before {
76+
display: block;
77+
content: "";
78+
width: 10px;
79+
height: 10px;
80+
top: -7px;
81+
position: absolute;
82+
background-color: #fff;
83+
transform: rotate(45deg);
84+
border-left: 1px solid #e6e6e6;
85+
border-top: 1px solid #e6e6e6;
86+
}
87+
&_left {
88+
.input-dialog {
89+
width: 100%;
90+
border: none;
91+
outline: none;
92+
box-sizing: border-box;
93+
background: none;
94+
height: 15px;
95+
margin-bottom: 2px;
96+
&:-webkit-autofill {
97+
box-shadow: 0 0 0px 1000px white inset !important;
98+
}
99+
}
100+
.underline {
101+
position: relative;
102+
border-top: 1px solid;
103+
}
104+
}
105+
.add-annotation-button {
106+
border: none;
107+
text-align: center;
108+
text-decoration: none;
109+
display: inline-block;
110+
padding: 0px;
111+
font-size: 13px;
112+
border-radius: 50%;
113+
height: 22px;
114+
width: 22px;
115+
margin-left: 5px;
116+
cursor: pointer;
117+
font-weight: bold;
118+
}
119+
}
120+
</style>

src/components/TextAnnotation.vue

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
<template>
2+
<span
3+
class="text-annotation"
4+
:style="{ borderColor: annotationBgColor, color: annotationTextColor }"
5+
>
6+
<span
7+
class="text-annotation__word"
8+
:class="{ 'data-masking': dataMasking }"
9+
>
10+
<template v-if="dataMasking">
11+
<span class="text-annotation__word-top">{{
12+
dataMaskingCharactor.repeat(textAnnotation.content.length)
13+
}}</span>
14+
<span class="text-annotation__word-bottom">{{
15+
textAnnotation.content
16+
}}</span>
17+
</template>
18+
<span v-else>
19+
{{ textAnnotation.content }}
20+
</span>
21+
</span>
22+
<span
23+
class="text-annotation__category"
24+
:style="{ backgroundColor: annotationBgColor }"
25+
>
26+
{{ textAnnotation.category }}
27+
</span>
28+
<button class="text-annotation__delete" @click="deleteAnnotation">x</button>
29+
</span>
30+
</template>
31+
<script lang="ts">
32+
import { Annotation } from "@/type";
33+
import { Vue, Prop, Component, Emit } from "vue-property-decorator";
34+
@Component
35+
export default class TextAnnotation extends Vue {
36+
@Prop({ required: true }) readonly textAnnotation!: Annotation;
37+
@Prop({ required: true }) readonly annotationBgColor!: string;
38+
@Prop({ required: true }) readonly annotationTextColor!: string;
39+
@Prop({ default: "" }) readonly dataMaskingCharactor!: string;
40+
@Prop({ required: true }) readonly dataMasking!: boolean;
41+
@Emit()
42+
deleteAnnotation(): number {
43+
return this.textAnnotation.start;
44+
}
45+
}
46+
</script>
47+
<style lang="scss" scoped>
48+
.text-annotation {
49+
margin-right: 3px;
50+
line-height: 1.3;
51+
border: 2px solid;
52+
display: inline-block;
53+
position: relative;
54+
cursor: pointer;
55+
&:hover &__delete {
56+
display: block;
57+
}
58+
&__word {
59+
float: left;
60+
height: 1.3em;
61+
line-height: 1.3;
62+
overflow: hidden;
63+
padding-left: 2px;
64+
padding-right: 2px;
65+
&-top,
66+
&-bottom {
67+
height: 1.3em;
68+
text-align: center;
69+
display: block;
70+
transition: margin-top 0.3s;
71+
}
72+
&.data-masking {
73+
&:hover .text-annotation__word-top {
74+
margin-top: -1.3em;
75+
}
76+
}
77+
}
78+
&__category {
79+
display: inline-block;
80+
font-weight: 700;
81+
height: 1.3em;
82+
padding-left: 2px;
83+
}
84+
&__delete {
85+
font-size: 16px;
86+
color: #fff;
87+
top: -9px;
88+
left: -9px;
89+
position: absolute;
90+
text-align: center;
91+
display: none;
92+
border-radius: 50%;
93+
line-height: 1;
94+
padding: 0px;
95+
width: 16px;
96+
height: 16px;
97+
background-color: rgba(0, 0, 0, 0.54);
98+
border: none;
99+
&:hover {
100+
cursor: pointer;
101+
}
102+
}
103+
}
104+
</style>

0 commit comments

Comments
 (0)