前端手写电子签名板实现方案

article/2025/7/2 4:22:51

前端手写电子签名板实现

作者:@ 很菜的小白在分享
时间:2022年12月29日



示例图

介绍

什么是电子签名

电子签名是指数据电文中以电子形式所含、所附用于识别签名人身份并表明签名人认可其中内容的数据。—— 百度百科

通俗点说其实就是通过在电子设备上进行类似纸面上签字的效果。在如今互联网快速发展的时代,可以实现云签名,在线签订合同等各种场景。


初衷

这个功能是我在日常开发项目时遇到的需求场景,背景是公司开发的在线教育客户端,允许学生在客户端进行学习和答题,题目类型中有一项“解答题”,需要学生通过手写答题的方式进行作答。因为是第一次接触在线教育类型项目和这样的需求,所以产生了一些思考。

由于项目是使用uniApp开发的Pad客户端,在实现上与原生js有所区别,所以本文将通过原生js的方式重新实现一遍,并且让组件更加灵活通用。


思考

在刚接触到这个需求时,有的同学表示懵逼3连,这怎么实现?其实你只要相信,只要产品能提出的需求,世面上存在这样的功能,不管是用什么语言实现的,排除一些特殊功能,js大部分都可以实现。<canvas> 标签会在页面上创建一块画布允许我们在上面绘制各种图形,下面介绍实现该功能的主要技术点,如果对 Canvas 技术了解的可以直接跳过介绍部分。


什么是 canvas

Canvas API 提供了一个通过JavaScript 和 HTML的<canvas>元素来绘制图形的方式。它可以用于动画、游戏画面、数据可视化、图片编辑以及实时视频处理等方面。 —— MDN

举个例子:比如我们要实现一个长、宽各为50px的正方形。

正常操作:

  <div style="width: 50px; height: 50px; background-color: #000;"></div>

Canvas方式:

  <canvas id="myCanvas" width="200px" height="200px"></canvas><script>const canvas = document.getElementById('canvas')const ctx = canvas.getContext("2d")ctx.fillStyle = "#000"ctx.fillRect(0, 0, 50, 50)</script>

实现效果

虽然这个例子中 Canvas 的实现方式更为复杂,那是因为 Canvas 在某些效果方面确实优于 html + css的方式,比如你需要绘制 sinx 的曲线,使用html+css方式就没有那么容易了,相反 Canvas可以轻松实现。

下面介绍一些常用到的 Canvas API。


Canvas 常用API

属性名说明返回值
width<canvas>元素的width属性,以CSS像素表示,未指定或者值为无效值(例如负数),则默认为300<canvas>元素的宽度
height<canvas>元素的height属性,以CSS像素表示,未指定或者值为无效值(例如负数),则默认为150<canvas>元素的高度

Canvas 常用方法

方法名说明参数返回值
captureStream()返回 CanvasCaptureMediaStream ,它是对画布表面的实时视频捕获。CanvasCaptureMediaStream
getContext()返回画布上的绘图上下文;如果不支持上下文 ID,则返回 null。2d webgl webgl2 bitmaprendererCanvasContext
toDataURL()返回由类型参数指定的格式的图像数据URL。参考type encoderOptionsData Url
toBlob()创建一个Blob 对象,表示 canvas 中包含的图像;该文件可以由用户代理决定是否缓存在磁盘上或存储在内存中。参考callback type type quality

CanvasRenderingContext2D 常用API

属性名说明
canvas获取上下文关联的Canvas元素
fillStyle描述颜色和样式的属性。默认值是 #000 (黑色)。
font描述绘制文字时,当前字体样式的属性。
lineCap指定如何绘制每一条线段末端的属性。有 3 个可能的值,分别是:butt, round and square。默认值是 butt。
lineWidth设置线段厚度的属性(即线段的宽度)。
strokeStyle描述画笔(绘制图形)颜色或者样式的属性。默认值是 #000 (black)。
textAlign描述绘制文本时,文本的对齐方式的属性。
textAlign描述绘制文本时,文本的对齐方式的属性。

CanvasRenderingContext2D 常用方法

参考

