Canvas是HTML5添加的新元素,这个元素负责在页面中设定一个区域,然后通过JavaScript动态的在这个区域绘制图形。<canvas>由几组API组成,除了具备基本绘图能力的2D上下文,<canvas>还建议了一个名为WebGL的3D上下文,目前,支持该元素的浏览器都支持2D上下文,但对WebGL的支持还不够好。以下仅介绍2D上下文。

一、2D上下文

1、进行填充和描边

  2D上下文的两种基本绘图操作是填充和描边;填充,是指的用指定的样式填充图形;描边,就是只在图像边缘划线。下例中绘制的矩形,是唯一一种可以直接在2D上下文绘制的图形。

<!doctype html>
<html>
    <head>
    <meta charset = "utf-8">
        <title>填充和描边</title>
    </head>
    <body>
    <!-- 出现在开始和结束标签中的是后备信息,如果浏览器不支持,就会显示: A drawing of something.-->
        <canvas id="drawing" height="400" width="400">A drawing of something.</canvas>
    <script>
        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);

            // 绘制红色描边的矩形
            context.strokeStyle = "#ff0000";
            context.strokeRect(50,50,50,50);

            // 绘制半透明蓝色描边的矩形
            context.strokeStyle = "rgba(0,0,255,0.5)";
            context.strokeRect(70,70,50,50);
        }
    </script>
    </body>
</html>

2、绘制路径和文本

  2D上下文支持很多在画布上绘制路径的方法,通过路径可以创建出复杂的线条的形状。

<!doctype html>
<html>
    <head>
    <meta charset = "utf-8">
        <title>绘制路径和文本</title>
    </head>
    <body>
    <!-- 出现在开始和结束标签中的是后备信息,如果浏览器不支持,就会显示: A drawing of something.-->
        <canvas id="drawing" height="400" width="400">A drawing of something.</canvas>
    <script>
        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.moveTo(194,100);  //移动绘图游标,不移动则内圆和外圆的线条相连
        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);        

        // 确定路径被关闭前,某一点是否在路径上
        if(context.isPointInPath(100,100)){
            // alert("Point (100,100) is not in the path");
        }

        // 描边路径
        context.stroke();
//---------------------------------------------------------------------------------
        // 绘制文本
        context.font = "bold 14px Arial";
        context.textAlign = "center";  //正常
        context.textBaseline = "middle";
        context.fillText("12",100,20);

        context.textAlign = "start";  //x表示的是文本的起始位置
        context.fillText("12",100,40);

        context.textAlign = "end";  //x表示的是文本的结束位置
        context.fillText("12",100,60);

//------------------------------------------------------------------------------
// 如果要在140px宽的区域中绘制文本,下面的像素从100px开始递减,最终找到合适的字体大小
        var fontSize = 100;
        context.font = fontSize+"px Arial";
        while(context.measureText("Hello World").width > 140){
            fontSize--;
            context.font = fontSize+"px Arial";
        }
        context.fillText("Hello World", 210,210);
        }
    </script>
    </body>
</html>

3、变换

  2D上下文支持各种基本的绘制变换;创建绘制上下文时,会以默认值初始化变换矩阵;使用不同的变换矩阵应用处理,会产生不同的结果。

<!doctype html>
<html>
<!--
2D绘制上下文支持以下的绘制变换
rotate(angle):围绕原点旋转图像angle角度
scale(scaleX, scaleY):缩放图像,在x轴上乘以scaleX, 在Y轴上乘以scaleY
translate(x, y):将原点坐标移动到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
 -->
    <head>
    <meta charset = "utf-8">
        <title>旋转时钟的指针</title>
    </head>
    <body>
    <!-- 出现在开始和结束标签中的是后备信息,如果浏览器不支持,就会显示: A drawing of something.-->
        <canvas id="drawing" height="400" width="400">A drawing of something.</canvas>
    <script>
        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.moveTo(194,100);
            context.arc(100,100,94,0,2*Math.PI,false);

            // 变换原点
            context.translate(100,100);
            // 旋转表针
            context.rotate(1);

            // 绘制分针
            context.moveTo(0,0);
            context.lineTo(0,-85);

            // 绘制时针
            context.moveTo(0,0);
            context.lineTo(-65,0);        

            context.stroke();
        }
    </script>
    </body>
</html>

4、绘制图像和模式

  2D上下文内置了对图像的支持;模式实际上是重复的图像,可以用来填充或描边图形。

