前提知识

canvas是提供了各种各样的接口去控制画布,比如旋转rotate方法。

这里的旋转并不是真的把这个画布旋转了,例如ctx.rotate(90 * Math.PI / 180)顺时针旋转90°了,并不是说我们在页面上就会看到canvas旋转了90°。我们可以理解为其实canvas是有两个部分组成的,一个是肉眼看得到的画布,一个是用于操作的虚拟画布,我们所有在虚拟画布上的动作都会映射到真实画布中去。

旋转画布的原点默认画布的左上角(0,0)点,如图:

总结下,常用画布相关的知识点:

  • 1.旋转画布的原点默认画布的左上角(0,0)点,可以使用ctx.translate(x, y)方法移动画布原点;
  • 2.ctx.rotate(90 * Math.PI / 180)顺时针旋转90°,ctx.rotate(-90 * Math.PI / 180)逆时针旋转90°;
  • 3.context.drawImage方法的使用,如下:

语法一-在画布上定位图像:

context.drawImage(img,x,y);

语法二-在画布上定位图像,并规定图像的宽度和高度:

context.drawImage(img,x,y,width,height);

语法三-剪切图像,并在画布上定位被剪切的部分:

context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);

参数值:

参数 描述
img 规定要使用的图像、画布或视频。
sx 可选。开始剪切的 x 坐标位置。
sy 可选。开始剪切的 y 坐标位置。
swidth 可选。被剪切图像的宽度。
sheight 可选。被剪切图像的高度。
x 在画布上放置图像的 x 坐标位置。
y 在画布上放置图像的 y 坐标位置。
width 可选。要使用的图像的宽度。(伸展或缩小图像)
height 可选。要使用的图像的高度。(伸展或缩小图像)

参考地址:《HTML5 canvas drawImage() 方法》

  • 4.会使用canvas的save和restore方法。

save:用来保存Canvas的状态。save之后,可以调用Canvas的平移、放缩、旋转、错切、裁剪等操作。 restore:用来恢复Canvas之前保存的状态。防止save后对Canvas执行的操作对后续的绘制有影响。

示例:

ar canvas = document.getElementById("canvas");
var context = canvas.getContext('2d');
context.lineWidth = "10";
context.strokeStyle = "#fe9901";
context.translate(canvas.width / 2, canvas.height / 2);
context.rotate( 30 / 180 * Math.PI);
context.beginPath();
context.moveTo(0, -180);
context.lineTo(0, -200);
context.stroke(); context.rotate( 30 / 180 * Math.PI);
context.beginPath();
context.moveTo(0, -140);
context.lineTo(0, -160);
context.stroke();

没有使用save,restore,第一次绘制时画布旋转30度,然后按照坐标绘制直线,第二次绘制在第一次基础上继续绘制,旋转30度,实际上相对于起点,旋转了60. 所以画出来两条直线不在一条指线上。

context.save();
context.rotate( 30 / 180 * Math.PI);
context.beginPath();
context.moveTo(0, -180);
context.lineTo(0, -200);
context.stroke();
context.restore(); context.rotate( 30 / 180 * Math.PI);
context.beginPath();
context.moveTo(0, -140);
context.lineTo(0, -160);
context.stroke();

第二次绘制加入save和restore, 再第一次绘制后,resore到起始状态,也就是现在画布又回到了0度位置,而不是30度,所以第二次绘制是从0度开始绘制,绘制出来应该和第一次的直线在一条指线上。

canvas移动与旋转示例

首先我们用如下图片绘制到canvas画布中,然后我们要保存旋转后的图片,如图所示。

画布图片:

旋转后保存的图片:

demo代码:

<!DOCTYPE html>
<html>
<head>
<title>canvas移动与旋转</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
<style>
html,body {
padding:0;
margin:0;
width: 100%;
height: 100%;
}
.canvasparent {
width: 100px;
height: 200px;
margin: 100px auto 20px;
border: 1px solid #cccccc;
box-sizing: content-box;
position: relative;
}
#canvas {
position: absolute;
top: 0;
left: 0;
width: 100px;
height: 200px;
border-top-left-radius: 30px;
} </style>
</head>
<body>
<div class="canvasparent" id="canvasparent">
<canvas id="canvas"></canvas>
</div>
<img src="" id="img" style="border: 1px solid #ccc"/>
<script>
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
canvas.width = 100;
canvas.height = 200;
var img = new Image();
img.src = './images/1.jpg';
img.onload = function() {
ctx.drawImage(img,0,0,100,200);
var imgSRC = canvas.toDataURL('image/png', 1);
var img2 = new Image();
img2.src = imgSRC;
img2.onload = function() {
var clipCanvas = document.createElement("canvas");
var ctx2 = clipCanvas.getContext('2d');
clipCanvas.width = 200;
clipCanvas.height = 100;
ctx2.translate(0,100);
ctx2.rotate(-90 * Math.PI / 180);
ctx2.drawImage(img2,0,0,100,200);
var imgSRC2 = clipCanvas.toDataURL('image/png', 1);
document.getElementById('img').src = imgSRC2;
}
}
</script>
</html>

