1.canvas 默认显示宽高:
宽300 高150【对于不支持canvas的浏览器,默认显示canvas里面的标签】
2.canvas 设置宽高在标签内设置:
<canvas id="canvasId" width="300" height="400"></canvas> 宽高如果写在stylez中,像素代表的是在默认宽高的基础上等比缩放,并不是代表真正的宽高
3.绘制环境:
var a = document.querySelector('#canvasId') var b = a.getContext('2d') 目前支持2d的场景
4.绘制方块:
b.fillRect(left,top,width,height):默认颜色是黑色
b.strokeRect(left,top,width,hight):带边框的方块【默认1px的黑色边框里,会有1px误差,实际是2px】
例:b.strokeRect(50,50,100,100)------>b.strokeRect(50.5,50.5,100,100)
就会解决这个误差问题 (绘制canvas是有顺序的)先写谁,谁就先出来b.fillRect(),b.strokeRect()
5.设置绘图:
b.fillStyle = 'red' 填充颜色【也可以填充背景图】
b.lineWidth = 20 线宽度,是一个数值 b.strokeStyle = 'red' 边线颜色
6.边界绘制:
lineJoin: 边界连接点样式 miter(默认)、round(圆角)、bevel(斜角)//线框和点组合的线条有效
lineCap:端点样式 butt(默认)、round(圆角)、square(高度多出为宽一半的值)//针对点组合的线条有效
例:b.lineJoin = 'round' b.lineCap = 'square'
7.绘制路径:
b.beginPath() :【开始绘制路径】
b.moveTo(100,100) : 【点的初始坐标】
b.lineTo(200,200) : 【新的目标点1】
b.lineTo(400,300) : 【新的目标点2】
b.closePath() :线条闭合,默认将线条连接闭合,路径结束【也就是回到初始坐标点(100,100)】
b.stroke() :【画线条】 必须写这个才生效,两点之间才能连成线条 b.fill() :【内容填充颜色,默认黑色】
b.rect(x,y,width,height) :【矩形线框区域】
b.clearRect(0,0,a.width,a.height) :【删除一个画布的矩形区域】
b.save() :【保存路径】//起到包裹作用头 //内容写在这两个方法里面,就可以单独给一个绘制图形添加样式了,不会影响其他
b.restore() :【恢复路径】//起到包裹作用尾
二:基础篇代码实战
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<style>
body{
background:black;
}
span{
color:red;
font-size:20px;
font-weight: bold;
}
#myCanvas1{
background:rgb(172, 124, 211);
/* color:#fff; */
/* border-radius:200px; */
}
</style>
<script>
window.onload = function(){
var canvas = document.querySelector('#myCanvas1')
var canvasObj = canvas.getContext('2d')
console.log(canvasObj)
//1线框
canvasObj.save()//代表局部作用域头
canvasObj.lineWidth = 20//线框宽度
canvasObj.strokeStyle = 'lightblue'//线框颜色
canvasObj.lineJoin = 'round'//边界连接点(圆角)
canvasObj.lineCap = 'round'//端点样式(圆角)
canvasObj.strokeRect(30,30,20,20)//绘制线框
canvasObj.restore()//代表局部作用域尾
//2线框
canvasObj.save()
canvasObj.lineWidth = 20
canvasObj.fillStyle = 'pink'//背景填充色
canvasObj.lineJoin = 'bevel'//边界连接点(斜角)
canvasObj.lineJoin = 'round'//边界连接点(圆角)
canvasObj.strokeRect(100,100,100,100)//绘制线框
canvasObj.restore()
//3填充色
canvasObj.save()
canvasObj.fillStyle = 'lightgreen'
canvasObj.fillRect(200,200,200,200)
canvasObj.restore()
//4绘制路径
canvasObj.save()
canvasObj.beginPath()//开始绘制路径
canvasObj.lineWidth = 10//线框宽度
canvasObj.strokeStyle = 'blue'//线框颜色
canvasObj.lineCap = 'square'//端点样式(高度多出为宽一半)
canvasObj.lineCap = 'round'//端点样式(圆角)
canvasObj.lineJoin = 'bevel'//边界连接点(斜角)
canvasObj.moveTo(10,200)//起点坐标
canvasObj.lineTo(20,300)//目标坐标
canvasObj.lineTo(100,300)//目标坐标
canvasObj.closePath()//线条闭合【相当于canvasObj.lineTo(10,200)】
canvasObj.fill()//线框内容填充颜色
canvasObj.rect(50,390,50,50)//绘制矩形线框
// canvasObj.clearRect(0,0,canvas.width,canvas.height)
canvasObj.stroke()//画线条必须加这个才生效[放在最后]
canvasObj.restore()
// 实例:鼠标划过出现线条
canvas.onmousedown = function(ev){
var ev = ev || window.event;
canvasObj.moveTo(ev.clientX - canvas.offsetLeft,ev.clientY - canvas.offsetTop);//起点坐标
document.onmousemove = function(ev){
var ev = ev || window.event;
canvasObj.lineWidth = 3//线框宽度
canvasObj.strokeStyle = 'pink'//线框颜色
canvasObj.lineCap = 'round'//端点样式(高度多出为宽一半)
canvasObj.lineTo(ev.clientX - canvas.offsetLeft,ev.clientY - canvas.offsetTop);//目标坐标
canvasObj.stroke()//画线条必须加这个才生效[放在最后]
};
document.onmouseup = function(){
document.onmousemove = null;
document.onmouseup = null;
}
}
// 实例:方块自己移动
var num = 0;
canvasObj.save()
canvasObj.fillRect(0,0,0,0)
setInterval(function(){
num++;
// canvasObj.clearRect(0,0,canvas.width,canvas.height)
canvasObj.clearRect(0,0,num,num)
if(num<300){
canvasObj.fillRect(num,num,100,100)
}
},10)
canvasObj.restore()
document.querySelector('.clear').onclick = function(){
location.reload() //刷新当前页面
};
}
</script>
</head>
<body>
<canvas id="myCanvas1" width="1400" height="2000">
<span>啥破浏览器才会不支持,笨蛋</span>
</canvas>
<button class="clear" style="width: 100px;height: 50px;background:black;color:#fff;font-weight:bold;font-size:18px;line-height:50px;text-align:center;z-index:100;position: absolute;
right: 100px;
top: 20px;border:none;border-radius:5px;cursor:pointer;">清除</button>
</body>
</html>
三:进阶篇
绘制环境:
var b = a.getContext('2d') 目前支持2d的场景
1.绘制圆形:
- x,y : 起始位置
- 弧度与角度的关系:弧度 = 角度*Math.pI/180
- 旋转方向:顺时针(false)、逆时针(true)
- 圆形相对弧度:0度,90度,正负180度,负90度【右下左上】
例1:
b.moveTo(200,200)//确定圆心位置
b.arc(200,200,150,0,90*Math.PI/180,false)
b.closePath()//闭合线路 b.stroke() //绘制线路
arcTo(x1,y1,x2,y2,r) //第一组坐标,第二组坐标,半径
quadraticCurveTo(dx,dy,x1,y1)//贝塞尔曲线:第一组控制点,第二组结束坐标【控制点就是曲线的偏移方向坐标点】
bezierCurveTo(dx1,dy1,dx2,dy2,x1,y1)//贝塞尔曲线:第一组控制点,第二组控制点,第三组结束坐标
例: canvasObj.moveTo(200,200)
canvasObj.arcTo(100,100,200,100,50)
canvasObj.quadraticCurveTo(100,100,200,100)
canvasObj.bezierCurveTo(100,100,200,200,200,100)
canvasObj.stroke()
3.变换:
b.translate(100,100) //偏移:从起始点为基准点,移动当前位置坐标
b.rotate(45*Math.PI/180) //旋转:参数为弧度【旋转点为方块左上角】
【如果旋转点想在中间,则b.translate(-50,-50) 偏移距离为方块大小的一半】
【如果一个方块写两个旋转,旋转的角度会累加】
【在定时器里使用旋转角度,避免角度累加,可以使用b.sava()和b.restore 进行包裹,只是局部变量】
b.scale(2,5) //缩放:2是宽放大的倍数,5是高放大的倍数
注意:fillRect(0,0,100,100)这个必须写在后面,前面的设置才能生效
三:进阶篇代码实战
钟表的实现:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<style>
body{
background:black;
}
span{
color:red;
font-size:20px;
font-weight: bold;
}
#myCanvas1{
background:rgb(172, 124, 211);
}
</style>
<script>
window.onload = function(){
var canvas = document.querySelector('#myCanvas1')
var canvasObj = canvas.getContext('2d')
// 绘制钟表
function drawWatch(){
var x = 200;
var y = 200;
var r = 150;
canvasObj.clearRect(0,0,canvas.width,canvas.height);//每过一秒就会调用一次这个函数,就要清除上一个画布,重新画一个
// 获取当前时间
var oDate = new Date();
var oHours = oDate.getHours();
var oMin = oDate.getMinutes();
var oSen = oDate.getSeconds();
// 获取当前时间对应的刻度【-90是因为,画圆是从0-右侧开始的,而时间是从-90度开始的,也就是12点位置】
// 【分针走30分钟,时针转15度,所以时针的度数再加上分针走的度数,即 +oMin/2】
var oHoursValue = (-90 + oHours*30 + oMin/2) * Math.PI/180;//时针走一小时转30度
var oMinValue = (-90 + oMin*6) * Math.PI/180;//分针走一分钟转6度
var oSenValue = (-90 + oSen*6) * Math.PI/180;//秒针走一秒钟转6度
canvasObj.strokeStyle = 'white'//设置全局边框颜色
canvasObj.fillStyle = 'rgba(0,0,0)';//设置全局填充颜色
// 画分针的刻度【分针走一个刻度是6度】
canvasObj.beginPath();
for(var i = 0;i<60;i++){
canvasObj.moveTo(x,y)
canvasObj.arc(x,y,r,6*i*Math.PI/180,6*(i+1)*Math.PI/180,false)
}
canvasObj.stroke();
canvasObj.closePath();
// 画一个比外圆小的圆形,将线条盖住,只留下短点的刻度
canvasObj.beginPath();//开始路线
canvasObj.moveTo(x,y);//圆心移到中间
canvasObj.arc(x,y,r*19/20,0,360*Math.PI/180,false);//画一个比外圆小的圆形
// canvasObj.fillStyle = 'rgba(0,0,0,.3)';//改变填充颜色
canvasObj.fill();//填充颜色必须加这个方法,[只想填充颜色就不用加线框]
canvasObj.closePath();//闭合路线
//画时针大刻度【时针走一个刻度是30度】
canvasObj.beginPath();
for(var i = 0;i<12;i++){
canvasObj.moveTo(x,y)
canvasObj.arc(x,y,r,30*i*Math.PI/180,30*(i+1)*Math.PI/180,false);
}
canvasObj.lineWidth = 3
canvasObj.stroke();
canvasObj.closePath();
// 画一个小圆,把大刻度指针盖住,留下相对短的刻度
canvasObj.beginPath();
canvasObj.moveTo(x,y);
canvasObj.arc(x,y,r*18/20,0,360*Math.PI/180,false);
// canvasObj.fillStyle = 'rgb(172, 124, 211)'
canvasObj.fill();
canvasObj.closePath();
// 画秒针指针
canvasObj.beginPath();
canvasObj.moveTo(x,y);
canvasObj.arc(x,y,r*18/20,oSenValue,oSenValue,false)
canvasObj.lineWidth = 1
canvasObj.stroke();
canvasObj.closePath();
// 画分针指针
canvasObj.save()//代表局部作用域
canvasObj.beginPath();
canvasObj.moveTo(x,y);
canvasObj.arc(x,y,r*16/20,oMinValue,oMinValue,false)
canvasObj.lineWidth = 3
canvasObj.stroke();
canvasObj.closePath();
canvasObj.restore()
// 画时针指针
canvasObj.save()//代表局部作用域
canvasObj.beginPath();
canvasObj.moveTo(x,y);
canvasObj.arc(x,y,r*12/20,oHoursValue,oHoursValue,false)
canvasObj.lineWidth = 5
canvasObj.stroke();
canvasObj.closePath();
canvasObj.restore()
}
//定时器,每一秒更新一下
setInterval(drawWatch,1000);
drawWatch()
}
</script>
</head>
<body>
<canvas id="myCanvas1" width="400" height="400">
<span>啥破浏览器才会不支持,笨蛋</span>
</canvas>
</body>
</html>
贝塞尔曲线和方块的缩放旋转:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<style>
body{
background:black;
}
span{
color:red;
font-size:20px;
font-weight: bold;
}
#myCanvas1{
background:rgb(172, 124, 211);
}
</style>
<script>
window.onload = function(){
var canvas = document.querySelector('#myCanvas1')
var canvasObj = canvas.getContext('2d')
// 贝塞尔曲线
// canvasObj.moveTo(200,200)
// canvasObj.arcTo(100,100,200,100,50)
// canvasObj.quadraticCurveTo(100,100,200,100)
// canvasObj.bezierCurveTo(100,100,200,200,200,100)
// canvasObj.stroke()
// 偏移
// canvasObj.moveTo(200,200)
// canvasObj.fillStyle = 'pink'
// canvasObj.translate(50,50)
// canvasObj.rotate(45*Math.PI/180)
// canvasObj.scale(1,1)
// canvasObj.fillRect(0,0,100,100)
// 旋转的小方块
function rotateRect(){
var num = 0;
var num2 = 0;
var value = 1;
canvasObj.fillStyle = 'lightBlue';
canvasObj.translate(200,200)
setInterval(function(){
num++;
canvasObj.save();//加这个局部生效的作用是避免旋转的角度累加
canvasObj.clearRect(0,0,canvas.width,canvas.height)//在定时器里,每次都要清除一下画布
if(num2 == 100){
value = -1;
}else if(num2 == 0){
value = 1
}
num += value
// canvasObj.scale( num2*1/50,num2*1/50 );
canvasObj.rotate(num*Math.PI/180)//旋转的角度是累加的
// canvasObj.translate(-50,-50)//将旋转基点设置在中间
canvasObj.fillRect(0,0,100,100)
canvasObj.restore()
},30)
}
rotateRect()
}
</script>
</head>
<body>
<canvas id="myCanvas1" width="400" height="400">
<span>啥破浏览器才会不支持,笨蛋</span>
</canvas>
</body>
</html>
四:进阶2(绘制图片)
1.插入图片
(1)图片预加载:在onload中调用方法
(2)b.drawImage(img,x,y,w,h)//img:当前图片 x,y:坐标 w,h:图片宽高
例:
var myImg = new Image();
myImg.onload = function(){
draw(this);
}
myImg.src = '2.png';
function draw(obj){
b.drawImage(obj,0,0,400,400)
}
2.给方块设置背景图片
var myImg = new Image();
myImg.onload = function(){
draw(this);
}
myImg.src = '2.png';
function draw(obj){
var bg = b.createPattern(obj,'repeat')
b.fillStyle = bg;//将背景当做填充样式
b.fillRect(0,0,300,300)
}
3.渐变色
//参数【起始点坐标,结束点坐标】 ----addColorStop(位置,颜色) 添加渐变点
(2)放射性渐变:b.createRadialGradient(x1,y1,r1,x2,y2,r2)
//参数【第一个圆的坐标半径,第二个圆的坐标半径】
例1:
var obj = b.createLinearGradient(150,100,150,200);//线性渐变
var obj = b.createRadialGradient(200,200,100,200,200,150);//放射性渐变
obj.addColorStop(0,'lightblue')
obj.addColorStop(0.5,'lightgreen')//渐变色过度能写多个颜色【0-1之间的数字】
obj.addColorStop(1,'pink')
b.fillStyle = obj
b.fillRect(0,0,400,400)
4.文本
(1)b.strokeText(文字,x,y) // 文字边框
(2)b.fillText(文字,x,y) // 文字填充
(3)b.font = '60px impact' //文字大小:'60px impact' 大小,字体[第二个字体必须写,否则大小设置不生效]
(4)b.textAlign = 'start' // 文字左右 默认是start跟left 效果一样,end,right,center
(5)b.textBaseline = 'top' // 文字上下 的位置的方式默认:alphabetic,top,middle,bottom
(6)b.measureText(str).width //str代表文字内容,获取文字的宽度,没有高度,高度就是文字大小例:文字居中
canvasObj.font = '60px impact'//字体不能不写,不写大小不生效
canvasObj.textBaseline = 'top' //上下对齐
var w = canvasObj.measureText('闫明爽').width;
//获取widthcanvasObj.fillText('闫明爽',(canvas.width - w)/2,(canvas.height - 60)/2)
5.阴影
(2)shadowOffsetY //y轴偏移
(3)shadowBlur //高斯模糊值
(4)shadowColor //阴影颜色 默认颜色是黑色透明rgba(0,0,0,0)
例:
b.shadowOffsetX = 20;
b.shadowOffsetY = 20;
b.shadowColor = 'pink'b.shadowBlur = 4
五:进阶2-代码实战
微博图片旋转效果
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<style>
body{
background:black;
}
span{
color:red;
font-size:20px;
font-weight: bold;
}
#myCanvas1{
background:rgb(172, 124, 211);
/* color:#fff; */
/* border-radius:200px; */
}
</style>
<script>
window.onload = function(){
var button = document.querySelectorAll('.button')//页面上的按钮
var img = document.getElementById('img')//页面上显示的图片
var now = 0;
var myImg = new Image();
myImg.onload = function(){//图片预加载,在onload中调用
draw(img)
}
myImg.src = img.src//创建的图片路径等于页面上的图片路径
function draw(obj){
// 动态创建canvas元素
var canvas = document.createElement('canvas')
var canvasObj = canvas.getContext('2d');
// 将页面上图片的宽高赋予canvas
canvas.width = obj.width;
canvas.height = obj.height;
// 图片的父节点div是被操作对象,参数是新节点,旧节点
// 所以这个操作是将div下的img换成canvas
obj.parentNode.replaceChild(canvas,obj)
// 绘制图片,当前图片,x,y:坐标
canvasObj.drawImage(myImg,0,0)
// 点击逆时针按钮
button[0].onclick = function(){//逆时针旋转
if(now==0){
now = 3;
}else{
now--;
}
toChange()
}
// 点击顺时针按钮
button[1].onclick = function(){//顺时针旋转
if(now==3){
now = 0;
}else{
now++;
}
toChange()
}
function toChange(){
switch(now){
case 1:
canvas.width = obj.height;
canvas.height = obj.width;
canvasObj.rotate(90*Math.PI/180)
canvasObj.drawImage(myImg,0,-obj.height)
break;
case 2:
canvas.width = obj.width
canvas.height = obj.height;
canvasObj.rotate(180*Math.PI/180);
canvasObj.drawImage(myImg,-obj.width,-obj.height);
break;
case 3:
canvas.width = obj.width
canvas.height = obj.height;
canvasObj.rotate(270*Math.PI/180);
canvasObj.drawImage(myImg,-obj.width,0);
break;
case 0:
canvas.width = obj.width
canvas.height = obj.height;
canvasObj.rotate(0);
canvasObj.drawImage(myImg,0,0);
break;
}
}
}
}
</script>
</head>
<body>
<button class="button">←</button>
<button class="button">→</button>
<div>
<img id="img" src="2.png" alt="">
</div>
</body>
</html>
插入图片:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<style>
body{
background:black;
}
span{
color:red;
font-size:20px;
font-weight: bold;
}
#myCanvas1{
background:rgb(172, 124, 211);
}
</style>
<script>
window.onload = function(){
var canvas = document.querySelector('#myCanvas1')
var canvasObj = canvas.getContext('2d')
var myImg = new Image();
myImg.onload = function(){
draw(this);
}
myImg.src = '2.png';
function draw(obj){
//绘制图片
canvasObj.drawImage(obj,0,0,400,400)
//将背景图片当做填充样式
var bg = canvasObj.createPattern(obj,'repeat')
canvasObj.fillStyle = bg;
canvasObj.fillRect(0,0,300,300)
}
}
</script>
</head>
<body>
<canvas id="myCanvas1" width="400" height="400">
<span>啥破浏览器才会不支持,笨蛋</span>
</canvas>
</body>
</html>
渐变色:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<style>
body{
background:black;
}
span{
color:red;
font-size:20px;
font-weight: bold;
}
#myCanvas1{
background:rgb(172, 124, 211);
}
</style>
<script>
window.onload = function(){
var canvas = document.querySelector('#myCanvas1')
var canvasObj = canvas.getContext('2d')
// var obj = canvasObj.createLinearGradient(150,100,150,200);
var obj = canvasObj.createRadialGradient(200,200,100,200,200,150);
obj.addColorStop(0,'lightblue')
obj.addColorStop(0.5,'lightgreen')
obj.addColorStop(1,'pink')
canvasObj.fillStyle = obj
canvasObj.fillRect(0,0,400,400)
}
</script>
</head>
<body>
<canvas id="myCanvas1" width="400" height="400">
<span>啥破浏览器才会不支持,笨蛋</span>
</canvas>
</body>
</html>
文字:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<style>
body{
background:black;
}
span{
color:red;
font-size:20px;
font-weight: bold;
}
#myCanvas1{
background:rgb(172, 124, 211);
}
</style>
<script>
window.onload = function(){
var canvas = document.querySelector('#myCanvas1')
var canvasObj = canvas.getContext('2d')
canvasObj.font = '60px impact'//字体不能不写,不写大小不生效
canvasObj.textBaseline = 'top' //上下对齐
// canvasObj.textAlign = 'end' //左右对齐
// canvasObj.fillText('闫明爽',200,200)
// canvasObj.strokeText('闫明爽',100,100)
// 阴影
canvasObj.shadowOffsetX = 20;
canvasObj.shadowOffsetY = 20;
canvasObj.shadowColor = 'pink'
canvasObj.shadowBlur = 4
// 文字居中
var w = canvasObj.measureText('闫明爽').width;
canvasObj.fillText('闫明爽',(canvas.width - w)/2,(canvas.height - 60)/2)
}
</script>
</head>
<body>
<canvas id="myCanvas1" width="400" height="400">
<span>啥破浏览器才会不支持,笨蛋</span>
</canvas>
</body>
</html>