canvas简介
- canvas标签是用来绘制图像的
- canvas本身没有绘画的能力,仅仅是图形的容器,相当于一块画板
- 必须要使用脚本完成绘制:JS
canvas绘画
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
#canvas{border: 1px solid black;}
</style>
</head>
<body>
<!-- 1、定义画板 -->
<canvas id="canvas" width="400" height="300"></canvas>
<script>
// 2、获取画板
var canvas = document.getElementById("canvas");
///3、铺上画纸或画布,获取绘画环境
var cv = canvas.getContext("2d");
// 4、开启一条路径或重置当前路径,相当于抬笔,表示准备开始画
cv.beginPath();
// 5、指定路径(画笔)起点: 画布.moveTo(X坐标,Y坐标);
cv.moveTo(50, 50);
// 6、指定路径(画笔)到达位置: 画布.lineTo(X坐标,Y坐标);
cv.lineTo(350, 50);
// 7、绘制当前路径(画笔),默认为黑色
cv.stroke();
</script>
</body>
</html>
画笔宽度和颜色
canvas.lineWidth = 数值;
:定义画笔宽度(粗细),值为数值类型,单位为像素canvas.strokeStyle = “颜色值”
:定义画笔(路径)颜色
多个到达点及开启多条路径
canvas.lineTo(X坐标, Y坐标);
:定义一个新到达点,然后从上一个点到该点画一条线条canvas.beginPath();
:开启一条路径,或重置当前路径;相当于抬笔
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
#canvas{border: 1px solid black;}
</style>
</head>
<body>
<!-- 1、定义画板 -->
<canvas id="canvas" width="400" height="300"></canvas>
<script>
var canvas = document.getElementById("canvas");
var cv = canvas.getContext("2d");
cv.beginPath();
cv.lineWidth = 10;
cv.strokeStyle = "red";
cv.moveTo(20, 20);
cv.lineTo(200, 100);
cv.lineTo(380, 20);
cv.stroke();
// ------------------------------------------
// 开始新的路径
cv.beginPath();
cv.lineWidth = 20;
cv.strokeStyle = "green";
cv.moveTo(20, 170);
cv.lineTo(200, 250);
cv.lineTo(380, 170);
cv.stroke();
</script>
</body>
</html>
闭合路径和填充路径
canvas.closePath();
:闭合路径,从当前点到开始点的路径canvas.fillStyle = “颜色值”;
:定义填充颜色canvas.fill();
:填充当前路径,默认为黑色
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
#canvas{border: 1px solid black;}
</style>
</head>
<body>
<!-- 1、定义画板 -->
<canvas id="canvas" width="400" height="300"></canvas>
<script>
var canvas = document.getElementById("canvas");
var cv = canvas.getContext("2d");
cv.beginPath();
cv.lineWidth = 10;
cv.strokeStyle = "red";
cv.moveTo(20, 20);
cv.lineTo(200, 100);
cv.lineTo(380, 20);
// 不能指定路径到达起点来关闭路径,不是正常的关闭路径
// cv.lineTo(20, 20);
// 创建闭合路径:从当前点到开始点的路径
cv.closePath();
// 绘制当前路径
cv.stroke();
// 定义填充颜色
cv.fillStyle = "orange";
// 填充当前路径,默认为黑色
cv.fill();
</script>
</body>
</html>
绘制贝塞尔曲线
canvas.quadraticCurveto(cpx, cpy, x, y);
:二次贝塞尔曲线,只有一个控制点canvas.bezierCurveto(cpx1, cpy1, cpx2, cpy2, x, y);
:三次贝塞尔曲线,有两个控制点- cpx,cpy:控制点
- x,y:到达点
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
#canvas{border: 1px solid black;}
</style>
</head>
<body>
<!-- 1、定义画板 -->
<canvas id="canvas" width="400" height="300"></canvas>
<script>
var canvas = document.getElementById("canvas");
var cv = canvas.getContext("2d");
cv.beginPath();
cv.moveTo(10, 100); //贝塞尔曲线的起始点
// 二次贝塞尔曲线:画布.quadraticCurveTo(cpx, cpy, x, y);
// cpx,cpy:控制点
// x,y:到达点
// 只有一个控制点
// cv.quadraticCurveTo(200, 300, 300, 100);
// 三次贝塞尔曲线:画布.bezierCurveTo(cpx1, cpy2, cpx2, cpy2, x, y);
// cpx,cpy:控制点
// x,y:到达点
// 有两个控制点
cv.bezierCurveTo(150, 200, 280, 50, 390, 100);
cv.stroke();
</script>
</body>
</html>
画布宽高设置及生产图片
canvas
:宽高应直接在头标签中设置,单位为像素,默认为宽300px,高为150px;在css中设置宽高,会把宽为300px,高为150px的画布进行拉伸,所以会变形canvas
:最终会生成一张图片,可以通过右键另存为图片;可以通过css来定义样式,但不会生成到图片中
绘制空心矩形
-
canvas.rect(左上角x坐标,左上角y坐标,矩形宽度,矩形高度)
:创建矩形路径,需使用stroke()
绘制当前路径 -
canvas.strokeRect(左上角x坐标,左上角y坐标,矩形宽度,矩形高度)
:创建并绘制矩形路径
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
#canvas{border: 1px solid black;}
</style>
</head>
<body>
<canvas id="canvas" width="400" height="300"></canvas>
<script>
var canvas = document.getElementById("canvas");
var cv = canvas.getContext("2d");
// 方法1;创建矩形路径,再绘制当前路径
// 创建矩形路径:画布.rect(左上角x坐标,左上角y坐标,矩形宽度,矩形高度)
// cv.rect(50, 50, 150, 100);
// 绘制当前路径
// cv.stroke();
// 方法2:创建并绘制矩形路径
// 创建矩形路径:画布.strokeRect(左上角x坐标,左上角y坐标,矩形宽度,矩形高度)
cv.strokeRect(50, 50, 250, 100);
</script>
</body>
</html>
绘制填充矩形及清空矩形像素
canvas.rect(左上角x坐标,左上角y坐标,矩形宽度,矩形高度)
:创建矩形路径,需使用fill()
填充当前路径canvas.fillRect(左上角x坐标,左上角y坐标,矩形宽度,矩形高度);
:创建并填充矩形路径canvas.clearRect(左上角x坐标,左上角y坐标,矩形宽度,矩形高度);
:清空给定矩形内的指定像素
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
#canvas{border: 1px solid black;}
</style>
</head>
<body>
<canvas id="canvas" width="400" height="300"></canvas>
<script>
var canvas = document.getElementById("canvas");
var cv = canvas.getContext("2d");
// 指定填充颜色
cv.fillStyle = "red";
// 方法1;创建矩形路径,再填充当前路径
// 创建矩形路径:画布.rect(左上角x坐标,左上角y坐标,矩形宽度,矩形高度)
// cv.rect(50, 50, 150, 100);
// 填充当前路径,默认为黑色
// cv.fill();
// 方法2:创建并填充矩形路径
// 创建矩形路径:画布.fillRect(左上角x坐标,左上角y坐标,矩形宽度,矩形高度)
cv.fillRect(50, 50, 250, 100);
// 清空给定矩形内的指定像素
// 画布.clearRect(左上角x坐标,左上角y坐标,矩形宽度,矩形高度)
cv.clearRect(100, 100, 50, 45);
</script>
</body>
</html>
绘制圆形
canvas.arc(圆心x坐标,圆心y坐标,半径, 起始弧度,结束弧度, 绘制方向(可选));
:创建圆形、圆弧路径,再使用stroke()
绘制或使用fill()
填充当前路径- 起始弧度:3点钟方向为0度
- 绘制方向:可选,默认为false;false=顺时针,true=逆时针
角度和弧度换算
- 圆周弧度 = 2π, 360度 = 2π弧度, 1度 = 2π/360 = π/180弧度
- π在js中用Math.PI表示
- 1角度 = Math.PI/180弧度
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
#canvas{border: 1px solid black;}
</style>
</head>
<body>
<canvas id="canvas" width="400" height="300"></canvas>
<script>
var canvas = document.getElementById("canvas");
var cv = canvas.getContext("2d");
// 指定填充颜色
cv.fillStyle = "#00ff00";
cv.lineWidth = 5;
// 创建圆形路径,再绘制或填充当前路径
// 创建矩形路径:画布.arc(圆心x坐标,圆心y坐标,半径, 起始弧度,结束弧度, 绘制方向(可选));
// 角度和弧度换算
// 圆周弧度 = 2π, 360度 = 2π弧度, 1度 = 2π/360 = π/180弧度
// π在js中用Math.PI表示
// 1角度 = Math.PI/180弧度
cv.arc(200, 150, 100, 0, 2*Math.PI);
cv.stroke();
cv.fill();
</script>
</body>
</html>
绘制圆弧
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
#canvas{border: 1px solid black;}
</style>
</head>
<body>
<canvas id="canvas" width="400" height="300"></canvas>
<script>
var canvas = document.getElementById("canvas");
var cv = canvas.getContext("2d");
cv.beginPath(); //x轴
cv.moveTo(0, 150);
cv.lineTo(400, 150);
cv.stroke();
cv.beginPath(); //y轴
cv.moveTo(200, 0);
cv.lineTo(200, 300);
cv.stroke();
// 绘制圆弧
cv.beginPath();
cv.arc(200, 150, 100, 0, 90*Math.PI/180, true);
// cv.arc(200, 150, 100,-90*Math.PI/180, 0);
cv.stroke();
</script>
</body>
</html>
绘制扇形
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
#canvas{border: 1px solid black;}
</style>
</head>
<body>
<canvas id="canvas" width="400" height="300"></canvas>
<script>
var canvas = document.getElementById("canvas");
var cv = canvas.getContext("2d");
cv.fillStyle = "#00ff00";
cv.strokeStyle = "#ff0000";
cv.beginPath(); //x轴
cv.moveTo(0, 150);
cv.lineTo(400, 150);
cv.stroke();
cv.beginPath(); //y轴
cv.moveTo(200, 0);
cv.lineTo(200, 300);
cv.stroke();
// 绘制闭合弧形
// cv.beginPath();
// cv.arc(200, 150, 100, 0, 90*Math.PI/180);
// cv.closePath();
// cv.stroke();
// cv.fill();
// 绘制扇形
cv.beginPath();
cv.moveTo(200, 150);
cv.arc(200, 150, 100, 0, 90*Math.PI/180);
cv.closePath();
cv.stroke();
cv.fill();
</script>
</body>
</html>
写入文字
convas.font = “字体样式 字体粗细 字号/行高 字体系列”;
:设置文本属性画布.fillText(“要写入的文字”, X坐标, Y坐标, 最大文本宽度(可选));
:实心文字convas.strokeText(“要写入的文字”, X坐标, Y坐标, 最大文本宽度(可选));
:空心文字
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
#canvas{border: 1px solid black;}
</style>
</head>
<body>
<canvas id="canvas" width="400" height="300"></canvas>
<script>
var canvas = document.getElementById("canvas");
var cv = canvas.getContext("2d");
cv.fillStyle = "#00ff00";
cv.strokeStyle = "#ff0000";
// 1、设置文本属性
// 画布.font = "字体样式 字体粗细 字号/行高 字体系列";
cv.font = "italic 700 50px/100px 宋体";
// 2、写入文字
// a、实心文字:画布.fillText("要写入的文字", X坐标, Y坐标, 最大文本宽度(可选));
cv.fillText("苦涩2020", 50, 100);
// b、空心文字:画布.strokeText("要写入的文字", X坐标, Y坐标, 最大文本宽度(可选));
cv.strokeText("苦涩2020", 50, 200);
</script>
</body>
</html>
绘制和定位图像
canvas.drawImage(图像对象,X坐标,Y坐标);
:在画布上绘制和定位图像;为了保险,通常应让图像加载完成后,再执行写入画布
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
#canvas{border: 1px solid black;}
</style>
</head>
<body>
<canvas id="canvas" width="400" height="300"></canvas>
<script>
var canvas = document.getElementById("canvas");
var cv = canvas.getContext("2d");
cv.fillStyle = "#00ff00";
cv.strokeStyle = "#ff0000";
// 1、创建图像资源
var pt = new Image();
pt.src = "./img/1.jpg";
// 2、在画布上绘制和定位图像 画布.drawImage(图像对象,X坐标,Y坐标);
// 为了保险,通常应让图像加载完成后,再执行写入画布
pt.onload = function(){
cv.drawImage(pt, 50, 50);
};
</script>
</body>
</html>
设置和剪切图像
convas.drawImage(图像对象,X坐标,Y坐标,图像宽度,图像高度);
:在画布上绘制和定位图像,并设置图像尺寸canvas.drawImage(图像对象,剪切图像X坐标,剪切图像Y坐标,剪切图像宽度,剪切图像高度,X坐标,Y坐标,图像宽度,图像高度);
:在画布上绘制和定位剪切的部分图像,并设置图像尺寸
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
#canvas{border: 1px solid black;}
</style>
</head>
<body>
<canvas id="canvas" width="400" height="300"></canvas>
<script>
var canvas = document.getElementById("canvas");
var cv = canvas.getContext("2d");
cv.fillStyle = "#00ff00";
cv.strokeStyle = "#ff0000";
// 1、创建图像资源
var pt = new Image();
pt.src = "./img/1.jpg";
// 2、在画布上绘制和定位图像,并设置图像尺寸
// 画布.drawImage(图像对象,X坐标,Y坐标,图像宽度,图像高度);
// 为了保险,通常应让图像加载完成后,再执行写入画布
// pt.onload = function(){
// cv.drawImage(pt, 50, 50, 150, 200);
// };
// 3、在画布上绘制和定位剪切的部分图像,并设置图像尺寸
// 画布.drawImage(图像对象,剪切图像X坐标,剪切图像Y坐标,剪切图像宽度,剪切图像高度,X坐标,Y坐标,图像宽度,图像高度);
// 为了保险,通常应让图像加载完成后,再执行写入画布
pt.onload = function(){
cv.drawImage(pt, 0, 200, 200, 100, 50, 50, 300, 150);
};
</script>
</body>
</html>
填充操作
canvas.createPattern(image, “repeat | repeat-x | repeat-y | no-repeat”);
:在指定的方向上重复指定的元素
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
#canvas{border: 1px solid black;}
</style>
</head>
<body>
<canvas id="canvas" width="400" height="300"></canvas>
<script>
var canvas = document.getElementById("canvas");
var cv = canvas.getContext("2d");
// 创建图像资源
var Iamp = new Image();
Iamp.src = "./img/1.jpg";
// createPattern(): 在指定的方向内重复指定的元素
// 语法:画布.createPattern(image, "repeat | repeat-x | repeat-y | no-repeat");
Iamp.onload = function(){
// 创建矩形路径
cv.rect(0, 0, 200, 150);
cv.fillStyle = cv.createPattern(Iamp, "repeat");
cv.fill();
}
</script>
</body>
</html>
实战画板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<!-- <link rel="stylesheet" href="./reset.css"> -->
<style type="text/css">
*{margin: 0; padding: 0;}
#box{width: 800px; height: 440px; margin: 50px auto; position: relative;}
#zz{
width: 800px; height: 400px;
position: absolute; top: 0; left: 0;
background-color: rgba(0, 0, 0, 0);
display: none;
}
.huabi{height: 40px; vertical-align: middle;}
.huabi li{
height: 40px; float: left;
margin-right: 20px;
list-style-type:none;
}
.huabi li span{
line-height: 40px; float: left;
display: block; margin-right: 10px;
}
.huabi li input{
width: 80px; height: 30px;
float: left; display: block;
}
.huabi li p{
width:80px; height:1px; float:left;
background:#000000;
margin: 10px 0 auto 10px;
}
.huabi li button{
width: 70px; height: 33px;
float: left; margin-right: 10px;
}
</style>
</head>
<body>
<div id="box">
<!-- 定义画板 -->
<canvas id="canvas" width="800" height="400" style="background-color:#999999"></canvas>
<div id="zz"></div>
<ul class="huabi">
<li>
<span>画笔颜色</span>
<input type="color" id="cvColor" value="#000000">
</li>
<li>
<span>画笔粗细</span>
<input type="range" id="cvRange" value="1" min="1" max="30">
<p id="bi"></p>
</li>
<li>
<span>画布颜色</span>
<input type="color" id="bgColor" value="#999999">
</li>
<li>
<button id="clear">清空画布</button>
<button id="eraser">橡皮擦</button>
</li>
</ul>
</div>
<script>
// 获取画板,获取画布环境
var canvas = document.getElementById("canvas");
var cv = canvas.getContext("2d");
// 画板添加鼠标点击事件
canvas.onmousedown = function(e){
// 获取鼠标相对于画板内的位置
var s_left = e.offsetX;
var s_top = e.offsetY;
// document.title = s_left + " | " + s_top;
// 开启路径
cv.beginPath();
// 定义画笔开始位置;将鼠标点击的位置作为新画笔开始的位置
cv.moveTo(s_left, s_top);
// 画板内鼠标移动事件
canvas.onmousemove = function(event){
// 获取鼠标在画板内移动的位置
var n_left = event.offsetX;
var n_top = event.offsetY;
document.title = n_left + " | " + n_top;
// 把路径画到当前鼠标的位置
cv.lineTo(n_left, n_top);
// 开始绘画
cv.stroke();
};
};
// 鼠标松开事件,取消canvas上的鼠标移动事件
canvas.onmouseup = function(){
canvas.onmousemove = null;
};
// 改变画笔颜色
document.getElementById("cvColor").onchange = function(){
cv.strokeStyle = this.value;
document.getElementById("bi").style.background = cv.strokeStyle;
}
// 改变画笔粗细
document.getElementById("cvRange").onchange = function(){
cv.lineWidth = this.value;
document.getElementById("bi").style.height = this.value+"px";
document.getElementById("bi").style.background = cv.strokeStyle;
}
// 改变画布颜色
document.getElementById("bgColor").onchange = function(){
canvas.style.backgroundColor = this.value;
}
// 清空绘画
document.getElementById("clear").onclick = function(){
cv.clearRect(0, 0, canvas.width, canvas.height);
}
// 橡皮擦功能
var abc = 1;
document.getElementById("eraser").onclick = function(){
// 获取遮罩层
var zz = document.getElementById("zz");
// 1:橡皮擦功能
if(abc == 1){
// 把遮罩层显示出来
zz.style.display = "block";
// 文字修改成绘制
this.innerText = "绘制";
abc = 0;
// 遮罩层添加鼠标点击事件
zz.onmousedown = function(){
// 画板内鼠标移动事件
zz.onmousemove = function(event){
// 获取鼠标在画板内移动的位置
var m_left = event.offsetX;
var m_top = event.offsetY;
// document.title = m_left + " | " + m_top;
// 清空画布上对应位置的像素
var bi = document.getElementById("cvRange").value;
console.log(bi);
cv.clearRect(m_left, m_top, bi, bi);
};
};
// 鼠标松开事件,取消遮罩层上的鼠标移动事件
zz.onmouseup = function(){
zz.onmousemove = null;
};
}else{
// 隐藏遮罩层
zz.style.display = "none";
// 文字修改成绘制
this.innerText = "橡皮擦";
abc = 1;
};
};
</script>
</body>
</html>