当然上面使用了translate和rotate,我们只有rotate和drawImage也是可以的,修改的JS代码如下:

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
canvas.width = 100;
canvas.height = 200;
var img = new Image();
img.src = './images/1.jpg';
img.onload = function() {
ctx.drawImage(img,0,0,100,200);
var imgSRC = canvas.toDataURL('image/png', 1);
var img2 = new Image();
img2.src = imgSRC;
img2.onload = function() {
var clipCanvas = document.createElement("canvas");
var ctx2 = clipCanvas.getContext('2d');
clipCanvas.width = 200;
clipCanvas.height = 100;
ctx2.rotate(-90 * Math.PI / 180);
ctx2.drawImage(img2,-100,0,100,200);
var imgSRC2 = clipCanvas.toDataURL('image/png', 1);
document.getElementById('img').src = imgSRC2;
}
}

手写签名demo

html代码:

<body>
<div class="app-container" style="padding-top: 100px;">
<button id="signature-button">开始手写签名</button>
<div class="signature-result__img">
<img src="" id="signature-img" alt="手写签名图片预览"/>
</div>
</div>
<div id="signature-pop">
<div id="signature-container">
<div class="demo-top-info" id="rotate-container">
<div class="return" id="return">返回</div>
<div class="signature-title text-center">手写签名</div>
</div>
<div class="canvas-container">
<div class="canvas-parent">
<canvas id="canvas"></canvas>
</div>
</div>
<div class="demo-bottom-info">
<div id="clean_canvas">清空</div>
<div id="sure_canvas">确认</div>
</div>
</div>
<canvas id="canvas2"></canvas>
</div> </body>

CSS代码:

html,body {
padding:0;
margin:0;
width: 100%;
height: 100%;
}
.text-center {
text-align: center;
}
#signature-button {
display: block;
margin: 0 auto;
}
#signature-img {
width: 200px;
height: 100px;
margin: 10px auto;
display: none;
}
#signature-pop {
position: fixed;
background-color: #fff;
top:0;
left:0;
bottom:0;
right:0;
width: 100%;
height: 100%;
display: none;
}
#signature-container {
width: 100%;
height: 100%;
}
.demo-top-info {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 40px;
background: #cccccc;
box-sizing: border-box;
text-align: center;
}
.demo-top-info .return {
padding-left: 5px;
height: 40px;
line-height: 40px;
position: absolute;
left: 10px;
display: inline-block;
}
.signature-title {
height: 40px;
line-height: 40px;
display: inline-block;
}
.canvas-container {
width: 100%;
height: 100%;
background-color: #ffffff;
box-sizing: border-box;
padding: 40px 0 40px 0;
}
.canvas-parent {
width: 100%;
height: 100%;
}
.demo-bottom-info {
position: absolute;
bottom:0;
left:0;
width: 100%;
height: 40px;
background: #cccccc;
padding: 0 2%;
box-sizing: border-box;
overflow: hidden;
}
#clean_canvas {
float: left;
font-size: 18px;
margin-top: 2px;
background: #f8f8f8;
border: 1px solid #ddd;
padding: 5px 10px;
border-radius: 4px;
}
#sure_canvas {
float: right;
padding: 3px 0;
background: #00005F;
padding: 5px 10px;
border: 1px solid #00005F;
border-radius: 4px;
color: #fff;
margin-top: 3px;
}
#canvas2 {
position: absolute;
top: 0;
left:0;
z-index: 999;
margin-left: 40px;
}

JS代码:

// 手绘签名类
var SignatureClass = (function(){
//获取当前位置(返回px)
function getStyle(obj, attr) {
if (obj.currentStyle) {
return obj.currentStyle[attr];
} else {
return getComputedStyle(obj, false)[attr];
}
} function Signatrue(options) {
this.cavnas = null;
this.ctx = null;
this.maxparams = {};
this.minparams = {};
this.entershuping = true; //是否是竖屏 true=是
this.firstTouch = true; // 第一次点击或touch
this.allowSubmit = false; // 是否手写了内容 是=才能提交 否=不能提交
if(options === void 0) {
options = {};
}
this.options = options;
} // 初始化
Signatrue.prototype.init = function() {
var self = this;
console.log(getStyle(document.getElementById("rotate-container"), "height")); // 不知道为什么加,否则有些Apple出问题
this.hengshuping();
this.clear();
this.submit(); window.addEventListener('resize',function() {
self.hengshuping();
},false);
} // 判断横竖屏
Signatrue.prototype.hengshuping = function() {
if (window.orientation == 90 || window.orientation == -90) {
this.entershuping = false; // 横屏
document.getElementById("canvas2").style.display = "none";
document.getElementById("canvas").style.display = "block";
this.canvas = document.getElementById("canvas");
this.ctx = this.canvas.getContext("2d");
this.ctx.lineWidth = 1;
this.ctx.strokeStyle = "#000000";
this.drawEvent();
document.querySelector("#signature-container").style.width = window.innerWidth + "px";
document.querySelector("#signature-container").style.height = window.innerHeight + "px";
this.canvas.height = parseInt(getStyle(document.getElementById("canvas").parentNode, 'height'));
this.canvas.width = parseInt(getStyle(document.getElementById("canvas").parentNode, 'width'));
document.querySelector("#signature-container").style.transform = "rotate(0deg)";
document.querySelector("#signature-container").style.transformOrigin = "0 0";
document.querySelector("#signature-container").style.marginLeft = "0px";
} else { // 竖屏
this.entershuping = true;
document.getElementById("canvas").style.display = "none";
document.getElementById("canvas2").style.display = "block";
this.canvas = document.getElementById("canvas2");
this.ctx = this.canvas.getContext("2d");
this.canvas.height = window.innerHeight;
this.canvas.width = window.innerWidth - 40 - 40;
this.ctx.lineWidth = 1;
this.ctx.strokeStyle = "#000000";
this.drawEvent();
document.querySelector("#signature-container").style.width = window.innerHeight + "px";
document.querySelector("#signature-container").style.height = window.innerWidth + "px";
document.querySelector("#signature-container").style.transform = "rotate(90deg)";
document.querySelector("#signature-container").style.transformOrigin = "0 0";
document.querySelector("#signature-container").style.marginLeft = window.innerWidth + "px";
}
} // 绘画事件
Signatrue.prototype.drawEvent = function() {
var self = this;
this.canvas.addEventListener("touchstart", function(evt) {
var oEvent = evt || event;
oEvent.preventDefault();
var position = self.pos(oEvent);
self.ctx.beginPath();
self.ctx.moveTo(position.x, position.y);
if (self.firstTouch) {
self.minparams = {
x: position.x,
y: position.y
};
self.maxparams = {
x: position.x,
y: position.y
};
self.firstTouch = false;
} else {
self.judgeSize(position);
}
self.canvas.addEventListener("touchmove", touchmove, false) function touchmove(evt) {
var oEvent = evt || event;
oEvent.preventDefault();
var position = self.pos(oEvent);
self.ctx.lineTo(position.x, position.y);
self.judgeSize(position);
self.ctx.stroke();
}
document.addEventListener("touchend", touchend, false) function touchend(evt) {
var oEvent = evt || event;
oEvent.preventDefault();
self.allowSubmit = true;
self.canvas.removeEventListener("touchmove", touchmove);
document.removeEventListener("touchend", touchend);
}
})
} // 清空画笔
Signatrue.prototype.clear = function() {
var self = this;
document.getElementById("clean_canvas").addEventListener("click", function() {
self.ctx.clearRect(0, 0, self.canvas.width, self.canvas.height);
self.allowSubmit = false;
})
} // 提交画笔内容
Signatrue.prototype.submit = function() {
var self = this;
document.getElementById("sure_canvas").addEventListener("click", function() {
if (self.allowSubmit) {
var imgSRC = self.canvas.toDataURL('image/png', 1);
var img = new Image();
img.src = imgSRC;
self.ctx.clearRect(0, 0, self.canvas.width, self.canvas.height);
img.onload = function() {
var width = self.maxparams.x - self.minparams.x;
var height = self.maxparams.y - self.minparams.y;
var targetWidth = 200;
var targetHeight = 100;
var clipCanvas = document.createElement("canvas");
clipCanvas.width = targetWidth;
clipCanvas.height = targetHeight;
var ctx2 = clipCanvas.getContext("2d");
if (self.entershuping) {
ctx2.translate(0, targetHeight);
ctx2.rotate(-90 * Math.PI / 180);
ctx2.drawImage(img, self.minparams.x, self.minparams.y, width, height, 0, 0, targetHeight, targetWidth);
} else {
ctx2.drawImage(img, self.minparams.x, self.minparams.y, width, height, 0, 0, targetWidth, targetHeight);
}
var imgSRC2 = clipCanvas.toDataURL('image/png', 1);
if(self.options && self.options.callback && typeof self.options.callback == 'function') {
self.options.callback(imgSRC2);
}
self.canvas = null;
self.ctx = null;
ctx2 = null;
clipCanvas = null; }
} else {
alert("没有手写签名,不能提交!")
}
})
} // 获取当前位置
Signatrue.prototype.pos = function(event) {
var x = event.touches[0].pageX - event.target.offsetLeft;
var y = event.touches[0].pageY - event.target.offsetTop;
return {
x: x,
y: y
};
} // 优化画笔界限,去掉空白区域
Signatrue.prototype.judgeSize = function(value) {
if (this.minparams.x > value.x) {
this.minparams.x = value.x;
}
if (this.maxparams.x < value.x) {
this.maxparams.x = value.x;
}
if (this.minparams.y > value.y) {
this.minparams.y = value.y;
}
if (this.maxparams.y < value.y) {
this.maxparams.y = value.y;
}
} return Signatrue;
})(); // 点击去手写签名-展示手写签名弹框
document.getElementById('signature-button').addEventListener('click',function(){
document.getElementById('signature-pop').style.display = 'block';
var signatrueDraw = new SignatureClass({
callback: function(base64) {
document.getElementById('signature-img').src = base64;
document.getElementById('signature-pop').style.display = 'none';
document.getElementById('signature-img').style.display = 'block';
}
});
signatrueDraw.init(); },false); // 点击弹框返回
document.getElementById('return').addEventListener('click',function(){
document.getElementById('signature-pop').style.display = 'none';
},false);

