权威的合肥网站建设石家庄网站建设方案咨询

当前位置: 首页 > news >正文

权威的合肥网站建设,石家庄网站建设方案咨询,wordpress文章标题后显示栏目标题,网站用户反馈话说#xff0c;2020年刚来杭州的时候#xff0c;有用到过uniapp#xff0c;距今已有三年时间了#xff0c;果然全忘了#xff0c;哈哈[笑中带泪] 昨天遇到一个需求#xff1a;就是要实现pdf文件的预览#xff0c;着实费了我很多的时间#xff0c;连晚饭都没有吃好。。…话说2020年刚来杭州的时候有用到过uniapp距今已有三年时间了果然全忘了哈哈[笑中带泪] 昨天遇到一个需求就是要实现pdf文件的预览着实费了我很多的时间连晚饭都没有吃好。。。 这里写目录标题 先写一个小的功能点记录文档预览功能的实现——openDocument放弃web-view放弃iframe决定用uni.openDocument来实现pdf的预览功能。 其他人的写法——没有进行测试哈 电子签名功能html部分代码js部分代码wx.createCanvasContext——用于创建一个canvas绘图上下文对象wx.createSelectorQuery——获取SelectorQuery 对象实例wx.canvasToTempFilePath——把当前画布指定区域的内容导出生成指定大小的图片wx.showToast——提示信息wx.saveImageToPhotosAlbum——保存到系统相册wx.previewImage——预览图片wx.uploadFile——上传文件 css代码 先写一个小的功能点记录文档预览功能的实现——openDocument 放弃web-view 预览pdf我先是考虑了web-view组件因为我有文档的链接然后通过web-view中的src属性链接文档然后实现的文档的预览。web端是没啥问题的但是在手机端打开h5网页的时候会出现空白页且退回时直接无法退回的情况。 放弃iframe 接着我又考虑了一下iframe组件通过给src属性链接文档的形式来展示但是在web端没啥问题但是手机端会直接下载文档而不是预览。放弃iframe 最后咨询了黄河爱浪大神黄河爱浪大神的博客地址https://blog.csdn.net/u013350495?typeblog
决定用uni.openDocument来实现pdf的预览功能。 但是这个api的弊端正如上图所示 pdf预览的效果: 在web端和vivo 小米的h5端可以预览pdf但是会有下载文件的提示不影响预览用华为直接提示下载没有预览功能。这个兼容性不是太好 其他人的写法——没有进行测试哈 uni.downloadFile({url: https://cdn.zhoukaiwen.com/kevin.pdf,success: function(res) {var filePath res.tempFilePath;uni.openDocument({filePath: filePath,success: function(res) {console.log(打开文档成功);}});} })先通过uni.downloadFile的方式拿到文档链接对应的文件临时地址tempFilePath然后再通过uni.openDocument的形式来预览。不知道这样的话会不会就不出现下载的提示了。。。。 电子签名功能 直接上效果图 上代码了 html部分代码 templateviewview classwrapperview classhandBtnimage clickselectColorEvent(black,#1A1A1A) :srcselectColor black ? ../static/other/color_black_selected.png : ../static/other/color_black.png:class[selectColor black ? color_select : , black-select]/imageimage clickselectColorEvent(red,#ca262a) :srcselectColor red ? ../static/other/color_red_selected.png : ../static/other/color_red.png:class[selectColor red ? color_select : , black-select]/imagebutton clickretDraw classdelBtn重写/buttonbutton clicksaveCanvasAsImg classsaveBtn保存/buttonbutton clickpreviewCanvasImg classpreviewBtn预览/buttonbutton clickuploadCanvasImg classuploadBtn上传/buttonbutton clicksubCanvas classsubBtn完成/button/viewview classhandCentercanvas classhandWriting :disable-scrolltrue touchstartuploadScaleStart touchmoveuploadScaleMovetouchenduploadScaleEnd canvas-idhandWriting/canvas/viewview classhandRightview classhandTitle请签名/view/view/view/view /templatejs部分代码 scriptexport default {data() {return {canvasName: handWriting,ctx: ,canvasWidth: 0,canvasHeight: 0,transparent: 1, // 透明度selectColor: black,lineColor: #1A1A1A, // 颜色lineSize: 1.5, // 笔记倍数lineMin: 0.5, // 最小笔画半径lineMax: 4, // 最大笔画半径pressure: 1, // 默认压力smoothness: 60, //顺滑度用60的距离来计算速度currentPoint: {},currentLine: [], // 当前线条firstTouch: true, // 第一次触发radius: 1, //画圆的半径cutArea: {top: 0,right: 0,bottom: 0,left: 0}, //裁剪区域bethelPoint: [], //保存所有线条 生成的贝塞尔点lastPoint: 0,chirography: [], //笔迹currentChirography: {}, //当前笔迹linePrack: [] //划线轨迹 , 生成线条的实际点};},onLoad() {let canvasName this.canvasName;let ctx wx.createCanvasContext(canvasName);this.ctx ctx;var query wx.createSelectorQuery();query.select(.handCenter).boundingClientRect(rect {this.canvasWidth rect.width;this.canvasHeight rect.height;/* 将canvas背景设置为 白底不设置 导出的canvas的背景为透明 */this.setCanvasBg(#fff);}).exec();},methods: {// 笔迹开始uploadScaleStart(e) {if (e.type ! touchstart) return false;let ctx this.ctx;ctx.setFillStyle(this.lineColor); // 初始线条设置颜色ctx.setGlobalAlpha(this.transparent); // 设置半透明let currentPoint {x: e.touches[0].x,y: e.touches[0].y};let currentLine this.currentLine;currentLine.unshift({time: new Date().getTime(),dis: 0,x: currentPoint.x,y: currentPoint.y});this.currentPoint currentPoint;// currentLineif (this.firstTouch) {this.cutArea {top: currentPoint.y,right: currentPoint.x,bottom: currentPoint.y,left: currentPoint.x};this.firstTouch false;}this.pointToLine(currentLine);},// 笔迹移动uploadScaleMove(e) {if (e.type ! touchmove) return false;if (e.cancelable) {// 判断默认行为是否已经被禁用if (!e.defaultPrevented) {e.preventDefault();}}let point {x: e.touches[0].x,y: e.touches[0].y};//测试裁剪if (point.y this.cutArea.top) {this.cutArea.top point.y;}if (point.y 0) this.cutArea.top 0;if (point.x this.cutArea.right) {this.cutArea.right point.x;}if (this.canvasWidth - point.x 0) {this.cutArea.right this.canvasWidth;}if (point.y this.cutArea.bottom) {this.cutArea.bottom point.y;}if (this.canvasHeight - point.y 0) {this.cutArea.bottom this.canvasHeight;}if (point.x this.cutArea.left) {this.cutArea.left point.x;}if (point.x 0) this.cutArea.left 0;this.lastPoint this.currentPoint;this.currentPoint point;let currentLine this.currentLine;currentLine.unshift({time: new Date().getTime(),dis: this.distance(this.currentPoint, this.lastPoint),x: point.x,y: point.y});this.pointToLine(currentLine);},// 笔迹结束uploadScaleEnd(e) {if (e.type ! touchend) return 0;let point {x: e.changedTouches[0].x,y: e.changedTouches[0].y};this.lastPoint this.currentPoint;this.currentPoint point;let currentLine this.currentLine;currentLine.unshift({time: new Date().getTime(),dis: this.distance(this.currentPoint, this.lastPoint),x: point.x,y: point.y});if (currentLine.length 2) {var info (currentLine[0].time - currentLine[currentLine.length - 1].time) / currentLine.length;//$(#info).text(info.toFixed(2));}//一笔结束保存笔迹的坐标点清空当前笔迹//增加判断是否在手写区域this.pointToLine(currentLine);var currentChirography {lineSize: this.lineSize,lineColor: this.lineColor};var chirography this.chirography;chirography.unshift(currentChirography);this.chirography chirography;var linePrack this.linePrack;linePrack.unshift(this.currentLine);this.linePrack linePrack;this.currentLine [];},retDraw() {this.ctx.clearRect(0, 0, 700, 730);this.ctx.draw();//设置canvas背景this.setCanvasBg(#fff);},//画两点之间的线条参数为:line会绘制最近的开始的两个点pointToLine(line) {this.calcBethelLine(line);return;},//计算插值的方式calcBethelLine(line) {if (line.length 1) {line[0].r this.radius;return;}let x0,x1,x2,y0,y1,y2,r0,r1,r2,len,lastRadius,dis 0,time 0,curveValue 0.5;if (line.length 2) {x0 line[1].x;y0 line[1].y;x2 line[1].x (line[0].x - line[1].x) * curveValue;y2 line[1].y (line[0].y - line[1].y) * curveValue;//x2 line[1].x;//y2 line[1].y;x1 x0 (x2 - x0) * curveValue;y1 y0 (y2 - y0) * curveValue;} else {x0 line[2].x (line[1].x - line[2].x) * curveValue;y0 line[2].y (line[1].y - line[2].y) * curveValue;x1 line[1].x;y1 line[1].y;x2 x1 (line[0].x - x1) * curveValue;y2 y1 (line[0].y - y1) * curveValue;}//从计算公式看三个点分别是(x0,y0),(x1,y1),(x2,y2) (x1,y1)这个是控制点控制点不会落在曲线上实际上这个点还会手写获取的实际点却落在曲线上len this.distance({x: x2,y: y2}, {x: x0,y: y0});lastRadius this.radius;for (let n 0; n line.length - 1; n) {dis line[n].dis;time line[n].time - line[n 1].time;if (dis this.smoothness) break;}this.radius Math.min((time / len) * this.pressure this.lineMin, this.lineMax) * this.lineSize;line[0].r this.radius;//计算笔迹半径if (line.length 2) {r0 (lastRadius this.radius) / 2;r1 r0;r2 r1;//return;} else {r0 (line[2].r line[1].r) / 2;r1 line[1].r;r2 (line[1].r line[0].r) / 2;}let n 5;let point [];for (let i 0; i n; i) {let t i / (n - 1);let x (1 - t) * (1 - t) * x0 2 * t * (1 - t) * x1 t * t * x2;let y (1 - t) * (1 - t) * y0 2 * t * (1 - t) * y1 t * t * y2;let r lastRadius ((this.radius - lastRadius) / n) * i;point.push({x: x,y: y,r: r});if (point.length 3) {let a this.ctaCalc(point[0].x, point[0].y, point[0].r, point[1].x, point[1].y, point[1].r, point[2].x, point[2].y, point[2].r);a[0].color this.lineColor;// let bethelPoint this.bethelPoint;// bethelPoint bethelPoint.push(a);this.bethelDraw(a, 1);point [{x: x,y: y,r: r}];}}this.currentLine line;},//求两点之间距离distance(a, b) {let x b.x - a.x;let y b.y - a.y;return Math.sqrt(x * x y * y);},ctaCalc(x0, y0, r0, x1, y1, r1, x2, y2, r2) {let a [],vx01,vy01,norm,n_x0,n_y0,vx21,vy21,n_x2,n_y2;vx01 x1 - x0;vy01 y1 - y0;norm Math.sqrt(vx01 * vx01 vy01 * vy01 0.0001) * 2;vx01 (vx01 / norm) * r0;vy01 (vy01 / norm) * r0;n_x0 vy01;n_y0 -vx01;vx21 x1 - x2;vy21 y1 - y2;norm Math.sqrt(vx21 * vx21 vy21 * vy21 0.0001) * 2;vx21 (vx21 / norm) * r2;vy21 (vy21 / norm) * r2;n_x2 -vy21;n_y2 vx21;a.push({mx: x0 n_x0,my: y0 n_y0,color: #1A1A1A});a.push({c1x: x1 n_x0,c1y: y1 n_y0,c2x: x1 n_x2,c2y: y1 n_y2,ex: x2 n_x2,ey: y2 n_y2});a.push({c1x: x2 n_x2 - vx21,c1y: y2 n_y2 - vy21,c2x: x2 - n_x2 - vx21,c2y: y2 - n_y2 - vy21,ex: x2 - n_x2,ey: y2 - n_y2});a.push({c1x: x1 - n_x2,c1y: y1 - n_y2,c2x: x1 - n_x0,c2y: y1 - n_y0,ex: x0 - n_x0,ey: y0 - n_y0});a.push({c1x: x0 - n_x0 - vx01,c1y: y0 - n_y0 - vy01,c2x: x0 n_x0 - vx01,c2y: y0 n_y0 - vy01,ex: x0 n_x0,ey: y0 n_y0});a[0].mx a[0].mx.toFixed(1);a[0].mx parseFloat(a[0].mx);a[0].my a[0].my.toFixed(1);a[0].my parseFloat(a[0].my);for (let i 1; i a.length; i) {a[i].c1x a[i].c1x.toFixed(1);a[i].c1x parseFloat(a[i].c1x);a[i].c1y a[i].c1y.toFixed(1);a[i].c1y parseFloat(a[i].c1y);a[i].c2x a[i].c2x.toFixed(1);a[i].c2x parseFloat(a[i].c2x);a[i].c2y a[i].c2y.toFixed(1);a[i].c2y parseFloat(a[i].c2y);a[i].ex a[i].ex.toFixed(1);a[i].ex parseFloat(a[i].ex);a[i].ey a[i].ey.toFixed(1);a[i].ey parseFloat(a[i].ey);}return a;},bethelDraw(point, is_fill, color) {let ctx this.ctx;ctx.beginPath();ctx.moveTo(point[0].mx, point[0].my);if (undefined ! color) {ctx.setFillStyle(color);ctx.setStrokeStyle(color);} else {ctx.setFillStyle(point[0].color);ctx.setStrokeStyle(point[0].color);}for (let i 1; i point.length; i) {ctx.bezierCurveTo(point[i].c1x, point[i].c1y, point[i].c2x, point[i].c2y, point[i].ex, point[i].ey);}ctx.stroke();if (undefined ! is_fill) {ctx.fill(); //填充图形 ( 后绘制的图形会覆盖前面的图形, 绘制时注意先后顺序 )}ctx.draw(true);},selectColorEvent(str, color) {this.selectColor str;this.lineColor color;},//将Canvas内容转成 临时图片 – cb 为回调函数 形参 tempImgPath 为 生成的图片临时路径canvasToImg(cb) {//这种写法移动端 出不来this.ctx.draw(true, () {wx.canvasToTempFilePath({canvasId: handWriting,fileType: png,quality: 1, //图片质量success(res) {// console.log(res.tempFilePath, canvas生成图片地址);wx.showToast({title: 执行了吗});cb(res.tempFilePath);}});});},//完成subCanvas() {this.ctx.draw(true, () {wx.canvasToTempFilePath({canvasId: handWriting,fileType: png,quality: 1, //图片质量success(res) {// console.log(res.tempFilePath, canvas生成图片地址);wx.showToast({title: 以保存});//保存到系统相册wx.saveImageToPhotosAlbum({filePath: res.tempFilePath,success(res) {wx.showToast({title: 已成功保存到相册,duration: 2000});}});}});});},//保存到相册saveCanvasAsImg() {/this.canvasToImg( tempImgPath{// console.log(tempImgPath, 临时路径);wx.saveImageToPhotosAlbum({filePath: tempImgPath,success(res) {wx.showToast({title: 已保存到相册,duration: 2000});}})} );/wx.canvasToTempFilePath({canvasId: handWriting,fileType: png,quality: 1, //图片质量success(res) {// console.log(res.tempFilePath, canvas生成图片地址);wx.saveImageToPhotosAlbum({filePath: res.tempFilePath,success(res) {wx.showToast({title: 已保存到相册,duration: 2000});}});}});},//预览previewCanvasImg() {wx.canvasToTempFilePath({canvasId: handWriting,fileType: jpg,quality: 1, //图片质量success(res) {// console.log(res.tempFilePath, canvas生成图片地址);wx.previewImage({urls: [res.tempFilePath] //预览图片 数组});}});/* //移动端出不来 ^~^this.canvasToImg( tempImgPath{wx.previewImage({urls: [tempImgPath], //预览图片 数组})} );/},//上传uploadCanvasImg() {wx.canvasToTempFilePath({canvasId: handWriting,fileType: png,quality: 1, //图片质量success(res) {// console.log(res.tempFilePath, canvas生成图片地址);//上传wx.uploadFile({url: https://example.weixin.qq.com/upload, // 仅为示例非真实的接口地址filePath: res.tempFilePath,name: file_signature,formData: {user: test},success(res) {const data res.data;// do something}});}});},//设置canvas背景色 不设置 导出的canvas的背景为透明//params字符串 colorsetCanvasBg(color) {/ 将canvas背景设置为 白底不设置 导出的canvas的背景为透明 *///rect() 参数说明 矩形路径左上角的横坐标左上角的纵坐标, 矩形路径的宽度, 矩形路径的高度//这里是 canvasHeight - 4 是因为下边盖住边框了所以手动减了写this.ctx.rect(0, 0, this.canvasWidth, this.canvasHeight - 4);// ctx.setFillStyle(red)this.ctx.setFillStyle(color);this.ctx.fill(); //设置填充this.ctx.draw(); //开画}}}; /scriptwx.createCanvasContext——用于创建一个canvas绘图上下文对象 wx.createCanvasContext是一个微信小程序API用于创建一个canvas绘图上下文对象。通过该对象可以进行canvas绘图操作例如绘制图形、文字、图片等。在小程序中可以使用该API来实现一些复杂的图形绘制和动画效果。 wx.createSelectorQuery——获取SelectorQuery 对象实例 获取SelectorQuery 对象实例 var query wx.createSelectorQuery() //返回一个SelectorQuery 对象实例 使用SelectorQuery 对象方法如 var nodesRef query.select(“#my”) //返回一个NodesRef 对象实例 wx.canvasToTempFilePath——把当前画布指定区域的内容导出生成指定大小的图片 wx.canvasToTempFilePath(Object object, Object this) 把当前画布指定区域的内容导出生成指定大小的图片。在 draw() 回调里调用该方法才能保证图片导出成功。 wx.showToast——提示信息 wx.saveImageToPhotosAlbum——保存到系统相册 小程序保存图片到系统相册wx.saveImageToPhotosAlbum wx.previewImage——预览图片 wx.uploadFile——上传文件 css代码 stylepage {background: #fbfbfb;height: auto;overflow: hidden;}.wrapper {width: 100%;height: 95vh;margin: 30rpx 0;overflow: hidden;display: flex;align-content: center;flex-direction: row;justify-content: center;font-size: 28rpx;}.handWriting {background: #fff;width: 100%;height: 95vh;}.handRight {display: inline-flex;align-items: center;}.handCenter {border: 4rpx dashed #e9e9e9;flex: 5;overflow: hidden;box-sizing: border-box;}.handTitle {transform: rotate(90deg);flex: 1;color: #666;}.handBtn button {font-size: 28rpx;}.handBtn {height: 95vh;display: inline-flex;flex-direction: column;justify-content: space-between;align-content: space-between;flex: 1;}.delBtn {position: absolute;top: 250rpx;left: 0rpx;transform: rotate(90deg);color: #666;}.delBtn image {position: absolute;top: 13rpx;left: 25rpx;}.subBtn {position: absolute;bottom: 52rpx;left: -3rpx;display: inline-flex;transform: rotate(90deg);background: #008ef6;color: #fff;margin-bottom: 30rpx;text-align: center;justify-content: center;}/Peach - 新增 - 保存/.saveBtn {position: absolute;top: 375rpx;left: 0rpx;transform: rotate(90deg);color: #666;}.previewBtn {position: absolute;top: 500rpx;left: 0rpx;transform: rotate(90deg);color: #666;}.uploadBtn {position: absolute;top: 625rpx;left: 0rpx;transform: rotate(90deg);color: #666;}/Peach - 新增 - 保存/.black-select {width: 60rpx;height: 60rpx;position: absolute;top: 30rpx;left: 25rpx;}.black-select.color_select {width: 90rpx;height: 90rpx;top: 100rpx;left: 10rpx;}.red-select {width: 60rpx;height: 60rpx;position: absolute;top: 140rpx;left: 25rpx;}.red-select.color_select {width: 90rpx;height: 90rpx;top: 120rpx;left: 10rpx;} /style 完成多多积累多多收获