Canvas
1.概述
Canvas是HTML5中非常重要的一个更新亮点,画布,替代Flash的!制作动画、制作游戏。渲染效率非常的高,浏览器不需要安装任何的插件就可以渲染这个动画。而Flash需要安装Flash Player这个插件才行。
Canvas适合动态图形绘制。小的动态效果也可以使用过渡或动画属性animation。
echarts图表使用Canvas绘制,https://echarts.apache.org/zh/index.html
1.1. Hello World
canvas是一个标签,有一个默认的宽高,此时注意,如果我们要设置宽度、高度,必须设置在HTML标签上面,而不能设置在CSS上。
注意:
- canvas本身布具有绘画功能, 只是一个画布标签, 但是H5提供给js的API具有绘画功能
2. IE9一下不兼容
<style>
* {
margin: 0;
padding: 0;
}
body {
background-color: #f3f3f3;
}
#canvas {
/*canvas虽然默认宽高300X150,但它是个行元素inline*/
display: block;
/*变块才能居中*/
margin: 50px auto;
background-color: #fff;
}
</style>
</head>
<body>
<canvas id="canvas" width="500" height="500">你的浏览器不支持canvas,请升级</canvas>
<script>
//仅仅获取画布对象
let mycanvas = document.getElementById('canvas');
//通过画布对象获取上下文对象(画笔对象)
let ctx = mycanvas.getContext('2d');
//绘制矩形路径
ctx.rect(50, 50, 50, 50);//距离画布左上角50 50 宽高50 50,只是路径看不到效果
//描边
ctx.stroke();
//填充
// ctx.fill()
</script>
2. 涉及的API
2.1 getContext()
get表示得到,context是上下文的意思。
canvas起初是空白的。为了展示,首先脚本需要找到渲染上下文,然后在它的上面绘制。<canvas>
元素有一个做 getContext() 的方法,这个方法是用来获得渲染上下文和它的绘画功能。getContext()只有一个参数,上下文的格式。
// 首先获取canvas 标签的dom对象
var mycanvas = document.querySelector("canvas");
// 获取上下文对象() 参数是2d绘图
var ctx = canvas.getContext('2d');
ctx对象,非常重要所有的绘制都是ctx的方法。canvas就是画布,功能就是生产画笔,
剩下所有的绘制都是有这支画笔ctx对象的属性来操作
//也就是说所有的绘制API都是ctx的事情,而不是canvas对象
ctx.fillStyle = "blue";
ctx.arc(300,300,100,0,Math.PI * 2,true);
ctx.fill();
2.2 绘制圆形 arc()
绘制圆形 arc(x,y,r,start, end, bol)
bol,是布尔值, 跟绘制圆弧有关
ctx.arc(300,300,100,0,Math.PI * 2,true);
<style>
* {
margin: 0;
padding: 0;
}
body {
background-color: #f3f3f3;
}
#canvas {
/*canvas虽然默认宽高300X150,但它是个行元素inline*/
display: block;
/*变块才能居中*/
margin: 50px auto;
background-color: #fff;
}
</style>
</head>
<body>
<canvas id="canvas" width="500" height="500">你的浏览器不支持canvas,请升级</canvas>
<script>
//仅仅获取画布对象
let mycanvas = document.getElementById('canvas');
//通过画布对象获取上下文对象(画笔对象)
let ctx = mycanvas.getContext('2d');
console.log(ctx);
//绘制一个圆
ctx.arc(200, 200, 100, 0, Math.PI * 2, true);//绘制圆的路径,圆心位置 圆心位置 半径 起始为0 终止为Math.PI*2 顺时针绘制
//描边后才可以看到边,之前只是路径
ctx.strokeStyle = 'blue';//改变描边颜色
ctx.stroke();
//改变填充颜色,填充之前定义填充颜色
ctx.fillStyle = 'red';
ctx.fill()//填充
</script>
2.3 绘制矩形 rect()
绘制矩形 rect(x,y,w,h)
ctx.rect(200, 200, 100, 100);
<script>
//仅仅获取画布对象
let mycanvas = document.getElementById('canvas');
//通过画布对象获取上下文对象(画笔对象)
let ctx = mycanvas.getContext('2d');
//绘制矩形路径
ctx.rect(50, 50, 50, 50);//距离画布左上角50 50 宽高50 50,只是路径看不到效果
//描边
ctx.stroke();
//填充
// ctx.fill()
</script>
2.4 stroke()笔触
绘制线条
ctx.stroke()
2.5 fill() 填充
ctx.fill()
2.6 可以合在一起写
-
strokeRect(x,y,w,h)
-
fillRect(x,y,w,h)
参数:
x,y 为起点的x,y坐标
w,h 为要绘制矩形的宽高
注意没有strokeArc 和 fillArc 的写法
ctx.strokeRect(100,100,200,100)//通过描边直接把矩形绘制出来
ctx.fillRect(200,300,200,100)//填充的时候直接绘制一个矩形
2.7 清除 clearRect()
清除clearRect(x,y,w,h)
ctx.clearRect(250, 250, 30, 30);
ctx.clearRect(300,300,100,100)
清除在绘制有先后属性之分
3. 笔触和填充
Canvas中能够产生颜色的是两个东西,一个叫做笔触(也叫做描边),一个叫做填充。
3.1. 笔触(描边) strokeRect(x,y,w,h)
参数,x,y 左上角起点坐标,w,h为绘制矩形的宽高
3.1.1 笔触的使用:
//笔触
ctx.strokeRect(100,100,300,40);
你会发现只有描边没有填充色
而我们刚学的 fillRect() API绘制的矩形是有填充色的
3.1.2 设置笔触的颜色
// 设置笔触颜色
ctx.strokeStyle = 'red';
// ctx.strokeStyle = 'hsl(250,50%,50%)'
// 绘制笔触矩形
ctx.strokeRect(100,100,300,50);
此时你就会发现你绘制的是一个没有填充色,只有红色边框的矩形
3.1.3 绘制笔触的宽度
ctx.lineWidth = 20; // 设置笔触的宽为20
//仅仅获取画布对象
let mycanvas = document.getElementById('canvas');
//通过画布对象获取上下文对象(画笔对象)
let ctx = mycanvas.getContext('2d');
console.log(ctx);
//绘制一个圆
ctx.arc(200, 200, 100, 0, Math.PI * 2, true);//绘制圆的路径,圆心位置 圆心位置 半径 起始为0 终止为Math.PI*2 顺时针绘制
//描边后才可以看到边,之前只是路径
ctx.strokeStyle = 'blue';//改变描边颜色
ctx.lineWidth =20;
ctx.stroke();
3.1.4 笔触绘制线段
划线之前你的先告诉浏览器怎么画
moveTo() 绘制开始位置 lineTo() 画笔移动的下一个位置
ctx.moveTo(100,100); //将画笔移动到一个位置(先移动到开始点的位置)
ctx.lineTo(300,300); //用画笔画,此时是抽象的一个线,没有显示在画布上(下一个点的位置)
ctx.stroke(); //划线(告诉浏览器,我说完了,你画吧)
我们可以多次使用lineTo:
告诉浏览器下一个点的位置,来绘制相邻点之间的线段
ctx.moveTo(100,100); // 将画笔移动到一个位置
ctx.lineTo(300,300); // 准备绘制从开始点到这个点的线,
ctx.lineTo(300,200); // 准备绘制从上一个点到这个点的线,
ctx.lineTo(430,180); // 准备绘制从上一个点到这个点的线,
ctx.stroke(); // 正式开始划线
<body>
<canvas id="canvas" width="500" height="500">你的浏览器不支持canvas,请升级</canvas>
<script>
//仅仅获取画布对象
let mycanvas = document.getElementById('canvas');
//通过画布对象获取上下文对象(画笔对象)
let ctx = mycanvas.getContext('2d');
ctx.lineWidth = 20;//笔触宽度
ctx.strokeStyle='red';
//绘制线段
//笔尖不在画布上moveTo
ctx.moveTo(100, 100)
//笔尖落在画布上lineTo绘制路径
ctx.lineTo(200, 200)
ctx.lineTo(200, 300)
ctx.lineTo(400, 300)
//笔触填充
ctx.stroke()//绘制
</script>
</body>
3.1.5 闭合路径
而且我们还可以使用closePath() ,来闭合路径
就是浏览器会自动的在开始点moveTo的点和最后一个lineTo的结束点之间绘制一条线
ctx.beginPath(); // 开始准备画线
ctx.moveTo(100,100); // 将画笔移动到一个位置
ctx.lineTo(300,300); // 准备绘制从开始点到这个点的线,
ctx.lineTo(300,200); // 准备绘制从上一个点到这个点的线,
ctx.lineTo(430,180); // 准备绘制从上一个点到这个点的线,
ctx.closePath(); // 闭合路径(加上就闭合了)
ctx.stroke(); // 正式开始划线
绘制新的线段
<body>
<canvas id="canvas" width="500" height="500">你的浏览器不支持canvas,请升级</canvas>
<script>
//仅仅获取画布对象
let mycanvas = document.getElementById('canvas');
//通过画布对象获取上下文对象(画笔对象)
let ctx = mycanvas.getContext('2d');
ctx.lineWidth = 20;//笔触宽度
ctx.strokeStyle = 'red';
//绘制线段
//笔尖不在画布上moveTo
ctx.moveTo(100, 100)
//笔尖落在画布上lineTo绘制路径
ctx.lineTo(200, 200)
//笔触填充
ctx.stroke()//绘制
ctx.moveTo(300, 200)//绘制新的线条
ctx.lineTo(200, 300)
ctx.stroke()
</script>
</body>
3.1.6 绘制新的线条开始(开始新的路径)
可以使用beginPath() 表示开始一个新的路径
ctx.beginPath()
ctx.moveTo(50, 50);
ctx.lineTo(300, 300);
ctx.stroke()
ctx.beginPath()
ctx.lineTo(300, 200);
ctx.lineTo(430, 180);
ctx.stroke()
<body>
<canvas id="canvas" width="500" height="500">你的浏览器不支持canvas,请升级</canvas>
<script>
//仅仅获取画布对象
let mycanvas = document.getElementById('canvas');
//通过画布对象获取上下文对象(画笔对象)
let ctx = mycanvas.getContext('2d');
ctx.lineWidth = 20;//笔触宽度
ctx.strokeStyle = 'red';
ctx.beginPath()//开始一个新路径beginPath() 一段路径
ctx.moveTo(100, 100)
ctx.lineTo(200, 200)
ctx.stroke()
ctx.beginPath()//开始一个新路径beginPath() 一段路径
ctx.moveTo(300, 200)
ctx.lineTo(400, 300)
ctx.stroke()
</script>
</body>
可以使用lineWidth属性设置线的宽度
ctx.beginPath();
ctx.moveTo(100,100);
ctx.lineTo(300,300);
ctx.lineTo(300,200);
ctx.lineTo(430,180);
ctx.strokeStyle = 'red';// 绘制描边的颜色
ctx.closePath(); // 闭合路径
ctx.lineWidth = '10'; // 绘制线的宽度
ctx.stroke();
ctx.filStyle = 'skyblue';// 绘制填充颜色
ctx.fill(); // 绘制填充色
3.1.7 绘制线条的转角
lineJoin : 边界连接点样式,要在画ctx.stroke()之前设置转角
- miter(默认值),
- round(圆角),
- bevel(平角)
ctx.moveTo(50, 50);
ctx.lineTo(300, 300);
ctx.lineTo(300, 200);
ctx.lineTo(430, 180);
ctx.closePath()
ctx.strokeStyle = 'red';
ctx.lineWidth = 20;
ctx.lineJoin = 'round'
ctx.stroke()
<style>
* {
margin: 0;
padding: 0;
}
body {
background-color: #f3f3f3;
}
#canvas {
/*canvas虽然默认宽高300X150,但它是个行元素inline*/
display: block;
/*变块才能居中*/
margin: 50px auto;
background-color: #fff;
}
</style>
</head>
<body>
<canvas id="canvas" width="700" height="600">你的浏览器不支持canvas,请升级</canvas>
<script>
let mycanvas = document.getElementById('canvas');
let ctx = mycanvas.getContext('2d');
ctx.beginPath();
ctx.moveTo(100, 100);
ctx.lineTo(300, 300);
ctx.lineTo(300, 200);
ctx.lineTo(430, 180);
ctx.strokeStyle = 'red';
ctx.closePath();
ctx.lineWidth = '10';
ctx.lineJoin = 'round'//线条转角
ctx.stroke();
</script>
</body>
3.1.8 端点样式
lineCap: 端点样式
- butt(默认值),
- round(圆角) (宽度左右两边分别多出线高的一半)
- square(宽度左右两边分别多出线高的一半)
ctx.moveTo(50, 50);
ctx.lineTo(300, 300);
ctx.strokeStyle = 'red';
ctx.lineWidth = 50;
ctx.lineCap = 'round'
ctx.stroke()
ctx.beginPath();
ctx.moveTo(490, 100);
ctx.lineTo(490, 350);
ctx.strokeStyle = 'blue';
ctx.lineCap = 'butt'//默认
ctx.stroke();
ctx.beginPath();
ctx.moveTo(450, 100);
ctx.lineTo(450, 350);
ctx.strokeStyle = 'blue';
ctx.lineCap = 'round'//圆角,线段宽度左右两端分别多出线高的一半
ctx.stroke();
ctx.beginPath();
ctx.moveTo(410, 100);
ctx.lineTo(410, 350);
ctx.strokeStyle = 'blue';
ctx.lineCap = 'square'//平角,线段宽度左右两端分别多出线高的一半
ctx.stroke();
3.2. 填充 fill()
还可以是用fill()给闭合路径后的闭合区域填充颜色
ctx.beginPath(); // 开始准备画线
ctx.moveTo(100,100); // 将画笔移动到一个位置
ctx.lineTo(300,300); // 准备绘制从开始点到这个点的线,
ctx.lineTo(300,200); // 准备绘制从上一个点到这个点的线,
ctx.lineTo(430,180); // 准备绘制从上一个点到这个点的线,
ctx.closePath(); // 闭合路径
ctx.stroke(); // 正式开始划线
ctx.fill(); // 绘制填充色
<style>
* {
margin: 0;
padding: 0;
}
body {
background-color: #f3f3f3;
}
#canvas {
/*canvas虽然默认宽高300X150,但它是个行元素inline*/
display: block;
/*变块才能居中*/
margin: 50px auto;
background-color: #fff;
}
</style>
</head>
<body>
<canvas id="canvas" width="700" height="600">你的浏览器不支持canvas,请升级</canvas>
<script>
let mycanvas = document.getElementById('canvas');
let ctx = mycanvas.getContext('2d');
ctx.fillStyle = 'red';
ctx.lineWidth = 10;
ctx.moveTo(200, 200);
ctx.lineTo(200, 400);
ctx.lineTo(400, 400);
ctx.lineTo(400, 200);
// ctx.closePath()闭合路径的方法之一 笔触
// ctx.stroke();
ctx.fill()//使用填充会自动闭合路径
</script>
</body>
3.2.1 绘制填充颜色 fillStyle
strokeStyle 属性修改描边颜色
fillStyle 属性修改填充颜色
ctx.beginPath();
ctx.moveTo(100,100);
ctx.lineTo(300,300);
ctx.lineTo(300,200);
ctx.lineTo(430,180);
ctx.strokeStyle = 'red';// 绘制描边的颜色
ctx.closePath(); // 闭合路径
ctx.stroke();
ctx.filStyle = 'skyblue';// 绘制填充颜色
ctx.fill(); // 绘制填充色
4.弧与圆形
1.1. 绘制弧度及圆形的公式
ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise)
参数
- x,y为圆心的坐标
- radius 为圆形的半径
- startAngle 为弧度的起始位置,0是正x轴的
- endAngle 为弧度的终点位置,
- anticlockwise 布尔值,true为逆时针绘制,false为顺时针绘制
注意
canvas中的度数都是弧度制
弧和圆形也是笔触(描边),所以也需要以beginPath()开始
var ctx = mycanvas.getContext('2d');
ctx.beginPath();
ctx.arc(150,150,100,0,2*Math.PI,false);
ctx.arc(200,200,100,0,2,false);
ctx.arc(150,150,100,2,2,false);
ctx.fill();
ctx.beginPath();
ctx.arc(150,150,100,2,0,true);
ctx.strokeStyle= 'red';
ctx.lineWidth = 2;
ctx.stroke();
<style>
* {
margin: 0;
padding: 0;
}
body {
background-color: #f3f3f3;
}
#canvas {
/*canvas虽然默认宽高300X150,但它是个行元素inline*/
display: block;
/*变块才能居中*/
margin: 50px auto;
background-color: #fff;
}
</style>
</head>
<body>
<canvas id="canvas" width="700" height="600">你的浏览器不支持canvas,请升级</canvas>
<script>
let mycanvas = document.getElementById('canvas');
let ctx = mycanvas.getContext('2d');
ctx.fillStyle = 'red';
ctx.lineWidth = 10;
ctx.beginPath();
ctx.arc(250, 250, 100, 0, Math.PI * 0.5, false);
ctx.stroke()
ctx.beginPath();
ctx.arc(450, 450, 100, Math.PI * 1.5, Math.PI * 0.5, false);
ctx.stroke()
</script>
</body>
5. 绘制曲线
5.1. 绘制弧度曲线
arcTo(x1,y1,x2,y2,r)
x1,y1 坐标一 x2,y2坐标二 r圆弧半径
ctx.moveTo(100, 300)
ctx.arcTo(100, 100, 200, 100, 50)
ctx.stroke()
<style>
* {
margin: 0;
padding: 0;
}
body {
background-color: #f3f3f3;
}
#canvas {
/*canvas虽然默认宽高300X150,但它是个行元素inline*/
display: block;
/*变块才能居中*/
margin: 50px auto;
background-color: #fff;
}
</style>
</head>
<body>
<canvas id="canvas" width="700" height="600">你的浏览器不支持canvas,请升级</canvas>
<script>
let mycanvas = document.getElementById('canvas');
let ctx = mycanvas.getContext('2d');
ctx.beginPath();
ctx.lineWidth = 10;
ctx.strokeStyle = 'red';
ctx.moveTo(100, 300);
ctx.arcTo(100, 100, 200, 100, 50);//弧线
ctx.stroke()
ctx.beginPath();
ctx.moveTo(150, 200);
ctx.arcTo(150, 100, 200, 100, 400);
ctx.stroke()
</script>
</body>
5.2. 绘制贝塞尔曲线
绘制公式
ctx.quadraticCurveTo(cp1x,cp1y,x,y)
参数
- cp1x, cp1y 为贝塞尔曲线的控制点
- x,y 为绘制曲线的终点
ctx.beginPath()
ctx.moveTo(100,100);
ctx.quadraticCurveTo(200,100,200,200)
ctx.stroke();
<canvas id="canvas" width="700" height="600">你的浏览器不支持canvas,请升级</canvas>
<script>
let mycanvas = document.getElementById('canvas');
let ctx = mycanvas.getContext('2d');
ctx.beginPath();
ctx.lineWidth = 10;
ctx.strokeStyle = 'red';
ctx.moveTo(100,100);//起点
//ctx.lineTo(300,100)//终点
ctx.quadraticCurveTo(150,400,300,100)//一次贝塞尔曲线,贝塞尔控制点(150,400),终点
ctx.stroke()
5.3. 绘制二次贝塞尔曲线
绘制公式
ctx.bezierCurveTo(cp1x,cp1y,cp2x,cp2y,x,y)
参数
- cp1x, cp1y 为贝塞尔曲线的第一个控制点
- cp2x, cp3y 为贝塞尔曲线的第二个控制点
- x,y 为绘制曲线的终点
ctx.beginPath()
ctx.moveTo(100,100);
ctx.bezierCurveTo(200,120,50,150,200,200);
ctx.stroke();
<script>
let mycanvas = document.getElementById('canvas');
let ctx = mycanvas.getContext('2d');
ctx.beginPath();
ctx.lineWidth = 10;
ctx.strokeStyle = 'red';
ctx.moveTo(100,100);//起点
// ctx.bezierCurveTo(150,100,300,100,500,100)点都在一条线上的贝塞尔曲线
ctx.bezierCurveTo(150,300,300,-50,500,100)//贝塞尔端点一 贝塞尔端点二 终点
ctx.stroke()
</script>
6. canvas变换
6.1. translate(x,y)
坐标基准点偏移 : 从起始点为基准,移动到当前位置
ctx.translate(100, 100)ctx.arc(100, 100, 50, 0, Math.PI * 2, true)ctx.strokeStyle = 'red';ctx.lineWidth = 5;ctx.stroke()
<style>
* {
margin: 0;
padding: 0;
}
body {
background-color: #f3f3f3;
}
#canvas {
/*canvas虽然默认宽高300X150,但它是个行元素inline*/
display: block;
/*变块才能居中*/
margin: 50px auto;
background-color: #fff;
}
</style>
</head>
<body>
<canvas id="canvas" width="700" height="600">你的浏览器不支持canvas,请升级</canvas>
<script>
let mycanvas = document.getElementById('canvas');
let ctx = mycanvas.getContext('2d');
ctx.lineWidth=10;
ctx.strokeStyle='red';
ctx.translate(100,100);//可以理解为偏移基准点
ctx.arc(100, 100,50,0,Math.PI*2,true)//元素位置通过基准点与参考点配合确定,调谁都可以
ctx.stroke();
</script>
</body>
6.2.rotate(弧度):
旋转 弧度公式 :角度*PI/180
ctx.rotate(Math.PI / 180 * 30)
ctx.rect(200, 200, 100, 100)
ctx.strokeStyle = 'red';
ctx.lineWidth = 5;
ctx.stroke()
let mycanvas = document.getElementById('canvas');
let ctx = mycanvas.getContext('2d');
ctx.lineWidth=10;
ctx.strokeStyle='red';
ctx.translate(100,100)//基准点
ctx.rotate(Math.PI/180 *80);//旋转,弧度值转成角度值
ctx.strokeRect(0,0,100,100)//参考点在自己中心位置
ctx.strokeRect(-50,-50,100,100)//参考点在自己中心位置
6.3. scale(wb,hb)
缩放比例(缩放canvas绘制的图片)
ctx.scale(1.5, 1.5)
ctx.rect(200, 200, 100, 100)
ctx.strokeStyle = 'red';
ctx.lineWidth = 5;
ctx.stroke()
这里将宽、高、圆心坐标等比缩放
let mycanvas = document.getElementById('canvas');
let ctx = mycanvas.getContext('2d');
ctx.lineWidth=10;
ctx.strokeStyle='red';
ctx.scale(1,0.5);//缩放 基准点 宽 高 线宽都等比例缩放
ctx.strokeRect(200,200,50,100)
示例:
var can = document.getElementById("canvas");
ctx = can.getContext("2d");
ctx.beginPath();
ctx.translate(160,30);
ctx.fillStyle = "#00ff00";
ctx.fillRect(0,0,100,50);
for (var i=0;i<50 ;i++ ){
ctx.translate(25,25);
ctx.scale(0.9,0.9);//缩放,针对后面要绘制的图形进行缩放(在前面绘制的那个图形的基础上进行缩放)
ctx.rotate(Math.PI/10);
ctx.fillRect(0,0,100,50);
}
7. 保存与恢复路径
7.1. 保存路径 save()
保存之前的路径状态
7.2.恢复路径 restore()
ctx.save()
ctx.scale(3, 2)
ctx.fillStyle = 'red';
ctx.fillRect(0, 0, 100, 20)
ctx.restore()
ctx.beginPath()
ctx.fillRect(0, 50, 100, 20)
会封闭一个独立路径 不会对外边的区域产生影响
<style>
* {
margin: 0;
padding: 0;
}
body {
background-color: #f3f3f3;
}
#canvas {
/*canvas虽然默认宽高300X150,但它是个行元素inline*/
display: block;
/*变块才能居中*/
margin: 50px auto;
background-color: #fff;
}
</style>
</head>
<body>
<canvas id="canvas" width="700" height="600">你的浏览器不支持canvas,请升级</canvas>
<script>
let mycanvas = document.getElementById('canvas');
let ctx = mycanvas.getContext('2d');
ctx.strokeStyle = 'blue';
ctx.beginPath();
ctx.save()//保存之前的的路径状态
ctx.strokeStyle = 'red';
ctx.lineWidth = 10;
ctx.moveTo(100, 100);
ctx.lineTo(300, 100);
ctx.stroke()
ctx.beginPath()
ctx.restore() //恢复之前保存的路径状态
ctx.moveTo(100, 200);
ctx.lineTo(300, 200);
ctx.stroke()
</script>
8 绘制图片
8.1. 绘制图片
8.1.1 创建图片对象,获取图片
图片预加载,获取图片文件
const img = new Image();
img.src = '../1.jpg'
8.1.2 onload事件,当图片加载完成执行绘制
img.onload = function(){}
8.1.3 图片加载完成后将图片绘制在画布上
ctx.drawImage(image, dx, dy, dWidth, dHeight);
绘制图片(图片对象,画布坐标x,画布坐标y,绘制显示图片宽度,绘制显示图片高度)
const img = new Image();
img.src = '../1.jpg';
img.onload = function () {
ctx.drawImage(this, 0, 0, 100, 300)
}
<body>
<canvas id="canvas" width="700" height="600">你的浏览器不支持canvas,请升级</canvas>
<script>
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
//加载图片
let img = new Image();//创建图片对象
img.src = './imgs/11.jpg';
img.onload = function () {//加载就会触发onload事件
ctx.drawImage(this, 20, 20, 300, 300);//画图片
}
</script>
</body>
8.1.4 切图
ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
参数:
-
image 绘制到上下文的元素
-
sx 可选
需要绘制到目标上下文中的,
image
的矩形(裁剪)选择框的左上角 X 轴坐标。 -
sy 可选
需要绘制到目标上下文中的,
image
的矩形(裁剪)选择框的左上角 Y 轴坐标。 -
sWidth 可选
需要绘制到目标上下文中的,
image
的矩形(裁剪)选择框的宽度。 -
sHeight 可选
需要绘制到目标上下文中的,
image
的矩形(裁剪)选择框的高度。 -
dx
image
的左上角在目标canvas上 X 轴坐标。 -
dy
image
的左上角在目标canvas上 Y 轴坐标。 -
dWidth 可选
image
在目标canvas上绘制的宽度。 -
dHeight 可选
image
在目标canvas上绘制的高度。 允许对绘制的image
进行缩放。
const img = new Image();
img.src = '../1.jpg';
img.onload = function () {
ctx.drawImage(this, 50, 50, 500, 500, 100, 100, 100, 100)
}
<body>
<canvas id="canvas" width="700" height="600">你的浏览器不支持canvas,请升级</canvas>
<script>
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
//加载图片
let img = new Image();//创建图片对象
img.src = './imgs/11.jpg';
img.onload = function () {//加载就会触发onload事件
ctx.drawImage(this, 20, 20, 300, 300);//画图片
ctx.drawImage(this, 50, 50, 100, 100, 20, 350, 300, 300);//可以做放大镜
}
</script>
</body>
<style>
* {
margin: 0;
padding: 0;
}
body {
background-color: #f3f3f3;
}
#canvas {
/*canvas虽然默认宽高300X150,但它是个行元素inline*/
display: block;
/*变块才能居中*/
background-color: #fff;
}
</style>
</head>
<body>
<canvas id="canvas" width="700" height="600">你的浏览器不支持canvas,请升级</canvas>
<script>
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
//加载图片
let img = new Image();//创建图片对象
img.src = './imgs/11.jpg';
img.onload = function () {//加载就会触发onload事件
ctx.drawImage(this, 20, 20, 300, 300);//画图片
canvas.onmousemove = function (e) {
console.log(e);
let sX = e.clientX - 50;
let sY = e.clientY - 50;
ctx.drawImage(img, sX, sY, 100, 100, 20, 350, 300, 300);
}
}
</script>
</body>
<body>
<canvas id="canvas" width="700" height="600">你的浏览器不支持canvas,请升级</canvas>
<script>
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
//加载图片
let img = new Image();//创建图片对象
img.src = './imgs/11.jpg';
img.onload = function () {//图片加载就会触发onload事件
//创建背景图片填充资源
let bg = ctx.createPattern(this, 'repeat')
ctx.fillStyle = bg;//填充背景资源
ctx.fillRect(0, 0, 500, 500)//填充一个矩形
}
</script>
</body>
8.2. 填充背景
8.2.1 createPattern(img,平铺方式)
参数: 平铺方式:repeat,repeat-x,repeat-y,no-repeat
const img = new Image();
img.src = '../1.jpg';
img.onload = function () {
const bg = ctx.createPattern(img, 'no-repeat');
ctx.fillStyle = bg;
ctx.fillRect(100, 100, 300, 200)
}
8.3. 颜色渐变
8.3.1 线性渐变:createLinearGradient(x1,y1,x2,y2)
x1,y1起始坐标点
x2,y2结束坐标点
8.3.2 径向渐变:createRadialGradient(x1,y1,r1,x2,y2,r2)
x1,y1,r1内圆坐标及半径
x2,y2,r2外圆坐标及半径
8.3.3 addColorStop(位置,颜色)
位置:渐变点 0-1之间 可多个
例子,
线性渐变
let color = ctx.createLinearGradient(0, 0, 500, 500);
color.addColorStop(0, 'pink');
color.addColorStop(0.5, 'yellow')
color.addColorStop(1, 'deeppink')
ctx.fillStyle = color;
ctx.fillRect(0, 0, 500, 500)
<body>
<canvas id="canvas" width="700" height="600">你的浏览器不支持canvas,请升级</canvas>
<script>
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
//加载图片
let color = ctx.createLinearGradient(0, 0, 500, 500)//渐变颜色对象
color.addColorStop(0, 'red')//添加颜色
color.addColorStop(.5, 'yellow')
color.addColorStop(1, 'blue')
ctx.fillStyle = color;//用渐变颜色填充
ctx.fillRect(0, 0, 500, 500)
</script>
</body>
径向渐变
let color = ctx.createRadialGradient(200, 200, 100, 200, 200, 200);
color.addColorStop(0, 'pink');
color.addColorStop(0.5, 'yellow')
color.addColorStop(1, 'deeppink')
ctx.fillStyle = color;
ctx.fillRect(0, 0, 500, 500)
<body>
<canvas id="canvas" width="700" height="600">你的浏览器不支持canvas,请升级</canvas>
<script>
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
//加载图片
let color = ctx.createRadialGradient(200,200,50,200,200,300)//渐变颜色对象
color.addColorStop(0, 'red')//添加颜色
color.addColorStop(.5, 'yellow')
color.addColorStop(1, 'blue')
ctx.fillStyle = color;//用渐变颜色填充
// ctx.fillRect(0, 0, 500, 500)
ctx.fillRect(0, 0, 100, 100)
</script>
</body>
9.绘制文本
9.1. 绘制文本
- strokeText(文本,x,y); 绘制空心文本(描边文字)
- fillText(文本,x,y); 绘制实心文本(填充文字)
- font = "font-size font-family" 注:尺寸 字体缺一不可
- textAlign = "";文本左右对齐方式 (参考文字坐标点对齐)
start center end left right - textBaseline文本上下对齐方式
alphabetic 默认。文本基线是普通的字母基线。
top 文本基线是 em 方框的顶端。。
hanging 文本基线是悬挂基线。
middle 文本基线是 em 方框的正中。
ideographic 文本基线是表意基线。
bottom 文本基线是 em 方框的底端。
let str = 'wuwei'
ctx.font = '50px 宋体'
ctx.textAlign = 'center'
ctx.textBaseline = 'top'
ctx.strokeText(str, 100, 100)
ctx.fillText(str, 100, 200)
9.2. 绘制阴影
- shadowOffsetX,shadowOffsetY x轴、y轴偏移
- shadowBlur 阴影模糊度
- shadowColor 阴影颜色
默认颜色:rgba(0,0,0,0)
ctx.shadowOffsetX = '10'
ctx.shadowOffsetY = '10'
ctx.shadowBlur = '3'
ctx.shadowColor = 'red'
案例:
body {
background-color: #000;
}
canvas {
display: block;
margin: 100px auto 0;
border: 1px solid skyblue;
background-color: #fff;
}
.box{
width: 360px;
margin: 10px auto;
}
input{
width: 50px;
height: 20px;
text-align: center;
}
<canvas width="500" height="500"></canvas>
<div class="box">
<input type="color" id='colorList'>
<button id='color'>随机颜色</button>
<input type="text" value='2px' id='storke'>
<button id='add'>笔触增加</button>
<button id='reduce'>笔触减小</button>
<button id="clear">清屏</button>
</div>
var canvas = document.getElementsByTagName('canvas')[0];
var ctx = canvas.getContext('2d');
var strokeColor = '#000000';
var lineWidth = 2;
colorList.onchange = function () {
strokeColor = colorList.value;
}
color.onclick = function () {
strokeColor = '#' + Math.random().toString(16).slice(2, 8);
colorList.value = strokeColor;
}
add.onclick = function () {
if (lineWidth >= 10) return;
lineWidth += 2;
storke.value = lineWidth + 'px'
}
reduce.onclick = function () {
if (lineWidth <= 2) return;
lineWidth -= 2;
storke.value = lineWidth + 'px'
}
canvas.onmousedown = function (ev) {
ev = ev || window.event;
var This = this;
var x = ev.clientX - this.offsetLeft;
var y = ev.clientY - this.offsetTop;
ctx.strokeStyle = strokeColor;
ctx.lineWidth = lineWidth;
ctx.beginPath();
ctx.moveTo(x, y);
document.onmousemove = function (ev) {
ev = ev || window.event;
var x = ev.clientX - This.offsetLeft;
var y = ev.clientY - This.offsetTop;
ctx.lineTo(x, y);
ctx.stroke();
}
document.onmouseup = function () {
this.onmousemove = null;
this.onmouseup = null
}
}
clear.onclick = function () {
console.log(1)
ctx.clearRect(0, 0, 500, 500)
}
<body>
<canvas id="canvas" width="700" height="600">你的浏览器不支持canvas,请升级</canvas>
<script>
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
let str = 'hello world';
ctx.font = '50px 微软雅黑'
ctx.textAlign = 'left'
ctx.textBaseline = 'top'
ctx.shadowOffsetX = '10'//水平偏移
ctx.shadowOffsetY = '10'//垂直偏移
ctx.shadowBlur = '3'//模糊
ctx.shadowColor = 'red'//颜色
ctx.strokeText(str, 50, 200)//空心文字
let str2 = '你好呀';
ctx.font = '50px 微软雅黑'
ctx.textAlign = 'left'
ctx.textBaseline = 'middle'
ctx.fillText(str2, 400, 200)//实心文字
</script>
</body>
10.API使用总结
10.1. canvas标签
<canvas width="" height="" id="">
您的浏览器不支持canvas,请更换浏览器!
</canvas>
默认宽度300px,默认高度 150px
10.2. canvas绘图环境设置
getContext("2d"); 目前支持2d绘图环境
10.3. 绘图路径:
- beginPath() :开始路径
- closePath():闭合路径
- moveTo(x,y):将触笔移动到x,y点
- lineTo(x,y):绘制到x,y点
- stroke(): 触笔方法 画线 默认为黑色
- fill():填充方法
- rect(x,y,w,h):矩形路径
- save():保存路径
- restore():恢复路径
10.4. 绘制矩形:
- fillRect(x,y,w,h) 填充实心矩形
- strokeRect(x,y,w,h) 绘制空心矩形
- clearRect(x,y,w,h) 清除矩形选区
10.5. 设置绘图样式:
- fillStyle: 填充颜色
- strokeStyle: 触笔颜色
- lineWidth: 触笔宽度(线宽)
10.6. 图形边界样式:
- lineJoin : 边界连接点样式
miter(默认值),round(圆角),bevel(斜角) - lineCap: 端点样式
butt(默认值),round(圆角),square(高度多出线宽一半)
10.7. 绘制圆形:
- arc(x,y,r,0,360,false)
x,y 圆心坐标位置
r 圆半径
0,360 从0度到360度 绘制一个圆形(用弧度公式)
true/false 逆时针/顺时针绘图
10.8. 绘制曲线
- arcTo(x1,y1,x2,y2,r)
x1,y1 坐标一 x2,y2坐标二 r圆弧半斤 - quadraticCurveTo(dx,dy,x1,y1)
贝塞尔曲线:dx,dy控制点 x1,y1结束坐标 - bezierCurveTo(dx1,dy1,dx2,dy2,x1,y1)
贝塞尔曲线:dx1,dy1 控制点一 dx2,dy2控制点二
x1,y1结束坐标
10.9. canvas变换
- translate(x,y)
坐标基准点偏移 : 从起始点为基准,移动到当前位置 - rotate(弧度): 旋转 弧度公式 :角度*PI/180
- scale(wb,hb)缩放比例(缩放canvas绘制的图片)
10.10. 绘制图片
- 图片预加载,获取图片文件
- onload事件,监听图片是否加载完毕,如果加载完毕执行第三步
- drawImage(img,x,y,w,h);绘制图片(图片,坐标x,坐标y,宽度,高度)
10.11.设置背景
- createPattern(img,平铺方式)
平铺方式:repeat,repeat-x,repeat-y,no-repeat
10.12. 颜色渐变
- 线性渐变:createLinearGradient(x1,y1,x2,y2)
x1,y1起始坐标点
x2,y2结束坐标点 - 径向渐变:createRadialGradient(x1,y1,r1,x2,y2,r2)
x1,y1,r1内圆坐标及半径
x2,y2,r2外圆坐标及半径 - addColorStop(位置,颜色)
位置:渐变点 0-1之间 可多个
10.13. 绘制文本
- strokeText(文本,x,y); 绘制空心文本
- fillText(文本,x,y); 绘制实心文本
- font = "font-size font-family" 注:尺寸 字体缺一不可
- textAlign = "";文本左右对齐方式
start center end left right - textBaseline文本上下对齐方式
alphabetic 默认。文本基线是普通的字母基线。
top 文本基线是 em 方框的顶端。。
hanging 文本基线是悬挂基线。
middle 文本基线是 em 方框的正中。
ideographic 文本基线是表意基线。
bottom 文本基线是 em 方框的底端。
10.14. 阴影
- shadowOffsetX,shadowOffsetY x轴、y轴偏移
- shadowBlur 阴影模糊度
- shadowColor 阴影颜色
- 默认颜色:rgba(0,0,0,0)
画板例子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body {
background-color: #000;
}
canvas {
display: block;
margin: 10px auto 0;
border: 1px solid skyblue;
background-color: #fff;
}
.box {
width: 500px;
margin: 10px auto;
}
input {
width: 50px;
height: 20px;
text-align: center;
}
</style>
</head>
<body>
<canvas width="600" height="400"></canvas>
<div class="box">
<input type="color" id='colorList'>
<!--type类型为color表示颜色选择器 -->
<button id='color'>随机颜色</button>
<input type="text" value='2px' id='storke' disabled> <!-- input 的阻止页面上手动编辑 disabled -->
<button id='add'>笔触增加</button>
<button id='reduce'>笔触减小</button>
<button id="clear">清屏</button>
</div>
<script>
//获取canvas
let canvas = document.getElementsByTagName('canvas')[0];
// 获取上下文对象(画笔)
let ctx = canvas.getContext('2d');
//信号量 定义初始画笔的颜色和大小
let strokeColor = '#000000';//笔触颜色信号量
let lineWidth = 2;//笔触大小信号量
//清屏
clear.onclock = function () {
ctx.clearRECT(0, 0, 600, 400)
}
// 颜色选择
colorList.onchange = function () {
strokeColor = this.value;
}
//随机颜色
color.onclick = function () {
strokeColor = '#' + Math.random().toString(16).substr(2, 6);
colorList.value = strokeColor//滑条颜色与随机颜色保持一致
}
//加减笔触
add.onclick = function () {
lineWidth += 2; //画笔值与页面显示保持一致
storke.value = lineWidth + 'px';
}
reduce.onclick = function () {
lineWidth -= 2;
storke.value = lineWidth + 'px';
}
//绘制
canvas.onmousedown = function (ev) {
ev = ev || window.event//事件对象做兼容
//获取鼠标按下时距离画布左上端点的距离 x 有
let x = ev.clientX - this.offsetLeft;//事件对象距离浏览器左边的距离减去canvas距离浏览器左边的距离
let y = ev.clientY - this.offsetTop;
//绘制
ctx.strokeStyle = strokeColor;
ctx.lineWidth = lineWidth;
//开启新路径
ctx.beginPath();
ctx.moveTo(x, y);//鼠标按下 绘制的坐标就移动到x y位置
document.onmousemove = function (ev) {
//使用外部this方法一 let This = this;定义一个大This,将外部this传给里面的This
//使用外部this方法二 .bind(this)
//使用外部this方法三 箭头函数 (ev)=>{} 箭头函数没有this,只能向上找this
ev = ev || window.event;
let x = ev.clientX - this.offsetLeft;
let y = ev.clientY - this.offsetTop;
ctx.lineTo(x, y);
ctx.stroke();
}.bind(this)
//现在的线段是由鼠标拖出来的
document.onmouseup = function () {//清理事件。鼠标抬起说明画完了,清理默认事件.onmousedown事件是入口不清理
this.onmousemove = null;
this.onmouseup = null;
}
}
</script>
</body>
</html>
网友评论