实现图
实现方案:
通过 web-view 外接h5界面实现
<web-view src="https://test.XXX.XXX.com/index.php/PdfH5EZ/pdfH5">
</web-view>
需要在小程序开发管理 添加业务域名
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="format-detection" content="telephone=no" />
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<title>合同签名</title>
<link rel="stylesheet" href="css/style.css" />
<link rel="stylesheet" href="css/pdfh5.css" />
<meta charset="utf-8">
<style>
body,
html {
width: 100%;
margin: 0;
padding: 0;
height: 100%;
}
#demo {
display: none;
height: 90%;
}
#canvas-btn {
display: flex;
align-items: center;
justify-content: center;
margin: 0;
/*padding: 0.13rem;*/
}
#clear_btn {
width: 30%;
background: #ca4341;
margin: auto;
text-align: center;
line-height: 1rem;
margin-top: 0.27rem;
color: #fff;
border-radius: 1.31rem;
clear: both;
}
#save_btn {
width: 30%;
background: #4cd964;
margin: auto;
text-align: center;
line-height: 1rem;
margin-top: 0.27rem;
color: #fff;
border-radius: 1.31rem;
clear: both;
}
#showToastWraper {
position: fixed;
z-index: 999;
top: 35%;
right: 0;
left: 0;
width: 90%;
margin: auto;
background: rgba(0, 0, 0, 0.6);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#7f000000, endColorstr=#7f000000);
text-align: center;
padding: 10px 20px;
color: #dcdcdc;
border-radius: 50px;
}
</style>
</head>
<body>
<div id="app">
<div class="text-wrapper">
<div class="text part1">
<div>
<span class="letter">
<div class="character">L</div> <span></span>
</span>
<span class="letter">
<div class="character">o</div> <span></span>
</span>
<span class="letter">
<div class="character">a</div> <span></span>
</span>
<span class="letter">
<div class="character">d</div> <span></span>
</span>
<span class="letter">
<div class="character">i</div> <span></span>
</span>
<span class="letter">
<div class="character">n</div> <span></span>
</span>
<span class="letter">
<div class="character">g</div> <span></span>
</span>
</div>
</div>
<div class="how-to"><span>正在加载中,请您耐心等待...</span></div>
</div>
</div>
<div id="demo"></div>
<!-- <canvas id='canvas'></canvas>-->
<div id="canvas-btn">
<div id="clear_btn" class="op_btn">返回订单</div>
<div id="save_btn" onclick="SendMsg()" class="save_btn">签署合同</div>
<div class="cleaerfix"></div>
</div>
<!-- pdf的js -->
<script src="js/pdf.js"></script>
<script src="js/pdf.worker.js"></script>
<script src="js/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script>
<script src="js/pdfh5.js" type="text/javascript" charset="utf-8"></script>
<!-- 签名的js -->
<script type="text/javascript" src="js/flexible.debug.js"></script>
<script type="text/javascript" src="js/zepto.js"></script>
<script type="text/javascript" src="js/touch.js"></script>
<script type="text/javascript" src="js/flexible.debug.js"></script>
<script type="text/javascript" src="js/flexible_css.debug.js"></script>
<script type="text/javascript">
var pdfh5;
$(function () {
$("#app").remove()
$("#demo").show()
var query = window.location.search.substring(1);
var url = query.split("=")[1]; //通过路由获取pdf文件线上地址
console.log('url??',url)
pdfh5 = new Pdfh5('#demo', {
//'https://feiyunphoneapp.oss-cn-shenzhen.aliyuncs.com/esign/esignfile/d4060a627c79489b85a4ca362f9870f5.pdf'
pdfurl: 'https://feiyunphoneapp.oss-cn-shenzhen.aliyuncs.com/esign/esignfile/d4060a627c79489b85a4ca362f9870f5.pdf',
// pdfurl: url, //pdf线上地址
// ,URIenable:true //开启浏览器地址栏file参数获取
});
//pdf准备开始渲染,此时可以拿到pdf总页数
pdfh5.on("ready", function () {
console.log("pdf准备开始渲染,总页数:" + this.totalNum)
})
//监听pdf渲染成功
pdfh5.on("success", function (time) {
time = time / 1000
console.log("pdf渲染完成,总耗时" + time + "秒")
})
})
</script>
<script>
//是否已签名
var isSign = false
//是否已提交签名
var haveSign = false
//获取页面尺寸
var canvasWidth = document.body.clientWidth;
var canvasHeight = canvasWidth;
//声明canvas
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
//设置canvas尺寸
canvas.width = canvasWidth * 0.98;
canvas.height = canvasHeight * 0.45;
//画笔颜色
var strokeColor = "#000";
//鼠标
isMouseDown = false;
//上一次绘制的的坐标
var lastLoc = { x: 0, y: 0 };
//初始记录事件
var lastTimestamp = 0;
//上一次线条宽度
var lastLineWidth = -1;
//var
var maxV = 10;
var minV = 0.1;
var maxLineWidth = 5;
var minLineWidth = 1;
//点击色块切换画笔颜色
$(".colorBtn").on("click", function (e) {
$(".colorBtn").removeClass('colorBtnBorder');
$(this).addClass("colorBtnBorder");
strokeColor = $(this).css("");
})
//清除
$('#clear_btn').on('click', function (e) {
context.clearRect(0, 0, canvasWidth, canvasHeight);
isSign = false
});
function submitImg (orderId,imgData) {
$.ajax({
url: "http://域名或ip地址/oa/order/qiangmingSaving", //假设这是pdf文件流的请求接口
type: "post",
data: {
orderId: orderId,
qianming: imgData.substring(22)
},
success: function (res) {
console.log(res)
if (res.code==200) {
haveSign = true
showToast('提交签名成功');
} else {
showToast('提交签名失败');
}
}
});
}
// 弹窗提示
function showToast(text, width, radius) {
var widthDiv = width ? width : '50%';//自定义宽度
var radiusDiv = radius ? radius : '50px';//自定义边框角度
//此处你还可以定义 位置、文字颜色大小、背景色、显示时长等等
var showToastDiv = "<div id='showToastWraper'></div>";
var showToastWraper = $("#showToastWraper");
var isExat = showToastWraper.length;
if (!isExat) {
//第一次创建元素 并且设置元素把显示状态的停止掉、渐隐显示、显示文本内容、设置自定义样式、1.5s后渐隐消失
$(document.body).append(showToastDiv);
$("#showToastWraper").stop().fadeIn(300).html(text).css({ width: widthDiv, borderRadius: radiusDiv }).delay(1500).fadeOut(500);
} else {
//第二次 就不需要创建元素了减少dom操作
showToastWraper.stop().fadeIn(300).html(text).css({ width: widthDiv, borderRadius: radiusDiv }).delay(1500).fadeOut(500);
}
}
// 消息推送
function SendMsg(){
$.ajax({
url: "https://test.xxxx.xxxx.com/index.php/WXApi/WXLogin/sendMsg", //
type: "post",
// data: {
// orderId: orderId,
// qianming: imgData.substring(22)
// },
success: function (res) {
console.log(res)
showToast('发送成功');
// if (res.code==200) {
// haveSign = true
// showToast('发送成功');
// } else {
// showToast('发送失败');
// }
}
});
}
// 将canvas转换成画布
function canvasToImage(canvas) {
// var image = new Image();
// image.src = canvas.toDataURL("image/png");
// return image;
return canvas.toDataURL("image/png");
}
//获取canvas 坐标 x,y 分别代表相对window内的xy
function windowToCanvas(x, y) {
//canvas提供的方法返回canvas 距 他外围包围盒子的距离left,top值
var bbox = canvas.getBoundingClientRect();
//返回的就是canvas 内的坐标值
return { x: Math.round(x - bbox.left), y: Math.round(y - bbox.top) }
}
//封装 事件
function beginStroke(point) {
isMouseDown = true;
//第一次用户画的坐标初始值
lastLoc = windowToCanvas(point.x, point.y);
//获取首次点击鼠标 事件戳
lastTimestamp = new Date().getTime();
}
function endStroke() {
isMouseDown = false;
}
function moveStroke(point) {
//开始绘制直线
var curLoc = windowToCanvas(point.x, point.y);
//路程
var s = calcDistance(curLoc, lastLoc);
//结束时间
var curTimestamp = new Date().getTime();
//时间差
var t = curTimestamp - lastTimestamp;
//绘制线条粗细
var lineWidth = calcLineWidth(t, s);
//绘制
context.beginPath();
context.moveTo(lastLoc.x, lastLoc.y);
context.lineTo(curLoc.x, curLoc.y);
context.strokeStyle = strokeColor;
context.lineWidth = lineWidth;
context.lineCap = "round";
context.lineJoin = "round";
context.stroke();
//给lastLoc赋值维护
lastLoc = curLoc;
//时间更新
lastTimestamp = curTimestamp;
lastLineWidth = lineWidth;
}
//pc鼠标事件
canvas.onmousedown = function (e) {
e.preventDefault();
beginStroke({ x: e.clientX, y: e.clientY });
}
canvas.onmouseup = function (e) {
e.preventDefault();
endStroke();
}
canvas.onmouseout = function (e) {
e.preventDefault();
endStroke();
isSign = true
}
canvas.onmousemove = function (e) {
e.preventDefault();
if (isMouseDown) {
moveStroke({ x: e.clientX, y: e.clientY });
}
}
//移动端
canvas.addEventListener("touchstart", function (e) {
e.preventDefault();
touch = e.touches[0]; //限制一根手指触碰屏幕
beginStroke({ x: touch.pageX, y: touch.pageY });
});
canvas.addEventListener("touchend", function (e) {
e.preventDefault();
endStroke();
isSign = true
});
canvas.addEventListener("touchmove", function (e) {
e.preventDefault();
if (isMouseDown) {
touch = e.touches[0];
moveStroke({ x: touch.pageX, y: touch.pageY });
}
});
//速度 = 路程 / 时间 用来计算书写速度来改变线条粗细
function calcDistance(loc1, loc2) {
//返回 数的平方根
return Math.sqrt((loc1.x - loc2.x) * (loc1.x - loc2.x) + (loc1.y - loc2.y) * (loc1.y - loc2.y));
}
//线条宽度
function calcLineWidth(t, s) {
var v = s / t;
var resultLineWidth;
if (v <= minV) {
resultLineWidth = maxLineWidth;
} else if (v >= maxV) {
resultLineWidth = minLineWidth;
} else {
resultLineWidth = maxLineWidth - (v - minV) / (maxV - minV) * (maxLineWidth - minLineWidth);
}
if (lastLineWidth == -1) {
return resultLineWidth;
} else {
return lastLineWidth * 2 / 3 + resultLineWidth * 1 / 3;
}
}
</script>
</body>
</html>