米字格

This commit is contained in:
weichengwu 2025-11-27 16:09:36 +08:00
parent e306019a7d
commit 30695c234d
2 changed files with 124 additions and 6 deletions

View File

@ -308,7 +308,12 @@ function submit() {
salesNo: Local.get("userInfo").salesNo,
};
Local.set("marriageInfo", params);
router.push("/Signature");
router.push({
path: "/Signature",
query: {
name: form.receiveName || "",
},
});
}
onMounted(() => {
getNumber();

View File

@ -24,6 +24,20 @@
</div>
</div>
<div class="signature" ref="signatureRef1">
<div
class="name_grid"
v-if="nameChars.length"
:style="{
'--grid-size': `${gridSize}px`,
'--grid-gap': `${gridGap}px`,
'--grid-padding': `${gridPadding}px`,
'--grid-font': `${gridFontSize}px`,
}"
>
<div class="grid_cell" v-for="(item, index) in nameChars" :key="index">
<span class="grid_cell_text">{{ item }}</span>
</div>
</div>
<van-signature
class="vantSignature"
ref="vanSignatureRef"
@ -43,14 +57,15 @@
</div>
</template>
<script setup>
import { ref, onMounted } from "vue";
import { useRouter } from "vue-router";
import { ref, onMounted, computed, onUnmounted, watch } from "vue";
import { useRouter, useRoute } from "vue-router";
import { Local } from "@/utils/storage.js";
import { receiveCode } from "@/api/index.js";
import toast from "@/components/toast/index1.vue";
import toast1 from "@/components/toast/index2.vue";
import submit from "@/components/toast/submit.vue";
const router = useRouter();
const route = useRoute();
const image = ref("");
const signatureRef = ref(null);
const signatureRef1 = ref(null);
@ -61,6 +76,20 @@ const submitRef = ref(null);
const btnType = ref(false);
const canvasRef = ref();
const submitType = ref(false);
const receiveName = ref("");
const gridSize = ref(72);
const gridGap = 8;
const gridPadding = 8;
const gridFontSize = computed(() => {
const target = gridSize.value * 0.9;
return Math.max(Math.min(target, gridSize.value - 6), 28);
});
const nameChars = computed(() =>
(receiveName.value || "")
.trim()
.split("")
.filter((item) => item)
);
const onSubmit = (data) => {
if (data.image) {
// image.value = data.image;
@ -80,6 +109,9 @@ const clearSignature = () => {
const closeSignature = () => {
router.back();
};
const onClear = () => {
btnType.value = false;
};
function setSignatureWidth() {
const signatureWidth = signatureRef1.value.clientWidth;
vanSignatureRef.value.setWidth(signatureWidth);
@ -89,9 +121,12 @@ function getSignatureHeight() {
setTimeout(() => {
if (signatureRef1.value) {
const signatureHeight = signatureRef1.value.offsetHeight;
const canvas = vanSignatureRef.value.$el.querySelector("canvas");
// const content = vanSignatureRef.value.$el.querySelector(".van-signature__content");
content.style.height = `${signatureHeight}px`;
const content = vanSignatureRef.value.$el.querySelector(
".van-signature__content"
);
if (content) {
content.style.height = `${signatureHeight}px`;
}
}
}, 100);
}
@ -149,11 +184,45 @@ async function rotateToBase64File(base64, mimeType = "image/png") {
function cancelSignature(){
btnType.value = false;
}
function updateGridSize() {
const wrapper = signatureRef1.value;
if (!wrapper) return;
const rect = wrapper.getBoundingClientRect();
const availableWidth = Math.max(rect.width - gridPadding * 2, 10);
const availableHeight = Math.max(rect.height - gridPadding * 2, 10);
const count = Math.max(nameChars.value.length, 1);
const gapTotal = gridGap * (count - 1);
const sizeByWidth = availableWidth;
const heightNeeded = sizeByWidth * count + gapTotal;
let size =
heightNeeded <= availableHeight
? sizeByWidth
: Math.max((availableHeight - gapTotal) / count, 40);
size = Math.min(size, availableWidth);
gridSize.value = size;
}
onMounted(() => {
//
setTimeout(() => {
getSignatureHeight();
updateGridSize();
}, 100);
const queryName = route.query.name || route.query.receiveName;
if (typeof queryName === "string" && queryName.trim()) {
receiveName.value = decodeURIComponent(queryName);
} else {
const marriageInfo = Local.get("marriageInfo");
if (marriageInfo?.receiveName) {
receiveName.value = marriageInfo.receiveName;
}
}
window.addEventListener("resize", updateGridSize);
});
onUnmounted(() => {
window.removeEventListener("resize", updateGridSize);
});
watch(nameChars, () => {
updateGridSize();
});
</script>
<style scoped lang="scss">
@ -205,6 +274,8 @@ onMounted(() => {
width: 100%;
height: 100%;
flex: 1;
position: relative;
overflow: hidden;
}
}
.btn_box {
@ -244,4 +315,46 @@ onMounted(() => {
position: fixed;
top: -100000px;
}
.name_grid {
position: absolute;
inset: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: var(--grid-gap);
padding: var(--grid-padding);
pointer-events: none;
z-index: 1;
box-sizing: border-box;
}
.grid_cell {
position: relative;
width: var(--grid-size);
height: var(--grid-size);
border: 1px solid rgba(0, 0, 0, 0.16);
border-radius: 0.08rem;
display: flex;
align-items: center;
justify-content: center;
font-size: var(--grid-font);
color: rgba(0, 0, 0, 0.32);
background:
linear-gradient(90deg, transparent calc(50% - 0.5px), rgba(0, 0, 0, 0.2) 50%, transparent calc(50% + 0.5px)),
linear-gradient(0deg, transparent calc(50% - 0.5px), rgba(0, 0, 0, 0.2) 50%, transparent calc(50% + 0.5px)),
linear-gradient(45deg, transparent calc(50% - 0.6px), rgba(0, 0, 0, 0.14) 50%, transparent calc(50% + 0.6px)),
linear-gradient(-45deg, transparent calc(50% - 0.6px), rgba(0, 0, 0, 0.14) 50%, transparent calc(50% + 0.6px));
box-shadow: inset 0 0 0 0.02rem rgba(0, 0, 0, 0.06);
}
.grid_cell_text {
display: block;
line-height: var(--grid-size);
transform: rotate(90deg);
transform-origin: center;
}
::v-deep(.van-signature__content) {
position: relative;
z-index: 2;
background: transparent;
}
</style>