HTML5-Canvas元素
1、Canvas(画布)的概述
- Canvas通过Javascript在网页上来绘制2D图形。Canvas是逐像素进行渲染的。开发者可以通过javascript脚本实现任意绘图。可以通过多种方法使用canvas元素绘制路径、矩形、圆形、字符以及添加图像。
- 在Canvas中,一旦图形被绘制完成,它就不会继续得到浏览器的关注。如果其位置发生变化,那么整个场景也需要重新绘制,包括任何或许已被图形覆盖的对象。
2、Canvas(画布)基本使用
<canvas id="tutorial" width="300" height="300"></canvas>
2.1、 <canvas> 元素
- canvas 是一个二维网格。
canvas 的左上角坐标为 (0,0) - <canvas> 看起来和 <img> 标签一样,只是 <canvas> 只有两个可选的属性 width、heigth 属性,而没有 src、alt 属性。如果不给<canvas>设置 widht、height 属性时,则默认 width为300、height 为 150,单位都是 px。也可以使用 css 属性来设置宽高,但是如宽高属性和初始比例不一致,他会出现扭曲。所以,建议永远不要使用 css 属性来设置<canvas>的宽高。
- 由于某些较老的浏览器(尤其是 IE9 之前的 IE 浏览器)或者浏览器不支持 HTML 元素<canvas>,在这些浏览器上你应该总是能展示替代内容。支持 <canvas>的浏览器会只渲染 <canvas>标签,而忽略其中的替代内容。
不支持 <canvas>的浏览器则 会直接渲染替代内容:
<canvas>
你的浏览器不支持 canvas,请升级你的浏览器。
</canvas>
用 <img> 替换:
<canvas>
<img src="" alt="">
</canvas>
- 结束标签 </canvas>不可省略。
2.2、渲染上下文(Thre Rending Context)
</canvas>会创建一个固定大小的画布,会公开一个或多个渲染上下文(画笔),使用渲染上下文来绘制和处理要展示的内容。
我们重点研究 2D 渲染上下文。 其他的上下文我们暂不研究,比如, WebGL 使用了基于 OpenGL ES的3D 上下文 (“experimental-webgl”) 。
var canvas = document.getElementById('tutorial');
//获得 2d 上下文对象
var ctx = canvas.getContext('2d');
2.3、检测支持性
var canvas = document.getElementById('tutorial');
if (canvas.getContext){
var ctx = canvas.getContext('2d');
// drawing code here
} else {
// canvas-unsupported code here
}
- 例子:绘制两个长方形
<canvas id="tutorial" width="300" height="300"></canvas>
<script type="text/javascript">
function draw(){
var canvas = document.getElementById('tutorial');
if(!canvas.getContext) return;
var ctx = canvas.getContext("2d");
ctx.fillStyle = "rgb(200,0,0)";
//绘制矩形
ctx.fillRect (10, 10, 55, 50);
ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
ctx.fillRect (30, 30, 55, 50);
}
draw();
</script>
3、绘制不同线条颜色的三角形
3.1、绘制三角形
3.1.1、 绘制一个简单的三角形
<script type="text/javascript">
// 获取画布元素
var example = document.getElementById('example')
// 获取工具集
var ctx = example.getContext('2d')
// 定位一个起始点
ctx.moveTo(50, 50)
// 绘制第二个点
ctx.lineTo(100, 50)
// 绘制第三个点
ctx.lineTo(75, 100)
// 连接起始点/闭合路径
// ctx.lineTo(50, 50)
ctx.closePath()
// 绘制线条
ctx.stroke()
</script>
3.1.2、 绘制一个不同边框颜色的三角形
- 绘制的颜色与线条宽度
// 设置线条的宽度,以像素为单位
ctx.linewidth = number
// 设置笔触图形的颜色
ctx.strokeStyle = color
// 设置填充图形的颜色
ctx.fillStyle = color
- 闭合路径
// 开始一条路径,或重置当前的路径,并切断和上一个图形的路径联系。
ctx.beginPath()
* 闭合路径的优势
可以实现不同大小和颜色图形的单独绘制。
<script type="text/javascript">
// 获取画布元素
var example = document.getElementById('example')
// 获取工具集
var ctx = example.getContext('2d')
// 1、绘制第一个点
// 设置绘制图形的颜色
ctx.strokeStyle = 'pink'
// 设置绘制图形的线条宽度
ctx.lineWidth = 4
ctx.moveTo(50, 50)
ctx.lineTo(100, 50)
// 重置当前路径
// 绘制线条
ctx.stroke()
ctx.beginPath()
// 2、绘制第二个点
ctx.strokeStyle = 'orange'
ctx.lineWidth = 4
ctx.moveTo(100, 50)
ctx.lineTo(75, 100)
ctx.stroke()
ctx.beginPath()
// 3、绘制第三个点
ctx.strokeStyle = 'blue'
ctx.lineWidth = 4
ctx.moveTo(75, 100)
ctx.lineTo(50, 50)
ctx.stroke()
// ctx.beginPath()
</script>
3.2、绘制文字和图片
- 指定位置
// 在指定位置和宽度内绘制文字
ctx.fillText(text, x, y, maxwidth)
- 设置字体名称和样式
// 设置字体名称和形状
ctx.font="字体属性" // bold 32px sans-serif
- 设置字体对齐位置
// 设置文本内容水平对齐方式
ctx.textAlign='水平方位' // center\left\right
// 设置文本内容垂直对齐方式
ctx.textBaseLine='垂直方位值' // top\middle\bottom
- 绘制内容另存为图片
// 当前绘制内容存为图片
ctx.toDataURL(type, encoderOptions) // image/png图片格式,0到1区间图片质量
<script type="text/javascript">
// 获取画布元素
var example = document.getElementById('example')
// 获取工具集
var ctx = example.getContext('2d')
// 设置文字样式(要在绘制之前)
ctx.font = "bold 20px 黑体"
// 这些代码只是容易区分文字位置
ctx.strokeStyle = "pink"
ctx.moveTo(10, 30)
ctx.lineTo(120, 30)
ctx.stroke()
ctx.beginPath()
ctx.moveTo(30, 10)
ctx.lineTo(30, 120)
ctx.stroke()
ctx.beginPath()
ctx.moveTo(10, 60)
ctx.lineTo(120, 60)
ctx.stroke()
ctx.beginPath()
ctx.moveTo(60, 10)
ctx.lineTo(60, 120)
ctx.stroke()
// 水平
ctx.textAlign = "center"
// 垂直
ctx.textBaseline = "middle"
// 调用工具集中的API绘制文字
// 第一种(填充式)
ctx.fillText('文字', 30, 30)
// 第二种(描边)
ctx.strokeText('画笔', 60, 60)
// 将绘制的内容另存为图片(会返回一个base64的字符集)
var imgUrl = example.toDataURL('image/png', 1)
console.log(imgUrl);
</script>
3.3、绘制矩形和圆形及图片
- 绘制矩形
// 1、先绘制矩形的路径,再描边或填充
ctx.rect(x, y, width, height);
ctx.stroke()
// 或
ctx.fill()
// 2、直接绘制无/有填充的矩形
ctx.strokeRect(x,y,width,height)
ctx.fillRect(x,y,width,height)
- 绘制有弧度的圆形
// 在指定位置绘制一个圆形
ctx.arc(x,y,startAngle,endAngle,clockwise) // 以(x, y) 为圆心,以r 为半径,从 startAngle 弧度开始到endAngle弧度结束。anticlosewise 是布尔值,true 表示逆时针,false 表示顺时针(默认是顺时针)。
- 绘制不同大小的图片
// 在画布上绘制固定坐标的图像
ctx.drawImage(img,x,y);
// 在画布上绘制不仅固定坐标,且规定图像的宽度和高度图像
ctx.drawImage(img,x,y,width,height)
// 在画布上剪切图像,并在画布上绘制被剪切的部分
ctx.drawImage(img,sx,sy,swidth,sheight,x,y,width,height)
4、刮刮卡案例
分为三个步骤:
- 将随机的中奖信息绘制到画布中
- 使用灰色的矩形覆盖中奖信息
- 使用鼠标划擦区域实现刮刮的效果
<script type="text/javascript">
// 获取画布元素
var example = document.getElementById('example')
// 获取工具集
var ctx = example.getContext('2d')
// 定义一个中奖信息的数组
var prices = ['步步高升', '幸福美满', '财运亨通', '财源广进']
ctx.fillStyle = 'red'
ctx.font = 'bold 36px 黑体'
ctx.textAlign = 'center'
ctx.textBaseline = 'middle'
// 随机生成一个中奖信息元素,并绘制到画布中间
ctx.fillText(prices[Math.floor(Math.random() * prices.length)], example.width / 2, example.height / 2)
// 将绘制的中奖信息另存图片并作为画布元素的背景图片
var imgUrl = example.toDataURL('image/png', 1)
example.style.background = 'url(' + imgUrl + ')';
// 绘制矩形盖住中奖信息
ctx.clearRect(0, 0, example.width, example.height)
// 设置矩形的绘制颜色
ctx.fillStyle = '#ddd'
// 绘制盖住的区域
ctx.fillRect(0, 0, example.width, example.height)
var flag = false
example.onmousedown = function () {
flag = true
ctx.globalCompositeOperation = 'destination-out';
}
example.ontouchstart = function () {
flag = true
ctx.globalCompositeOperation = 'destination-out';
}
example.onmousemove = function (e) {
if (flag) {
console.log(e);
var x = e.offsetX
var y = e.offsetY
ctx.fillStyle = 'pink'
ctx.fillRect(x, y, 30, 30)
}
}
example.ontouchmove = function (e) {
if (flag) {
console.log(e);
var x = e.touches[0].clientX
var y = e.touches[0].clientY
ctx.fillStyle = 'pink'
ctx.fillRect(x, y, 30, 30)
}
}
example.onmouseleave = function () {
flag = false
}
example.ontouchend = function () {
flag = false
}
</script>