<!doctype html>
<html>
    <head>
    <meta charset = "utf-8">
        <title>绘制图像/模式</title>
    </head>
    <body onload="drawPic()">
        <img src="data:image1.png" alt="" id="myImg"/>
        <canvas id="drawing" height="400" width="400" style="border:1px solid #d3d3d3;">A drawing of something.</canvas>

    <script>
    function drawPic(){
        var drawing = document.getElementById("drawing");
        var image = document.getElementById("myImg");

        // 确认浏览器支持canvas元素
        if(drawing.getContext){

            // 绘制图片
            var context = drawing.getContext("2d");
            context.drawImage(image, 50,10,20,30);

            // 使用模式重复绘制图片
            // 创建模式,在一个矩形区域重复显示图像
            var    pattern = context.createPattern(image, "repeat");
            context.fillStyle = pattern;
            context.fillRect(100,100,100,100);

        }
    }
    </script>
    </body>
</html>

5、阴影和渐变

  不同浏览器对阴影的支持有一些差异,有些甚至根本不支持阴影;可以通过createLinearGradient和createRadialGradient创建线性渐变和径向渐变。

<!doctype html>
<html>
    <head>
    <meta charset = "utf-8">
        <title>阴影和渐变</title>
    </head>
    <body>
        <canvas id="drawing" height="400" width="400" style="border:1px solid #d3d3d3;">A drawing of something.</canvas>

    <script>
        var drawing = document.getElementById("drawing");
        var context = drawing.getContext("2d");

        //设置阴影
        context.shadowOffsetX = 5;  //x轴方向的阴影偏移量
        context.shadowOffsetY = 5;  //y轴方向的阴影偏移量
        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,1)";
        context.fillRect(30,30,50,50);        

        // 设置线性渐变
        var gradient = context.createLinearGradient(100,100,150,150);
        gradient.addColorStop(0,"white");
        gradient.addColorStop(1,"black");

        context.fillStyle = gradient;
        context.fillRect(100,100,50,50);    

        // 设置径向渐变
        gradient = context.createRadialGradient(175,175,10,175,175,30);
        gradient.addColorStop(0,"white");
        gradient.addColorStop(1,"black");

        context.fillStyle = gradient;
        context.fillRect(150,150,50,50);

    </script>
    </body>
</html>

6、使用图像数据

  2D上下文可以通过getImageData()取得原始图像数据,并对其中的每一个像素进行处理;注意这个函数操作的图像和html文件需要在同一个域,否则会有跨域问题。下例是一个简单的灰阶过滤器。

<!doctype html>
<html>
    <head>
    <meta charset = "utf-8">
        <title>灰阶过滤器</title>
    </head>
    <body onload = "filter()">
        <img src="data:image1.png" alt="" id="myImg"/>
        <canvas id="drawing" height="400" width="400" style="border:1px solid #d3d3d3;">A drawing of something.</canvas>

    <script>
        function filter(){
            var drawing = document.getElementById("drawing");

        if(drawing.getContext){
            var context = drawing.getContext("2d"),
                image = document.images[0];

//             绘制原始图像
            context.drawImage(image, 0,0);

            // 取得图像数据
            var imageData = context.getImageData(0,0,image.width,image.height);
            var data = imageData.data;

            for(var i = 0, len = data.length;i<len;i+=4){
                // 每个data数组中,都有四个元素红、绿、蓝和透明度的值
                var red = data[i],
                    green = data[i+1],
                    blue = data[i+2],
                    alpah = data[i+3];

                    // 求rgb的平均值
                var average = Math.floor((red+green+blue)/3);

                // 设置颜色值、透明度不变
                data[i] = average;
                data[i+1] = average;
                data[i+2] = average;
            }
            // 回写图像数据并显示结果
            imageData.data = data;
            context.putImageData(imageData,0,0);
        }
        }
    </script>
    </body>
</html>

7、合成

  globalAlpha是一个介于0和1之间的值(包括0和1),用于指定所有绘制的透明度;globalCompositionOperation表示绘制后的图像怎么与先绘制的图形结合。

<!doctype html>
<html>
    <head>
    <meta charset = "utf-8">
        <title>合成</title>
    </head>
    <body>
        <canvas id="drawing" height="400" width="400" style="border:1px solid #d3d3d3;">A drawing of something.</canvas>

    <script>
            var drawing = document.getElementById("drawing");

        if(drawing.getContext){
            var context = drawing.getContext("2d");

            context.fillStyle = "#ff0000";
            context.fillRect(10,10,50,50);

            // 设置合成操作
            context.globalCompositeOperation = "destination-over";
            // 后绘制的图像位于先绘制的图像下方 

            context.fillStyle = "rgba(0,0,255,1)";
            context.fillRect(30,30,50,50);
        }
    </script>
    </body>
</html>