方法名说明
arc()绘制圆弧路径的方法。
beginPath()通过清空子路径列表开始一个新路径的方法。当你想创建一个新的路径时,调用此方法。
clearRect()通过把像素设置为透明以达到擦除一个矩形区域的目的。
drawImage()提供了多种在画布(Canvas)上绘制图像的方式。
getImageData()返回一个ImageData对象,用来描述 canvas 区域隐含的像素数据,这个区域通过矩形表示,起始点为(sx, sy)、宽为sw、高为sh。
lineTo()使用直线连接子路径的终点到 x,y 坐标的方法(并不会真正地绘制)。
moveTo()将一个新的子路径的起始点移动到 (x,y) 坐标的方法。
measureText()返回一个关于被测量文本TextMetrics 对象包含的信息(例如它的宽度)。
save()通过将当前状态放入栈中,保存 canvas 全部状态的方法。
stroke()使用非零环绕规则,根据当前的画线样式,绘制当前或已经存在的路径的方法。

由于文章内容有限所以只列举常用 API 及 方法,想了解更多可以前往 MDN 了解更多 Canvas 相关知识。


实现

实现思路

实现思路大致就是,通过当前鼠标移动的位置在 Canvas 画布上绘制出鼠标的移动轨迹点,然后利用 Canvas 提供的 API 将点连成线来实现手写签名的过程。


具体实现

  /*** @class* @classdesc 实现手写签名的构造函数* @param {Object} 手写签名画板的配置项*/function DrawingBoard(options) {if (!(this instanceof DrawingBoard)) {throw new TypeError("DrawingBoard constructor cannot be invoked without 'new'")}this.options = optionsthis.canvas = nullthis.ctx = nullthis.drawStatus = falseconst _this = this/*** @method* @param {Event} event 事件对象* @desc 鼠标按下事件*/DrawingBoard.prototype.touchStartPC = function (event) {_this.drawStatus = trueconst {offsetX, offsetY} = event_this.createBrush(offsetX, offsetY)}/*** @method* @param {Event} event 事件对象* @desc 鼠标移动事件*/DrawingBoard.prototype.touchMovePC = function (event) {if (!_this.drawStatus) return;const {offsetX, offsetY} = event_this.drawPixel({offsetX, offsetY})}/*** @method* @param {Event} event 事件对象* @desc 鼠标抬起事件*/DrawingBoard.prototype.touchEndPC = function (event) {_this.drawStatus = false}this.initSignatureCanvas()}/*** 初始化画板*/DrawingBoard.prototype.initSignatureCanvas = function () {let canvas = document.createElement('canvas')canvas.setAttribute('width', '200px')canvas.setAttribute('height', '200px')this.canvas = canvasthis.bindEvent(canvas)this.ctx = canvas.getContext('2d')this.options.el?.appendChild(canvas)}/*** @method* @param {Number} x 画笔的 x 坐标* @param {Number} y 画笔的 y 坐标* @desc 移动画笔创建连接点*/DrawingBoard.prototype.createBrush = function (x, y) {this.ctx.beginPath()this.ctx.moveTo(x, y)}/*** @method* @param {Object} options 绘制线条的 x,y 坐标* @desc 根据点坐标绘制连线*/DrawingBoard.prototype.drawPixel = function (options) {const {offsetX, offsetY} = optionsthis.ctx.lineTo(offsetX, offsetY)this.ctx.fill()this.ctx.stroke();this.createBrush(offsetX, offsetY)}/*** @method* @desc 事件绑定*/DrawingBoard.prototype.bindEvent = function () {this.canvas.addEventListener("mousedown", this.touchStartPC)this.canvas.addEventListener("mousemove", this.touchMovePC)this.canvas.addEventListener("mouseup", this.touchEndPC)}

示例

  <style>#drawingBoard {position: absolute;top: 200px;left: 200px;width: 200px;border: 2px solid #000;border-radius: 4px;overflow: hidden;}</style><div id="drawingBoard"></div>
  var board = DrawingBoard({el: document.getElementById('drawingBoard'),})

效果

实现效果

扩展

自定义画布尺寸

