一、canvas的简介
<canvas> 是 HTML5 新增的元素,可用于通过使用JavaScript中的脚本来绘制图形。例如,它可以用于绘制图形,制作照片,创建动画,甚至可以进行实时视频处理或渲染。请注意 canvas 是行内样式。
总结起来 canvas 的功能就是:
- 使用路径功能来画图
- 渲染图片,和面向对象一起制作小游戏
- 视频渲染,制作开场视频动画,尤其是游戏的开场
看到这里你该猜到了,没错,canvas 就是用来制作 H5 小游戏的。
二、canvas 常见 API
注意:canvas画布设置宽度和高度【不允许使用内部样式、外部样式】,只能通过属性width、height进行设置。
- 文字
// 文字的font-style,font-weight;font-size;font-family
ctx.font = "italic bold 16px Arial";
// 文字的颜色
ctx.fillStyle = "red";
// 绘画开始
// 实心文字,文字的x,ys
ctx.fillText("我是实心文字",100,100);
//空心文字的颜色
ctx.strokeStyle = "blue";
// 空心文字,文字的x,y
ctx.strokeText("我是空心文字",100,200);
- 矩形
// 实心矩形的x,y,w,h
ctx.fillRect(100,100,100,100);
// 空心矩形
ctx.strokeRect(200,200,50,50);
- 直线
<body>
<canvas width="300" height="300"></canvas>
</body>
</html>
<script>
//得到canvas标签
var myCanvas = document.querySelector("canvas");
//得到canvas标签的上下文
var ctx = myCanvas.getContext("2d");
// 绘画开始
ctx.beginPath();
// 线的起点
ctx.moveTo(100,100);
// 线的粗细
ctx.lineWidth = 20;
// 线的终点
ctx.lineTo(200,200);
// 线的颜色
ctx.strokeStyle = "red";
// stroke 划线
ctx.stroke();
// 封闭路径
ctx.colsePath();
</script>
- 圆
ctx.arc(100,100,80,2*Math.PI,false);
// 设置填充色
ctx.strokeStyle = "red";
// 空心圆
ctx.stroke();
// 圆的x,y,r,弧度制的回执角度,逆时针
ctx.arc(100,100,80,2*Math.PI,false);
// 设置填充色
ctx.fillStyle = "red";
// 设置透明
ctx.globalAlpha = 0.3;
// 实心圆
ctx.fill();
- 坐标体系
canvas 的坐标体系默认情况下是左上角为(0,0)
。
更改坐标体系:
ctx.translate(100,100)//由零零点移动到 x 等于一百, y 等于一百
- 旋转特效
// 旋转信号量
var idx = 0;
setInterval(function(){
idx+=0.8;
// 旋转特效
// 清屏
ctx.clearRect(0,0,300,300);
// 保存坐标系的原点坐标
ctx.save();
// 转移坐标系
ctx.translate(100,100);
// 旋转1 弧度
ctx.rotate(idx);
// 透明度
ctx.globalAlpha = 0.5
//
ctx.fillStyle = "blue";
// 画一个圆
ctx.fillRect(-50,-50,100,100);
// 恢复原点坐标
ctx.restore();
},200);
- 元素可以绑定多个同类型事件【后者覆盖前者】
- 如果想给某一个元素的事件移除:后者覆盖前者,把后者置空即可。
三、canvas实现炫彩小球
<body>
<canvas width="800" height="500"></canvas>
</body>
</html>
<script>
//得到canvas标签
var myCanvas = document.querySelector("canvas");
//得到canvas标签的上下文
var ctx = myCanvas.getContext("2d");
// 创建一个数组来存放数组
var arr = [];
// 鼠标移动获取设置小球的x,y
myCanvas.onmousemove = function(event){
var x = event.offsetX;
var y = event.offsetY;
var r = parseInt(Math.random() * 10) + 15;
// new 出一个实例
new Ball(x,y,r);
}
// 构造函数的声明
function Ball(x,y,r){
this.x = x;
this.y = y;
this.r = r;
// 小球x,y 的改变量
this.idx = parseInt(Math.random() * 5) - 2;
this.idy = parseInt(Math.random() * 5) - 2;
// 渲染小球
this.render();
// 把这个实例放在数组里面
arr.push(this);
}
Ball.prototype.render = function(){
// 绘制小球
ctx.beginPath();
ctx.arc(this.x,this.y,this.r,2*Math.PI,false);
ctx.fillStyle = "rgb("+ parseInt(Math.random() * 256) +"," + parseInt(Math.random() * 256)+ ","+ parseInt(Math.random() * 256)+")";
ctx.fill();
ctx.closePath();
}
// 更新小球
Ball.prototype.update = function(){
this.x-=this.idx;
this.y-=this.idy;
this.r--;
if(this.r <= 0){
// 小球半径小于零的时候,移除这个小球
this.die();
}
this.render();
}
Ball.prototype.die = function(){
// 数组删除这个小球
arr.splice(arr.indexOf(this),1);
}
// 定时器定时渲染小球
setInterval(()=>{
ctx.clearRect(0,0,800,600);
ctx.font = "bold 30px Arail";
ctx.fillStyle = "#ffeb3b";
ctx.fillText("炫彩小球实例!",0,50);
for(let i = 0;i < arr.length;i++){
arr[i].update();
}
},50);
四、图片裁剪
//得到canvas标签
var myCanvas = document.querySelector("canvas");
//得到canvas标签的上下文
var ctx = myCanvas.getContext("2d");
//系统内置构造Image:创建广义对象img
var img = new Image();
// 给对象添加地址
img.src = "6.jpg";
//如果想在画布当中显示图片:图片需要加载完毕才可以在画布当中进行显示
//onload:DOM0级事件:当元素加载完毕的时候,会立即执行一次
img.onload = function(){
// 当ctx.drawImage有五个参数,表示此图片距离边框的x,y和图片的width,height
ctx.drawImage(img,0,0,300,341);
// 当ctx.drawImage有九个参数,前四个数字表示此图片某部分距离此图片左上角原点的x,y和只显示图片某部分大小的width,height
// 后四个数字表示内容和五个参数的相同
ctx.drawImage(img,290,100,300,341,400,200,110,130);
}
五、视频的加载
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Canvas</title>
<style>
canvas{
border:1px solid #333;
position: relative;
left:50%;
top:50%;
margin-left: -400px;
}
/*视频一共有两个canvas上一个,网页一个所以让网页的视屏消失,让其宽高为零*/
video{
width: 0;
height: 0;
}
</style>
</head>
<body>
<canvas width="800" height="500"></canvas>
<video src="./bboom bboom -momoland.mp4" autoplay></video>
</body>
</html>
<script>
//得到canvas标签
var myCanvas = document.querySelector("canvas");
//得到canvas标签的上下文
var ctx = myCanvas.getContext("2d");
// 得到video标签
var video = document.querySelector("video");
// 视频渲染必须放在定时器里面
setInterval(()=>{
ctx.drawImage(video,0,0,800,460);
// 播放完成之后自动清屏
if(video.ended){
ctx.clearRect(0,0,800,500);
}
},100);
</script>
六、图片资源管理器
因为 canvas 要求所有的图片必须完成加载完成,才能在 Canvas 中进行渲染,所以如果demo 里面有很多图片的话,我们就得像个办法来解决这个问题,这个技术就叫图片资源管理器。其中图片的JSON可以单独创建一个文件引包进去,这样就不用写在同一个界面里面了。以下是实现的源代码。
//得到canvas标签
var myCanvas = document.querySelector("canvas");
//得到canvas标签的上下文
var ctx = myCanvas.getContext("2d");
// 图片的JSON,value是图片的真是名字,一共五张
var picJSON = {
"si_1" : "si_1.png",
"si_2" : "si_2.png",
"si_3" : "si_3.png",
"si_4" : "si_4.png",
"si_5" : "si_5.png"
}
// 加法器,计算图片加载的张数
var count = 0;
for(let k in picJSON){
// 备份图片的地址
var src = picJSON[k];
// 图片的值变为对象
picJSON[k] = new Image();
// 往图片对象上添加图片物理路径
picJSON[k].src = "./image/" + src;
}
// 再次拿到改变后的图片JSON
for(let k in picJSON){
// 所有的图片加载完成才能,使用canvas的drawImage
picJSON[k].onload = function(){
// 加载完一张计数器就加一
count++;
// 计数器的数量等于JSON里面对象的数量,表示所有的图片都加载完成
if(count == Object.keys(picJSON).length){
// 输出结果
console.log("图片加载完成!一共有"+count+"张图");
}
}
}
canvas的基本概念和常用API已经了解了,接下来我们就用它来做一些简单的 H5 小游戏。
敬请期待。。。