|
@@ -1,12 +1,27 @@
|
|
<template>
|
|
<template>
|
|
- <div class="signatures-popup" :class="{ mobile: isMobileDevice }">
|
|
|
|
|
|
+ <div class="signatures-popup">
|
|
<div class="sign-popup-header">
|
|
<div class="sign-popup-header">
|
|
<div @click="changeActiveSignWay('trackpad')" :class="{ active: activeSignWay === 'trackpad' }">{{ $t('signatures.trackpad') }}</div>
|
|
<div @click="changeActiveSignWay('trackpad')" :class="{ active: activeSignWay === 'trackpad' }">{{ $t('signatures.trackpad') }}</div>
|
|
<div @click="changeActiveSignWay('keyboard')" :class="{ active: activeSignWay === 'keyboard' }">{{ $t('signatures.keyboard') }}</div>
|
|
<div @click="changeActiveSignWay('keyboard')" :class="{ active: activeSignWay === 'keyboard' }">{{ $t('signatures.keyboard') }}</div>
|
|
<div @click="changeActiveSignWay('image')" :class="{ active: activeSignWay === 'image' }">{{ $t('signatures.image') }}</div>
|
|
<div @click="changeActiveSignWay('image')" :class="{ active: activeSignWay === 'image' }">{{ $t('signatures.image') }}</div>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <div :class="{ mobile: isMobile }">
|
|
|
|
+ <div class="paint-container" ref="paintContainer">
|
|
|
|
+ <canvas v-show="activeSignWay === 'trackpad'" id="electronicTrackpadCanvas" :width="canvasWidth" :height="canvasHeight"></canvas>
|
|
|
|
+
|
|
|
|
+ <div class="keyboard-paint" v-show="activeSignWay === 'keyboard'">
|
|
|
|
+ <input type="text" :placeholder="$t('signatures.signHere')" v-model="textSgin" name="signature">
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <div class="image-paint" v-show="activeSignWay === 'image'">
|
|
|
|
+ <a>{{ $t('signatures.selectFile') }}<input type="file" id="signImageInput" @change="handleFile" accept=".png, .jpg, .jpeg" @click="clickUpload" name="signature"></a>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
|
|
- <div v-if="isMobileDevice" class="property-container">
|
|
|
|
|
|
+ <div class="property-container" v-show="['trackpad', 'keyboard'].includes(activeSignWay)">
|
|
<div v-show="activeSignWay === 'trackpad'" class="width-tool">
|
|
<div v-show="activeSignWay === 'trackpad'" class="width-tool">
|
|
|
|
+ <span v-if="!isMobile">{{ $t('signatures.lineWidth') }}</span>
|
|
<n-slider v-model:value="widthValue" :step="1" :max="10" :min="1" class="width-slider">
|
|
<n-slider v-model:value="widthValue" :step="1" :max="10" :min="1" class="width-slider">
|
|
<template #thumb>
|
|
<template #thumb>
|
|
<Slider />
|
|
<Slider />
|
|
@@ -16,7 +31,7 @@
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<div v-show="activeSignWay === 'keyboard'" class="font-tool">
|
|
<div v-show="activeSignWay === 'keyboard'" class="font-tool">
|
|
- <span>{{ $t('font') }}</span>
|
|
|
|
|
|
+ <span v-if="!isMobile">{{ $t('font') }}</span>
|
|
<select id="fontFamily" v-model="fontFamily" v-on:change="handleFontChange">
|
|
<select id="fontFamily" v-model="fontFamily" v-on:change="handleFontChange">
|
|
<option value="Arial">Arial</option>
|
|
<option value="Arial">Arial</option>
|
|
<option value="Courier New">Courier New</option>
|
|
<option value="Courier New">Courier New</option>
|
|
@@ -25,81 +40,39 @@
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<div v-show="activeSignWay === 'trackpad' || activeSignWay === 'keyboard'" class="color-tool">
|
|
<div v-show="activeSignWay === 'trackpad' || activeSignWay === 'keyboard'" class="color-tool">
|
|
|
|
+ <span v-if="!isMobile">{{ $t('color') }}</span>
|
|
<div class="colors-container">
|
|
<div class="colors-container">
|
|
<span class="cell-container">
|
|
<span class="cell-container">
|
|
- <span class="cell-outer" :class="{ active: fontColor === '#FF0000' }" @click="setActiveToolColor('#FF0000')">
|
|
|
|
|
|
+ <span class="cell-outer" :class="{ active: areColorsSimilar(fontColor, 'rgb(255, 0, 0)') }" @click="setActiveToolColor('rgb(255, 0, 0)')">
|
|
<span class="cell red"></span></span>
|
|
<span class="cell red"></span></span>
|
|
</span>
|
|
</span>
|
|
<span class="cell-container">
|
|
<span class="cell-container">
|
|
- <span class="cell-outer" :class="{ active: fontColor === '#000000' }" @click="setActiveToolColor('#000000')">
|
|
|
|
|
|
+ <span class="cell-outer" :class="{ active: areColorsSimilar(fontColor, 'rgb(0, 0, 0)') }" @click="setActiveToolColor('rgb(0, 0, 0)')">
|
|
<span class="cell black"></span></span>
|
|
<span class="cell black"></span></span>
|
|
</span>
|
|
</span>
|
|
<span class="cell-container">
|
|
<span class="cell-container">
|
|
- <span class="cell-outer" :class="{ active: fontColor === '#2D77FA' }" @click="setActiveToolColor('#2D77FA')">
|
|
|
|
|
|
+ <span class="cell-outer" :class="{ active: areColorsSimilar(fontColor, 'rgb(45, 119, 250)') }" @click="setActiveToolColor('rgb(45, 119, 250)')">
|
|
<span class="cell blue"></span></span>
|
|
<span class="cell blue"></span></span>
|
|
</span>
|
|
</span>
|
|
|
|
+ <div class="color-picker">
|
|
|
|
+ <div class="preview" :style="{ backgroundColor: colorPickerValue }"></div>
|
|
|
|
+ <n-color-picker
|
|
|
|
+ to=".signatures-popup"
|
|
|
|
+ @complete="onColorPickerComplete"
|
|
|
|
+ @update:value="onColorPickerUpdate"
|
|
|
|
+ :value="colorPickerValue"
|
|
|
|
+ :show-alpha="false"
|
|
|
|
+ >
|
|
|
|
+ <template #label><img src="../Icon/colorful.svg" alt="colorPicker"></template>
|
|
|
|
+ </n-color-picker>
|
|
|
|
+ </div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
- <div class="paint-container" ref="paintContainer">
|
|
|
|
- <canvas v-show="activeSignWay === 'trackpad'" id="electronicTrackpadCanvas" :width="canvasWidth" :height="canvasHeight"></canvas>
|
|
|
|
-
|
|
|
|
- <div class="keyboard-paint" v-show="activeSignWay === 'keyboard'">
|
|
|
|
- <input type="text" :placeholder="$t('signatures.signHere')" v-model="textSgin" name="signature">
|
|
|
|
- </div>
|
|
|
|
-
|
|
|
|
- <div class="image-paint" v-show="activeSignWay === 'image'">
|
|
|
|
- <a>{{ $t('signatures.selectFile') }}<input type="file" id="signImageInput" @change="handleFile" accept=".png, .jpg, .jpeg" @click="clickUpload" name="signature"></a>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
-
|
|
|
|
- <div v-if="!isMobileDevice" class="property-container">
|
|
|
|
- <div v-show="activeSignWay === 'trackpad'" class="width-tool">
|
|
|
|
- <span>{{ $t('signatures.lineWidth') }}</span>
|
|
|
|
- <n-slider v-model:value="widthValue" :step="1" :max="10" :min="1" class="width-slider">
|
|
|
|
- <template #thumb>
|
|
|
|
- <Slider />
|
|
|
|
- </template>
|
|
|
|
- </n-slider>
|
|
|
|
- <input v-model="widthValue" type="text" pattern="\d*" onkeypress="return (/[\d]/.test(String.fromCharCode(event.keyCode)))" @blur="handleBlur" name="signature">
|
|
|
|
- </div>
|
|
|
|
-
|
|
|
|
- <div v-show="activeSignWay === 'keyboard'" class="font-tool">
|
|
|
|
- <span>{{ $t('font') }}</span>
|
|
|
|
- <select id="fontFamily" v-model="fontFamily" v-on:change="handleFontChange">
|
|
|
|
- <option value="Arial">Arial</option>
|
|
|
|
- <option value="Courier New">Courier New</option>
|
|
|
|
- <option value="Times New Roman">Times New Roman</option>
|
|
|
|
- </select>
|
|
|
|
- </div>
|
|
|
|
-
|
|
|
|
- <div v-show="activeSignWay === 'trackpad' || activeSignWay === 'keyboard'" class="color-tool">
|
|
|
|
- <span>{{ $t('color') }}</span>
|
|
|
|
- <div class="colors-container">
|
|
|
|
- <!-- <span class="cell-container">
|
|
|
|
- <span class="cell-outer" :class="{ active: fontColor === '#000000' }" @click="setActiveToolColor('#000000')">
|
|
|
|
- <div class="box cell"><div class="box-outer"></div><div class="box-inner"></div></div></span>
|
|
|
|
- </span> -->
|
|
|
|
- <span class="cell-container">
|
|
|
|
- <span class="cell-outer" :class="{ active: fontColor === '#FF0000' }" @click="setActiveToolColor('#FF0000')">
|
|
|
|
- <span class="cell red"></span></span>
|
|
|
|
- </span>
|
|
|
|
- <span class="cell-container">
|
|
|
|
- <span class="cell-outer" :class="{ active: fontColor === '#000000' }" @click="setActiveToolColor('#000000')">
|
|
|
|
- <span class="cell black"></span></span>
|
|
|
|
- </span>
|
|
|
|
- <span class="cell-container">
|
|
|
|
- <span class="cell-outer" :class="{ active: fontColor === '#2D77FA' }" @click="setActiveToolColor('#2D77FA')">
|
|
|
|
- <span class="cell blue"></span></span>
|
|
|
|
- </span>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
-
|
|
|
|
<div class="buttons-container">
|
|
<div class="buttons-container">
|
|
- <div class="button" @click="clearData">{{ $t('signatures.clear') }}</div>
|
|
|
|
|
|
+ <div class="clear" :class="{ 'button': !isMobile }" @click="clearData">{{ $t('signatures.clear') }}</div>
|
|
<div class="right-btns">
|
|
<div class="right-btns">
|
|
<div class="button" @click="closePanel('cancel')">{{ $t('cancel') }}</div>
|
|
<div class="button" @click="closePanel('cancel')">{{ $t('cancel') }}</div>
|
|
<div class="button blue" @click="save">{{ $t('signatures.save') }}</div>
|
|
<div class="button blue" @click="save">{{ $t('signatures.save') }}</div>
|
|
@@ -114,8 +87,9 @@ import { useViewerStore } from '@/stores/modules/viewer'
|
|
import { useDocumentStore } from '@/stores/modules/document'
|
|
import { useDocumentStore } from '@/stores/modules/document'
|
|
import core from '@/core'
|
|
import core from '@/core'
|
|
import MessageError from '@/assets/icons/icon-message-error.svg'
|
|
import MessageError from '@/assets/icons/icon-message-error.svg'
|
|
-import { NSlider } from 'naive-ui'
|
|
|
|
-import { isMobileDevice } from '@/helpers/device'
|
|
|
|
|
|
+import { NSlider, NColorPicker } from 'naive-ui'
|
|
|
|
+import { isMobile } from '@/helpers/device'
|
|
|
|
+import { areColorsSimilar } from '@/helpers/utils'
|
|
|
|
|
|
const instance = getCurrentInstance().appContext.app.config.globalProperties
|
|
const instance = getCurrentInstance().appContext.app.config.globalProperties
|
|
|
|
|
|
@@ -135,6 +109,7 @@ const fontFamily = ref('Courier New')
|
|
const paintContainer = ref()
|
|
const paintContainer = ref()
|
|
const canvasWidth = ref(578)
|
|
const canvasWidth = ref(578)
|
|
const canvasHeight = ref(270)
|
|
const canvasHeight = ref(270)
|
|
|
|
+const colorPickerValue = ref('rgb(0, 0, 0)')
|
|
|
|
|
|
watch(() => toolMode.value, (newValue, oldValue) => {
|
|
watch(() => toolMode.value, (newValue, oldValue) => {
|
|
if (!(oldValue === 'sign' && newValue === 'view') && newValue !== oldValue) {
|
|
if (!(oldValue === 'sign' && newValue === 'view') && newValue !== oldValue) {
|
|
@@ -169,6 +144,7 @@ watch(() => fontColor.value, (newValue, oldValue) => {
|
|
})
|
|
})
|
|
|
|
|
|
if (activeSignWay.value === "keyboard") {
|
|
if (activeSignWay.value === "keyboard") {
|
|
|
|
+ colorPickerValue.value = fontColor.value
|
|
let inputElement = document.querySelector(".keyboard-paint input")
|
|
let inputElement = document.querySelector(".keyboard-paint input")
|
|
if (inputElement) {
|
|
if (inputElement) {
|
|
inputElement.style.color = fontColor.value
|
|
inputElement.style.color = fontColor.value
|
|
@@ -178,7 +154,7 @@ watch(() => fontColor.value, (newValue, oldValue) => {
|
|
|
|
|
|
watch(() => show.value, (newValue, oldValue) => {
|
|
watch(() => show.value, (newValue, oldValue) => {
|
|
if (newValue) {
|
|
if (newValue) {
|
|
- if (isMobileDevice) {
|
|
|
|
|
|
+ if (isMobile) {
|
|
nextTick(() => {
|
|
nextTick(() => {
|
|
const { clientWidth, clientHeight } = paintContainer.value
|
|
const { clientWidth, clientHeight } = paintContainer.value
|
|
clientWidth && canvasWidth.value !== clientWidth && (canvasWidth.value = clientWidth)
|
|
clientWidth && canvasWidth.value !== clientWidth && (canvasWidth.value = clientWidth)
|
|
@@ -418,6 +394,16 @@ const handleFontChange = (evt) => {
|
|
inputElement.style.fontFamily = evt.target.value
|
|
inputElement.style.fontFamily = evt.target.value
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+// 颜色选择器选中颜色事件
|
|
|
|
+const onColorPickerComplete = (value) => {
|
|
|
|
+ if (!areColorsSimilar(value, fontColor.value)) setActiveToolColor(value)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// 颜色选择器颜色改变事件
|
|
|
|
+const onColorPickerUpdate = (value) => {
|
|
|
|
+ colorPickerValue.value = value
|
|
|
|
+}
|
|
</script>
|
|
</script>
|
|
|
|
|
|
<style lang="scss">
|
|
<style lang="scss">
|
|
@@ -555,13 +541,13 @@ const handleFontChange = (evt) => {
|
|
height: 24px;
|
|
height: 24px;
|
|
}
|
|
}
|
|
.red {
|
|
.red {
|
|
- background-color: #FF0000;
|
|
|
|
|
|
+ background-color: rgb(255, 0, 0);
|
|
}
|
|
}
|
|
.black {
|
|
.black {
|
|
- background-color: #000;
|
|
|
|
|
|
+ background-color: rgb(0, 0, 0);
|
|
}
|
|
}
|
|
.blue {
|
|
.blue {
|
|
- background-color: #2D77FA;
|
|
|
|
|
|
+ background-color: rgb(45, 119, 250);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
& + .cell-container {
|
|
& + .cell-container {
|
|
@@ -647,52 +633,67 @@ const handleFontChange = (evt) => {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-.signatures-popup.mobile {
|
|
|
|
- display: flex;
|
|
|
|
- flex-direction: column;
|
|
|
|
- justify-content: space-between;
|
|
|
|
- width: 100vh;
|
|
|
|
- height: 100vw;
|
|
|
|
- transform: rotate(90deg);
|
|
|
|
- -ms-transform: rotate(90deg);
|
|
|
|
- -moz-transform: rotate(90deg);
|
|
|
|
- -webkit-transform: rotate(90deg);
|
|
|
|
- -o-transform: rotate(90deg);
|
|
|
|
|
|
+@media screen and (max-width: 640px) {
|
|
|
|
+ .signatures-popup {
|
|
|
|
+ width: calc(100% - 40px);
|
|
|
|
+ border-radius: 4px;
|
|
|
|
|
|
- .sign-popup-header {
|
|
|
|
- padding: 2px 16px;
|
|
|
|
- background-color: var(--c-bg);
|
|
|
|
- }
|
|
|
|
|
|
+ .sign-popup-header {
|
|
|
|
+ padding: 0;
|
|
|
|
+ background-color: var(--c-bg);
|
|
|
|
+ }
|
|
|
|
|
|
- .property-container {
|
|
|
|
- flex: 1;
|
|
|
|
- flex-direction: row-reverse;
|
|
|
|
- justify-content: flex-start;
|
|
|
|
- margin: auto 0;
|
|
|
|
|
|
+ .mobile {
|
|
|
|
+ display: flex;
|
|
|
|
+ flex-direction: column-reverse;
|
|
|
|
+ }
|
|
|
|
|
|
- .color-tool {
|
|
|
|
- margin-right: 30px;
|
|
|
|
|
|
+ .property-container {
|
|
|
|
+ margin: 24px 25px 0;
|
|
|
|
+ flex-direction: row-reverse;
|
|
|
|
+
|
|
|
|
+ .color-tool .colors-container {
|
|
|
|
+ margin-left: 0;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- }
|
|
|
|
|
|
|
|
- .paint-container {
|
|
|
|
- flex: 1;
|
|
|
|
- margin: 0;
|
|
|
|
- background-color: var(--c-header-bg);
|
|
|
|
|
|
+ .paint-container {
|
|
|
|
+ margin: 24px 20px;
|
|
|
|
+ background-color: var(--c-side-bg);
|
|
|
|
+ border: 1px solid var(--c-header-border);
|
|
|
|
+ border-radius: 4px;
|
|
|
|
+
|
|
|
|
+ .keyboard-paint input {
|
|
|
|
+ font-family: Segoe UI;
|
|
|
|
+ font-size: 30px;
|
|
|
|
+
|
|
|
|
+ &::placeholder {
|
|
|
|
+ color: rgba(0, 0, 0, 0.3);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ .buttons-container {
|
|
|
|
+ margin: 0 20px 16px;
|
|
|
|
+ align-items: center;
|
|
|
|
+
|
|
|
|
+ .clear {
|
|
|
|
+ font-size: 14px;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-@media screen and (max-width: 628px) {
|
|
|
|
- .signatures-popup:not(.mobile) {
|
|
|
|
- width: calc(100% - 40px);
|
|
|
|
|
|
+@media screen and (max-width: 450px) {
|
|
|
|
+ .signatures-popup .property-container .color-tool .colors-container {
|
|
|
|
|
|
- .property-container {
|
|
|
|
- flex-direction: column;
|
|
|
|
- align-items: flex-start;
|
|
|
|
|
|
+ span {
|
|
|
|
+ display: none;
|
|
|
|
+ }
|
|
|
|
|
|
- .color-tool {
|
|
|
|
- margin-top: 10px;
|
|
|
|
- }
|
|
|
|
|
|
+ .color-picker {
|
|
|
|
+ margin-left: 0;
|
|
|
|
+ height: 30px;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|