initSignatureCanvas方法调整,新增 addAttribute 为画布添加属性样式。

  /*** 初始化画板*/DrawingBoard.prototype.initSignatureCanvas = function () {let canvas = document.createElement('canvas')this.canvas = canvas// 新增this.addAttribute(canvas)this.bindEvent(canvas)this.ctx = canvas.getContext('2d')this.options.el?.appendChild(canvas)}/*** @method* @desc 为容器和画布添加属性样式*/DrawingBoard.prototype.addAttribute = function () {let { width, height, style } = this.optionsconst container = this.getClientRect()let styleParse = ''if(!width) width = '200px'if(!height) height = '200px'for (const key in style) {if (Object.prototype.hasOwnProperty.call(style, key)) {styleParse += `${toSplitLine(key)}: ${style[key]};`}}this.canvas.setAttribute('width', width)this.canvas.setAttribute('height', height)this.canvas.setAttribute('style', styleParse)if (this.options.el) { if(container.width <= 0) this.options.el.style.width = widthif (container.height <= 0) this.options.el.style.height = heightif (this.options.brush && this.options.brush.pointer) {this.options.el.style.cursor = `url(${this.options.brush.pointer}) 0 16, default`}}}

options 配置项增加 width height 属性,允许传入画布尺寸信息,例:‘200px’。当未设置 #drawingBoard 容器宽高时,使用 options.width,默认:200px

示例

  var board = new DrawingBoard({el: document.getElementById('drawingBoard'),width: '200px',height: '200px'})

画板的禁用&启用

disable enable 用于切换画板是否启用。

  /*** @method* @desc 禁用画布*/DrawingBoard.prototype.disable = function () {this.isDisable = truethis.unBindEvent()}/*** @method* @desc 启用画布*/DrawingBoard.prototype.enable = function () {this.isDisable = falsethis.bindEvent()}/*** @method* @desc 解除事件绑定*/DrawingBoard.prototype.unBindEvent = function () {this.canvas.removeEventListener("mousedown", this.touchStartPC)this.canvas.removeEventListener("mousemove", this.touchMovePC)this.canvas.removeEventListener("mouseup", this.touchEndPC)}

示例

  <div id="drawingBoard"></div><button id="disableBtn">禁用</button><button id="enableBtn">启用</button>
  var board = new DrawingBoard({el: document.getElementById('drawingBoard'),})disableBtn.onclick = disabledenableBtn.onclick = enabledfunction disabled() {board.disable()}function enabled() {board.enable()}

设置画笔样式&画板背景

  /*** @method* @param {Event} event 事件对象* @desc 鼠标按下事件*/DrawingBoard.prototype.touchStartPC = function (event) {_this.drawStatus = trueconst { offsetX, offsetY } = event// 新增if (_this.isRubber) {_this.eraseBoard(offsetX, offsetY)return}_this.createBrush(offsetX, offsetY)}/*** @method* @param {Event} event 事件对象* @desc 鼠标移动事件*/DrawingBoard.prototype.touchMovePC = function (event) {if (!_this.drawStatus) return;const { offsetX, offsetY } = event// 新增if (_this.isRubber) {_this.eraseBoard(offsetX, offsetY)return}_this.drawPixel({offsetX, offsetY})}/*** 初始化画板*/DrawingBoard.prototype.initSignatureCanvas = function () {let canvas = document.createElement('canvas')this.canvas = canvasthis.addAttribute(canvas)this.bindEvent(canvas)this.ctx = canvas.getContext('2d')this.options.el?.appendChild(canvas)// 新增this.ctx.fillStyle = this.options.background || '#fff'this.ctx.fillRect(0, 0, canvas.width, canvas.height)}/*** @method* @param {Object} options 绘制线条的 x,y 坐标* @desc 根据点坐标绘制连线*/DrawingBoard.prototype.drawPixel = function (options) {const {offsetX, offsetY} = options// 新增this.ctx.strokeStyle = this.options.brush.color || '#000'this.ctx.lineWidth = this.options.brush.lineWidth || 2// 设置绘制线段末端结束的形式this.ctx.lineCap = 'round'this.ctx.lineJoin = 'round'this.ctx.lineTo(offsetX, offsetY)this.ctx.fill()this.ctx.stroke();this.createBrush(offsetX, offsetY)}/*** @method* @param {Number} x 画笔的 x 坐标* @param {Number} y 画笔的 y 坐标* @desc 擦除画布*/DrawingBoard.prototype.eraseBoard = function (x, y) {this.ctx.clearRect(x, y, this.options.brush.lineWidth, this.options.brush.lineWidth)}/*** @mehtod* @desc 切换画笔和橡皮模式*/DrawingBoard.prototype.switchBrush = function () {if (this.isRubber) {this.isRubber = falsethis.options.el.style.cursor = `url(${this.options.brush.pointer}) 0 16, default`} else {this.isRubber = truethis.options.el.style.cursor = `url('./assets/rubber.png') 0 16, default`}}/*** @mehtod* @param {Object} brush 画笔样式配置项* @desc 设置画笔样式*/DrawingBoard.prototype.setBrush = function (brush) {Object.assign(this.options.brush, brush)}

options 配置项增加 background brush 属性,允许传入画布背景与画笔配置信息。brush 属性包含 画笔颜色:color,画笔粗细:lineWidth,画笔icon:pointer(目前仅支持设置PC端鼠标指针)。

示例

  <div id="drawingBoard"></div><div><label for="colorSelect">画笔颜色:</label><input type="color" id="colorSelect"></div><div><label for="numberSelect">画笔粗细:</label><input type="number" id="numberSelect"></div>
  var board = new DrawingBoard({el: document.getElementById('drawingBoard'),background: '#000',brush: {color: '#fff',lineWidth: 10,pointer: './assets/brush.png'}})colorSelect.onchange = colorSelectChangenumberSelect.onchange = numberSelectChangefunction colorSelectChange (event) {board.setBrush({color: event.target.value})}function numberSelectChange(event) {board.setBrush({lineWidth: event.target.value})}

导出画布信息为图片资源

  /*** @method* @param {Function} cb 通过回调函数返回画布信息* @desc 保存画布信息为图片资源*/DrawingBoard.prototype.save = function (cb) {if (this.options.exportType === 'blob') {this.canvas.toBlob(function (blob) {const blobUrl = URL.createObjectURL(blob)cb(blobUrl)}, this.options.mimeType)} else {const base64 = this.canvas.toDataURL(this.options.mimeType)cb(base64)}}

options 配置项增加 mimeType exportType 属性,mimeType 设置导出图片资源格式,默认 image/pngexportType 设置导出资源的数据形式,例如:base64 or blob,默认:base64,目前仅支持PC端,暂不支持移动端导出。

完整代码

文档

  /*** @method* @param {String} str 需要转换的字符串* @returns 转换后的字符串* @desc 将驼峰命名转化为使用分隔符的字符串*/function toSplitLine(str) {var reg = /[A-Z]/g;var newStr = str.replace(reg, function ($0) {return '-' + $0.toLocaleLowerCase();});if (newStr.substring(0, 1) === '-') {newStr = newStr.substring(1);}return newStr;}/*** @class* @classdesc 实现手写签名的构造函数* @param {Object} 手写签名画板的配置项*/function DrawingBoard(options) {if (!(this instanceof DrawingBoard)) {throw new TypeError("DrawingBoard constructor cannot be invoked without 'new'")}this.options = optionsthis.canvas = nullthis.ctx = nullthis.drawStatus = falsethis.isDisable = truethis.isRubber = falseconst _this = this/*** @method* @param {Event} event 事件对象* @desc 鼠标按下事件*/DrawingBoard.prototype.touchStartPC = function (event) {_this.drawStatus = trueconst { offsetX, offsetY } = eventif (_this.isRubber) {_this.eraseBoard(offsetX, offsetY)return}_this.createBrush(offsetX, offsetY)}/*** @method* @param {Event} event 事件对象* @desc 鼠标移动事件*/DrawingBoard.prototype.touchMovePC = function (event) {if (!_this.drawStatus) return;const { offsetX, offsetY } = eventif (_this.isRubber) {_this.eraseBoard(offsetX, offsetY)return}_this.drawPixel({offsetX, offsetY})}/*** @method* @param {Event} event 事件对象* @desc 鼠标抬起事件*/DrawingBoard.prototype.touchEndPC = function (event) {_this.drawStatus = false}this.initSignatureCanvas()}/*** 初始化画板*/DrawingBoard.prototype.initSignatureCanvas = function () {this.isDisable = falselet canvas = document.createElement('canvas')this.canvas = canvasthis.addAttribute(canvas)this.bindEvent(canvas)this.ctx = canvas.getContext('2d')this.options.el?.appendChild(canvas)this.ctx.fillStyle = this.options.background || '#fff'this.ctx.fillRect(0, 0, canvas.width, canvas.height)}/*** @method* @param {Number} x 画笔的 x 坐标* @param {Number} y 画笔的 y 坐标* @desc 移动画笔创建连接点*/DrawingBoard.prototype.createBrush = function (x, y) {this.ctx.beginPath()this.ctx.moveTo(x, y)}/*** @method* @param {Object} options 绘制线条的 x,y 坐标* @desc 根据点坐标绘制连线*/DrawingBoard.prototype.drawPixel = function (options) {const {offsetX, offsetY} = optionsthis.ctx.strokeStyle = this.options.brush.color || '#000'this.ctx.lineWidth = this.options.brush.lineWidth || 2// 设置绘制线段末端结束的形式this.ctx.lineCap = 'round'this.ctx.lineJoin = 'round'this.ctx.lineTo(offsetX, offsetY)this.ctx.fill()this.ctx.stroke();this.createBrush(offsetX, offsetY)}/*** @method* @param {Number} x 画笔的 x 坐标* @param {Number} y 画笔的 y 坐标* @desc 擦除画布*/DrawingBoard.prototype.eraseBoard = function (x, y) {this.ctx.clearRect(x, y, this.options.brush.lineWidth, this.options.brush.lineWidth)}/*** @mehtod* @desc 切换画笔和橡皮模式*/DrawingBoard.prototype.switchBrush = function () {if (this.isRubber) {this.isRubber = falsethis.options.el.style.cursor = `url(${this.options.brush.pointer}) 0 16, default`} else {this.isRubber = truethis.options.el.style.cursor = `url('./assets/rubber.png') 0 16, default`}}/*** @mehtod* @param {Object} brush 画笔样式配置项* @desc 设置画笔样式*/DrawingBoard.prototype.setBrush = function (brush) {Object.assign(this.options.brush, brush)}/*** @method* @param {Function} cb 通过回调函数返回画布信息* @desc 保存画布信息为图片资源*/DrawingBoard.prototype.save = function (cb) {if (this.options.exportType === 'blob') {this.canvas.toBlob(function (blob) {const blobUrl = URL.createObjectURL(blob)cb(blobUrl)}, this.options.mimeType)} else {const base64 = this.canvas.toDataURL(this.options.mimeType)cb(base64)}}/*** @method* @desc 禁用画布*/DrawingBoard.prototype.disable = function () {this.isDisable = truethis.unBindEvent()}/*** @method* @desc 启用画布*/DrawingBoard.prototype.enable = function () {this.isDisable = falsethis.bindEvent()}/*** @method* @desc 获取父容器宽高*/DrawingBoard.prototype.getClientRect = function () {return {width: this.options.el.scrollWidth,height: this.options.el.scrollHeight}}/*** @method* @desc 为容器和画布添加属性样式*/DrawingBoard.prototype.addAttribute = function () {let { width, height, style } = this.optionsconst container = this.getClientRect()let styleParse = ''for (const key in style) {if (Object.prototype.hasOwnProperty.call(style, key)) {styleParse += `${toSplitLine(key)}: ${style[key]};`}}if(!width) width = '200px'if(!height) height = '200px'this.canvas.setAttribute('width', width)this.canvas.setAttribute('height', height)this.canvas.setAttribute('style', styleParse)if (this.options.el) { if(container.width <= 0) this.options.el.style.width = widthif (container.height <= 0) this.options.el.style.height = heightif (this.options.brush && this.options.brush.pointer) {this.options.el.style.cursor = `url(${this.options.brush.pointer}) 0 16, default`}}}/*** @method* @desc 事件绑定*/DrawingBoard.prototype.bindEvent = function () {this.canvas.addEventListener("mousedown", this.touchStartPC)this.canvas.addEventListener("mousemove", this.touchMovePC)this.canvas.addEventListener("mouseup", this.touchEndPC)}/*** @method* @desc 解除事件绑定*/DrawingBoard.prototype.unBindEvent = function () {this.canvas.removeEventListener("mousedown", this.touchStartPC)this.canvas.removeEventListener("mousemove", this.touchMovePC)this.canvas.removeEventListener("mouseup", this.touchEndPC)}

工具类函数

  /*** @method* @param {String} str 需要转换的字符串* @returns 转换后的字符串* @desc 将驼峰命名转化为使用分隔符的字符串*/function toSplitLine(str) {var reg = /[A-Z]/g;var newStr = str.replace(reg, function ($0) {return '-' + $0.toLocaleLowerCase();});if (newStr.substring(0, 1) === '-') {newStr = newStr.substring(1);}return newStr;}

完结

以上就是整个功能的实现,如果存在缺陷请联系及时改正。
如果本文对你有帮助,记得留下点痕迹,让我知道你来过。
欢迎评论区讨论,共同进步,2022 即将结束,2023继续努力!!

完结


http://chatgpt.dhexx.cn/article/bf3qJqIQ.shtml

相关文章

sign-canvas 一个基于canvas开发,封装于Vue组件的通用手写签名板(电子签名板),支持pc端和移动端;

写在前面 : 在项目的开发过程中可能会涉及到手写签名(电子签名)那些&#xff0c;在前端的思路是使用canvas 来签名&#xff0c;导出成图片进行保存。 此轮子是继 https://blog.csdn.net/qq_33270001/article/details/81809535之后,用于vue项目中,为了方便自己与众人和复用而开…

无纸化手写电子签名是现今不可或缺的技术

说到手写电子签名&#xff0c;相信不少人都有所耳闻。在21世纪的今天&#xff0c;移动信息时代&#xff0c;在国家政策指引与倡导下&#xff0c;“无纸化”已成为一种趋势&#xff0c;手写电子签名技术正快速在各行各业推行&#xff0c;不仅节约了纸张资源&#xff0c;助力环境…

VB.net调用蒙恬Write2Go笔迹手写板进行电子签名

最近的项目需要用到手写电子签名的功能,挑来挑去最后选择了蒙恬Write2Go这款手写板设备,因为手写板上面直接就有一块电子油墨显示屏,所写即所得,还可以看到写的笔迹 安装完蒙恬的驱动及自带应用程序之后,经过测试发现,其工作原理是利用了windows剪切板作为中间桥梁来交换图片数…

uni-app - 电子签字板组件(签名专用写字画板,支持调整写字板 “横纵“ 方向,可调整线条粗细颜色等,Canvas 绘制非常丝滑流畅)完美兼容 H5 APP 小程序,最好用的画板签字教程插件源码

前言 网上的教程代码非常乱且都有 BUG 存在,非常难移植到自己的项目中,本文代码干净整洁注释详细。 本文实现了 全端兼容,签名专用的写字板组件,真机流畅丝滑且无 BUG, 您直接复制组件源码,按照详细示例+超详细的注释轻松几分钟完成, 如下图 真机测试,您还可以通过组件…

H5手写板电子签名开发

如图所示:前端实现H5canvas手写板电子签名:<!DOCTYPE html> <html lang"en"><head><meta charset"utf-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0, maximum-scale1.0, user-scala…

uniapp - 实现微信小程序电子签名板,横屏手写姓名签名专用写字画板(详细运行示例,一键复制开箱即用)

效果图 实现了在uniapp项目中,微信小程序平台流畅的写字签名板(也可以绘图)功能源码,复制粘贴,改改样式几分钟即可搞定! 支持自动横屏、持预览,真机运行测试非常流畅不卡顿。 基础模板 如下代码所示。 <template><view class=

Vue Canvas 实现电子签名 手写板

直接上代码 <template><section class"signature"><div class"signatureBox"><div class"canvasBox" ref"canvasHW"><canvas ref"canvasF" touchstarttouchStart touchmovetouchMove touchendt…

锁---一些锁学习

1、java锁之公平锁和非公平锁 公平锁 是指多个线程按照申请的顺序来获取&#xff0c;类似排队打饭&#xff0c;先来后到。 非公平锁 是指多个线程获取锁的顺序并不是按照申请锁的顺序&#xff0c;有可能后申请的线程比先申请的线程优先获取锁&#xff0c;在高并发的情况下&a…

C# 实现锁屏

首先&#xff0c;将窗体的FormBorderStyle设置为none&#xff0c;WindowState设为Maximized 让窗体占据整个页面。 form窗体代码&#xff1a; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using …

win11中睡眠唤醒后如何禁止锁屏界面及登录界面

第一步禁止锁屏界面 gpedit.msc 不显示锁屏-》已启用 第二步&#xff1a;不显示登陆框 netplwiz 经过以上设置以后&#xff0c;打开笔记本就可以直接显示桌面了。

办公计算机锁屏方法,电脑快速锁屏,办公室神技能,再也不怕别人看我的电脑了!...

原标题&#xff1a;电脑快速锁屏&#xff0c;办公室神技能&#xff0c;再也不怕别人看我的电脑了&#xff01; 现在快节奏的社会&#xff0c;电脑的更方面性能与功能是非常之大&#xff0c;我们对电脑的使用频率也越来越高&#xff0c;可见它对我们生活越来越重要。在我们平时使…

Android锁屏的解锁(九个点),使用画的方式,大致的步骤

这篇博客是全部代码(没有解释,纯代码): https://blog.csdn.net/weixin_44614751/article/details/103101104 效果: 第一步:添加背景 第二步:创建九个点 先读取每一个点的图片: creatDot 创建九个点: initNin

ubuntu 18.04取消自动锁屏功能

有时候几分钟不用Ubuntu&#xff0c;系统就自动锁屏了&#xff0c;这是一种安全措施&#xff0c;防止别人趁你不在时使用你的系统。但对于大部分人而言&#xff0c;这是没有必要的&#xff0c;尤其是Ubuntu虚拟机&#xff0c;里面没啥重要的东西&#xff0c;每次锁屏后需要重新…

Android 通知栏,锁屏播放音乐,类似音乐播放器

项目中需要用到播放音频的功能&#xff0c;想做一个类似酷狗、酷我这样的音频播放功能&#xff0c;在通知栏和锁屏时都可以操控音乐&#xff0c;开发中发现oppo reno手机在锁屏时不显示通知栏&#xff0c;研究了整整一天终于解决&#xff0c;特作记录&#xff0c;给遇到同样问题…

Android自定义锁屏实现----仿正点闹钟滑屏解锁

本文原创&#xff0c;转载请注明出处&#xff1a;http://blog.csdn.net/qinjuning 前几周看了下解锁的框架&#xff0c;基本上算是弄了个脸熟。看着别人花哨的解锁界面&#xff0c;心里也很痒痒的。于是&#xff0c;画了一天时间&#xff0c; 捣鼓出了这个成果----仿正点闹钟解…

易安卓打开Android系统中的解锁方式选择页面(锁屏方式选择)

感谢名单 感谢fylfyl2写的https://blog.csdn.net/fyilun/article/details/21257595 E4A打开锁屏方式页面 Intent intent new Intent(); ComponentName cm new ComponentName("com.android.settings","com.android.settings.ChooseLockGeneric"); inte…

Android锁屏的解锁(九个点),使用画的方式

一、效果展示: 这篇博客有解释大概的步骤: https://blog.csdn.net/weixin_44614751/article/details/103101199 二、代码部分: MainActivity.java中的代码: package com.example.drawunlock1;import androidx.appcompat.app.AppCompatActivity;import android.content.re…

让电脑不被锁屏的方法,亲测有效

通过JS来控制键盘&#xff0c;定时按下SCROLLLOCK键&#xff0c;达到电脑不会被锁屏的效果。 通常公司电脑都会自动锁屏&#xff0c;只是时间有长短。有时候闲着了不用电脑&#xff0c;但是却不想让电脑锁屏。那么可以用js代码来控制键盘的按键循环按下实现不锁屏的效果&#x…

android 强制锁屏app,自制力app强制锁屏

自制力app强制锁屏非常适合在学习工作中没有自律性的用户们&#xff0c;当打开app后开启锁屏状态&#xff0c;手机就打不开了&#xff0c;重启也不可能解除锁屏&#xff1b;在此期间&#xff0c;就可以免于手机的打扰&#xff0c;专注学习&#xff1b;感兴趣的小伙伴们快来下载…

android系统密码设置功能,手机锁屏密码怎么设置 三种安卓手机锁屏方式推荐

手机中有很多应用都是与金钱挂钩&#xff0c;特别是微信与支付宝等等既涉及到隐私又与财产关联&#xff0c;这是后手机的安全就尤为重要的&#xff0c;而手机的锁屏密码就是一道最基本的防护措施&#xff0c;那么手机锁屏密码怎么设置?来看看小编推荐的三种安卓手机锁屏方式吧…