学习第十天(2019-11-23)

第十五章 使用Canvas绘图javascript

HTML5添加的<canvas>元素负责在页面中设定一个区域,而后就能够经过JavaScript动态地在这个区域中绘制图形。      如:<canvas id="drawing" width=" 200" height="200">A drawing of something.</canvas> html

在使用<canvas>元素以前,首先要检测getContext()方法是否存在,这一步很是重要。有些浏览器会为HTML规范以外的元素建立默认的HTML元素对象。在这种状况下,即便 drawing 变量中保存着一个有效的元素引用,也检测不到 getContext()方法。java

1、使用2D上下文web

    使用2D绘图上下文提供的方法,能够绘制简单的2D图形,好比矩形、弧线和路径。2D上下文的坐标开始于<canvas>元素的左上角,原点坐标是(0,0)。全部坐标值都基于这个原点计算,x值越大表示越靠右,y值越大表示越靠下。默认状况下,width和height表示水平和垂直两个方向上可用的像素数目。 编程

一、填充和描边 canvas

   填充和描边两个操做取决于两个属性:fillStyle 和 strokeStyle。这两个属性的值能够是字符串、渐变对象或模式对象,并且它们的默认值都是"#000000"。数组

二、绘制矩形浏览器

  与矩形有关的方法包括 fillRect()、 strokeRect()和 clearRect()。服务器

   fillRect()方法在画布上绘制的矩形会填充指定的颜色,填充的颜色经过fillStyle属性指定;strokeRect()方法在画布上绘制的矩形会使用指定的颜色描边,描边颜色经过strokeStyle属性指定,clearRect()方法用于清除画布上的矩形区域。app

   下面是一个例子:

1 <html>
2 <head> 
3 <script type="text/javascript" src="myscript.js"></script>
4 </head>
5 <body>
6 <canvas id="drawing" width=" 200" height="200">A drawing of something.</canvas>
7 </body>
8 </html>
 1 window.onload = function(){
 2    var drawing = document.getElementById("drawing"); 
 3 //肯定浏览器支持<canvas>元素 
 4    if(drawing.getContext){ 
 5       var context = drawing.getContext("2d");
 6       //绘制红色矩形  
 7       context.fillStyle = "#ff0000";
 8       context.fillRect(10, 10, 50, 50);
 9       //绘制半透明的蓝色矩形
10       context.fillStyle = "rgba(0,0,255,0.5)";
11       context.fillRect(30, 30, 50, 50); 
12       //绘制黑色描边矩形
13       context.strokeStyle = "#000000";     
14       context.strokeRect(10, 10, 50, 50); 
15       //绘制半透明的绿色描边矩形
16       context.strokeStyle = "rgba(0,255,0,0.5)";
17       context.strokeRect(30, 30, 50, 50);
18       //在两个矩形重叠的地方清除一个小矩形
19       context.clearRect(40, 40, 10, 10); 
20    } 
21 }

效果图:

 

 

 三、绘制路径 

    要绘制路径,首先必须调用beginPath()方法,而后可调用其余方法绘制路径,经常使用方法(省略了参数):arc()、arcTo()、bezierCurveTo()、lineTo()、moveTo()、quadraticCurveTo()、rect()。

  如绘制一个不带数字的时钟表盘:

 1 window.onload = function(){
 2    var drawing = document.getElementById("drawing");  
 3    //肯定浏览器支持<canvas>元素
 4    if(drawing.getContext){ 
 5        var context = drawing.getContext("2d"); 
 6        //开始路径
 7        context.beginPath(); 
 8        //绘制外圆
 9        context.arc(100, 100, 99, 0, 2 * Math.PI, false); 
10        //绘制内圆
11        //在绘制内圆以前,须把路径移动到内圆上的某一点,避免绘制出多余的线条。
12        context.moveTo(194, 100);
13        context.arc(100, 100, 94, 0, 2 * Math.PI, false); 
14        //绘制分针
15        context.moveTo(100, 100);
16        context.lineTo(100, 15); 
17        //绘制时针
18        context.moveTo(100, 100);
19        context.lineTo(35, 100);  
20        //描边路径 
21        context.stroke();
22    } 
23 }

