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

做网站服务器软件wordpress无法连接远程mysql

做网站服务器软件,wordpress无法连接远程mysql,兰州网站关键词优化,超短链接生成器文章目录 获取一个高度会变的元素的高度获取元素设置的 transform适配手机transform-origin: 5% 0; 的原因修改后 签字效果取消el-dialog的头部边距为什么禁止界面滚动vue3 使用 nextTick实现效果 签字判断是横是竖canvas 去掉空白部分canvas裁剪图片最终完善代码#xff0c;可… 文章目录 获取一个高度会变的元素的高度获取元素设置的 transform适配手机transform-origin: 5% 0; 的原因修改后 签字效果取消el-dialog的头部边距为什么禁止界面滚动vue3 使用 nextTick实现效果 签字判断是横是竖canvas 去掉空白部分canvas裁剪图片最终完善代码可以直接使用 最近菜鸟公司要做一个这样的功能后端返回一个合同的整体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 classbigBox :style{ height: bigBoxHeight px }div classcontractBoxdiv v-htmlprintData/div/div!-- 遮罩层返回的printData里设置了可编辑但是这里只是展示用且修改了也不会有影响所以就简单的加个遮罩就行了 --div classmarkBox :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/paddingconst 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为displayflex不然里面的内容就是按照width100%然后缩放0.5而不是width700px来缩放的 是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/paddingconst height bigBox.offsetHeight * 0.5 50;// 不用 st.witdh 是因为 st.witdh 获取的值是 700px不能直接运算这里菜鸟就偷懒了不想处理了bigBoxmargin.value (window.innerWidth - 700 * 0.5) / 2;bigBoxHeight.value height; }template 代码 div classbigBox :style{ height: bigBoxHeight px }div classcontractBox :style{ marginLeft: isScale ? bigBoxmargin px : auto }div v-htmlprintData/div/divdiv classmarkBox :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, // 设置线条两端圆角lineJoin: round, // 线条交汇处圆角 };let canvas null; let ctx null; onMounted(async () {await nextTick();// 获取canvas 实例canvas document.querySelector(.canvas);// 设置宽高canvas.width config.width;canvas.height config.height;// 设置一个边框canvas.style.border 1px solid #000;// 创建上下文ctx canvas.getContext(2d);// 设置填充背景色ctx.fillStyle transparent;// 绘制填充矩形ctx.fillRect(0, // x 轴起始绘制位置0, // y 轴起始绘制位置config.width, // 宽度config.height // 高度); });// 保存上次绘制的 坐标及偏移量 const client {offsetX: 0, // 偏移量offsetY: 0,endX: 0, // 坐标endY: 0, };// 判断是否为移动端 const mobileStatus /Mobile|Android|iPhone/i.test(navigator.userAgent);// 初始化 const init (event) {// 获取偏移量及坐标const { offsetX, offsetY, pageX, pageY } mobileStatus ? event.changedTouches[0] : event;// 修改上次的偏移量及坐标client.offsetX offsetX;client.offsetY offsetY;client.endX pageX;client.endY pageY;// 清除以上一次 beginPath 之后的所有路径进行绘制ctx.beginPath();// 根据配置文件设置相应配置ctx.lineWidth config.lineWidth;ctx.strokeStyle config.strokeStyle;ctx.lineCap config.lineCap;ctx.lineJoin config.lineJoin;// 设置画线起始点位ctx.moveTo(client.endX, client.endY);// 监听 鼠标移动或手势移动window.addEventListener(mobileStatus ? touchmove : mousemove, draw); }; // 绘制 const draw (event) {console.log(event);// 获取当前坐标点位const { pageX, pageY } mobileStatus ? event.changedTouches[0] : event;// 超出范围不监听if (pageY config.height) {return;}// 修改最后一次绘制的坐标点client.endX pageX;client.endY pageY;// 根据坐标点位移动添加线条ctx.lineTo(pageX, pageY);// 绘制ctx.stroke(); }; // 结束绘制 const cloaseDraw () {// 结束绘制ctx.closePath();// 移除鼠标移动或手势移动监听器window.removeEventListener(mousemove, draw); }; // 创建鼠标/手势按下监听器 window.addEventListener(mobileStatus ? touchstart : mousedown, init); // 创建鼠标/手势 弹起/离开 监听器 window.addEventListener(mobileStatus ? touchend : mouseup, cloaseDraw);// 取消-清空画布 const cancel () {// 清空当前画布上的所有绘制内容ctx.clearRect(0, 0, config.width, config.height); }; // 保存-将画布内容保存为图片 const save () {// 将canvas上的内容转成blob流canvas.toBlob((blob) {// 获取当前时间并转成字符串用来当做文件名const date Date.now().toString();// 创建一个 a 标签const a document.createElement(a);// 设置 a 标签的下载文件名a.download ${date}.png;// 设置 a 标签的跳转路径为 文件流地址a.href URL.createObjectURL(blob);// 手动触发 a 标签的点击事件a.click();// 移除 a 标签a.remove();});handleClose(); }; /scripttemplatedivel-dialogtitle签字refdialogBox:modelValuedialogVisible:before-closehandleCloseclosecloseDialog:close-on-click-modalfalse:destroy-on-closetruetop0width100%canvas classcanvas/canvastemplate #footerdivel-button typeprimary clicksave保存/el-buttonel-button clickcancel清除/el-buttonel-button clickhandleClose关闭/el-button/div/template/el-dialog/div /templatestyle langscss .el-dialog__header {display: none; } .el-dialog__body {padding: 0 !important; } /style取消el-dialog的头部边距 因为这里的 client 设置的偏移量都是 0菜鸟不会改感觉应该加上el-dialog的头部边框的偏移量如果不取消的话就是错位着写的 为什么禁止界面滚动 这里禁止是因为手机端签名时写 “竖” 操作时容易触发下拉整个界面的事件导致写字中断体验感极差所以弹窗弹出时阻止事件关闭后移除 这里函数 preventDefault 必须提出不然会取消不掉 vue3 使用 nextTick 获取元素必须在 onMounted 中但是 el-dialog 即使写在 onMounted 里面也不行需要加上 nextTick 实现效果 签字判断是横是竖 今天菜鸟又遇见了大麻烦就是这个签字不能知道别人是横屏横着写的还是竖屏横着写的eg 菜鸟的思路就是获取到签字部分然后如果横着签字就直接截取那部分设置样式如果竖着签字就设置样式旋转 -90deg那如何获取签字部分的大小呢 canvas 去掉空白部分 canvas 去掉空白部分 修改上面 save 中代码 const save () {// 将canvas上的内容转成blob流var imgData ctx.getImageData(0, 0, canvas.width, canvas.height).data;var lOffset canvas.width,rOffset 0,tOffset canvas.height,bOffset 0;for (var i 0; i canvas.width; i) {for (var j 0; j canvas.height; j) {var pos (i canvas.width * j) * 4;if (imgData[pos] 0 || imgData[pos 1] 0 || imgData[pos 2] || imgData[pos 3] 0) {// 说第j行第i列的像素不是透明的// 楼主貌似底图是有背景色的,所以具体判断RGBA的值可以根据是否等于背景色的值来判断bOffset Math.max(j, bOffset); // 找到有色彩的最底部的纵坐标rOffset Math.max(i, rOffset); // 找到有色彩的最右端tOffset Math.min(j, tOffset); // 找到有色彩的最上端lOffset Math.min(i, lOffset); // 找到有色彩的最左端}}} }canvas.getContext(‘2d’).getImageData(0, 0, 宽, 高) 会返回一个当前 canvas 的图像数据对象其中有一个data属性是一个一维数组,这个一维数组每4个下标分别代表了一个像素点的 R,G,B,A 的值只需要遍历这些值就能找到边界了。 感谢canvas 裁剪空白区域 canvas裁剪图片 canvas裁剪图片 但是获取到了区域并不行因为我还需要将其截取然后转成图片传给后端且还要让后端知道到底是横着放 html 模板里还是竖着放思来想去感觉直接返回 base64 的 img 元素给后端更好因为我就可以直接设置style后端只需要放到对应的地方就行所以save继续修改为 const save () {// 将canvas上的内容转成blob流var imgData ctx.getImageData(0, 0, canvas.width, canvas.height).data;var lOffset canvas.width,rOffset 0,tOffset canvas.height,bOffset 0;for (var i 0; i canvas.width; i) {for (var j 0; j canvas.height; j) {var pos (i canvas.width * j) * 4;if (imgData[pos] 0 || imgData[pos 1] 0 || imgData[pos 2] || imgData[pos 3] 0) {// 说第j行第i列的像素不是透明的// 楼主貌似底图是有背景色的,所以具体判断RGBA的值可以根据是否等于背景色的值来判断bOffset Math.max(j, bOffset); // 找到有色彩的最底部的纵坐标rOffset Math.max(i, rOffset); // 找到有色彩的最右端tOffset Math.min(j, tOffset); // 找到有色彩的最上端lOffset Math.min(i, lOffset); // 找到有色彩的最左端}}}// 重新创建一个canvas将之前的canvas上的图片按照获取到的大小去截取const trimmedWidth rOffset - lOffset 1;const trimmedHeight bOffset - tOffset 1;const trimmedCanvas document.createElement(canvas);trimmedCanvas.width trimmedWidth;trimmedCanvas.height trimmedHeight;const trimmedContext trimmedCanvas.getContext(2d);trimmedContext.putImageData(ctx.getImageData(lOffset, tOffset, trimmedWidth, trimmedHeight),0,0);// 将截取后的生成图片并设置样式console.log(trimmedWidth);console.log(trimmedHeight);var newUrl trimmedCanvas.toDataURL();var newImage new Image();newImage.src newUrl;console.log(trimmedWidth trimmedHeight);if (trimmedWidth trimmedHeight) {newImage.style.height 100px;newImage.style.transform rotate(- 90 deg);} else {newImage.style.width 100px;}console.log(newImage);handleClose(); };newImage 打印出来是一个元素 img srcdata:image/png;base64,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 styletransform: rotate(-90deg);至此算是完成了整个签字功能 最终完善代码可以直接使用 其实这里还有一个问题就是不知道横屏后的用户到底是哪边横屏可能要旋转-90deg也可能是正90deg这里菜鸟想的是一个简单办法就是给个示例文字让用户根据示例文字进行签字 template templatedivel-dialogtitle签字refdialogBox:modelValuedialogVisible:before-closehandleCloseclosecloseDialog:close-on-click-modalfalse:destroy-on-closetruetop0width100%div classcanvasBox :style{ height: config.height px }canvas classcanvas/canvasdiv classtipTxt v-showshowTipp示例文字/pp classredTxt请按示例文字方向正楷清晰书写。谢谢/p/div/divtemplate #footerdivel-button typeprimary clicksave保存/el-buttonel-button clickcancel清除/el-buttonel-button clickhandleClose(false)关闭/el-button/div/template/el-dialog/div /templatestyle langscss .el-dialog__header {display: none; } .el-dialog__body {padding: 0 !important; } .canvasBox {position: relative; } .canvas, .tipTxt {position: absolute;top: 0;left: 0;bottom: 0;right: 0; } .tipTxt {display: flex;flex-direction: column;align-items: center;justify-content: center; } .tipTxt p {color: #999;font-size: 80px; } .tipTxt .redTxt {color: rgba(255, 0, 0, 0.5);font-size: 50px; }media screen and (max-width: 690px) {.tipTxt {transform: rotate(90deg);}.tipTxt p {font-size: 50px;}.tipTxt .redTxt {font-size: 18px;} } /stylejs 控制 showTip 的展示 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(imgEl) {console.log(imgEl);emit(closeEvent, imgEl);// 禁止页面滚动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 - 150, // 高度lineWidth: 5, // 线宽strokeStyle: red, // 线条颜色lineCap: round, // 设置线条两端圆角lineJoin: round, // 线条交汇处圆角 };let canvas null; let ctx null; onMounted(async () {await nextTick();// 获取canvas 实例canvas document.querySelector(.canvas);console.log(canvas);// 设置宽高canvas.width config.width;canvas.height config.height;// 设置一个边框canvas.style.border 1px solid #000;// 创建上下文ctx canvas.getContext(2d);// 设置填充背景色ctx.fillStyle transparent;// 绘制填充矩形ctx.fillRect(0, // x 轴起始绘制位置0, // y 轴起始绘制位置config.width, // 宽度config.height // 高度); });// 保存上次绘制的 坐标及偏移量 const client {offsetX: 0, // 偏移量offsetY: 0,endX: 0, // 坐标endY: 0, };// 判断是否为移动端 const mobileStatus /Mobile|Android|iPhone/i.test(navigator.userAgent);// 初始化 const init (event) {// 获取偏移量及坐标const { offsetX, offsetY, pageX, pageY } mobileStatus ? event.changedTouches[0] : event;// 修改上次的偏移量及坐标client.offsetX offsetX;client.offsetY offsetY;client.endX pageX;client.endY pageY;// 清除以上一次 beginPath 之后的所有路径进行绘制ctx.beginPath();// 根据配置文件设置相应配置ctx.lineWidth config.lineWidth;ctx.strokeStyle config.strokeStyle;ctx.lineCap config.lineCap;ctx.lineJoin config.lineJoin;// 设置画线起始点位ctx.moveTo(client.endX, client.endY);// 监听 鼠标移动或手势移动window.addEventListener(mobileStatus ? touchmove : mousemove, draw); }; // 绘制 const draw (event) {showTip.value false;// 获取当前坐标点位const { pageX, pageY } mobileStatus ? event.changedTouches[0] : event;// 修改最后一次绘制的坐标点client.endX pageX;client.endY pageY;// 根据坐标点位移动添加线条ctx.lineTo(pageX, pageY);// 绘制ctx.stroke(); }; // 结束绘制 const cloaseDraw () {// 结束绘制ctx.closePath();// 移除鼠标移动或手势移动监听器window.removeEventListener(mousemove, draw); }; // 创建鼠标/手势按下监听器 window.addEventListener(mobileStatus ? touchstart : mousedown, init); // 创建鼠标/手势 弹起/离开 监听器 window.addEventListener(mobileStatus ? touchend : mouseup, cloaseDraw);// 取消-清空画布 const cancel () {// 清空当前画布上的所有绘制内容ctx.clearRect(0, 0, config.width, config.height);showTip.value true; }; // 保存-将画布内容保存为图片 const save () {// 将canvas上的内容转成blob流var imgData ctx.getImageData(0, 0, canvas.width, canvas.height).data;var lOffset canvas.width,rOffset 0,tOffset canvas.height,bOffset 0;for (var i 0; i canvas.width; i) {for (var j 0; j canvas.height; j) {var pos (i canvas.width * j) * 4;if (imgData[pos] 0 || imgData[pos 1] 0 || imgData[pos 2] || imgData[pos 3] 0) {// 说第j行第i列的像素不是透明的// 楼主貌似底图是有背景色的,所以具体判断RGBA的值可以根据是否等于背景色的值来判断bOffset Math.max(j, bOffset); // 找到有色彩的最底部的纵坐标rOffset Math.max(i, rOffset); // 找到有色彩的最右端tOffset Math.min(j, tOffset); // 找到有色彩的最上端lOffset Math.min(i, lOffset); // 找到有色彩的最左端}}}if (lOffset config.width rOffset 0 tOffset config.height bOffset 0) {// eslint-disable-next-lineElMessage({message: 请签名后保存,type: warning,});return;}const trimmedWidth rOffset - lOffset 1;const trimmedHeight bOffset - tOffset 1;const trimmedCanvas document.createElement(canvas);trimmedCanvas.width trimmedWidth;trimmedCanvas.height trimmedHeight;const trimmedContext trimmedCanvas.getContext(2d);trimmedContext.putImageData(ctx.getImageData(lOffset, tOffset, trimmedWidth, trimmedHeight),0,0);const newUrl trimmedCanvas.toDataURL();const newImage new Image();newImage.src newUrl;console.log(trimmedWidth trimmedHeight);if (trimmedWidth trimmedHeight) {newImage.style.height 100px;newImage.style.transform rotate(- 90 deg);} else {newImage.style.width 100px;}// console.log(newImage.outerHTML /img);handleClose(newImage.outerHTML /img); };// 示例文字 let showTip ref(true); /script效果
http://www.w-s-a.com/news/641953/

