canvas想必对于前端的工程师都不陌生了,它是 HTML5 新增的「画布」元素,是HTML5 的一大亮点,canvas翻译过来其实就是画布的意思,它可以替代flash,制作网页的很多动画效果以及游戏。渲染效率非常高,不像flash要在游览器安装flash adobe插件,canvas不需要安装任何插件即可渲染这个动画。这时候广大吃瓜群众肯定就会问,他的兼容性咋样呀,它的兼容性所有主流游览器都支持。大家可以放心使用,做出好效果叫你老板给你加鸡腿。。先做会梦在来写代码。
介绍了这么多那怎么使用呢?Canvas其实只是一个画布,如果想要实现绘画功能只能通过javascript去调用api来绘画。打个比方,大家小时候都学过美术吧,首先是不是要有一个白纸或者白板,然后需要笔对吧,那个白板就相当于是canvas,看下下面的例子,下面这个就相当于绘画工具箱,笔或者颜料等绘画工具。ctx其实就是得到了画布的上下文对象,那么以后我们都是通过ctx来操作绘图的。
在游览器打开的效果:
如果想让画布满屏怎么办?有小伙伴肯定说,设置css呀,答案是no,你在css里面设置它里面的元素会变形的,强调设置canvas的宽高不要在css里面设置,可以在canvas行内样式写,也可以在js里面写。我们来写个满屏的背景颜色为黑色的画布。
在我们绘制图形之前,必须要搞清楚canvas的坐标系统,这样才能知道我们具体要在哪里绘制图形。
canvas的2D环境绘图坐标系统,原点(0,0)位于canvas元素的左上角顶点处,沿x轴向右为正值,沿y轴向下为正值,与我们数学中的直角坐标系是不同的
首先我们来画个圆,arc() 方法创建弧/曲线(用于创建圆或部分圆)。
context.arc(x,y,r,sAngle,eAngle,counterclockwise);
第1,2个参数坐标就是圆心的位置,第3个数学不差的都知道是半径哈,第4,5个就是开始角和结束角,第6个就是选是顺时针还是逆时针,False = 顺时针,true = 逆时针。例子,
arc(100,75,50,0*Math.PI,1.5*Math.PI)
如果就是下面一句话没有任何效果,你只是给他瞄了一个路径而已,这时候我们要给它描边和填充。他们默认的颜色都是黑色,我们可以通过调用api改变颜色
fill(): 填充当前绘图
stroke(): 绘制已定义的路径
fillStyle: 改变填充颜色
strokeStyle:改变描边颜色
现在我们来画一个橘色的圆
实现的效果:
下面我们来做一个网页中常见的一个效果,就是从无到与有动态生成一个圆,这个该怎么实现呢?
假设有个开始角度startAngle,一个结束角度endAngle,他们的关系是不是他们加起来是2π
var startAngle = -(1 / 2 * Math.PI); //开始角度
var endAngle = startAngle + 2 * Math.PI; //结束角度
现在角度有了,那怎么让它动起来呢?我们给它定义一个临时变量来存储tmpAngle,最开始应该是startAngle 对吧,然后呢一点一点给它加角度,那我们给它一个增量
var xAngle = 1 * (Math.PI / 180); //偏移角度量
var tmpAngle = startAngle; //临时角度变量
现在开始角度,结束角度,偏移量有了,那接下来是不是应该整个定时器让他跑起来,这里我们介绍下最新的定时器 requestAnimationFrame,官方定义 requestAnimationFrame方法告诉浏览器您希望执行动画并请求浏览器在下一次重绘之前调用指定的函数来更新动画。该方法使用一个回调函数作为参数,这个回调函数会在浏览器重绘之前调用。有兴趣的可以下去研究下
现在来分析下重要的渲染函数,其实很简单是不是相当于每次画一个圆弧,临时角度作为结束角度,每次给临时角度加上偏移角度量就可以了,那结束条件是不是就是当tmpAngle>endSngle就结束了
if(tmpAngle >= endAngle){
return;
}else{
tmpAngle += xAngle;
}
现在干正事画圆圈,现在就so easy了
ctx.arc(r, r, cR, startAngle, tmpAngle);
接下来写中间的文字,我们要用到context.fillText(text,x,y,maxWidth);绘制填色的,主要是第一个文本值应该怎么写呢
(tmpAngle - startAngle) / (endAngle - startAngle) * 100
但是有小数点,我们给它取个整数,这样是不是就可以了
Math.round((tmpAngle - startAngle) / (endAngle - startAngle) * 100) + '%'
现在就一个简单的圆环效果就出来了,我把全部代码都贴在后面
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
*{
margin:0px;
padding:0px;
}
</style>
</head>
<body>
<canvas id="canvas" style="background: black;"></canvas>
</body>
<script type="text/javascript">
var c=document.getElementById('canvas');
//得到画布的上下文
var ctx=canvas.getContext('2d')
//给画布的宽度设置为预览器的宽高
canvas.width=document.documentElement.clientWidth;
canvas.height=document.documentElement.clientHeight;
// var mW = c.width = 300;
//var mH = c.height = 300;
var lineWidth = 5;
var r = canvas.width/5; //中间位置
var cR = r - 4 * lineWidth; //圆半径
var startAngle = -(1 / 2 * Math.PI); //开始角度
var endAngle = startAngle + 2 * Math.PI; //结束角度
var xAngle = 1 * (Math.PI / 180); //偏移角度量
var fontSize = 35; //字号大小
var tmpAngle = startAngle; //临时角度变量
//渲染函数
var rander = function(){
if(tmpAngle >= endAngle){
return;
}else{
tmpAngle += xAngle;
}
ctx.clearRect(0, 0, canvas.width, canvas.height);
//画圈
ctx.beginPath();
ctx.lineWidth = lineWidth;
ctx.strokeStyle = 'deeppink';
ctx.arc(r, r, cR, startAngle, tmpAngle);
ctx.stroke();
ctx.closePath();
//写字
ctx.fillStyle = 'deeppink';
ctx.font= fontSize + 'px Microsoft Yahei';
ctx.textAlign='center';
ctx.fillText( Math.round((tmpAngle - startAngle) / (endAngle - startAngle) * 100) + '%', r, r + fontSize / 2);
requestAnimationFrame(rander);
};
rander();
</script>
</body>
</html>
接下来我们在来看一个实例
实现一个画板的效果
可以在里面随意的写字画图,实现原理,我们要结合javascript里面的鼠标事件,当鼠标按下的时候就获取鼠标的位置设置起点,当鼠标移动的时候也获取当前的坐标,这是不是就用到javascipt的移动事件(注意移动事件是在鼠标按下事件里面的,你按下才有移动事件),并跟前一个坐标点使用lineTo连接起来,然后连接起来就可以了,非常简单。做完这一步肯定还有一个鼠标抬起事件,鼠标抬起来要清除鼠标移动事件。
canvas.onmousedown=function(ev){
// 兼容ie和火狐
var event=ev||window.event
//获得鼠标的位置
var mousex=ev.layerX||ev.offsetX;
var mousey=ev.layerY||ev.offsetY;
// 设置起点
ctv.moveTo(mousex,mousey);
canvas.onmousemove=function(ev){
//获得鼠标的位置
var movex=ev.layerX||ev.offsetX;
var movey=ev.layerY||ev.offsetY;
// 与前面的点连接起来
ctv.lineTo(movex,movey);
// 绘制
ctv.stroke()
}
}
// 鼠标抬起取消移动事件
canvas.onmouseup=function(){
canvas.onmousemove=null;
}
我们现在这个还做的不完整,在给它弄个改变颜色改变线条粗细,以及擦除功能,我们直接用html5的标签,在配合onchanges事件来获取值,给线条的画笔赋值即可
这是改变颜色,但是有个问题,就是前面画的线条颜色也会改变,这就需要我们加开始路径和结束路径,结束路径要在鼠标抬起事件里面加
document.getElementById('color').onchange=function(){
console.log(this.value)
ctv.strokeStyle=this.value;
}
我用刚才做出来的画了一幅非常美丽的画,现在我们来改下线条的粗细,可以用到html5新增的表单属性range,其实给改变颜色是一样的写法,只是属性不一样
<label for="range" style="margin-left:10px">粗细</label>
<input type="range" value="1" max="30" min="1" id="range"/>
<span id="rangeNum">1</span>
document.getElementById("range").onchange=function(){
// 把span里面的值改了
document.getElementById('rangeNum').innerHTML=this.value;
ctv.lineWidth=this.value
}
我突然绘画的灵感来了又给大家画了一幅,很有意境,慢慢体会
就只剩下一个橡皮擦功能没完成了,这个更简单,直接就是点击橡皮擦的时候,把画笔的颜色改为背景的颜色就可以了。
document.getElementById('btn').onclick=function(){
ctv.strokeStyle="#3F6D50";
}
我把整体的代码贴出来给大家:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>画板效果</title>
<style type="text/css">
*{
margin: 0px;
padding: 0px;
}
body{
overflow: hidden;
}
canvas{
background-image: url(50.jpg);
background-size: cover;
}
</style>
</head>
<body>
<div style="text-align: center;">
<label for="color">颜色</label>
<input type="color" id="color"/>
<label for="range" style="margin-left:10px">粗细</label>
<input type="range" value="1" max="30" min="1" id="range"/>
<span id="rangeNum">1</span>
<button type="button" id="btn">橡皮擦</button>
<canvas id="canvas" width="" height="">
</div>
</canvas>
<script type="text/javascript">
var canvas=document.getElementById('canvas');
var ctv=canvas.getContext('2d');
canvas.width=document.documentElement.clientWidth;
canvas.height=document.documentElement.clientHeight;
// 鼠标按下时
canvas.onmousedown=function(ev){
// 兼容ie和火狐
var event=ev||window.event
//获得鼠标的位置
var mousex=ev.layerX||ev.offsetX;
var mousey=ev.layerY||ev.offsetY;
ctv.beginPath();
// 设置起点
ctv.moveTo(mousex,mousey);
canvas.onmousemove=function(ev){
//获得鼠标的位置
var movex=ev.layerX||ev.offsetX;
var movey=ev.layerY||ev.offsetY;
// 与前面的点连接起来
ctv.lineTo(movex,movey);
// 绘制
ctv.stroke()
}
}
// 鼠标抬起取消移动事件
canvas.onmouseup=function(){
canvas.onmousemove=null;
ctv.closePath()
}
document.getElementById('color').onchange=function(){
ctv.strokeStyle=this.value;
}
document.getElementById("range").onchange=function(){
// 把span里面的值改了
document.getElementById('rangeNum').innerHTML=this.value;
ctv.lineWidth=this.value
}
document.getElementById('btn').onclick=function(){
ctv.strokeStyle="#3F6D50";
}
</script>
</body>
</html>
最后用刚做的画图画了一幅画,送给大家一幅画,给大家乐乐,咋写字这么丑呢。
HTML5热点新闻
前端开发技术库