《JAVASCRIPT高级程序设计》Canvas绘图-2D上下文的更多相关文章

  1. 15. javacript高级程序设计-Canvas绘图

    1. Canvas绘图 HTML5的<canvas>元素提供了一组JavaScript API,让我们可以动态的创建图形和图像.图形是在一个特定的上下文中创建的,而上下文对象目前有两种. ...

  2. JavaScript高级程序设计第三版.CHM【带实例】

    从驱动全球商业.贸易及管理领域不计其数的复杂应用程序的角度来看,说 JavaScript 已经成为当今世界上最流行的编程语言一点儿都不为过. JavaScript 是一种非常松散的面向对象语言,也是 ...

  3. JavaScript高级程序设计(第4版)知识点总结

    介绍 JavaScript高级程序设计 第四版,在第三版的基础上添加了ES6相关的内容.如let.const关键字,Fetch API.工作者线程.模块.Promise 等.适合具有一定编程经验的 W ...

  4. 《JavaScript高级程序设计(第3版)》阅读总结记录第一章之JavaScript简介

    前言: 为什么会想到把<JavaScript 高级程序设计(第 3 版)>总结记录呢,之前写过一篇博客,研究的轮播效果,后来又去看了<JavaScript 高级程序设计(第3版)&g ...

  5. 赠书《JavaScript高级程序设计(第三版)》5本

    本站微博上正在送书<JavaScript高级程序设计>走过路过的不要错过,参与方式,关注本站及简寻网+转发微博:http://weibo.com/1748018491/DoCtp6B8r ...

  6. javascript高级程序设计学习笔记

    javascript高级程序设计,当枕头书已经好久了~zz  现在觉得自己在js的开发上遇到了一些瓶颈,归根究底还是基础太薄弱,所以重新刷一遍js高程希望有更新的认识. 一.javascript简介 ...

  7. 《JavaScript高级程序设计(第3版)》笔记-序

    很少看书,不喜欢看书,主要是上学时总坐不住,没有多大定性,一本书可以两天看完,随便翻翻,也可以丢在角落里几个月不去动一下. 上次碰到了<JavaScript高级程序设计(第3版)>感觉真的 ...

  8. 【javascript学习——《javascript高级程序设计》笔记】DOM操作

    DOM(文档对象模型)是针对HTML和XML文档的一个API(应用程序编程接口).DOM描绘了一个层次节点树,允许开发人员添加.移除和修改. 1.节点层次 <html> <head& ...

  9. 读javascript高级程序设计00-目录

    javascript高级编程读书笔记系列,也是本砖头书.感觉js是一种很好上手的语言,不过本书细细读来发现了很多之前不了解的细节,受益良多.<br/>本笔记是为了方便日后查阅,仅作学习交流 ...

随机推荐

  1. css3的box-sizing--从此不用担心盒模型的不兼容

    前段时间阿里的面试问了关于盒模型的东西,众所周知,ie和标准盒模型是有着区别的.面试官问有没有什么办法可以改变盒模型的显示效果.答案是css3的box-sizing: 其可以取三个值: 1.值cont ...

  2. js优化与注意点

    1.使用尽可能少的全局变量.尽量用var来声明变量,避免隐式使用全局变量. 隐式全局变量和明确定义的全局变量间有些小的差异,就是通过delete操作符让变量未定义的能力. 通过var创建的全局变量(任 ...

  3. iOS查错机制

    转自: http://mp.weixin.qq.com/s?__biz=MjM5OTM0MzIwMQ==&mid=404478233&idx=2&sn=ae55d4f70fce ...

  4. 如何获取app的素材,做出一个高仿的app

    第一步:在iTunes中搜索你想要的app,然后点击下载: 下载完成之后右键点击:在Finder中显示 在finder中右键用"归档工具打开" 会显示如下内容: "显示包 ...

  5. Blog开始

    好久没更新Blog了,去看了下之前的csdn的blog感觉特别的乱,为此决心重开blog,记录工作及学习中的一些事 2013-10-28 ymc ...

  6. lvs(+keepalived)、haproxy(+heartbeat)、nginx 负载均衡的比较分析

    目前使用比较多的就是标题中提到的这两者,其实lvs和haproxy都是实现的负载均衡的作用,keepalived和heartbeat都是提高高可用性的,避免单点故障.那么他们为什么这么搭配,而又有什么 ...

  7. python数据类型之 dict(map)

    字典  一.创建字典  方法①:  >>> dict1 = {}  >>> dict2 = {'name': 'earth', 'port': 80}  >& ...

  8. mysql中SQL执行过程详解与用于预处理语句的SQL语法

    mysql中SQL执行过程详解 客户端发送一条查询给服务器: 服务器先检查查询缓存,如果命中了缓存,则立刻返回存储在缓存中的结果.否则进入下一阶段. 服务器段进行SQL解析.预处理,在优化器生成对应的 ...

  9. FireBug 调试工具(推荐)

    Firebug是网页浏览器 Mozilla Firefox 下的一款开发类扩展,如同一把精巧的瑞士军刀,从各个不同的角度剖析Web页面内部的细节层面,给Web开发者带来很大的便利. 安装如下: 下面是 ...

  10. [转载] centos6.x x64 安装python2.7

    本文转载自: http://www.centoscn.com/image-text/install/2016/0323/6906.html CentOS的设计理念中有一点是:持久可用.要达到这个目的, ...