feat: signature dialog
This commit is contained in:
parent
b3f04aa6cf
commit
f98093835f
2 changed files with 183 additions and 5 deletions
143
src/components/CanvasComponent.vue
Normal file
143
src/components/CanvasComponent.vue
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
<script lang="ts" setup>
|
||||
import { onMounted, ref } from 'vue';
|
||||
import SignaturePad from 'signature_pad';
|
||||
|
||||
defineExpose({ clearCanvas });
|
||||
|
||||
let canvasRef: HTMLCanvasElement | null = null;
|
||||
const signaturePad = ref();
|
||||
const currentColor = ref('blue');
|
||||
const tab = ref('draw');
|
||||
|
||||
const initializeSignaturePad = () => {
|
||||
if (canvasRef) {
|
||||
signaturePad.value = new SignaturePad(canvasRef, {
|
||||
backgroundColor: 'rgb(248,249,250)',
|
||||
penColor: 'blue',
|
||||
});
|
||||
} else {
|
||||
console.warn('Canvas reference not found. SignaturePad not initialized.');
|
||||
}
|
||||
};
|
||||
|
||||
function changeColor(color: string) {
|
||||
signaturePad.value.penColor = color;
|
||||
currentColor.value = color;
|
||||
}
|
||||
|
||||
function clearCanvas() {
|
||||
signaturePad.value.clear();
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
canvasRef = document.querySelector('canvas');
|
||||
initializeSignaturePad();
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<div class="surface-1 bordered rounded">
|
||||
<q-tabs
|
||||
v-model="tab"
|
||||
dense
|
||||
align="left"
|
||||
class="text-grey"
|
||||
active-color="primary"
|
||||
indicator-color="primary"
|
||||
>
|
||||
<q-tab
|
||||
name="draw"
|
||||
label="Draw"
|
||||
style="border-top-left-radius: var(--radius-2)"
|
||||
/>
|
||||
<q-tab name="upload" label="Upload" />
|
||||
</q-tabs>
|
||||
<q-separator />
|
||||
|
||||
<q-tab-panels v-model="tab" animated>
|
||||
<q-tab-panel name="draw">
|
||||
<div class="column relative-position">
|
||||
<div
|
||||
class="absolute-top-right q-ma-md q-gutter-x-md row items-center"
|
||||
>
|
||||
<span
|
||||
class="dot"
|
||||
:class="{ active: currentColor === 'black' }"
|
||||
style="background-color: black"
|
||||
@click="changeColor('black')"
|
||||
>
|
||||
<q-icon
|
||||
v-if="currentColor === 'black'"
|
||||
name="mdi-check"
|
||||
color="white"
|
||||
size="sm"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
:class="{ active: currentColor === 'red' }"
|
||||
class="dot"
|
||||
style="background-color: red"
|
||||
@click="changeColor('red')"
|
||||
>
|
||||
<q-icon
|
||||
v-if="currentColor === 'red'"
|
||||
name="mdi-check"
|
||||
color="white"
|
||||
size="sm"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
:class="{ active: currentColor === 'blue' }"
|
||||
class="dot"
|
||||
style="background-color: blue"
|
||||
@click="changeColor('blue')"
|
||||
>
|
||||
<q-icon
|
||||
v-if="currentColor === 'blue'"
|
||||
name="mdi-check"
|
||||
color="white"
|
||||
size="sm"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<canvas
|
||||
class="signature-canvas"
|
||||
ref="canvasRef"
|
||||
id="signature-pad"
|
||||
width="650"
|
||||
height="300"
|
||||
></canvas>
|
||||
</div>
|
||||
</q-tab-panel>
|
||||
</q-tab-panels>
|
||||
|
||||
<!-- <div class="text-right q-gutter-x-md">
|
||||
<q-btn id="clear" label="Clear" @click="signaturePad.clear()" />
|
||||
</div> -->
|
||||
</div>
|
||||
</template>
|
||||
<style scoped lang="scss">
|
||||
.signature-canvas {
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: var(--radius-2);
|
||||
}
|
||||
|
||||
.dot {
|
||||
height: 25px;
|
||||
width: 25px;
|
||||
border-radius: 50%;
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
&.active {
|
||||
height: 35px;
|
||||
width: 35px;
|
||||
}
|
||||
}
|
||||
|
||||
.color-palette {
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -13,7 +13,9 @@ import { useI18n } from 'vue-i18n';
|
|||
|
||||
import useLoader from 'stores/loader';
|
||||
import DrawerComponent from 'components/DrawerComponent.vue';
|
||||
import CanvasComponent from 'components/CanvasComponent.vue';
|
||||
import useUserStore from 'src/stores/user';
|
||||
import FormDialog from 'src/components/FormDialog.vue';
|
||||
import { Option } from 'src/stores/user/types';
|
||||
import { dialog } from 'src/stores/utils';
|
||||
|
||||
|
|
@ -37,12 +39,13 @@ const { visible } = storeToRefs(loaderStore);
|
|||
const { locale } = useI18n({ useScope: 'global' });
|
||||
const userStore = useUserStore();
|
||||
|
||||
const canvasModal = ref(false);
|
||||
const leftDrawerOpen = ref(false);
|
||||
const filterUnread = ref(false);
|
||||
const unread = ref<number>(1);
|
||||
const filterRole = ref<string[]>();
|
||||
const userImage = ref<string>();
|
||||
|
||||
const canvasRef = ref();
|
||||
const currentLanguage = ref<string>('ไทย');
|
||||
const language: {
|
||||
value: string;
|
||||
|
|
@ -89,10 +92,16 @@ const notification = ref<Notification[]>([
|
|||
const options = ref([
|
||||
{
|
||||
icon: 'mdi-lock-outline',
|
||||
label: 'เปลี่ยนรหัสผ่าน',
|
||||
label: 'changePassword',
|
||||
value: 'op1',
|
||||
color: 'primary',
|
||||
},
|
||||
{
|
||||
icon: 'mdi-signature-freehand',
|
||||
label: 'signature',
|
||||
value: 'signature',
|
||||
color: 'primary',
|
||||
},
|
||||
]);
|
||||
|
||||
function setActive(button: NotificationButton) {
|
||||
|
|
@ -343,12 +352,21 @@ onMounted(async () => {
|
|||
<q-separator />
|
||||
<div class="column justify-center">
|
||||
<q-list dense v-for="op in options" :key="op.label">
|
||||
<q-item clickable>
|
||||
<q-item
|
||||
clickable
|
||||
@click="
|
||||
() => {
|
||||
if (op.value === 'signature') {
|
||||
canvasModal = true;
|
||||
}
|
||||
}
|
||||
"
|
||||
>
|
||||
<q-item-section avatar>
|
||||
<q-icon :name="op.icon" :color="op.color" size="20px" />
|
||||
</q-item-section>
|
||||
<q-item-section class="q-py-sm">
|
||||
{{ op.label }}
|
||||
{{ $t(op.label) }}
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
|
|
@ -376,7 +394,7 @@ onMounted(async () => {
|
|||
style="color: var(--gray-6)"
|
||||
@click="$q.dark.toggle()"
|
||||
/>
|
||||
<!-- เปลี่นรภาษา -->
|
||||
<!-- เปลี่นนภาษา -->
|
||||
<q-btn
|
||||
flat
|
||||
color="grey"
|
||||
|
|
@ -417,6 +435,23 @@ onMounted(async () => {
|
|||
|
||||
<drawer-component v-model:leftDrawerOpen="leftDrawerOpen" />
|
||||
|
||||
<FormDialog
|
||||
v-model:modal="canvasModal"
|
||||
:title="$t('addSignature')"
|
||||
no-app-box
|
||||
:max-width="80"
|
||||
>
|
||||
<CanvasComponent ref="canvasRef" v-model:modal="canvasModal" />
|
||||
<template #footer>
|
||||
<q-btn
|
||||
flat
|
||||
dense
|
||||
:label="$t('clear')"
|
||||
@click="canvasRef.clearCanvas()"
|
||||
/>
|
||||
</template>
|
||||
</FormDialog>
|
||||
|
||||
<global-loading :visibility="visible" />
|
||||
</q-layout>
|
||||
</template>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue