javascript dashboard怎么画dashboard

developerWorks 社区
新的 HTML5 规范旨在帮助开发人员更轻松的编写出各类 Web 应用,以顺应当前 SaaS,云计算以及 RIA 等技术的最新趋势。在 HTML5 得以广泛推广之前,开发人员通常使用 SVG,VML 等技术进行 Web 绘图操作,但这些基于 XML 的绘图语言声明式的绘图方式并不能满足复杂绘图操作在性能上的需求,比如 Web 游戏所需要的像素级别的绘图能力。HTML5 canvas 元素的出现填补了这种不足,开发人员可以使用 JavaScript 脚本语言在 canvas 中进行一系列基于命令的图形绘制操作,本文将通过讲解如何使用 canvas 元素进行基本绘图操作,以及完成简单的动画和用户交互任务,阐明 canvas 在帮助构建 Web 图形类应用时所能够提供的能力。
, 软件工程师, IBM
林林,毕业于北京邮电大学,获得计算机硕士学位。现就职于 IBM 中国软件开发中心 ETI 部门,从事 Web 2.0 相关产品的研发工作,对 Java EE,语义 Web,敏捷开发以及三网融合相关技术有着浓厚兴趣和丰富经验。
背景介绍HTML5 中新引入的 canvas 元素使得 Web 开发人员在无须借助任何第三方插件(如 Flash,Silverlight)的情况下,可以直接使用 JavaScript 脚本在 Web 页面进行绘图。它首次由苹果公司的 Webkit 框架引入实现,并成功运用在 Safari 浏览器中,读者在 可以体验到基于 canvas 的精彩示例。目前,canvas 已成为 HTML5 规范中的事实性标准,并且已经被 Firefox 3.0+, Safari 3.0+, Chrome 3.0+, Opera10.0+ 等浏览器所支持。最近(本文撰写之时),IE 也正式宣称将在其 9.0 版本之后,开始对 canvas 元素进行支持。基于 canvas 的绘图填补了 SVG 绘图的在复杂绘图操作,特别是性能方面的不足,可广泛应用于 Dashboard,2D/3D Game 等 Web 应用中。基本绘图 API在了解了什么是 canvas 元素之后,是时候使用 canvas 在 Web 页面上真正进行的绘图操作了。实际上,单独的一个 canvas 标记只是在页面中定义了一块矩形区域,并无特别之处,开发人员只有配合使用 JavaScript 脚本,才能够完成各种图形,线条,以及复杂的图形变换操作,与基于 SVG 来实现同样绘图效果来比较,canvas 绘图是一种像素级别的位图绘图技术,而 SVG 则是一种矢量绘图技术。正鉴于这种本质机理的不同,如何更快速高效的进行 canvas 渲染成为各主流 JavaScript 执行引擎性能比拼的重要指标之一。目前,Chrome 的 V8, Firefox 的 SpiderMonkey 以及 Safari 的 Nitro 等引擎都已经能够很好的满足二维绘图所需的必要性能指标,虽然在运行一些基于 canvas 的游戏时 CPU 占用率还是相对较高,但我们有理由相信随着 NVIDIA 和 AMD 等一系列硬件厂商的参与,硬件加速技术将大大提升 Web 应用的性能。在开始绘图之前,我们需要首先创建一个指定大小的 canvas,并为其指定一个 id,方便在 JavaScript 脚本中获取该 DOM 实例对象。声明一个 canvas 节点的方式如下所示。 &canvas id="canvas" width="300" height="200"&
Fallback content, in case the browser does not support Canvas.
&/canvas&需要指明的是,由于无法保证所有用户使用的浏览器都能够支持 canvas 元素,所以在目前开发基于 canvas 的 Web 应用中需要增加“Fallback content”,以提示用户他们无法正常体验此功能的原因或建议他们去下载最新的浏览器。这里,好奇的读者可能会问,既然这是一个普通的 DOM 节点,那么便意味着可以通过直接改变其 width 或 height 属性值来改变 canvas 的大小?确实如此,但是,正如之前提到的 canvas 是一种像素级别的绘图方法,因而,一旦动态调整 canvas 的大小,canvas 将被“重置”到一个新的初始状态,即便是如下这种操作,也会将 canvas 内的位图清除并将所有相关属性恢复到初始值的状态。当然,我们也可以把这当作重置 canvas 的小技巧来使用。 document.getElementById("canvas").width = document.getElementById("canvas").简单图形绘制基于 canvas 的绘图并不是直接在 canvas 标记所创建的绘图画面上进行各种绘图操作,而是依赖画面所提供的 渲染上下文(Rendering Context),所有的绘图命令和属性都定义在渲染上下文当中。在通过 canvas id 获取相应的 DOM 对象之后首先要做的事情就是获取渲染上下文对象。 渲染上下文与 canvas 一一对应,无论对同一 canvas 对象调用几次 getContext() 方法,都将返回同一个上下文对象。目前,所有支持 canvas 标签的浏览器都支持 2D 渲染上下文,可以使用如下的代码来获取该对象。 var context = document.getElementById("canvas").getContext("2d");除此之外,在不久的将来,开发人员还会能够得到基于 OpenGL 的 3D 渲染上下文以在 canvas 中进行 3D 绘图。与 SVG 不同,canvas 原生支持的基本图形只有矩形一种,至于其他的圆形,多边形等图形则都由路径来负责绘制实现。清单 1 展示了如何使用渲染上下文中的矩形绘图方法完成了图 1 所示图形。图 1. 清单 1 对应的示例图形清单 1. 绘制 canvas 矩形 function drawRect(){
var canvas = document.getElementById('canvas');
if (canvas.getContext){
var ctx = canvas.getContext('2d');
// 获取 2D 渲染上下文
ctx.clearRect(0,0,300,200)// 清除以(0,0)为左上坐标原点,300*200 矩形区域内所有像素
ctx.fillStyle = '#00f';
// 设置矩形的填充属性,#00f 代表蓝色
ctx.strokeStyle = '#f00';
// 设置矩形的线条颜色,#f00 代表红色
ctx.fillRect(50,25,150,80); // 使用 fillStyle 填充一个 150*80 大小的矩形
ctx.strokeRect(45,20, 160, 90);
// 以 strokeStype 属性为边的颜色绘制一个无填充矩形
}绘制路径在开始动手绘制路径之前,首先需要明确的是:矩形绘制 API 是一种即时性的 API,他会在相应的绘图函数执行完毕之后,将图形即时的渲染在画面上。然而路径绘制 API 并非如此,完整的路径绘制过程大致可以分为如下两个阶段:
定义路径轮廓:在每个 canvas 实例对象中都拥有一个 path 对象,创建自定义图形的过程就是不断对 path 对象操作的过程。每当开始一次新的图形绘制任务,都需要先使用 beginPath() 方法来重置 path 对象至初始状态,进而通过一系列对 moveTo/lineTo 等画线方法的调用,绘制期望的路径,其中 moveTo(x, y) 方法设置绘图起始坐标,而 lineTo(x,y) 等画线方法可以从当前起点绘制直线,圆弧以及曲线到目标位置。最后一步,也是可选的步骤,是调用 closePath() 方法将自定义图形进行闭合,该方法将自动创建一条从当前坐标到起始坐标的直线。
绘制路径定义完路径的轮廓,此时 canvas 画面中没有显示任何路径,开发人员还可以对路径进行修改。一旦确定完成,则需要继续调用 stroke()/fill() 函数来完成将路径渲染到画面的最后一步。路径的轮廓颜色和填充颜色由 strokeStyle 和 fillStyle 属性决定。清单 2 绘制一个图 2 所示半圆弧,并通过 closePath() 方法完成图形的闭合。图 2. 清单 2 对应的示例图形清单 2. 绘制 canvas 路径 function draw(){
var canvas = document.getElementById('canvas');
if (canvas.getContext){
var ctx = canvas.getContext('2d');
ctx.fillStyle = '#00f';
ctx.strokeStyle = '#f00';
ctx.beginPath();
ctx.arc(75,75,30,0,Math.PI, false);
// 绘制一条半圆弧线
ctx.closePath();
// 自动绘制一条直线来关闭弧线。若不调用此方法,将仅仅显示一条半圆弧
ctx.fill();
// 可以尝试注释掉 fill 或者 stroke 函数,观察图形的变化
ctx.stroke();
}二维变形Canvas 绘图中另一个重要的概念是 绘画状态(Drawing State),绘画状态反映了渲染上下文当前的瞬时状态,开发人员可以通过对绘画状态的保存 / 恢复操作而快速的回到之前使用的各种属性和变形操作。绘画状态主要由以下三个部分构成:
当前的变形矩阵(transformation matrix)
当前的裁剪区域(clipping region)
当前上下文中的属性,比如 strokeStyle, fillType, globalAlpha, font 等等。需要指出的是,当前路径对象以及当前的位图都不包含在绘画状态之中,路径是持续性的对象,如前文所讲,只有通过 beginPath() 操作才会进行重置,而位图则是 canvas 的属性,并非属于渲染上下文的。开发人员可以使用 save 和 restore 两种方法来保存和恢复 canvas 状态,每调用 save 方法,都会将当前状态压入堆栈中,而相应的 restore 方法则会从堆栈中弹出一个状态,并将当前画面恢复至该状态。绘画状态在 canvas 图形变形操作中应用极为广泛,也非常重要,因为调用一个 restore 方法远比手动恢复先前状态要简单许多,因而,一个较好的习惯是在做变形操作之前先保存 canvas 状态。二维绘图的常用变形操作在 canvas 中都可到了很好的支持,包括平移(Translate),旋转(Rotate),伸缩(Scale)等等。由于所有的变形操作都基于变形矩阵,因而开发人员始终需要记住一点的就是,一旦没有使用 save/restore 操作保持住原来的绘图状态,那么后续的绘图操作,都会在当前所应用的变形状态下完成。清单 3 使用平移和旋转方法绘制了如下所示画面。图 3. 清单 3 所示示例图形清单 3. 使用平移 / 旋转变形方法绘制复杂位图 function drawPointCircle(){
var canvas = document.getElementById('canvas');
if (canvas.getContext){
var ctx = canvas.getContext('2d');
ctx.translate(150,150);
// 将 canvas 的原点从 (0,0) 平移至(150,150)
for (i=1;i&=2;i++){
// 绘制内外 2 层
if ((i % 2) == 1) {ctx.fillStyle = '#00f';}
else{ ctx.fillStyle = '#f00'; }
ctx.save();
// 保持开始绘制每一层时的状态一致
for (j=0;j&=i*6;j++){
// 每层生成点的数量
ctx.rotate(Math.PI/(3*i));
// 绕当前原点将坐标系顺时针旋转 Math.Pi/(3*i) 度
ctx.beginPath();
ctx.arc(0,20*i,5,0,Math.PI*2,true);
ctx.fill();
// 使用 fillType 值填充每个点
ctx.restore();
}像素级绘图像素级别的绘图操作是 canvas 绘图区别于 SVG,VML 等绘图技术的最为明显特征之一,渲染上下文提供了 createImageData, getImageData, 和 putImageData 三种方法来进行针对像素的操作,所基于的对象都是 imageData 对象。imageData 对象包含 width、height 和 data 三个属性,其中 data 包含了 width × height × 4 个像素值,之所以乘以 4,在于每个像素都有 RGB 值和透明度 alpha 值。清单 4 中所示代码为上一节中示例图形增添了简单的颜色反转滤镜效果,通过调用 getImageData(x,y,width,height) 方法获取以(x,y)为左上坐标的矩形区域内所有像素,而后对所有像素的 RGB 值做取反操作,最后通过 putImageData(imageData, x, y)将修改后的像素值重新绘制到在 canvas 上。图 4. 清单 4 所示示例图形清单 4. 实现简单滤镜效果 function revertImage(){
var canvas = document.getElementById('canvas');
if (canvas.getContext){
var context = canvas.getContext('2d');
// 从指定的矩形区域获取 canvas 像素数组
var imgdata = context.getImageData(100, 100, 100, 100);
var pixels = imgdata.
// 遍历每个像素并对 RGB 值进行取反
for (var i=0, n=pixels. i&n; i+= 4){
pixels[i] = 255-pixels[i];
pixels[i+1] = 255-pixels[i+1];
pixels[i+2] = 255-pixels[i+2];
// 在指定位置进行像素重绘
context.putImageData(imgdata, 100, 100);
}实现动画效果Canvas 并非为了制作动画而出现,自然没有动画制作中帧的概念。因而,使用定时器不断的重绘 canvas 画面成为了实现动画效果的通用解决方式。Javascript 中的 setInterval(code,millisec) 方法可以按照指定的时间间隔 millisec 来反复调用 code 所指向的函数或代码串,这样,通过将绘图函数作为第一个参数传给 setInterval 方法,在每次被调用的过程中移动画面中图形的位置,来最终达到一种动画的体验。需要注意的一点是,虽然 setinterval 方法的第二个参数允许开发人员对绘图函数的调用频率进行设定,但这始终都是一种最为理想的情况,由于这种绘图频率很大程度上取决于支持 canvas 的底层 JavaScript 引擎的渲染速度以及相应绘图函数的复杂性,因而实际运行的结果往往都是要慢于指定绘图频率的。清单 5 显示了一个小弹力球动画效果,在球没有到达四周边界时,绘图方法不断的移动所绘小球的横纵坐标。并且,在每次重绘之前,都是用 clear 方法将之前的画面清除。清单 5. 实现小弹力球动画 &script type="text/javascript"&
var x=0,y=0,dx=2,dy=3,context2D;
// 小球从(0,0)开始移动,横向步长为 2,纵向步长为 3
function draw(){
context2D.clearRect(0, 0, canvas.width, canvas.height);
// 清除整个 canvas 画面
drawCircle(x, y);
// 使用自定义的画圆方法,在当前(x,y)坐标出画一个圆
// 判断边界值,调整 dx/dy 以改变 x/y 坐标变化方向。
if (x + dx & canvas.width || x + dx & 0) dx = -
if (y + dy & canvas.height || y + dy & 0) dy = -
window.onload = function (){
var canvas = document.getElementById('canvas');
context2D = canvas.getContext('2d');
setInterval(draw, 20);
// 设置绘图周期为 20 毫秒
&/script&提高可访问性一款优秀的 Web 应用必须要做到的就是提供给用户很好的可访问性,这包括对鼠标,键盘以及快捷键等操作的响应,canvas 画面的本质仍是一个 DOM 节点,因而开发人员可以通过常规的方法来处理响应。这里,与基于 SVG 的绘图不同,由于 SVG 是一种基于 XML 的声明式的绘图方式,因而,SVG 中任何的图形都可以作为一个独立的 DOM 节点去接收并响应特定事件,而 canvas 由于其像素绘图的本质,则只可以在 canvas 元素节点去处理。图 5 所示示例代码,当鼠标在 canvas 中移动时,鼠标当前相对于 canvas 中的横纵坐标将实时输出到上方提示信息区域;当用户在 canvas 中单击鼠标左键,将在相应位置创建一个蓝色小球,而后用户可以通过键盘上的左 / 右方向键对蓝色小球进行控制,使其进行横向的移动。示例代码如清单 6 所示。图 5. 清单 6 所示示例展现清单 6. 实现 canvas 对方向键和鼠标点击事件的响应 &script type="text/javascript"&
var g_x,g_y;
// 鼠标当前的坐标
var g_pointx, g_
// 蓝色小球当前的坐标
function drawCircle(x,y){
// 以鼠标当前位置为原点绘制一个蓝色小球
var ctx = canvas.getContext('2d');
ctx.clearRect(0,0,300,300);
ctx.fillStyle = '#00f';
ctx.beginPath();
ctx.arc(x,y,20,0,Math.PI*2,true);
ctx.fill();
g_pointx =
g_pointy = y
function onMouseMove(evt) {
// 获取鼠标在 canvas 中的坐标位置
if (evt.layerX || evt.layerX == 0) { // FireFox
g_x = evt.layerX;
g_y = evt.layerY;
document.getElementById("xinfo").innerHTML = g_x;
document.getElementById("yinfo").innerHTML = g_y;
function onKeyPress(evt) {
var dx = 3;
// 横向平移步长
var kbinfo = document.getElementById("kbinfo");
if (evt.keyCode == 39){
kbinfo.innerHTML="right";
if (g_x&300-dx) drawCircle(g_pointx+dx,g_pointy);
document.getElementById("xinfo").innerHTML = g_
}else if (evt.keyCode == 37){
kbinfo.innerHTML = "left";
if (g_x&dx) drawCircle(g_pointx-dx,g_pointy);
document.getElementById("xinfo").innerHTML = g_
window.onload = function(){
canvas = document.getElementById('canvas');
// 增加 canvas 节点对鼠标单击,移动以及键盘事件的响应函数
canvas.addEventListener('click', function(evt){drawCircle(g_x, g_y);} , false);
canvas.addEventListener('mousemove', onMouseMove, false);
canvas.addEventListener('keypress', onKeyPress, false);
canvas.focus();
// 获得焦点之后,才能够对键盘事件进行捕获
&/script&这里我们对鼠标的移动,单击操作进行响应,在实际应用中可以视特定应用的需求,增加对鼠标摁下,松开或双击等更为丰富操作的响应,增强应用的可访问性。细心的读者可能发现,在通过不断重绘画面以达到动画效果的过程中,我们的重绘方法首先做的事情都是调用 clearRect(x, y, width, height) 方法将原画面清空,这种销毁而后重绘的方式丢失了之前的画面,使得开发人员不得不重绘整幅画面,这在性能上是难以接受的,一种可行的做法是通过多个 canvas 叠加的方式,根据不同 canvas 上的不同刷新频率,分别完成各自的重绘任务。这种多 canvas 技巧,在处理绘图类应用中最为常见的“撤销”操作时也非常有效,所有的绘图都发生在上层 canvas,只有被用户确认的画面,才会被绘制到底层 canvas 上。鉴于本文所讨论技术范围,这里不做过多讲解,有兴趣的读者可以通过本文参考文献所列资源,进行进一步的深入学习。总结本文对 HTML5 新引入的 canvas 元素在 Web 绘图中所扮演的角色和所发挥的作用做了最基本的介绍,其中包括使用 canvas 完成基本的 Web 绘图,动画和交互任务,虽然 Flash,Silverlight 也都可以完成相同的任务,甚至在性能上更胜一筹,但是作为一种不依赖任何插件的标准 Web 像素级绘图技术,我们有理由相信随着各大浏览器厂商的加入,canvas 将会更加成熟完善,也会有更多基于 canvas 的绘图类应用不断涌现。声明本人所发表的内容仅为个人观点,不代表 IBM 公司立场、战略和观点。
参考资料 查看 ,了解更多和 HTML5 相关的知识和动向。查看 ,了解更多 HTML5 canvas 知识。查看 WhatWG 制定的关于 ,了解更多底层绘图 API。查看 ,了解如何使用 canvas 创建 Web 绘图类应用。通过 ,了解如何基于 SVG 和 Dojo 构建 Web 绘图类应用。访问 ,查看更多基于 HTML5 canvas 构建的精彩示例。:通过专门关于 Web 技术的文章和教程,扩展您在网站开发方面的技能。:这是有关 Ajax 编程模型信息的一站式中心,包括很多文档、教程、论坛、blog、wiki 和新闻。任何 Ajax 的新信息都能在这里找到。,这是有关 Web 2.0 相关信息的一站式中心,包括大量 Web 2.0 技术文章、教程、下载和相关技术资源。您还可以通过
栏目,迅速了解 Web 2.0 的相关概念。加入
developerWorks: 登录
标有星(*)号的字段是必填字段。
保持登录。
单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件。
在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。
所有提交的信息确保安全。
选择您的昵称
当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。昵称长度在 3 至 31 个字符之间。
您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。
标有星(*)号的字段是必填字段。
(昵称长度在 3 至 31 个字符之间)
单击提交则表示您同意developerWorks 的条款和条件。 .
所有提交的信息确保安全。
文章、教程、演示,帮助您构建、部署和管理云应用。
立即加入来自 IBM 的专业 IT 社交网络。
免费下载、试用软件产品,构建应用并提升技能。
static.content.url=/developerworks/js/artrating/SITE_ID=10Zone=Web developmentArticleID=605595ArticleTitle=使用 HTML5 canvas 进行 Web 绘图publish-date=JavaScript(21)
HTML5添加的最受欢迎的功能就是&canvas&元素。这个元素负责在页面中设定一个区域,然后就可以通过JavaScript动态地在这个区域中绘制图形。&canvas&元素最早是由苹果公司推出的,当时主要用在其Dashboard中。很快,HTML5也加入了这个元素,主流浏览器开始支持它。
要使用&canvas&元素,必须先设置其width和height属性,指定可以绘图的区域大小。出现在开始和结束标签中的内容是后备信息,如果浏览器不支持&canvas&元素,就会显示这些信息。
width=&800&
height=&800&style=&background-color:antiquewhite&&A drawing
of something.&/canvas&
与其他元素一样,&canvas&元素对应的DOM元素也有width和height属性,可以随意修改。而且,也能通过CSS为该元素添加样式,如果不添加任何样式或者不绘制任何图形,在页面中是看不到该元素的。
要在这块画布上绘图,需要取得绘图上下文。而取得绘图上下文对象的引用,需要调用getContext()方法并传入上下文的名字。传入”2d”,就可以取得2D上下文对象。
var drawing =document.getElementById(&drawing&);
//确定浏览器支持&canvas&元素
if(drawing.getContext){
&&& var context = drawing.getContext(&2d&);
&&& //更多代码
在使用&canvas&元素之前,首先要检测getContext()方法是否存在,这一步非常重要。有些浏览器会为HTML规范之外的元素创建默认的HTML元素对象。在这种情况下,即使drawing变量中保存着一个有效的元素引用,也检测不到getContext()方法。
使用toDataURL()方法,可以导出在&canvas&元素上绘制的图像。这个方法接受一个参数,即图像的MIME类型格式,而且适用于创建图像的任何上下文。比如,要取得画布中的一幅PNG格式的图像,可以使用以下代码。
var drawing =document.getElementById(&drawing&);
//确定浏览器支持&canvas&元素
if(drawing.getContext){
&&& var context = drawing.getContext(&2d&);
&&& //取得图像的数据URI
&&& var imageURI = drawing.toDataURL(&image/png&);
&&& var image = document.createElement(&img&);
&&& image.src=imageURI;
&&& document.body.appendChild(image);
使用2D绘图上下文提供的方法,可以绘制简单的2D图形,比如矩形、弧形和路径。2D上下文的坐标开始于&canvas&左上角,原始坐标是(0,0)。所有坐标值都基于这个原点计算,x值越大表示靠右,y值越大表示越靠下。默认情况下,width和height表示水平和垂直两个方向上可用的像素数目。
填充和描边
2D上下文的两种基本绘图操作是填充和描边。填充,就是用指定的样式(颜色、渐变或图像)填充图形;描边,就是只在图形的边缘画线。大多数2D上下文操作都会细分为填充和描边两个操作,而操作的结果取决于两个属性:fillStyle和strokeStyle。
这两个属性的值可以是字符串。渐变对象或模式对象,而且它们的默认值都是”#000000”。如果为它们指定表示颜色的字符串,可以使用CSS中指定颜色值的任何格式,包括颜色名、十六进制码、rgb、rgba、hsl或hsla。举个例子:
var drawing =document.getElementById(&drawing&);
//确定浏览器支持&canvas&元素
if(drawing.getContext){
&&& var context = drawing.getContext(&2d&);
&&& context.strokeStyle=&red&;
&&& context.fillStyle=&#0000ff&;
矩形是唯一一种可以直接在2D上下文中绘制的形状。与矩形有关的方法包括fillRect()、strokeRect()和clearRect()。这三个方法都接受4个参数:矩形的x坐标、矩形的y坐标、矩形宽度和矩形高度。这些参数的单位都是像素。
首先,fillRect()方法在画布上绘制的矩形会填充指定的颜色。填充的颜色通过fillStyle属性指定,比如:
var drawing =document.getElementById(&drawing&);
//确定浏览器支持&canvas&元素
if(drawing.getContext){
&&& var context = drawing.getContext(&2d&);
&&& context.fillStyle=&#ff0000&;
&&& context.fillRect(10,10,50,50);
&&& context.fillStyle=&rgba(0,0,255,0.5)&;
&&& context.fillRect(30,30,50,50);
strokeRect()方法在画布上绘制的矩形会使用指定的颜色描边。描边颜色通过strokeStyle属性指定。比如:
var drawing =document.getElementById(&drawing&);
//确定浏览器支持&canvas&元素
if(drawing.getContext){
&&& var context = drawing.getContext(&2d&);
&&& context.strokeStyle=&#ff0000&;
&&& context.strokeRect(10,10,50,50);
&&& context.strokeStyle=&rgba(0,0,255,0.5)&;
&&& context.strokeRect(30,30,50,50);
最后,clearRect()方法用于清除画布上的矩形区域。本质上,这个方法可以把绘制上下文中的某一矩形变透明。通过绘制形状然后再清除指定区域,就可以生成有意思的效果,例如把某个形状切掉一块。如:
var drawing =document.getElementById(&drawing&);
//确定浏览器支持&canvas&元素
if(drawing.getContext){
&&& var context = drawing.getContext(&2d&);
&&& context.fillStyle=&#ff0000&;
&&& context.fillRect(10,10,50,50);
&&& context.fillStyle=&rgba(0,0,255,0.5)&;
&&& context.fillRect(30,30,50,50);
&&& context.clearRect(40,40,10,10);
2D上下文支持很多在画布上绘制路径的方法。通过路径可以创造出复杂的形状和线条。要绘制路径,首先必须调用beginPath()方法,表示要开始绘制新路径。然后,再通过调用下列方法来实际地绘制路径。
arc(x,y,radius,startAngle,endAngle,counterclockwise):以(x,y)为圆心绘制一条弧线,弧线半径为radius,起始和结束角度(用弧度表示)分别为startAngle和endAngle。最后一个参数表示startAngle和endAngle是否按逆时针方向计算,值为false表示按顺时针方向计算。
arcTo(x1,y1,x2,y2,radius):从上一点开始绘制一条弧线,到(x2,y2)为止,并且以给定的半径radius穿过(x1,y1)。
bezierCurveTo(c1x,c1y,c2x,c2y,x,y):从上一点开始绘制一条曲线,到(x,y)为止,并且以(c1x,c1y)和(c2x,c2y)为控制点。
lineTo(x,y):从上一点开始绘制一条直线,直到(x,y)为止。
moveTo(x,y):将绘图游标移动到(x,y),不画线。
quadraticCurveTo(cx,cy,x,y):从上一点开始绘制一条二次曲线,到(x,y)为止,并且以(cx,cy)作为控制点。
rect(x,y,width,height):从点(x,y)开始绘制一个矩形,宽度和高度分别由width和height指定。这个方法绘制的是矩形路径,而不是strokeRect()和fillRect()所绘制的独立的形状。
创建了路径后,接下来有集中可能的选择。如果想绘制一条连接到路径起点的线条,可以调用closePath()。如果路径已经完成,你想用fillStyle填充它,可以调用fill()方法。另外,还可以调用stroke(0方法对路径描边,描边使用的是strokeStyle。最后还可以调用clip(),这个方法可恶意在路径上创建一个剪切区域。
下面看一个例子,即绘制一个不带数字的时钟表盘。
var drawing =document.getElementById(&drawing&);
//确定浏览器支持&canvas&元素
if(drawing.getContext){
&&& var context = drawing.getContext(&2d&);
&&& //开始路径
&&& context.beginPath();
&&& //绘制外圆
&&& context.arc(100,100,99,0,2*Math.PI,false);
&&& //绘制内圆
&&& context.arc(100,100,94,0,2*Math.PI,false);
&&& //绘制分针
&&& context.moveTo(100,100);
&&& context.lineTo(100,15);
&&& //绘制时针
&&& context.moveTo(100,100);
&&& context.lineTo(35,100);
&&& //描边路径
&&& context.stroke();
在2D绘图上下文中,路径是一种主要的绘图方式,因为路径能为要绘制的图形提供更多控制。由于路径的使用很频繁,所以就有了一个名为isPointInPath()的方法。这个方法接收x和y坐标作为参数,用于在路径被关闭之前确定画布上的某一点是否位于路径上,例如:
if(context.isPointInPath(100,100)){
&&& alert(&Point (100,100) is in the path.&);
文本与图形总是如影随行。为此,2D绘图上下文也提供了绘制文本的方法。绘制文本主要有两个方法:fillText()和strokeText()。这两个方法都可以接收4个参数:要绘制的文本字符串、x坐标、y坐标和可选的最大像素宽度。而且,这两个方法都以下列3个属性为基础:
font:表示文本样式、大小及字体,用CSS中指定字体的格式来指定,例如“10px Arial”。
textAlign:表示文本对齐方式。可能的值有“start”、“end”、“left”、“right”和“center”。建议使用“start”和“end”,不要使用“left”和“right”,因为前两者的意思更稳妥,能同时适合从左到右和从右到左显示的语言。
textBaseline:表示文本的基线。可能的值有“top”、“hanging”、“middle”、“alphabetic”、“ideographic”和“buttom”。
这几个属性都有默认值,因此没必要每次使用它们都重新设置一遍值。fillText()方法使用fillStyle属性绘制文本,而strokeText()方法使用strokeStyle属性为文本描边。相对来说,还是使用fillText()的时候更多,因为该方法模仿了在网页中正常显示文本。例如,在上面的表盘中绘制数字12.
&&& context.font=&bold 14px Arial&;
&&& context.textAlign=&center&;
&&& context.textBaseline=&middle&;
&&& context.fillText(&12&,100,20);
因为这里把textAlign设置为center,把textBaseline设置为“middle”,所以坐标(100,20)表示的是文本水平和垂直中点的坐标。如果将textAlign设置为start,则x坐标表示的是文本左端的距离;设置为end,则x坐标表示的是文本有段的位置。
通过上下文的变换,可以把处理后的图像绘制到画布上。2D绘制上下文支持各种基本的绘制变换。创建绘制上下文时,会以默认值初始化变换矩阵,在默认的变换矩阵下,了所有处理都按描述直接绘制。为绘制上下文应用变换,会导致使用不同的变换矩阵应用处理,从而产生不同的结果。
可以通过如下方法来修改变换矩阵。
rotate(angle):围绕原点旋转angle弧度。
scale(csaleX,scaleY):缩放图像,在x方向乘以scaleX,在y方向乘以scaleY。scaleX和scaleY的默认值都是1.0。
translate(x,y):将坐标原点移动到(x,y)。执行这个变换之后,坐标(0,0)会变成之前由(x,y)表示的点。
transform(m1_1,m1_2,m2_1,m2_2,dx,dy):直接修改变换矩阵,方式是乘以如下矩阵。
m1_1&&&&&&& m1_2&&&&&&& dx
m2_1&&&&&&& m2_2&&&&&&& dy
0&&&&&&&&&&&&&&& 0&&&&&&&&&&&&&&& 1
setTransform(m1_1,m1_2,m2_1,m2_2,dx,dy) :将变换矩阵重置为默认状态,然后再调用transform()。
变换有可能很简单,但也有可能很复杂,这都要视情况而定。比如,就拿前面例子中绘制表针来说,如果把原点变换到表盘的中信,然后再绘制表针就容易多了。如:
var drawing =document.getElementById(&drawing&);
//确定浏览器支持&canvas&元素
if(drawing.getContext){
&&& var context = drawing.getContext(&2d&);
&&& //开始路径
&&& context.beginPath();
&&& //绘制外圆
&&& context.arc(100,100,99,0,2*Math.PI,false);
&&& //绘制内圆
&&& context.arc(100,100,94,0,2*Math.PI,false);
&&& //变换原点
&&& context.translate(100,100);
&&& //绘制分针
&&& context.moveTo(0,0);
&&& context.lineTo(0,-85);
&&& //绘制时针
&&& context.moveTo(0,0);
&&& context.lineTo(-65,0);
&&& //描边路径
&&& context.stroke();
&&& context.font=&bold 14px Arial&;
&&& context.textAlign=&center&;
&&& context.textBaseline=&middle&;
&&& context.fillText(&12&,0,-85);
还可以像下面这样使用rotate()方法旋转时钟的表针。
&&& //变换原点
&&& context.translate(100,100);
&&& context.rotate(1);
无论是刚才执行的变换,还是fillStyle、strokeStyle等属性,都会在当前上下文中一直有效,除非再对上下文进行什么修改。对冉没有什么办法把上下文中的一切都重置回默认值,但有两个方法可以跟踪上下文的状态变化。如果你知道将来还要返回某组属性与变换的组合,可以调用save()方法。调用这个方法后,当时的所有设置都会进入一个栈结构,得意妥善保管。然后可以对上下文进行其他修改。等想要回到之前保存的设置时,可以调用restore()方法,在保存设置的栈结构中向前返回一级,恢复之前的状态。连续调用save()可以把更多设置保存到栈结构中,之后再连续调用restore()则可以一级一级返回。如:
var drawing =document.getElementById(&drawing&);
//确定浏览器支持&canvas&元素
if(drawing.getContext){
&&& var context = drawing.getContext(&2d&);
&&& context.fillStyle=&#ff0000&;
&&& context.save();
&&& context.fillStyle=&#00ff00&;
&&& context.translate(100,100);
&&& context.save();
&&& context.fillStyle=&#0000ff&;
&&& context.fillRect(0,0,100,100);//从点(100,100)开始绘制蓝色矩形
&&& context.restore();
&&& context.fillRect(10,10,100,100);//从点(110,110)开始绘制绿色矩形
&&& context.restore();
&&& context.fillRect(0,0,100,100);//从点(0,0)开始绘制红色矩形
需要注意的是,save()方法保存的只是对绘图上下文的设置和变换,不会保存绘图上下文的内容。
2D绘图上下文内置了对图像的支持。如果你想把一幅图像绘制到画布上,可以使用drawImage()方法。根据期望的最终结果不同,调用这个方法时,可以使用三种不同的参数组合。最简单的调用方式是传入一个HTML&img&元素,以及绘制该图像的起点的x和y坐标。例如:
var image = document.images[0];
context.drawImage(image,10,10);
这两行代码取得了文档中的第一幅图像,然后将它绘制到上下文中,起点为(10,10)。绘制到画布上的图像与原始大小一样。如果你想改变绘制后图像的大小,可以再多传入两个参数,分别表示目标宽度和目标高度。通过这种方式来缩放图像并不影响上下文的矩阵变换。
context.drawImage(image,50,10,20,30);
执行代码后,绘制出来的图像大小会变成20x30像素。
除了上述两种方式,还可以把图像中的某个区域绘制到上下文中。drawImage()方法的这种调用方式总共需要传入9个参数:要绘制的图像、源图像的x坐标、源图像的y坐标、源图像的宽度、源图像的高度、目标图像的x坐标、目标图像的y坐标、目标图像的宽度、目标图像的高度。这样调用drawImage()方法可以获得最多的控制。
前面的文章中有模仿购物网站中放大图片的效果,这里使用canvas来实现就更加简单了,也不需要准备两张图片:
type=&text/css&&
&&& #drawing{
&&&&&&& background-color:antiquewhite;
&&& #image_{
&&&&&&& max-width:220px;
type=&text/javascript&&
&&& function showBig(image){
&&&&&&& var drawing = document.getElementById(&drawing&);
&&&&&&& if(drawing.getContext){
&&&&&&&&&&& var context = drawing.getContext(&2d&);
&&&&&&&&&&& var ptX=event.offsetX;
&&&&&&&&&&& var ptY=event.offsetY;
&&&&&&&&&&& context.drawImage(image,ptX*2.5,ptY*2.5,50,50,0,0,320,320);
id=&image_&src=&files/images/cymini.jpg&
onmousemove=&showBig(this)&&&/img&
&&& &canvas
id=&drawing&width=&320&
height=&320&&A drawing of something.&/canvas&
2D上下文会根据以下几个属性的值,自动为形状或路径绘制出阴影。
shadowColor:用CSS颜色格式表示的阴影颜色,默认为黑色。
shadowOffsetX:形状或路径X轴方向的阴影偏移量,默认为0。
shadowOffsetY:形状或路径Y轴方向的阴影偏移量,默认为0。
shadowBlur:模糊的像素数,默认0,即不模糊。
这些属性都可以通过context对象来修改。
var drawing =document.getElementById(&drawing&);
//确定浏览器支持&canvas&元素
if(drawing.getContext){
&&& var context = drawing.getContext(&2d&);
&&& context.shadowOffsetX=5;
&&& context.shadowOffsetY=5;
&&& context.shadowBlur=4;
&&& context.shadowColor=&rgba(0,0,0,0.5)&
&&& context.fillStyle=&#ff0000&;
&&& context.fillRect(10,10,50,50);
&&& context.fillStyle=&rgba(0,0,255,0.5)&;
&&& context.fillRect(30,30,50,50);
渐变由CanvasGradient实例表示,很容易通过2D上下文来创建和修改。要创建一个新的线性渐变,可以调用createLinearGradient()方法。这个方法接收4个参数:起点的x坐标、起点的y坐标、终点的x坐标、终点的y坐标。调用这个方法后,它就会创建一个指定大小的渐变,并返回CanvasGradient对象的实例。
创建了渐变对象后,下一步就是使用addColorStop()方法来指定色标。这个方法接收两个参数:色标为止和CSS颜色值。色标为止是一个0(开始的颜色)到1(结束的颜色)之间的数字。例如:
var drawing =document.getElementById(&drawing&);
//确定浏览器支持&canvas&元素
if(drawing.getContext){
&&& var context = drawing.getContext(&2d&);
&&& var gradient = context.createLinearGradient(30,30,70,70);
&&& gradient.addColorStop(0,&white&);
&&& gradient.addColorStop(1,&black&);
&&& context.shadowOffsetX=5;
&&& context.shadowOffsetY=5;
&&& context.shadowBlur=4;
&&& context.shadowColor=&rgba(0,0,0,0.5)&
&&& context.fillStyle=&#ff0000&;
&&& context.fillRect(10,10,50,50);
&&& context.fillStyle=
&&& context.fillRect(30,30,50,50);
要创建径向渐变(或放射渐变),可以使用createRadialGradient()方法。这个方法接收6个参数,对应着两个圆的圆心和半径。前三个参数指定的是起点圆心和半径,后三个参数指定的是终点圆的圆心和半径。可以把径向渐变想象成一个长圆通,而这6个参数定义的正式这个桶的两个圆形开口的为止,就可达到像旋转这个圆锥体一样的效果。
var gradient =context.createRadialGradient(55,55,10,55,55,35);
模式其实就是重复的图像,可以用来填充或描边图形。要创建一个新模式,可以调用createPattern()方法并传入两个参数:一个HTML&img&元素和一个表示如何重复图像的字符串。其中,第二个参数的值与CSS的background-repate属性值相同,包括“repeat”、“repeat-x”、“repeat-y”和“no- repeat”。
var drawing =document.getElementById(&drawing&);
&&& //确定浏览器支持&canvas&元素
&&& if(drawing.getContext){
&&&&&&& var context = drawing.getContext(&2d&);
&&&&&&& var img = document.images[0];
&&&&&&& var pattern = context.createPattern(img,&repeat&);
&&&&&&& context.fillStyle =
&&&&&&& context.fillRect(10,10,100,100);
createPattern()方法的第一个参数也可以是一个&vedio&元素,或者另一个&canvas&元素。
使用图像数据
2D上下文的一个明显的长处就是,可以通过getImageData()取得原始图像数据。这个方法接收4个参数:要取得其数据的画面区域的x和y坐标以及该区域的像素宽度和高度。例如,要取得左上角坐标为(10,5),大小为50x50像素的图像数据,可以使用如下代码:
var imageData =context.getImageData(10,5,50,50);
这里返回的对象是ImageData的实例。每个ImageData对象都有三个属性:width、height和data。其中data属性是一个数组,保存着图像中每一个像素的数据。在data数组中,每一个像素用4个元素来保存,分别表示红、绿、蓝和透明度值。因此,第一个像素的数据就保存数据的第0到第3个元素中。数组中每个元素的值都介于0到255之间。能够直接访问到原始图像数据,就能够以各种方式来操作这些数据。例如,通过修改图像数据,可以像下面这样创建一个简单的灰阶过滤器。
&&& var drawing = document.getElementById(&drawing&);
&&& //确定浏览器支持&canvas&元素
&&& if(drawing.getContext){
&&&&&&& var context = drawing.getContext(&2d&);
&&&&&&& var img = document.images[0],
&&&&&&& imageData,data,i,len,average,
&&&&&&& red,green,blue,
&&&&&&& context.drawImage(img,0,0);
&&&&&&& imageData =context.getImageData(0,0,img.width,img.height);
&&&&&&& data = imageData.
&&&&&&& for(i=0,len=data. i& i+=4){
&&&&&&&&&&& red=data[i];
&&&&&&&&&&& green=data[i+1];
&&&&&&&&&&& blue=data[i+2];
&&&&&&&&&&& alpha=data[i+3];
&&&&&&&&&&& average=Math.floor((red+green+blue)/3);
&&&&&&&&&&& data[i]=
&&&&&&&&&&& data[i+1]=
&&&&&&&&&&& data[i+2]=
&&&&&&& imageData.data=
&&&&&&& context.putImageData(imageData,0,0);
还有两个会应用到2D上下问中所有绘制操作的属性:globalAlpha和globalCompositionOperation。其中,globalAlpha是一个介于0到1之间的值,用于指定所有绘制的透明度。默认值为0.如果所有后续操作都要基于相同的透明度,就可以先把globalAlpha设置为适当的值。然后绘制,最后再把它设置回默认值0.
第二个属性globalCompositionOperation表示后绘制的图形怎样与先绘制的图形结合。这个属性的值是字符串,可能的值如下:
source-over(默认值):后绘制的图形位于先绘制的图形上方。
source-in:后绘制的图形与先绘制的图形重叠的部分可见,两者其他部分完全透明。
source-out:后绘制的图形与先绘制的图形不重叠的部分可见,先绘制的图形完全透明。
source-atop:后绘制的图形与先绘制的图形不重叠的部分可见,先绘制的图形不受影响。
destination-over:后绘制的图形位于先绘制的图形下方,只有之前透明像素下的部分才可见。
destination-in:后绘制的图形位于先绘制的图形下方,两者不重叠的部分完全透明。
destination-out:后绘制的图形擦除与先绘制的图形重叠的部分。
destination-atop:后绘制的图形位于先绘制的图形下方,在两者不重叠的地方,先绘制的图形会变透明。
lighter:后绘制的图形与先绘制的图形重叠部分的值相加,使该部分变亮。
copy:后绘制的图形完全替代与之重叠的先绘制图形。
xor:后绘制的图形与先绘制的图形重叠的部分执行“异或”操作。
WebGL是针对Canvas的3D上下文。与其他Web技术不同,WebGL并不是W3C制定的标准,而是由KhronosGroup制定的。学习网址:。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:53939次
积分:1441
积分:1441
排名:千里之外
原创:92篇
(1)(1)(4)(4)(10)(9)(6)(5)(11)(14)(15)(16)(1)(1)(1)}

我要回帖

更多关于 希捷dashboard怎么用 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信