效果图:

 

四、绘制文本 

  绘制文本主要有两个方法:fillText()和strokeText()。这两个方法均可以接收4个参数:要绘制的文本字符串、x坐标、y坐标和可选的大像素宽度。

  因为绘制文本比较复杂,特别是须要把文本控制在某一区域中的时候,2D上下文提供了辅助肯定文本大小的方法measureText()。这个方法接收一个参数,即要绘制的文本,返回一个TextMetrics 对象。返回的对象目前只有一个 width 属性,但未来还会增长更多度量属性。

  measureText()方法利用 font、textAlign和textBaseline的当前值计算指定文本的大小,假如想在一个140像素宽的矩形区域中绘制文本Hello world!,下面的代码从100像素的字体大小开始递减,最终找到合适的字体大小。

1 var fontSize = 100; context.font = fontSize + "px Arial";  
2 while(context.measureText("Hello world!").width > 140){
3      fontSize--;
4      context.font = fontSize + "px Arial";
5 } 
6 context.fillText("Hello world!", 10, 10);
7 context.fillText("Font size is " + fontSize + "px", 10, 50); 

五、变换

经过上下文的变换,能够把处理后的图像绘制到画布上。经常使用方法: 

rotate(angle):围绕原点旋转图像 angle 弧度;
scale(scaleX, scaleY):缩放图像;
translate(x,y):将坐标原点移动到(x,y);
transform(m1_1, m1_2, m2_1, m2_2, dx, dy):直接修改变换矩阵,
setTransform(m1_1, m1_2, m2_1, m2_2, dx, dy):将变换矩阵重置为默认状态,而后再调用transform()。

 例如:能够把原点变换到时钟表盘的中心点(100,100),全部数学计算都基于(0,0),而不是(100,100)。还可使用 rotate()方法旋转时钟的表针。 

 

 代码以下:

 1 window.onload = function(){
 2    var drawing = document.getElementById("drawing"); 
 3 //肯定浏览器支持<canvas>元素
 4    if(drawing.getContext){ 
 5      var context = drawing.getContext("2d"); 
 6      //开始路径
 7      context.beginPath();  
 8      //绘制外圆
 9      context.arc(100, 100, 99, 0, 2 * Math.PI, false);  
10      //绘制内圆
11      context.moveTo(194, 100);
12      context.arc(100, 100, 94, 0, 2 * Math.PI, false); 
13      //变换原点
14      context.translate(100, 100); 
15      //旋转表针
16      context.rotate(1); 
17      //绘制分针 
18      context.moveTo(0,0);
19      context.lineTo(0, -85); 
20      //绘制时针
21      context.moveTo(0, 0);
22      context.lineTo(-65, 0); 
23      //描边路径
24      context.stroke();
25    } 
26 }

效果图:

 

  不管是刚才执行的变换,仍是fillStyle、strokeStyle 等属性,都会在当前上下文中一直有效, 除非再对上下文进行什么修改,经过save()、 restore()方法可保存和恢复上下文,这两个方法经过一个栈来实现。

六、绘制图像 

   若是想把一幅图像绘制到画布上,可使用drawImage()方法,结合其余方法,能够对图像进行各类基本操做,操做的结果能够经过 toDataURL()方法得到,有一个例外,即图像不能来自其余域。若是图像来自其余域,调用 toDataURL()会抛出一个错误。

七、阴影

 2D上下文会根据如下几个属性的值,自动为形状或路径绘制出阴影。

   shadowColor:用CSS颜色格式表示的阴影颜色,默认为黑色;
   shadowOffsetX:形状或路径x轴方向的阴影偏移量,默认为0。
   shadowOffsetY:形状或路径y轴方向的阴影偏移量,默认为0。
   shadowBlur:模糊的像素数,默认0,即不模糊。

