Canvas笔记
一.canvas概述
Falsh:长久以来,web上的动画大都是由Flash实现的,Flash缺点也很明显,漏洞多,重量大,卡顿与不流畅,需要安装Adobe Flash Player
Canvas:HTML5提出的新标签,颠覆了Flash的主导地位,是一个轻量级的画布,我们使用Canvas进行JavaScript的编程,不需要额外插件,性能好不卡顿,在手机中也很流畅
1.canvas的标签属性只有width与height,表示宽高,尽量不要用css样式来设置,因为这样画布会失真变形
2.canvas标签内的文本用于低版本浏览器的提示信息(IE6/7/8)
高版本浏览器是看不到标签内的文本
3.初次使用
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<canvas width="200px" height="200px" id="myCanvas">
当前浏览器版本不支持,请升级版本
</canvas>
<script>
//1.获取canvas元素
var myCanvas=document.getElementById("myCanvas");
console.log(myCanvas)
//2.获取canvas元素的上下文,分为2d的上下文与3d的上下文
// 所有的图像绘制都是使用ctx中所包含的属性/方法进行设置的,此时和canvas标签已无关
var ctx=myCanvas.getContext("2d");
//设置颜色-fillStyle
ctx.fillStyle='deepskyblue';
//绘制矩形-fillRect(x轴坐标,y轴坐标,w宽度,h高度)
ctx.fillRect(100,100,200,50);
console.log(ctx);
</script>
</body>
</html>
二.Canvas的编程思想
1.canvas的像素化
-使用canvas进行绘制,一旦绘制成功,canvas就像素化了他们,也就是说才女爱上不能在获取到该图形进行修改,这就是canvas轻量的原因。Flash重的原因之一是flash可以通过对应的api得到该图形的内容来进行再次绘制
-想要这个canvas图形进行移动,必须按照清屏-更新-渲染的动画思想
-动画其实就是连续播放的香相关静态画面,我们把每一次绘制的静态画面叫做“二帧”,定时器的间隔叫做帧的间隔
<body>
<canvas id="myCanvas" width="300" height="300">本文本仅作为低版本浏览器的提示语</canvas>
<script>
var canvas=document.getElementById("myCanvas");
var ctx=canvas.getContext("2d");//获取canvas的上下文
ctx.fillStyle="chocolate"; //设置颜色
ctx.fillRect(left,200,300,300); //绘制矩形
var left=100; //定义水平移动的初始信号量
setInterval(function(){
ctx.clearRect(0,0,700,700);//1.清除画布-clearRect(x,,y轴,清除的width,清除的height)
left++; //2.更新信号量
ctx.fillRect(left,200,300,300);//3.重新渲染绘制
},10)
</script>
</body>
2.,面向对象的canvas动画实现
<body>
<canvas id="mycanvas" width="300" height="300"></canvas>
<script>
var canvas=document.getElementById("mycanvas");
var ctx=canvas.getContext("2d");
function Rect(x,y,w,h,color){
this.x=x;
this.y=y;
this.w=w;
this.h=h;
this.color=color;
}
Rect.prototype.update=function(){
this.x++;
}
Rect.prototype.render=function(){
ctx.fillStyle=this.color;
ctx.fillRect(this.x,this.y,this.w,this.h);
}
//获取实例
var r1=new Rect(100,100,400,400,"blue");
setInterval(function(){
//1.清屏 2.更新 3.再次渲染
ctx.clearRect(0,0,canvas.width,canvas.height)
r1.update();
r1.render();
},10)
</script>
</body>
三.Canvas的基本功能
3.1填充矩形
//设置颜色
ctx.fillStyle='green';
//填充矩形
ctx.fillRect(100,100,100,100)
参数含义:填充坐标x,填充坐标y,矩形的宽度,矩形的高度
3.2绘制矩形边框
ctx.strokeStyle='red';
//绘制矩形
ctx.strokeRect(100,100,100,100)
参数含义:填充坐标x,填充坐标y,矩形的宽度,矩形的高度
3.3清除矩形
ctx.clearRect(0,0,400,400)
参数含义:清除坐标x,清除坐标y,清除的宽度,清除的高度
**
3.4 绘制路径
**
绘制路径是为了设置一个不规则的多边形状态,路径都是闭合的,步骤:
①. 设置路径的起点
②. 使用绘制路径画出起点
③. 封闭路径
④. 填充/绘制已封闭的路径
--在使用fill()进行填充路径的内容区域时,
可以不关闭路,这时会出现自封闭现象(只针对fill)
<body>
<canvas id="c1" width="300" height="250" style="border:2px black solid;"></canvas>
<script>
var canvas=document.getElementById("c1");
var ctx=canvas.getContext("2d");
ctx.beginPath();//1.创建路径
ctx.moveTo(100,100);//2.设置绘制起点
ctx.lineTo(150,50); //描述路径
ctx.lineTo(200,100);
ctx.lineTo(175,150);
ctx.lineTo(125,150);
ctx.closePath();//3.关闭路径
//4.绘制不规则矩形边框并设置颜色
ctx.strokeStyle='black';
ctx.stroke();
//5.填充不规则图形
ctx.fillStyle='coral';
ctx.fill();
</script>
</body>
3.5 绘制圆弧
<body>
<canvas width="400px" height="400px" id="myCanvas" style="border: 2px black solid;"></canvas>
<script>
var myCanvas=document.getElementById("myCanvas");
var ctx=myCanvas.getContext("2d");
ctx.beginPath();
/*true是逆时针,false是顺时针,Math.PI约等于3.14,
一个整圆的的弧度为2*Math.PI,约等于7个弧度
如果2个参数的差为7,并且是顺时针方向,则表示绘制一个圆 */
ctx.arc(200,200,100,0,2*Math.PI,false);
ctx.stroke();
ctx.fillStyle="lightcoral";
ctx.fill();
</script>
</body>
3.5 透明度
//值在0~1之间
ctx.globalAlpha=0.5;
3.6 线型
1.利用lineWidth设置线的粗细,属性值必须是数字,没有单位,默认值为1.0
ctx.lineWidth=20
2.lineCap决定了每一条线段末端的属性,默认为butt,
三个属性分别为butt,squre,round
ctx.lineCap="round";
3.lineJoin决定了图形中两条线段连接时所显示的样子,
可选值为:round,bevel,miter
ctx.lineJoin="miter";
4.setLineDash来设置虚线的样式,参数为数组形式
([虚线长度,虚线间隔,虚线长度,虚线间隔,...])交替状态
ctx.setLineDash([10,20,30,40,50])
5.lineDashOffset设置虚线的起始偏移量
ctx.lineDashOffset=10;
3.7 绘制文字
ctx.font="20px 微软雅黑";
ctx.textalign="start";//可选值start(默认),end,left,right,center
ctx.fillText("Canvas绘制文字",100,100);
3.8 线性渐变与径向渐变
线性渐变:
//四个参数表示起点坐标与终点坐标
var linear=ctx.createLinearGradient(0,0,200,200);
linear.addColorStop(0.2,"red");
linear.addColorStop(0.5,"yellow");
linear.addColorStop(0.7,"blue");
linear.addColorStop(1,"orange");
ctx.fillStyle=linear;
ctx.fillRect(50,50,200,200);
径向渐变:
var radial=ctx.createRadialGradient(100,80,30,110,80,60);
radial.addColorStop(0,"red");
radial.addColorStop(0.5,"yellow");
radial.addColorStop(1,"orange");
ctx.fillStyle=radial;
ctx.fillRect(0,0,200,200);
3.9 阴影
<body>
<canvas id="canvas" width="350" height="100" style="border: 2px black solid;"></canvas>
<script>
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
ctx.shadowOffsetX=10; //阴影水平方向的偏移量,默认为0
ctx.shadowOffsetY=20; //阴影垂直方向的偏移量,默认为0
ctx.shadowBlur=1; //描述模糊效果,默认为0,数值越大越模糊
ctx.shadowColor="red"; //阴影的颜色
ctx.font="20px 微软雅黑";
ctx.fillText("迪迦奥特曼登陆bilibili",50,50);
</script>
</body>
3.10 使用图片
<canvas id="canvas" width="350" height="200" style="border: 2px black solid;"></canvas>
<script>
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var img=new Image(); //创建Image对象的实例
img.src="images/qinshi.jpg"; //引入图片路径
img.onload=function(){//必须在onload之后渲染图片,
//四个数值参数为图片的位置与图片的宽高
ctx.drawImage(img,50,50,200,100);
}
</script>
-如果有8个参数,则前4个参数表示图片中切片的位置以及宽高
后4个表示切片在画布中的位置及宽高
<canvas id="canvas" width="300" height="400" style="border: 2px black solid;"></canvas>
<script>
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var img=new Image(); //创建Image对象的实例
img.src="images/qinshi.jpg"; //引入图片路径
img.onload=function(){//必须在onload之后渲染图片,
//四个数值参数为图片的位置与图片的宽高
// ctx.drawImage(img,50,50,200,100);
ctx.drawImage(img,0,0,170,304,50,50,170,304);
}
</script>
四.资源管理
4.1获取对象中属性的长度
function dongman(){
this.dom=document.getElementById("canvas");
this.ctx=this.dom.getContext("2d");
this.images={
"佛之战国":"./images/1.png",
"秦时明月":"./images/2.png",
"海贼王":"./images/3.png",
"鬼谷纵横":"./images/4.png",
"七武海":"./images/5.png"
}
var imgAmount=Object.keys(this.images).length;
console.log(imgAmount);
}
4.2图片加载
<canvas id="canvas" width="600" height="400"></canvas>
<script type="text/javascript">
function dongman(){
this.dom=document.getElementById("canvas");
this.ctx=this.dom.getContext("2d");
this.images={
"佛之战国":"./images/1.png",
"秦时明月":"./images/2.png",
"海贼王":"./images/3.png",
"鬼谷纵横":"./images/4.png",
"七武海":"./images/5.png"
}
var imgAmount=Object.keys(this.images).length;
console.log(imgAmount);
var count=1;
for(k in this.images){
var src=this.images[k];
this.images[k]=new Image();
this.images[k].src=src;
var self=this;
this.images[k].onload=function(){
count++;
self.ctx.clearRect(0,0,600,400);
self.ctx.font="18px 微软雅黑";
self.ctx.fillText("图片加载进度:"+count+" / "+imgAmount,80,80);
if(count==imgAmount){
self.start();
}
}
}
}
dongman.prototype.start=function(){
this.ctx.drawImage(this.images["佛之战国"],100,100,300,140);
}
</script>
五.变形
-变形的不是元素,而是画布的渲染区域ctx
-我们需要在画布变形前进行保存与恢复-save()和restore()
都没有参数,就是保存与恢复所有样式与变形的一个快照
<canvas id="canvas" width="600" height="400"></canvas>
<script type="text/javascript">
function translate(){
var dom=document.getElementById("canvas");
var ctx=this.dom.getContext("2d");
ctx.fillStyle="blue";
ctx.fillRect(50,50,300,300);
ctx.save(); //保存默认状态
ctx.fillStyle="green";
ctx.fillRect(60,60,290,290);
ctx.save(); //保存当前状态
ctx.fillStyle="red";
ctx.globalAlpha=0.5;
ctx.fillRect(70,70,280,280);
ctx.restore();
</script>