完整的demo代码:

<!DOCTYPE html>
<html>
<head>
<title>手写签名demo</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
<style>
html,body {
padding:0;
margin:0;
width: 100%;
height: 100%;
}
.text-center {
text-align: center;
}
#signature-button {
display: block;
margin: 0 auto;
}
#signature-img {
width: 200px;
height: 100px;
margin: 10px auto;
display: none;
}
#signature-pop {
position: fixed;
background-color: #fff;
top:0;
left:0;
bottom:0;
right:0;
width: 100%;
height: 100%;
display: none;
}
#signature-container {
width: 100%;
height: 100%;
}
.demo-top-info {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 40px;
background: #cccccc;
box-sizing: border-box;
text-align: center;
}
.demo-top-info .return {
padding-left: 5px;
height: 40px;
line-height: 40px;
position: absolute;
left: 10px;
display: inline-block;
}
.signature-title {
height: 40px;
line-height: 40px;
display: inline-block;
}
.canvas-container {
width: 100%;
height: 100%;
background-color: #ffffff;
box-sizing: border-box;
padding: 40px 0 40px 0;
}
.canvas-parent {
width: 100%;
height: 100%;
}
.demo-bottom-info {
position: absolute;
bottom:0;
left:0;
width: 100%;
height: 40px;
background: #cccccc;
padding: 0 2%;
box-sizing: border-box;
overflow: hidden;
}
#clean_canvas {
float: left;
font-size: 18px;
margin-top: 2px;
background: #f8f8f8;
border: 1px solid #ddd;
padding: 5px 10px;
border-radius: 4px;
}
#sure_canvas {
float: right;
padding: 3px 0;
background: #00005F;
padding: 5px 10px;
border: 1px solid #00005F;
border-radius: 4px;
color: #fff;
margin-top: 3px;
}
#canvas2 {
position: absolute;
top: 0;
left:0;
z-index: 999;
margin-left: 40px;
}
</style>
</head>
<body>
<div class="app-container" style="padding-top: 100px;">
<button id="signature-button">开始手写签名</button>
<div class="signature-result__img">
<img src="" id="signature-img" alt="手写签名图片预览"/>
</div>
</div>
<div id="signature-pop">
<div id="signature-container">
<div class="demo-top-info" id="rotate-container">
<div class="return" id="return">返回</div>
<div class="signature-title text-center">手写签名</div>
</div>
<div class="canvas-container">
<div class="canvas-parent">
<canvas id="canvas"></canvas>
</div>
</div>
<div class="demo-bottom-info">
<div id="clean_canvas">清空</div>
<div id="sure_canvas">确认</div>
</div>
</div>
<canvas id="canvas2"></canvas>
</div> </body>
<script type="text/javascript"> // 手绘签名类
var SignatureClass = (function(){
//获取当前位置(返回px)
function getStyle(obj, attr) {
if (obj.currentStyle) {
return obj.currentStyle[attr];
} else {
return getComputedStyle(obj, false)[attr];
}
} function Signatrue(options) {
this.cavnas = null;
this.ctx = null;
this.maxparams = {};
this.minparams = {};
this.entershuping = true; //是否是竖屏 true=是
this.firstTouch = true; // 第一次点击或touch
this.allowSubmit = false; // 是否手写了内容 是=才能提交 否=不能提交
if(options === void 0) {
options = {};
}
this.options = options;
} // 初始化
Signatrue.prototype.init = function() {
var self = this;
console.log(getStyle(document.getElementById("rotate-container"), "height")); // 不知道为什么加,否则有些Apple出问题
this.hengshuping();
this.clear();
this.submit(); window.addEventListener('resize',function() {
self.hengshuping();
},false);
} // 判断横竖屏
Signatrue.prototype.hengshuping = function() {
if (window.orientation == 90 || window.orientation == -90) {
this.entershuping = false; // 横屏
document.getElementById("canvas2").style.display = "none";
document.getElementById("canvas").style.display = "block";
this.canvas = document.getElementById("canvas");
this.ctx = this.canvas.getContext("2d");
this.ctx.lineWidth = 1;
this.ctx.strokeStyle = "#000000";
this.drawEvent();
document.querySelector("#signature-container").style.width = window.innerWidth + "px";
document.querySelector("#signature-container").style.height = window.innerHeight + "px";
this.canvas.height = parseInt(getStyle(document.getElementById("canvas").parentNode, 'height'));
this.canvas.width = parseInt(getStyle(document.getElementById("canvas").parentNode, 'width'));
document.querySelector("#signature-container").style.transform = "rotate(0deg)";
document.querySelector("#signature-container").style.transformOrigin = "0 0";
document.querySelector("#signature-container").style.marginLeft = "0px";
} else { // 竖屏
this.entershuping = true;
document.getElementById("canvas").style.display = "none";
document.getElementById("canvas2").style.display = "block";
this.canvas = document.getElementById("canvas2");
this.ctx = this.canvas.getContext("2d");
this.canvas.height = window.innerHeight;
this.canvas.width = window.innerWidth - 40 - 40;
this.ctx.lineWidth = 1;
this.ctx.strokeStyle = "#000000";
this.drawEvent();
document.querySelector("#signature-container").style.width = window.innerHeight + "px";
document.querySelector("#signature-container").style.height = window.innerWidth + "px";
document.querySelector("#signature-container").style.transform = "rotate(90deg)";
document.querySelector("#signature-container").style.transformOrigin = "0 0";
document.querySelector("#signature-container").style.marginLeft = window.innerWidth + "px";
}
} // 绘画事件
Signatrue.prototype.drawEvent = function() {
var self = this;
this.canvas.addEventListener("touchstart", function(evt) {
var oEvent = evt || event;
oEvent.preventDefault();
var position = self.pos(oEvent);
self.ctx.beginPath();
self.ctx.moveTo(position.x, position.y);
if (self.firstTouch) {
self.minparams = {
x: position.x,
y: position.y
};
self.maxparams = {
x: position.x,
y: position.y
};
self.firstTouch = false;
} else {
self.judgeSize(position);
}
self.canvas.addEventListener("touchmove", touchmove, false) function touchmove(evt) {
var oEvent = evt || event;
oEvent.preventDefault();
var position = self.pos(oEvent);
self.ctx.lineTo(position.x, position.y);
self.judgeSize(position);
self.ctx.stroke();
}
document.addEventListener("touchend", touchend, false) function touchend(evt) {
var oEvent = evt || event;
oEvent.preventDefault();
self.allowSubmit = true;
self.canvas.removeEventListener("touchmove", touchmove);
document.removeEventListener("touchend", touchend);
}
})
} // 清空画笔
Signatrue.prototype.clear = function() {
var self = this;
document.getElementById("clean_canvas").addEventListener("click", function() {
self.ctx.clearRect(0, 0, self.canvas.width, self.canvas.height);
self.allowSubmit = false;
})
} // 提交画笔内容
Signatrue.prototype.submit = function() {
var self = this;
document.getElementById("sure_canvas").addEventListener("click", function() {
if (self.allowSubmit) {
var imgSRC = self.canvas.toDataURL('image/png', 1);
var img = new Image();
img.src = imgSRC;
self.ctx.clearRect(0, 0, self.canvas.width, self.canvas.height);
img.onload = function() {
var width = self.maxparams.x - self.minparams.x;
var height = self.maxparams.y - self.minparams.y;
var targetWidth = 200;
var targetHeight = 100;
var clipCanvas = document.createElement("canvas");
clipCanvas.width = targetWidth;
clipCanvas.height = targetHeight;
var ctx2 = clipCanvas.getContext("2d");
if (self.entershuping) {
ctx2.translate(0, targetHeight);
ctx2.rotate(-90 * Math.PI / 180);
ctx2.drawImage(img, self.minparams.x, self.minparams.y, width, height, 0, 0, targetHeight, targetWidth);
} else {
ctx2.drawImage(img, self.minparams.x, self.minparams.y, width, height, 0, 0, targetWidth, targetHeight);
}
var imgSRC2 = clipCanvas.toDataURL('image/png', 1);
if(self.options && self.options.callback && typeof self.options.callback == 'function') {
self.options.callback(imgSRC2);
}
self.canvas = null;
self.ctx = null;
ctx2 = null;
clipCanvas = null; }
} else {
alert("没有手写签名,不能提交!")
}
})
} // 获取当前位置
Signatrue.prototype.pos = function(event) {
var x = event.touches[0].pageX - event.target.offsetLeft;
var y = event.touches[0].pageY - event.target.offsetTop;
return {
x: x,
y: y
};
} // 优化画笔界限,去掉空白区域
Signatrue.prototype.judgeSize = function(value) {
if (this.minparams.x > value.x) {
this.minparams.x = value.x;
}
if (this.maxparams.x < value.x) {
this.maxparams.x = value.x;
}
if (this.minparams.y > value.y) {
this.minparams.y = value.y;
}
if (this.maxparams.y < value.y) {
this.maxparams.y = value.y;
}
} return Signatrue;
})(); // 点击去手写签名-展示手写签名弹框
document.getElementById('signature-button').addEventListener('click',function(){
document.getElementById('signature-pop').style.display = 'block';
var signatrueDraw = new SignatureClass({
callback: function(base64) {
document.getElementById('signature-img').src = base64;
document.getElementById('signature-pop').style.display = 'none';
document.getElementById('signature-img').style.display = 'block';
}
});
signatrueDraw.init(); },false); // 点击弹框返回
document.getElementById('return').addEventListener('click',function(){
document.getElementById('signature-pop').style.display = 'none';
},false);
</script>
</html>