八、渐变

   渐变由 CanvasGradient 实例表示,很容易经过 2D上下文来建立和修改。要建立一个新的线性渐变,能够调用createLinearGradient()方法; addColorStop()方法用来指定渐变的色标。

   以下是一个例子:

 1 window.onload = function(){
 2    //这个函数基于起点的x和y坐标以及宽度和高度来建立渐变对象,使得在fillRect()中可用相同的值,便于控制。 
 3    function createRectLinearGradient(context, x, y, width, height){
 4       return context.createLinearGradient(x, y, x+width, y+height);
 5    }
 6    var drawing = document.getElementById("drawing"); 
 7    if(drawing.getContext){ 
 8        var context = drawing.getContext("2d"); 
 9        //绘制红色矩形
10        context.fillStyle = "#ff0000";
11        context.fillRect(10, 10, 50, 50); 
12        var gradient = createRectLinearGradient(context, 30, 30, 50, 50);  
13        gradient.addColorStop(0, "white");
14        gradient.addColorStop(1, "black"); 
15        //绘制渐变矩形
16        context.fillStyle = gradient;
17        context.fillRect(30, 30, 50, 50); 
18    }
19 }

效果图:

 

若是要建立径向渐变(或放射渐变),可使用 createRadialGradient()方法。

代码:

window.onload = function(){
   var drawing = document.getElementById("drawing"); 
   if(drawing.getContext){ 
       var context = drawing.getContext("2d"); 
       var gradient = context.createRadialGradient(55, 55, 10, 55, 55, 30); 
       gradient.addColorStop(0, "white"); gradient.addColorStop(1, "black"); 
       //绘制红色矩形
       context.fillStyle = "#ff0000";
       context.fillRect(10, 10, 50, 50); 
       //绘制渐变矩形
       context.fillStyle = gradient;
       context.fillRect(30, 30, 50, 50);  
   }
}

效果图:

 

九、模式

模式其实就是重复的图像,能够用来填充或描边图形。要建立一个新模式,能够调用 createPattern()方法并传入两个参数:一个 HTML<img>元素和一个表示如何重复图像的字符串。

十、使用图像数据

    2D上下文的一个明显的长处就是,能够经过 getImageData()取得原始图像数据。这个方法接收 4个参数:要取得其数据的画面区域的x和y坐标以及该区域的像素宽度和高度。

    例如,要取得左上角坐标为(10,5)、大小为 50×50像素的区域的图像数据,可使用如下代码:
        var imageData = context.getImageData(10, 5, 50, 50); 

    这里返回的对象是ImageData的实例。每一个ImageData对象都有三个属性:width、height和data。其中data属性是一个数组,保存着图像中每个像素的数据。在data数组中,每个像素用4个元素来保存,分别表示红、绿、蓝和透明度值。所以,第一个像素的数据就保存在数组的第0到第3个元素中能够据此直接操做原始图像数据。

十一、合成

    还有两个会应用到 2D上下文中全部绘制操做的属性:globalAlpha 和 globalComposition-Operation。

   其中,globalAlpha 是一个介于 0和 1之间的值(包括0和1),用于指定全部绘制的透明度。默认值为0。若是全部后续操做都要基于相同的透明度,就能够先把 globalAlpha设置为适当值,而后绘制,后再把它设置回默认值0。

  globalCompositionOperation属性则表示后绘制的图形怎样与先绘制的图形结合。这个属性的值是字符串。

 

2、WebGL

 WebGL上下文是一种3D上下文。WebGL是从OpenGL ES 2.0移植到浏览器中的,OpenGL ES 2.0是游戏开发人员在建立计算机图形图像时常用的一种语言。

 WebGL支持比 2D上下文更丰富 和更强大的图形图像处理能力,好比:

         a、用GLSL编写的顶点和片断着色器;
         b、支持类型化数组,即可以将数组中的数据限定为某种特定的数值类型;
         c、建立和操做纹理;        

 从稳妥的角度考虑,在使用 WebGL以前,最好检测其是否获得了支持。WebGL 仍是一个正在制定和发展中的规范。无论是函数名、函数签名,仍是数据类型,都有可能改变。能够说,WebGL目前只适合实验性地学习,不适合真正开发和应用。 

 

