H5C3 canvas画布
canvas画布
获取canvas元素
搭建canvas画布的绘制环境(我们所有的绘制行为都是在这个环境下进行的)
getContext(“2d”)
在内存绘制(仅仅存在于内存中 我们看不到)
绘制到页面 stroke()
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<canvas id="myCanvas" width="" height="">
您的浏览器版本过低 请更新
</canvas>
</body>
<script type="text/javascript">
//获取canvas元素
var canvas=document.getElementById("myCanvas");
//搭建canvas画布的绘制环境
var ctx=canvas.getContext("2d");
//绘制一条线(0,0)到(100,100);
//使用moveTo 和 lineTo 只是在内存里面创建了一条路线
ctx.moveTo(0,0);
ctx.lineTo(100,100);
//绘制到页面
ctx.stroke();
</script>
</html>
设置画布大小
canvas默认的宽高为300*150
css中的宽高指的是拉伸后的宽高
行内或者js设置的宽高是 真实的设置画布的宽高
画布的宽高在js里面也可以设置 不带单位
.width
.height
beginPath(); 清空所有路径
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
#myCanvas{
border: 1px solid red;
width: 200px;
height: 200px;
}
</style>
</head>
<body>
<!-- <canvas id="myCanvas" width="200" height="200"></canvas> -->
<canvas id="myCanvas">
您的浏览器版本过低 请更新
</canvas>
</body>
<script type="text/javascript">
//获取canvas元素
var canvas=document.getElementById("myCanvas");
//搭建canvas画布的绘制环境
var ctx=canvas.getContext("2d");
console.log(canvas.width,canvas.height); //300 150
//画布的宽高在js里面也可以设置
canvas.width=100;
canvas.height=100;
//绘制一条线(0,0)到(100,100);
//使用moveTo 和 lineTo 只是在内存里面创建了一条路线
ctx.moveTo(0,0);
ctx.lineTo(100,100);
//绘制到页面
ctx.stroke();
</script>
</html>
画线
moveTo() 起始点坐标
lineTo 线画到的坐标
设置线条颜色 strokeStyle
问题
发现问题 绘制两条线 在页面上呈现以后 会发现一个问题 第一条线的颜色会比第二条颜色要深
分析问题 绘制第一条线的时候 在内存中生成一个路径 当地一个storke走完过后 然后绘制第二条 此时 内存中有两条路径 再调用一次storke 就会把这两个路径在绘制一次 就出现第一条线比第二条深
解决问题 把所有需要绘制的线条的moveTo 和 lineTo全部写完 只调用一次stroke 一次性绘制
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
#myCanvas{
border: 1px solid red;
}
</style>
</head>
<body>
<canvas id="myCanvas">
您的浏览器版本过低 请更新
</canvas>
</body>
<script type="text/javascript">
//获取canvas元素
var canvas=document.getElementById("myCanvas");
//搭建canvas画布的绘制环境
var ctx=canvas.getContext("2d");
//画布的宽高在js里面也可以设置
canvas.width=600;
canvas.height=400;
ctx.moveTo(0,0);
ctx.lineTo(100,100);
ctx.lineTo(100,200);
// 设置线条颜色
ctx.strokeStyle="#FF0000"
ctx.moveTo(100,0);
ctx.lineTo(200,100);
ctx.lineTo(200,200);
// 设置线条颜色
ctx.strokeStyle="#0f0"
//绘制到页面
ctx.stroke();
</script>
</html>
画圆
arc()
参数1和参数2 表示圆心的坐标
参数3 表示圆的大小 半径
参数4 圆的起始角度
参数5 圆的结束的角度
参数6 规定画圆是沿顺时针还是逆时针 true表示逆时针 false表示顺时针
画一个整圆 就是0 到2Π
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
#myCanvas{
border: 1px solid red;
}
</style>
</head>
<body>
<canvas id="myCanvas">
您的浏览器版本过低 请更新
</canvas>
</body>
<script type="text/javascript">
//获取canvas元素
var canvas=document.getElementById("myCanvas");
//搭建canvas画布的绘制环境
var ctx=canvas.getContext("2d");
//画布的宽高在js里面也可以设置
canvas.width=600;
canvas.height=400;
// 设置线条颜色
ctx.strokeStyle="#FF0000"
//画圆
ctx.arc(250,200,50,0,2*Math.PI,true)
//绘制到页面
ctx.stroke();
</script>
</html>
画矩形
strokeRect()
参数1 参数2 表示的是矩形左上角那个点的坐标
参数3 参数4 表示的是矩形的宽高
和绘制圆相比 绘制矩形 并没有调用stroke方法 因为strokeRect方法已经将stroke方法封装到里面了
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
#myCanvas{
border: 1px solid red;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="" height=""></canvas>
</body>
<script type="text/javascript">
// 获取canvas元素
var canvas=document.getElementById("myCanvas");
// 设置绘制环境
var ctx=canvas.getContext("2d");
canvas.width=600;
canvas.height=400;
ctx.strokeRect(100,100,200,200);
</script>
</html>
闭合图形
closePath() 方法就是用来闭合路径的
填充和描边
填充
fill()
其实填充和描边是可以同时调用的
描边
stroke()
设置描边线条的宽度
lineWidth
其实填充和描边是可以同时调用的
调用画矩形的方法 其实和分开调用stroke和fill是一样的
ctx.strokeRect(100,200,200,100);
ctx.fillRect(100,200,200,100);
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
#myCanvas{
border: 1px solid red;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="" height=""></canvas>
</body>
<script type="text/javascript">
// 获取canvas元素
var canvas=document.getElementById("myCanvas");
// 设置绘制环境
var ctx=canvas.getContext("2d");
canvas.width=600;
canvas.height=400;
ctx.moveTo(10,0);
ctx.lineTo(100,100);
ctx.lineTo(100,200);
ctx.lineTo(0,0);
ctx.strokeStyle="red";
ctx.stroke();
// 上述方法不便于维护代码 一直需要找到起点
ctx.beginPath();
ctx.moveTo(100,0);
ctx.lineTo(200,100);
ctx.lineTo(200,200);
ctx.lineTo(500,300);
ctx.lineTo(100,0);
// closePath() 方法就是用来闭合路径的
ctx.closePath();
ctx.strokeStyle="#008000";
ctx.stroke();
// beginPath(); 清空所有路径
//closePath() 闭合路径
</script>
</html>
图形变换
平移
translate()
参数1 是沿x轴平移的距离
参数2 是沿沿轴平移的距离
其实是平移的原点 而不是直接地平移线条
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
#myCanvas{
border: 1px solid red;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="" height=""></canvas>
</body>
<script type="text/javascript">
// 获取canvas元素
var canvas=document.getElementById("myCanvas");
// 设置绘制环境
var ctx=canvas.getContext("2d");
canvas.width=600;
canvas.height=400;
//translate 平移 其实是平移的原点 而不是直接地平移线条
//放在这里 相当于所有的坐标都是在平移后的坐标系下找到的
// ctx.translate(0,100);
ctx.moveTo(0,0);
//把原点平移到(0,100)的情况下 那么初始的原点坐标不变 而(100,100)是在平移之后的坐标系里面找
// ctx.translate(0,100);
ctx.lineTo(100,100);
//这个和原始状态一样 因为进行平移原点之后 内存中所有的路径已经绘制完毕 不能产生影响了
//但是会影响新绘制的
ctx.translate(0,100);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(0,0);
ctx.lineTo(100,100);
ctx.stroke();
</script>
</html>
旋转
rotate()
但是不能使用传统旋转的角度(deg) 全部使用Π表示,这里的效果是可以叠加的
ctx.rotate(Math.PI/4);
缩放
scale()
两个参数分别表示宽度的缩放倍数 和 高度的缩放倍数
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
#myCanvas{
border: 1px solid red;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="" height=""></canvas>
</body>
<script type="text/javascript">
// 获取canvas元素
var canvas=document.getElementById("myCanvas");
// 设置绘制环境
var ctx=canvas.getContext("2d");
canvas.width=600;
canvas.height=400;
//translate 平移 其实是平移的原点 而不是直接地平移线条
//放在这里 相当于所有的坐标都是在平移后的坐标系下找到的
// ctx.translate(0,100);
ctx.moveTo(0,0);
//把原点平移到(0,100)的情况下 那么初始的原点坐标不变 而(100,100)是在平移之后的坐标系里面找
// ctx.translate(0,100);
ctx.lineTo(100,100);
//这个和原始状态一样 因为进行平移原点之后 内存中所有的路径已经绘制完毕 不能产生影响了
//但是会影响新绘制的 不会产生覆盖
ctx.translate(10,100);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(0,0);
ctx.lineTo(100,100);
ctx.stroke();
ctx.rotate(Math.PI/4);
/*
注意点:旋转还是rotate 但是不能使用传统旋转的角度(deg) 全部使用Π表示
这里的效果是可以叠加的
*/
ctx.beginPath();
ctx.moveTo(0,0);
ctx.lineTo(100,100);
ctx.lineWidth=10;
ctx.stroke();
ctx.scale(1.5,0.5);
// 这里的两个参数分别表示宽度的缩放倍数 和 高度的缩放倍数
ctx.fillRect(0,-100,100,100);
</script>
</html>
渐变
线性渐变
创建线性渐变的方法有个参数 前面两个表是线性渐变的起始点坐标 后面两个参数表示结束点坐标
ctx.createlinearGradient(50,50,150,150);
使用线性渐变 是要把线性渐变 设置给fillStyle
如果需要填充的元素不在渐变范围内 那么就是用离他最近的串色填充
如果我们需要修改填充的方向 只需要修改createLinearGradient的参数 修改坐标(线性渐变的方向其实就是两点连成的线段的方向)
addColorStop() 的作用就是该渐变设置颜色
参数1 百分比 指的是从百分之多少的点是什么颜色
参数2 颜色
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
#myCanvas{
border: 1px solid red;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="" height=""></canvas>
</body>
<script type="text/javascript">
// 获取canvas元素
var canvas=document.getElementById("myCanvas");
// 设置绘制环境
var ctx=canvas.getContext("2d");
ctx.canvas.width=600;
ctx.canvas.height=400;
var linearGradient=ctx.createLinearGradient(50,50,150,150);
// 表示的是0%的时候 是红色
linearGradient.addColorStop(0,"rgb(255,0,0)");
//表示的是100%的时候 是绿色
linearGradient.addColorStop(0.5,"rgb(0,255,0)");
ctx.fillStyle=linearGradient;
ctx.fillRect(0,0,200,200);
//上述的矩形正好将渐变的区域包含在内 所以有渐变的效果 那么如果渐变的坐标不在矩形区域内,用离他最近的串色填充
ctx.fillRect(300,200,200,200);
</script>
</html>
径向渐变
createRadialGradient()
前三个参数 表示开始渐变的圆的圆心坐标以及半径
后三个参数 表示结束渐变的圆的圆心坐标以及半径
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
#myCanvas{
border: 1px solid red;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="" height=""></canvas>
</body>
<script type="text/javascript">
// 获取canvas元素
var canvas=document.getElementById("myCanvas");
// 设置绘制环境
var ctx=canvas.getContext("2d");
ctx.canvas.width=600;
ctx.canvas.height=400;
//创建径向渐变
var radialGradient=ctx.createRadialGradient(400,150,50,400,150,100);
// 给径向渐变添加颜色
//添加颜色 addColorStop
radialGradient.addColorStop(0,"rgb(255,255,0)");
radialGradient.addColorStop(1,"rgb(0,0,0)");
ctx.arc(400,150,100,0,2*Math.PI,true);
ctx.fillStyle=radialGradient;
ctx.fill();
</script>
</html>
图片绘制drawImage()
drawImage的参数中 目标图片 在画布中放置图片的x和y轴坐标是必填的
参数1 目标图片
参数2 在画布上放置图片的x轴坐标
参数3 在画布上的放置图片的y轴的坐标
参数4 需要绘制的图片的宽度(放大或者缩小 实际显示出来的宽度)
参数5 需要绘制的图片的高度(放大或者缩小 实际显示出来的高度)
直接使用drawImage不能将图片绘制到页面上 因为图片加载需要时间 所以直接绘制 有可能 图片还没有加载所以无法绘制
调用img的onload方法 其实就是等到图片加载完毕之后 再开始绘制
图片剪切drawImage()
参数1 目标图片
参数2 是以图片为坐标系 左上角为原点 开始剪裁的x轴坐标
参数3 是以图片为坐标系 左上角为原点 开始剪裁的y轴坐标
参数4 被剪切下来的图片的宽度
参数5 被剪切下来的图片的高度
参数6 在画布上放置图片的x轴坐标
参数7 在画布上放置图片的轴坐标y
参数8 对于剪切的图片在画布上所占的宽度
参数9 对于剪切的图片在画布上所占的高度
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
#myCanvas{
border: 1px solid red;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="" height=""></canvas>
</body>
<script type="text/javascript">
var canvas=document.getElementById("myCanvas");
var ctx=canvas.getContext("2d");
ctx.canvas.width=600;
ctx.canvas.height=400;
var img=new Image();
img.src="./img/PJ%60YSTKI1$~(HN)WTK_K0GH.png";
//直接使用drawImage不能将图片绘制到页面上 因为图片加载需要时间 所以直接绘制 有可能 图片还没有加载
//所以无法绘制
// ctx.drawImage(img,0,0);
//调用img的onload方法 其实就是等到图片加载完毕之后 再开始绘制
img.onload=function(){
// ctx.drawImage(img,0,0);
// ctx.drawImage(img,0,0,100,100);
ctx.drawImage(img,0,0,84,52,100,100,100,104);
}
</script>
</html>
设置文字
textAlign 是设置文字水平对齐方式
left
left 就是文字的左边线和坐标值对齐
center
center 就是文字的中心线和坐标值对齐
right
right 就是文字的右边线和坐标值对齐
默认值left
设置textAlign值 就是将fillText里面设置的横坐标与文字对应的边线或者中心点对齐
textBaseline 设置文字的垂直对齐方式
top
top 文字上边线和纵坐标值对齐
middle
middle 文字的中心线和纵坐标值对齐
bottom
默认bottom
设置textFill里面的纵坐标 与文字对应的边线或者中心对齐
font 可以设置字体的一些样式
sans-serif 无衬线字体 相当于汉字中的黑体
ctx.font=“bold 50px sans-serif”;
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
#myCanvas{
border: 1px solid red;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="" height=""></canvas>
</body>
<script type="text/javascript">
var canvas=document.getElementById("myCanvas");
var ctx=canvas.getContext("2d");
ctx.canvas.width=600;
ctx.canvas.height=400;
// sans-serif 无衬线字体 相当于汉字中的黑体
ctx.font="bold 50px sans-serif";
//设置水平对齐
ctx.textAlign="center";
// 设置垂直对齐
ctx.textBaseline="middle";
//设置填充样式
ctx.fillStyle="yellow";
// fillText的两个参数
//参数1 需要显示的文字
//参数2 文字显示的坐标
ctx.fillText("啦啦啦",100,200);
ctx.fillText("hello,world",200,300);
//检测文字长度
var width=ctx.measureText("啦啦啦").width;
console.log(width);
</script>
</html>
阴影绘制
设置阴影在水平方向的偏移 shadowOffsetX
设置阴影在垂直方向的偏移 shadowOffsetY
设置阴影颜色 shadowColor
设置模糊度 shadowBlur
只要前面设置了阴影 那么对后面绘制的所有的内容都起作用
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
#myCanvas{
border: 1px solid red;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="" height=""></canvas>
</body>
<script type="text/javascript">
// 获取canvas元素
var canvas=document.getElementById("myCanvas");
// 设置绘制环境
var ctx=canvas.getContext("2d");
ctx.canvas.width=600;
ctx.canvas.height=400;
// 设置阴影在水平方向的偏移
ctx.shadowOffsetX=10;
// 设置阴影在垂直方向的偏移
ctx.shadowOffsetY=10;
// 设置阴影颜色
ctx.shadowColor="rgba(0,0,0,.5)";
// 设置模糊度
ctx.shadowBlur=2;
ctx.fillStyle="rgba(255,0,0,.3)";
// 只要前面设置了阴影 那么对后面绘制的所有的内容都起作用
ctx.fillRect(10,10,100,100);
ctx.arc(200,200,100,0,2*Math.PI,true);
ctx.fill();
ctx.font="60px sans-serif";
ctx.fillText("你好",400,100);
</script>
</html>
曲线绘制
1.用画圆的方法来绘制曲线
ctx.arc(150,150,100,0,Math.PI/2,false); ctx.stroke();
2.二次样条曲线 quadraticCurveTo
前两个参数 表示的是曲线顶上的那个点的坐标
后两个参数 表示的是曲线右端点的那个坐标
3.三次贝塞尔曲线 bezierCurveTo
前面四个参数 分别为曲线上的固定点坐标 最后两个是右端点坐标
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
#myCanvas{
border: 1px solid red;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="" height=""></canvas>
</body>
<script type="text/javascript">
// 获取canvas元素
var canvas=document.getElementById("myCanvas");
// 设置绘制环境
var ctx=canvas.getContext("2d");
ctx.canvas.width=600;
ctx.canvas.height=400;
ctx.arc(150,150,100,0,Math.PI/2,false);
ctx.stroke();
ctx.moveTo(50,350) //固定的是曲线的左端点坐标
// 二次样条曲线
//前两个参数 表示的是曲线顶上的那个点的坐标
//后两个参数 表示的是曲线右端点的那个坐标
ctx.quadraticCurveTo(230,250,350,350);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(200,350); //同样是起始点坐标
//前面四个参数 分别为曲线上的固定点坐标 最后两个是右端点坐标
ctx.bezierCurveTo(200,250,300,250,300,250);
// ctx.stroke();
ctx.fill();
</script>
</html>
保存和恢复绘制环境
save是用来保存当前的绘制环境
restore方法使用恢复前面的保存的绘制环境 也就是说在restore后面绘制的图形 使用的是
save保存的绘制环境
save和restore方法一般情况下 都是成对出现的,save和restore之间发生的各种转换 变化 对后面的绘制不会产生任何影响
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
#myCanvas{
border: 1px solid red;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="" height=""></canvas>
</body>
<script type="text/javascript">
// 获取canvas元素
var canvas=document.getElementById("myCanvas");
// 设置绘制环境
var ctx=canvas.getContext("2d");
canvas.width=600;
canvas.height=400;
ctx.strokeStyle="gold";
ctx.fillStyle="red";
/*
save和restore方法一般情况下 都是成对出现的
save是用来保存当前的绘制环境
*/
ctx.save();
ctx.moveTo(0,0);
ctx.lineTo(100,100);
ctx.translate(10,100);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(0,0);
ctx.lineTo(100,100);
ctx.stroke();
ctx.rotate(Math.PI/4);
ctx.beginPath();
ctx.moveTo(0,0);
ctx.lineTo(100,100);
ctx.lineWidth=10;
ctx.stroke();
ctx.scale(1.5,0.5);
ctx.fillRect(0,-100,100,100);
ctx.restore();
ctx.fillRect(200,0,100,100);
ctx.beginPath();
ctx.moveTo(200,200);
ctx.lineTo(300,300);
ctx.storke();
</script>
</html>
clearRect() 方法
clearRect() 方法清除指定的矩形的像素点。
参数1 要清除的矩形左上角的x轴坐标
参数2 要清除的矩形左上角y轴坐标
参数3 要清除的矩形的宽
参数4 要清除的矩形的高
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
#myCanvas{
border: 1px solid red;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="" height=""></canvas>
</body>
<script type="text/javascript">
// 获取canvas元素
var canvas=document.getElementById("myCanvas");
// 设置绘制环境
var ctx=canvas.getContext("2d");
ctx.fillRect(0,0,300,150);
// clearRect() 方法清除指定的矩形的像素点。
ctx.clearRect(20,20,100,100);
</script>
</html>
图像画刷
创建填充模式 createPattern()
参数1 目标元素
参数2 设置填充的模式 一共四个值 repeat no-repeat repeat-x repeat-y
getImageData() 修改图像数据
x 开始复制的左上角位置的x坐标
y 开始复制的左上角位置的y坐标
width 将要复制的矩形区域的宽度
height 将要复制的矩形区域的高度
对于 ImageData 对象中的每个像素 都存在四方面的信息,即 RGBA 值
R - 红色(0-255)
G - 绿色(0-255)
B - 蓝色(0-255)
A - alpha 通道 (0-255 0是透明 255是完全可见的)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
#myCanvas{
border: 1px solid red;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="" height=""></canvas>
</body>
<script type="text/javascript">
// 获取canvas元素
var canvas=document.getElementById("myCanvas");
// 设置绘制环境
var ctx=canvas.getContext("2d");
var img=new Image();
img.src="./img/PJ%60YSTKI1$~(HN)WTK_K0GH.png";
img.onload=function(){
// 创建填充模式
//参数1 目标元素
//参数2 设置填充的模式 一共四个值 repeat no-repeat repeat-x repeat-y
var pattern=ctx.createPattern(img,"repeat");
// fillStyle 纯色填充颜色 线性渐变 径向渐变 图像填充
ctx.fillStyle=pattern;
ctx.fillRect(0,0,canvas.width,canvas.height);
// ctx.fillStyle="red";
// ctx.fillRect(10,10,50,50);
// 修改图像数据
var imageData=ctx.getImageData(10,10,50,50);
console.log(imageData);
for(var i=0;i<imageData.data.length;i+=4){
imageData.data[i]=255-imageData.data[i];
imageData.data[i+1]=255-imageData.data[i+1];
imageData.data[i+2]=255-imageData.data[i+2];
}
ctx.putImageData(imageData,100,100);
}
</script>
</html>
区域剪辑
调用clip方法进行剪辑 其实就是clip后续多有的剪辑都在前面这个图像的基础上进行剪辑
可以使用save 和 restore来显示和隐藏多个图形的交集区域或者显示多个图像
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
#myCanvas{
border: 1px solid red;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="" height=""></canvas>
</body>
<script type="text/javascript">
// 获取canvas元素
var canvas=document.getElementById("myCanvas");
// 设置绘制环境
var ctx=canvas.getContext("2d");
ctx.canvas.width=600;
ctx.canvas.height=400;
ctx.save();
ctx.arc(200,150,100,0,2*Math.PI,true);
ctx.fillStyle="#00f";
ctx.fill();
// 调用clip方法进行剪辑 其实就是clip后续多有的剪辑都在前面这个圆的基础上进行剪辑
ctx.clip();
ctx.fillStyle="#f00";
ctx.fillRect(200,150,200,200);
//如果不显示交集部分 想让这个圆完整显示 那么就可以使用save 和 restore
ctx.restore();
ctx.beginPath();
ctx.arc(300,200,100,0,2*Math.PI,true);
ctx.fillStyle="yellow";
ctx.fill();
</script>
</html>
canvas中的动画
用定时器来配合完成动画效果
Canvas动画原理
快速切换的静态画面。
基本步骤
绘制 - 清空 - 绘制 - 清空 - 绘制 …
控制函数
setTimeout
setInterval
requestAnimationFrame
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
#myCanvas{
border: 1px solid red;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="" height=""></canvas>
</body>
<script type="text/javascript">
// 获取canvas元素
var canvas=document.getElementById("myCanvas");
// 设置绘制环境
var ctx=canvas.getContext("2d");
ctx.canvas.width=600;
ctx.canvas.height=400;
// 写一个动画 让一个小矩形 向右移动
ctx.fillRect(10,10,50,50);
// 声明一个变量 来保存矩形坐标位置
var posX=0,posY=0,isTrue=1;
// 新需求 矩形到达边界之后 就会反弹回来 来回的运动
// 声明一个变量来保存鼠标是否在小矩形上面的状态
var isMouseInRect=false;
// 给canvas注册鼠标移动事件
canvas.onmousemove=function(e){
e=e||window.event;
if(e.offsetX>posX&&e.offsetX<posX+50&&e.offsetY>posY&&e.offsetY<posY+50){
isMouseInRect=true;
}else{
isMouseInRect=false;
}
}
var timer=setInterval(function(){
if(!isMouseInRect){
posX+=10*isTrue;
}
// clearRect() 方法清空给定矩形内的指定像素。
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.fillRect(posX,posY,50,50);
// 到达边界的时候 清除定时器
if(posX>=canvas.width-50){
isTrue=-1;
}else if(posX<=0){
isTrue=1;
}
},100)
</script>
</html>
canvas离屏
1.创建一个新的离屏canvas;
2.把一些复杂额绘画操作(背景),画在离屏canvas上;
3.将离屏canvas通过drawImage(离屏canvas对象,x1,y1,offcanvas.width,offcanvas.height,x2,y2,canvas.width,canvas.height)
拷贝到原始的canvas上,减少不断绘制复杂操作,提高性能-----最后使用css:display:none将离屏canvas隐藏;
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
#myCanvas{
border: 1px solid red;
}
#offCanvas{
display: none;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="" height=""></canvas>
<canvas id="offCanvas" width="" height=""></canvas>
</body>
<script type="text/javascript">
// 获取canvas元素
var canvas=document.getElementById("myCanvas");
// 设置绘制环境
var ctx=canvas.getContext("2d");
ctx.canvas.width=600;
ctx.canvas.height=400;
var offCanvas=document.getElementById("offCanvas");
// 设置绘制环境
var offctx=offCanvas.getContext("2d");
offCanvas.width=600;
offCanvas.height=400;
var posX=0,posY=0,isTrue=1;
var isMouseInRect=false;
function drawBg(){
for(var k=0;k<10;k++){
for(var i=0;i<canvas.width;i+=10){
for(var j=0;j<canvas.height;j+=10){
offctx.beginPath();
offctx.arc(i,j,5,0,2*Math.PI,true);
offctx.stroke();
}
}
}
}
canvas.onmousemove=function(e){
e=e||window.event;
if(e.offsetX>posX&&e.offsetX<posX+50&&e.offsetY>posY&&e.offsetY<posY+50){
isMouseInRect=true;
}else{
isMouseInRect=false;
}
}
var timer=setInterval(function(){
if(!isMouseInRect){
posX+=10*isTrue;
}
// clearRect() 方法清空给定矩形内的指定像素。(清空画布区域)
ctx.clearRect(0,0,canvas.width,canvas.height);
//为了防止背景绘制的东西一直存在 所以每次清屏过后 都要重新绘制背景
// drawBg();
//使用drawImage(canvas对象)拷贝到原始canvas上
ctx.drawImage(offCanvas,0,0,offCanvas.width,offCanvas.height,0,0,canvas.width,canvas.height);
ctx.fillRect(posX,posY,50,50);
// 到达边界的时候 清除定时器
if(posX>=canvas.width-50){
isTrue=-1;
}else if(posX<=0){
isTrue=1;
}
},100);
drawBg();
ctx.drawImage(offCanvas,0,0,offCanvas.width,offCanvas.height,0,0,canvas.width,canvas.height);
</script>
</html>