canvas图片旋转扩展出原生JS实现移动端横竖屏手写签名示例的更多相关文章

  1. 【原】js检测移动端横竖屏

    摘要:上周做了一个小项目,但是要放到我们的app上,然而需要横竖屏使用不同的样式.横屏一套,竖屏一套.调用了手机APP那里的api,可是他们那里ios和安卓返回的不一样. 各种头疼.于是用了css3的 ...

  2. JS检测移动端横竖屏

    (function () {                                var supportOrientation = (typeof window.orientation == ...

  3. HTML 5 +CSS3 + 原生js 做(雪花全屏飘落 + 3d旋转图)

    原文:HTML 5 +CSS3 + 原生js 做(雪花全屏飘落 + 3d旋转图) 3d旋转图:主要用css3中transform属性中的rotate,translate;以及用来做舞台效果的 pers ...

  4. 用js实现web端录屏

    用js实现web端录屏 原创2021-11-14 09:30·无意义的路过 随着互联网技术飞速发展,网页录屏技术已趋于成熟.例如可将录屏技术运用到在线考试中,实现远程监考.屏幕共享以及录屏等:而在我们 ...

  5. canvas画布实现手写签名效果

    最近项目中涉及到移动端手写签名的功能需求,将实现代码记录于此,供小伙伴们参考指摘哦~ HTML代码: <!--手写区--> <div class="mSign_signMa ...

  6. js判断手机的横竖屏调整样式

    在移动端,我们经常遇到横竖屏的问题,所以我们改如何判断或针对横竖屏来写代码呢.首先需要在head中加入如下代码: <meta name="viewport" content= ...

  7. Blazor组件自做二 : 使用JS隔离制作手写签名组件

    Blazor组件自做二 : 使用JS隔离制作手写签名组件 本文相关参考链接 JavaScript 模块中的 JavaScript 隔离 Viewer.js工程 Blazor组件自做一 : 使用JS隔离 ...

  8. uni-app通过canvas实现手写签名

    分享一个uni-app实现手写签名的方法 具体代码如下: <template> <view > <view class="title">请在下面 ...

  9. js移动端横竖屏检测

    方法一:用resize事件来判断,利用屏幕的宽高比,来判断横竖屏 (兼容性较好) (function () { var updateOrientation = function () { var or ...

  10. 原生 JS 实现移动端 Touch 滑动反弹

    什么是 Touch滑动?就是类似于 PC端的滚动事件,但是在移动端是没有滚动事件的,所以就要用到 Touch事件结合 js去实现,效果如下: 1. 准备工作 什么是移动端的 Touch事件?在移动端 ...

随机推荐

  1. 历代iPhone及Android手机的屏幕参数对比

    手机逻辑分辨率Point,也就是CSS像素,是进行网页适配的关键,以下是平时整理的一些备忘录数据,可以收藏. 屏幕清晰度分类 SD标清 HD高清(2倍屏) FHD全高清(3倍屏) QHD倍高清(4倍屏 ...

  2. ps -ef | grep xxx 解释

    上述内容为:命令拆解: ps:将某个进程显示出来-A 显示所有程序.-e 此参数的效果和指定"A"参数相同.-f 显示UID,PPIP,C与STIME栏位.grep命令是查找中间的 ...

  3. [oeasy]python0141_自制模块_module_reusability_复用性

    自制包内容 回忆上次内容 上次导入了外部的py文件 import my_module 导入一个自己定义的模块   可以使用my_module中的变量 不能 直接使用 my_module.py文件中的变 ...

  4. [oeasy]python0125_汉字打印机_点阵式打字机_汉字字形码

    汉字字形码 回忆上次内容 IBM 将 ASCII 扩展之后 规定了 一个字节的字符集 并制作了 相应的字形库   ​   添加图片注释,不超过 140 字(可选)   这种显示模式和字符大小之下 中文 ...

  5. [oeasy]python0053_ 续行符_line_continuation_python行尾续行

    续行符与三引号 回忆上次内容 上次还是转义序列 类型 英文 符号 \a bell 响铃 \b backspace 退格 \t tab 水平制表符 \v vertical tab 垂直制表符换行不回车 ...

  6. 解决Win平台VSCode中Python在控制台输出中文乱码的问题

    在菜单Debug->Open Configurations,打开launch.json,新增如下粉红色字符内容: { "configurations": [ { " ...

  7. 找实习,三本计算机 > 985文科 ?

    2018年3月,大三下学期. 写了一段时间博客以后,竟有人说要内推我. 我说我大三,还没毕业,准备暑假去找实习. 网上认识的朋友建议我去春招实习试试,还有些厂在走流程中,还有机会. 我婉拒了,感觉我自 ...

  8. Vue仿微信PC客户端

    一个模仿PC微信客户端的纯前端vue项目 项目地址 github: https://github.com/TomHusky/vue-wechat-demo gitee: https://gitee.c ...

  9. ComfyUI插件:ComfyUI Impact 节点(三)

    前言: 学习ComfyUI是一场持久战,而 ComfyUI Impact 是一个庞大的模块节点库,内置许多非常实用且强大的功能节点 ,例如检测器.细节强化器.预览桥.通配符.Hook.图片发送器.图片 ...

  10. 【JavaScript】前端算法题(重建二叉树、反向输出链表每个节点)

    前言 今天复习了一些前端算法题,写到一两道比较有意思的题:重建二叉树.反向输出链表每个节点 题目 重建二叉树: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的 ...