第十六章、HTML5脚本编程

    HTML5除了定义了新的标记规则,还定义了一些 JavaScript API。这些 API是为了让开发人员建立出更好的、可以与桌面应用媲美的用户界面而设计的。

1、跨文档消息传递

    跨文档消息传送,有时候简称为XDM,指的是在来自不一样域的页面间传递消息。

   XDM的核心是postMessage()方法。在HTML5规范中,除了XDM部分以外的其余部分也会提到这个方法名,但都是为了同一个目的:向另外一个地方传递数据。对于XDM而言,“另外一个地方”指的是包含在当前页面中的<iframe>元素,或者由当前页面弹出的窗口。 

   接收到 XDM消息时,会触发 window 对象的message事件。这个事件是以异步形式触发的。

2、原生拖放

   原生拖放功能让咱们能够方便地指定某个元素可拖动,并在操做系统要放置时作出响应。还能够建立自定义的可拖动元素及放置目标。

   一、 与拖放相关的事件有:dragstart、drag、dragend、dragenter、dragover、dragleave(或drop);

   二、 dataTransfer 对象,它是事件对象的一个属性,用于从被拖动元素向放置目标传递字符串格式的数据。dataTransfer对象有两个主要方法:getData()和 setData()。

      如:

             //设置和接收文本数据
              event.dataTransfer.setData("text", "some text");
              var text = event.dataTransfer.getData("text");
            //设置和接收 URL
              event.dataTransfer.setData("URL", "http://www.wrox.com/"); 
              var url = event.dataTransfer.getData("URL");

    三、利用 dataTransfer 对象,还能经过它来肯定被拖动的元素以及做为放置目标的元素可以接收什么操做。为此,须要访问dataTransfer对象的两个属性:dropEffect和 effectAllowed。

   四、HTML5还为全部 HTML元素规定了一个 draggable属性,表示元素是否能够拖动。

3、媒体元素 

    HTML5新增了<audio>和<video>这两个与媒体相关的标签,让开发人员没必要依赖任何插件就能在网页中嵌入跨浏览器的音频和视频内容。 

    用法以下:

<!-- 嵌入视频 --> 
<video src="conference.mpg" id="myVideo">Video player not available.</video> 
<!-- 嵌入音频 --> 
<audio src="song.mp3" id="myAudio">Audio player not available.</audio> 

   使用这两个元素时,至少要在标签中包含src属性,指向要加载的媒体文件。还能够设置width和height属性以指定视频播放器的大小,而为poster属性指定图像的URI能够在加载视频内容期间显示一幅图像。另外,若是标签中有controls属性,则意味着浏览器应该显示UI控件,以便用户直接操做媒体。

   由于并不是全部浏览器都支持全部媒体格式,因此能够指定多个不一样的媒体来源。为此,不用在标签中指定src 属性,而是要像下面这样使用一或多个<source>元素。 

<!-- 嵌入视频 -->
<video id="myVideo">
    <source src="conference.webm" type="video/webm; codecs='vp8, vorbis'">
    <source src="conference.ogv" type="video/ogg; codecs='theora, vorbis'">
    <source src="conference.mpg">
    Video player not available.
</video>
<!-- 嵌入音频 -->
<audio id="myAudio">
    <source src="song.ogg" type="audio/ogg">
    <source src="song.mp3" type="audio/mpeg">
    Audio player not available.
