前端实现签字效果+合同展示

最近菜鸟公司要做一个这样的功能,后端返回一个合同的整体html,前端进行签字,以下是一些重要思路!

注:本文章是给自己看的,读者酌情考虑!

获取一个高度会变的元素的高度

script 代码

let bigBoxHeight = ref(0);
// 获取到元素
let bigBox = document.querySelector(".bigBox");
// 设置高度为 auto
bigBox.style.height = "auto";
// 获取 offsetHeight
const height = bigBox.offsetHeight;
// 设置值
bigBoxHeight.value = height;

注:
offsetHeight:返回一个元素的高度,包括其padding和border,但不包括其margin。

template 代码

<div class="bigBox" :style="{ height: bigBoxHeight + 'px' }">
  <div class="contractBox">
    <div v-html="printData"></div>
  </div>
  <!-- 遮罩层,返回的printData里设置了可编辑,但是这里只是展示用,且修改了也不会有影响,所以就简单的加个遮罩就行了 -->
  <div class="markBox" :style="{ height: bigBoxHeight + 'px' }"></div>
</div>

获取元素设置的 transform

感谢:原生js获取元素transform的scale和rotate

// 获取设置了transform的元素
let contractBox = document.querySelector(".contractBox");
// 获取浏览器计算后的结果
let st = window.getComputedStyle(contractBox, null);
// 从结算后的结果中找到 transform,也可以直接 st.transform
var tr = st.getPropertyValue("transform");
if (tr === "none") {
   
  // 为none表示未设置
  bigBox.style.height = "auto";
  const height = bigBox.offsetHeight + 50;
  bigBoxHeight.value = height;
} else {
   
  bigBox.style.height = "auto";
  // 缩放需要 * 缩放比例 + 边距(margin/padding)
  const height = bigBox.offsetHeight * 0.5 + 50;
  bigBoxHeight.value = height;
}

getComputedStyle 可以学习我的博客:看 Javascript实战详解 收获一

适配手机

上面设置transform是因为返回的html文档不是那么的自适应,所以菜鸟就在手机端,让其渲染700px,但是再缩小0.5倍去展示,即可解决!

css 代码

@media screen and (max-width: 690px) {
   
  .contractBox {
   
    width: 700px !important;
    transform: scale(0.5);
    // 防止延中心点缩放而导致上面留白很多(合同很长,7000px左右)
    transform-origin: 5% 0;
  }
}

.bigBox {
   
  position: relative;
  // 设置是因为 scale 缩放了但是元素还是占本身那么大,所以要超出隐藏
  overflow: hidden;
  .markBox {
   
    width: 100%;
    position: absolute;
    left: 0;
    bottom: 0;
    top: 0;
    bottom: 0;
  }
}
.contractBox {
   
  width: 70%;
  margin: 50px auto 0px;
  overflow: hidden;
}

transform-origin: 5% 0; 的原因

这里设置 5% 是为了居中,因为这里有个问题就是不能设置bigBox为display:flex,不然里面的内容就是按照width:100%然后缩放0.5,而不是width:700px来缩放的!

是flex搞的鬼,菜鸟这里就用了个简单办法。

其实正统做法应该是获取宽度,再用窗口宽度减去获取的宽度 / 2,然后通过该值设置margin!

修改后

菜鸟既然想到了上面的居中方式,那就直接实现了,这里给上代码!

script 代码

// 是否缩放,来确定margin-left取值
let isScale = ref(false);
let bigBoxmargin = ref(0);

let bigBox = document.querySelector(".bigBox");
let contractBox = document.querySelector(".contractBox");
let st = window.getComputedStyle(contractBox, null);
var tr = st.getPropertyValue("transform");
if (tr === "none") {
   
  isScale.value = false;
  bigBox.style.height = "auto";
  const height = bigBox.offsetHeight + 50;
  bigBoxHeight.value = height;
} else {
   
  isScale.value = true;
  bigBox.style.height = "auto";
  // 缩放需要 * 缩放比例 + 边距(margin/padding)
  const height = bigBox.offsetHeight * 0.5 + 50;
  // 不用 st.witdh 是因为 st.witdh 获取的值是 700px,不能直接运算,这里菜鸟就偷懒了,不想处理了
  bigBoxmargin.value = (window.innerWidth - 700 * 0.5) / 2;
  bigBoxHeight.value = height;
}

template 代码

<div class="bigBox" :style="{ height: bigBoxHeight + 'px' }">
  <div class="contractBox" :style="{ marginLeft: isScale ? bigBoxmargin + 'px' : 'auto' }">
    <div v-html="printData"></div>
  </div>
  <div class="markBox" :style="{ height: bigBoxHeight + 'px' }"></div>
</div>

签字效果

这里签字效果,菜鸟是使用 el-dialog 实现的,el-dialog 的使用方式见:element plus 使用细节

这里主要粘贴签字的代码

<script setup>
import {
    ref, onMounted, nextTick } from "vue";

// eslint-disable-next-line
const props = defineProps({
   
  dialogVisible: {
   
    type: Boolean,
    default: false,
  },
});

// eslint-disable-next-line
const emit = defineEmits(["closeEvent"]);

// 关闭弹窗
function handleClose() {
   
  emit("closeEvent", false);
  // 解除禁止页面滚动
  document.body.removeEventListener("touchmove", preventDefault);
}
const dialogBox = ref();
function closeDialog() {
   
  dialogBox.value.resetFields();
}

// 禁止页面滚动
function preventDefault(e) {
   
  e.preventDefault();
}
document.body.addEventListener("touchmove", preventDefault, {
    passive: false });

// 签名
// 配置内容
const config = {
   
  width: window.innerWidth, // 宽度
  height: window.innerHeight - 300, // 高度,减300是为了给dialog的footer一点空间显示
  lineWidth: 5, // 线宽
  strokeStyle: "red", // 线条颜色
  lineCap: "round", 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

PBitW

可以去掘金看更完善版本

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值