相关文章:

  • 网站制作过程内容深圳最好的活动策划公司
  • 深圳网站关键词排名查询公司网站怎么做啊
  • 微网站 制作平台广州电商聚集地
  • 建设外国商城网站网站服务器 虚拟主机
  • 天河网站建设开发电子商务公司名字大全
  • 站长推荐为何用wdcp建立网站连不上ftp
  • 云南旅行社网站开发学编程多久可以写游戏辅助
  • 推广网站的步骤网站备案号中信息有变
  • 优秀企业建站织梦能不能做门户网站
  • 广东省建设局官方网站wordpress 自动安装 插件怎么用
  • 哪类小网站容易做h5页面制作代码
  • 北京网站建设公司华网百度热搜seo
  • 小清新博客网站中山做网站公司
  • 美团做团购网站如何新建自己的网站
  • 安卓软件制作网站电子商务网站建设实训总结报告
  • 肃宁网站制作价格外国设计师素材网站
  • 自已建网站用jsp做的可运行的网站
  • 外贸建站代理网站建设设计公司哪家好
  • 普升高端品牌网站建设台州中兴建设咨询有限公司网站
  • 模板演示网站移动网站开发公司
  • 网站管理办法制度公司招聘信息
  • 宜昌市建设监理协会网站免备案免费域名
  • 河北省建设银行网站首页备案号怎么放到网站
  • 做电脑网站用什么软件有哪些wordpress版权修改
  • 加强部门网站建设工作wordpress文章页横幅
  • 中英网站怎么做wordpress本地音乐
  • 万网提供的网站建设服务的具体项目祥云平台网站建设
  • ftp网站怎么看后台的代码网站 制作软件
  • 网站开发软件教程网站tag 怎么实现
  • 中国建设监理协会化工监理协会网站彩票站自己做网站吗