</audio>

  这两个媒体元素有许多属性,还能够触发不少的事件。使用<audio>和<video>元素的 play()和 pause()方法,能够手工控制媒体文件的播放。组合使用属性、事件和这两个方法,很容易建立一个自定义的媒体播放器,以下面的例子所示。

  <div class="mediaplayer">
    <div class="video">
       <video id="player" src="movie.mov" poster="mymovie.jpg"             width="300" height="200">
         Video player not available.
       </video>
    </div>
    <div class="controls">
       <input type="button" value="Play" id="video-btn">
       <span id="curtime">0</span>/<span id="duration">0</span>
    </div>
  </div>
   //取得元素的引用
   var player = document.getElementById("player"),
       btn = document.getElementById("video-btn"),
       curtime = document.getElementById("curtime"),
       duration = document.getElementById("duration");
   //更新播放时间
   duration.innerHTML = player.duration;
   //为按钮添加事件处理程序
   EventUtil.addHandler(btn, "click", function(event){
    if (player.paused){
        player.play();
        btn.value = "Pause";
    } else {
        player.pause();
        btn.value = "Play";
    }
   });
   //定时更新当前时间
   setInterval(function(){
    curtime.innerHTML = player.currentTime;
   }, 250);

     以上JavaScript代码给按钮添加了一个事件处理程序,单击它能让视频在暂停时播放,在播放时暂停。经过<video>元素的load事件处理程序,设置了加载完视频后显示播放时间。最后,设置了一个 计时器,以更新当前显示的时间。

 4、历史状态管理

     历史状态管理让咱们没必要卸载当前页面便可修改浏览器的历史状态栈。有了这种机制,用户就能够经过“后退”和“前进”按钮在页面状态间切换,而这些状态彻底由JavaScript进行控制。要管理历史状态首选使用hashchange事件。HTML5经过更新history对象为管理历史状态提供了方便。 

 

第十七章 错误处理与调试 

 1、错误处理

   一、try-catch语句 

      常见用法:

1 try {// 可能会致使错误的代码
2     window.someNonexistentFunction();
3 } catch (error){ // 在错误发生时怎么处理
4     alert(error.message);
5 }

 二、finally 子句

 finally在try-catch语句中是可选的,但finally子句一经使用,其代码不管如何都会执行。注意,只要代码中包含finally子句,那么不管 try仍是catch语句块中的return语句都将被忽略。所以,在使用finally子句以前,必定要很是清楚你想让代码怎么样。 

1 function testFinally(){
2     try {
3         return 2;
4     } catch (error){
5         return 1;
6     } finally {
7         return 0;
8     }
9 }

上述代码,执行后函数会返回0。

三、错误类型 

ECMA-262 定义了下列7种错误类型:Error、EvalError、RangeError、ReferenceError、SyntaxError、TypeError、URIError。

Error是基类型,其余错误类型都继承自该类型。

四、抛出错误

  与try-catch语句相配的还有一个throw操做符,用于随时抛出自定义错误。抛出错误时,必须 要给throw操做符指定一个值,这个值是什么类型,没有要求。

  在遇到throw操做符时,代码会当即中止执行。仅当有try-catch语句捕获到被抛出的值时,代码才会继续执行。

      抛出错误示范:throw new Error("Something bad happened."); 

  还能够建立抛出自定义的错误,下面是利用原型链继承Error来建立自定义错误类型:

1 //建立自定义错误类型
2 function CustomError(message){
3     this.name = "CustomError";
4     this.message = message;
5 }
6 CustomError.prototype = new Error();
7 throw new CustomError("My message");

 抛出错误的时机:应该在出现某种特定的已知错误条件,致使函数没法正常执行时抛出错误,如:

 1 function process(values){
 2     if (!(values instanceof Array)){
 3         throw new Error("process(): Argument must be an array.");
 4     }
 5     values.sort();
 6     for (var i=0, len=values.length; i < len; i++){
 7         if (values[i] > 100){
 8             return values[i];
 9         }
10     }
11     return -1;
12 }

五、错误(error)事件

任何没有经过try-catch处理的错误都会触发window对象的error事件。要指定onerror事件处理程序,必须使用以下所示的DOM0级技术,它没有遵循“DOM2级事件”的标准格式。 

