HTML5 <canvas> 标签用于绘制图像(通过脚本,通常是 JavaScript)。
不过,<canvas> 元素本身并没有绘制能力(它仅仅是图形的容器) - 您必须使用脚本来完成实际的绘图任务。
getContext() 方法可返回一个对象,该对象提供了用于在画布上绘图的方法和属性。
一般写法:<canvas id="tutorial"width="150"height="150"></canvas>
getContext()用来获得渲染上下文和它的绘画功能,只有一个参数,目前只支持2d,即:
var canvas=document.getElementById('tutorial');
var ctx=canvas.getContext('2d');
getContext()可以用来检测当前浏览器是不是支持canvas,如果不支持可以用指定文本替代:
var canvas=document.getElementById('tutorial');
if (canvas.getContext){
var ctx=canvas.getContext('2d');// 支持
} else {
// 不支持,可以写相关提示文字
}
案例:
<script type="text/javascript">
function draw(){
var canvas=document.getElementById('tutorial');
if (canvas.getContext){
var ctx=canvas.getContext('2d');
}
}
</script>
<style type="text/css">
canvas { border: 1px solid black; }
</style>
<body onload="draw();">
<canvas id="tutorial" width="150" height="150"></canvas>
</body>
效果:只是一个空画布
canvas提供了四种方法绘制矩形
rect(): 创建矩形,仅仅创建并未画出,仍需要fill或者stroke填充或者画出来!
fillRect(x, y, width, height) 绘制一个填充的矩形
strokeRect(x, y, width, height) 绘制一个矩形的边框
clearRect(x, y, width, height)清 除指定矩形区域,让清除部分完全透明。
例子:
function draw() {
var canvas=document.getElementById('canvas');
if (canvas.getContext) {
var ctx=canvas.getContext('2d');
ctx.fillRect(25,25,100,100);//绘制一个100*100矩形,默认黑色
ctx.clearRect(45,45,60,60);//删除一个60*60的矩形
ctx.strokeRect(50,50,50,50);//绘制一个50*50的边框
}}
效果图:
路径绘制图形需要的步骤:
1、首先,你需要创建路径起始点。
2、然后你使用画图命令去画出路径。
3、之后你把路径封闭。
4、一旦路径生成,你就能通过描边或填充路径区域来渲染图形。
通过以下常用函数来画图:
beginPath()新建一条路径,生成之后,图形绘制命令被指向到路径上生成路径。
closePath()闭合路径之后图形绘制命令又重新指向到上下文中。
stroke()通过线条来绘制图形轮廓。
fill()通过填充路径的内容区域生成实心的图形。
moveTo(x,y)将笔触移动到指定的坐标x以及y上。
lineTo(x, y)绘制一条从当前位置到指定x以及y位置的直线。
arc(x, y, radius, startAngle, endAngle, anticlockwise)画一个以(x,y)为圆心的以radius为半径的圆弧(圆),从startAngle开始到endAngle结束,按照anticlockwise给定的方向(默认为顺时针)来生成。
arcTo(x1, y1, x2, y2, radius)根据给定的控制点和半径画一段圆弧,再以直线连接两个控制点。
注意:注意:arc()函数中的角度单位是弧度,不是度数。角度与弧度的js表达式:radians=(Math.PI/180)*degrees。
例子1:绘制一个三角形
function draw() {
var canvas=document.getElementById('canvas');
if (canvas.getContext){
var ctx=canvas.getContext('2d');
ctx.beginPath();//新建路径
ctx.moveTo(75,50);//从75*20的位置开始
ctx.lineTo(100,75);//画到100*75
ctx.lineTo(100,25);//再画到100*25
ctx.fill();//填充颜色
}}
效果:
例子2:画一个是描边三角形。
function draw() {
var canvas=document.getElementById('canvas');
if (canvas.getContext){
var ctx=canvas.getContext('2d');
// 描边三角形
ctx.beginPath();
ctx.moveTo(125,125);
ctx.lineTo(125,45);
ctx.lineTo(45,125);
ctx.closePath();
ctx.stroke();//描边
}}
效果图:
例子3:通过圆弧画图:
function draw() {
var canvas=document.getElementById('canvas');
if (canvas.getContext){
var ctx=canvas.getContext('2d');
ctx.beginPath();
ctx.arc(75,75,50,0,Math.PI*2,true); // 绘制
ctx.moveTo(110,75);
ctx.arc(75,75,35,0,Math.PI,false); // 口(顺时针)
ctx.moveTo(65,65);
ctx.arc(60,65,5,0,Math.PI*2,true); // 左眼
ctx.moveTo(95,65);
ctx.arc(90,65,5,0,Math.PI*2,true); // 右眼
ctx.stroke();
}}
效果:
(4)二次贝塞尔曲线及三次贝塞尔曲线
quadraticCurveTo(cp1x, cp1y, x, y)绘制二次贝塞尔曲线,cp1x,cp1y为一个控制点,x,y为结束点。
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)绘制三次贝塞尔曲线,cp1x,cp1y为控制点一,cp2x,cp2y为控制点二,x,y为结束点。
贝塞尔曲线图:
二次贝塞尔曲线例子:、
function draw() {
var canvas=document.getElementById('canvas');
if (canvas.getContext) {
var ctx=canvas.getContext('2d');
// 二次贝尔赛曲线
ctx.beginPath();
ctx.moveTo(75,25);
ctx.quadraticCurveTo(25,25,25,62.5);
ctx.quadraticCurveTo(25,100,50,100);
ctx.quadraticCurveTo(50,120,30,125);
ctx.quadraticCurveTo(60,120,65,100);
ctx.quadraticCurveTo(125,100,125,62.5);
ctx.quadraticCurveTo(125,25,75,25);
ctx.stroke();
}}
效果:
三次贝塞尔曲线例子:
functiondraw(){
var canvas=document.getElementById('canvas');
if(canvas.getContext){
var ctx=canvas.getContext('2d');
//三次贝塞尔曲线
ctx.beginPath();
ctx.moveTo(75,40);
ctx.bezierCurveTo(75,37,70,25,50,25);
ctx.bezierCurveTo(20,25,20,62.5,20,62.5);
ctx.bezierCurveTo(20,80,40,102,75,120);
ctx.bezierCurveTo(110,102,130,80,130,62.5);
ctx.bezierCurveTo(130,62.5,130,25,100,25);
ctx.bezierCurveTo(85,25,75,37,75,40);
ctx.fill();
}}
效果:
canvas还有很多不错的功能,如果想学习,可以接续看我的后续教程.
委外待续....
oogle Docs宣布将会把HTML迁移到基于Canvas渲染,这一消息的出现再次把几年前随HTML5诞生的标签重新推到了人们视线之中。Canvas在刚推出时主打的优势就是更快的渲染速度,堪称HTML届的“小飞人”,刷新了人们对Web页面元素绘制速度的印象。但Canvas的优势仅限于此吗?
(图片来源于网络)
Canvas是HTML5时代引入的“新”标签。与很多标签不同,Canvas不具有自己的行为,只将一组API 展现给客户端 JavaScript ,让开发者使用脚本把想绘制的东西画到一张画布上。
在HTML5之前,人们通常使用SVG来在页面上绘制出图形。SVG使用XML来定义图形,就像使用HTML标签和样式定义DIV一样,我们也可以将一个空白的DIV想象为长方形的SVG,两者的设计思想是相通的,SVG的本质就是一个DOM元素。而Canvas则不同,Canvas提供的是 JavaScript 的绘图 API,而不是像 SVG那样使用XML 描述绘图,通过JavaScript API直接完成绘制,比起修改XML来说要更简便、更直接。
除了定义的方式不同,Canvas和DOM(当然也包含SVG)的差异更多的体现在浏览器的渲染方式上。
浏览器在做页面渲染时,Dom元素是作为矢量图进行渲染的。每一个元素的边距都需要单独处理,浏览器需要将它们全都处理成像素才能输出到屏幕上,计算量十分庞大。当页面上内容非常多,存在大量DOM元素的时候,这些内容的渲染速度就会变得很慢。
而Canvas与DOM的区别则是Canvas的本质就是一张位图,类似img标签,或者一个div加了一张背景图(background-image)。所以,DOM那种矢量图在渲染中存在的问题换到Canvas身上就完全不同了。在渲染Canvas时,浏览器只需要在JavaScript引擎中执行绘制逻辑,在内存中构建出画布,然后遍历整个画布里所有像素点的颜色,直接输出到屏幕就可以了。不管Canvas里面的元素有多少个,浏览器在渲染阶段也仅需要处理一张画布。
然而这样更加强大的功能,不可避免的让使用canvas渲染有很高的门槛。Google Docs在构建Canvas的过程中重新定义了往常已经被人们所熟悉的内容,例如精确定位、文本选择、拼写检查、重画调优等。为什么更多开发者还是选择了接纳Canvas这个门槛更高的技术路线呢?这就得回到Canvas的最大优势:渲染性能。
这里的渲染是指浏览器将页面的代码呈现为屏幕上内容的过程。Canvas和Dom的渲染模式完全不同,搞清楚这个差异对理解Canvas的性能优势至关重要。
Dom:驻留模式
驻留模式(Retained Mode)是Dom在浏览器中的渲染模式。下图粗略展示了这一过程的工作流程。
DOM的核心是标签,一种文本标记型语言,多样性很强且多个标签之间存在各种关联(如在同一个DIV下设置为float的子DIV)。浏览器为了更好的处理这些DOM元素,减少对绘制API的调用,就设计了一套将中间结果存放于内存的“驻留模式”。首先,浏览器会将解析DOM相关的全部内容(包含HTML标签、样式和JavaScript),将其转化为场景(scene)和模型(model)存储到内存中,然后再调用系统的绘制API(如Windows程序员熟悉的GDI/GDI+),把这些中间产物绘制到屏幕。
驻留模式通过场景和模型缓存减少了对绘制API的调用频次,将性能压力转移到场景和模型生成阶段,即浏览器需要根据DOM上下文和BOM中的尺寸数据,“自行判断”每一个元素的绘制结果。
Canvas:快速模式
Canvas采用了和DOM不同的快速模式(Immediate Mode),让我们先来看看快速模式是如工作的:
与驻留模式相比,快速模式将场景和模型的生成从浏览器移交给了开发者。开发者在设计页面时,就通过Canvas的JavaScript API定义了画布内所有元素的绘制方式。浏览器只需要简单的执行这些脚本即可,而不需要像渲染DOM一样逐个处理子元素了。
在快速模式中,页面的绘制性能得到了大幅提升。但开发者不仅需要指定什么需要画,还要创建和维护一个模型。此外,开发者还需要管理好当前场景重绘时带来的改变,以及响应用户的点击或输入操作等。
上面介绍的两种不同的模式直接造成了Dom和Canvas的性能差异。对于使用快速模式渲染的Canvas而言,浏览器的每次重绘都是基于代码的,不存在能让处理流程变慢的多层解析,所以它真的很快。除了快之外,Canvas的灵活性也大大超出DOM。我们可以通过代码精确的控制如何、何时绘制出我们想要的效果。
在资源消耗上,DOM的驻留模式意味着场景中每增加一点东西就需要额外消耗一些内存,而Canvas并没有这个问题。这个差异会随着页面元素的数量增多而愈加明显。以B端的企业应用场景为例,表单那种数据量比较小的场景,不同渲染模式带来的效果差异并不明显;但在工业制造、金融财会等类Excel电子表格操作的场景下,单元格数量动辄便是上百万(5万行x 20列)甚至上亿个,浏览器需要对表格所有单元格本身内容进行渲染,同时还涉及到丰富的数据处理,情况就完全不同了。
(Web页面上的电子表格,包含1百万个单元格)
在Canvas出现之前,在前端渲染表格时只能通过构建复杂的DOM来实现。这种方式下,浏览器的性能成为了Web应用瓶颈,让很多开发者放弃了在浏览器上实现电子表格的想法。
在Canvas出现后,快速模式带来的性能优势无疑是一个巨大的亮点,大量、复杂的DOM渲染处理带来的性能问题终于有了解决途径。
回到电子表格的应用场景,业内已经出现了使用Canvas绘制画布的表格组件,这类组件在渲染数据层时不仅无需重复创建和销毁DOM元素,在画布的绘制过程中,也比Dom元素渲染的限制更少。除了表格之外,Canvas也为数字孪生可视化大屏、页面游戏等场景带来了变革。
(数字孪生大屏,精确控制各种形状、样式)
总结一下,在渲染模式上,Canvas站在了DOM的对面,浏览器对其内容一无所知,一切渲染的权利回到了开发者的手上,这个改变带来了显著的性能优势。此外,我们可以使用Canvas绘制种类更为丰富的UI元素,如线形、特殊图形等,通过画法逻辑,还可以实现更加精准的UI界面渲染,解决了浏览器差异造成的样式误差,让更多应用场景可以顺利迁移到Web平台上来。
为一名前端攻城狮,Canvas 和 SVG 对于我们并不陌生,canvas 是 HTML5 提供的新元素,而 svg 存在的时间要比 canvas 长很多,svg 并不属于 html,最初的 svg 是由 XML 定义的,在 html 5 中 canvas 与 svg 看着相似,其实不同。
Canvas
SVG
2.1、功能上来说
canvas 是一个画布,绘制出来的图形是位图,因此 canvas 可以绘制图片,在实际应用中,由于渲染性能高,所以大型游戏开发都用的 canvas 。除此之外,还有统计中常见的柱状图、饼图、雷达图等也使用的 canvas 。而 svg 绘制的是矢量图,放大后不会失真,所以很适合做地图。
2.2、操作方面讲
canvas 绘制的图形,只能给 canvas 整个画布添加事件,而不能给某个图形或文件添加事件处理器,但是 svg 支持事件绑定,如果需要添加带有事件的动画效果时,就需要选择 svg。
*请认真填写需求信息,我们会在24小时内与您取得联系。