window.onerror = function(message, url, line){
    alert(message);
};

 图像也支持 error 事件。只要图像的src特性中的URL不能返回能够被识别的图像格式,就会触发error事件。此时的error事件遵循 DOM格式,会返回一个以图像为目标的event对象,下面是 一个例子。

1 var image = new Image();
2 EventUtil.addHandler(image, "load", function(event){
3     alert("Image loaded!");
4 });
5 EventUtil.addHandler(image, "error", function(event){
6     alert("Image not loaded!");
7 });
8 image.src = "smilex.gif"; //指定不存在的文件

在这个例子中,当加载图像失败时就会显示一个警告框。须要注意的是,发生error事件时,图像下载过程已经结束,也就是说不能再从新下载了。 

六、常见的致使错误的类型:

      a、类型转换错误:类型转换错误发生在使用某个操做符,或者使用其余可能会自动转换值的数据类型的语言结构时。在使用相等            (==)和不相等(!=)操做符,或者在 if、 for 及 while 等流控制语句中使用非布尔值时,最常发生类型转换错误。
      b、数据类型错误:在将预料以外的值传递给函数的状况下,最容易发生数据类型错误。
      c、通讯错误:第一种通讯错误与格式不正确的 URL 或发送的数据有关。最多见的问题是在将数据发送给服务器以前,没有使用                encodeURIComponent()对数据进行编码。 另外,在服务器响应的数据不正确时,也会发生通讯错误。

七、非致命错误:不影响用户的主要任务;只影响页面的一部分;能够恢复;重复相同操做能够消除错误。
      致命错误: 应用程序根本没法继续运行; 错误明显影响到了用户的主要操做; 会致使其余连带错误。 

八、开发 Web 应用程序过程当中的一种常见的作法,就是集中保存错误日志,以便查找重要错误的缘由。推荐把JavaScript错误回写到服务器。

2、调试技术 

 一、将消息记录到控制台 

    对 IE八、 Firefox、 Chrome 和 Safari 来讲,能够经过 console 对象向 JavaScript 控制台中写入消息,这个对象具备下列方法。
        a、error(message):将错误消息记录到控制台
        b、info(message):将信息性消息记录到控制台
        c、log(message):将通常消息记录到控制台
        d、warn(message):将警告消息记录到控制台

 如:

function sum(num1, num2){
    console.log("Entering sum(), arguments are " + num1 + "," + num2);
    console.log("Before calculation");
    var result = num1 + num2;
    console.log("After calculation");
    console.log("Exiting sum()");
    return result;
}

   还有一种方案是使用 LiveConnect,也就是在 JavaScript 中运行Java代码。 Firefox、 Safari 和 Opera都支持LiveConnect,所以能够操做Java 控制台。

1 function sum(num1, num2){
2     java.lang.System.out.println("Entering sum(), arguments are " + num1 + "," + num2);
3     java.lang.System.out.println("Before calculation");
4     var result = num1 + num2;
5     java.lang.System.out.println("After calculation");
6     java.lang.System.out.println("Exiting sum()");
7     return result;
8 }

二、将消息记录到当前页面 

  另外一种输出调试消息的方式,就是在页面中开辟一小块区域,用以显示消息。这个区域一般是一个元素,而该元素能够老是出如今页面中,但仅用于调试目的;也能够是一个根据须要动态建立的元素。 例如,能够将 log()函数修改成以下所示:

 1 function log(message){
 2     var console = document.getElementById("debuginfo");
 3     if (console === null){
 4         console = document.createElement("div");
 5         console.id = "debuginfo";
 6         console.style.background = "#dedede";
 7         console.style.border = "1px solid silver";
 8         console.style.padding = "5px";
 9         console.style.width = "400px";
10         console.style.position = "absolute";
11         console.style.right = "0px";
12         console.style.top = "0px";
13         document.body.appendChild(console);
14     }
15     console.innerHTML += "<p>" + message + "</p>";
16 }

3、常见的 IE错误 

  常见IE错误有:操做终止、无效字符、未找到成员、未知运行时错误、语法错误、系统没法找到指定资源等 

相关文章
相关标签/搜索