• JavaScript入门之Canvas(一): 2D Context


    概念 

        Canvas    是 HTML5 新增的元素,可用于通过使用JavaScript中的脚本来绘制图形。例如,它可以用于绘制图形,制作照片,创建动画,甚至可以进行实时视频处理或渲染。自HTML5添加Canvas这个库,很快便得到了普及和发展,各个主流浏览器也速速支持,可见其强大。目前为止,IE9+、Firefox、Safari、Opera、Chrome、iOS版Safari以及Android版WebKit都已经基本上支持canvas标签。

    添加Canvas元素

          首先,我们需要在html页面中创建一个<canvas>元素,并指定一个绘图区域(width,height):

    <canvas id="myCanvas" width=" 400" height="400">抱歉,你的浏览器版本不支持canvas</canvas>

          如果不指定,则默认宽度为 300px, 高度 150px。标签中的内容不会显示,当你的浏览器不支持<canvas>标签时,才会显示这些信息。

          宽度和高度定义的绘图区域可以理解为一张画纸,你要做的便是在这张画纸上画东西,而你要在画纸上画图,自然需要一只画笔,它在canvas里面叫做Context(上下文)。

    2D Context

          为什么Context前面有个2D呢,没错,它还有个3D Context,叫做WebGL,这篇文章不做讨论。

          要取得这只“画笔”,需要用到getContext()方法,并传入"2d"作为参数:

    var drawing=document.getElementById("myCanvas");
    var context=drawing.getContext("2d");

          好,我们有了这只“画笔”,就可以为所欲为了。我们可以画矩形、弧线和路径等。

          还有一点要说明,2D Context的 坐标开始于元素的左上角,原点坐标是(0,0)。所有坐标值都基于这个原点计算,x 方向自左向右为正,y 方向自上而下为正。

          我们先来随便画点东西:

    context.fillRect(10, 10, 50, 50);

          没错,我们画了个矩形,这个矩形从(10,10)开始画,宽和高都为50px。

     

    填充还是描边

          这只画笔有两个基本的作用,画画的时候总要先画个轮廓,先有个边,然后再给它上色。

          因此,这只画笔第一个作用便是描边(stroke),第二个作用便是上色,也就是填充(fill)。专业一点的话来说:

    填充,就是用指定的样式(颜色、渐变或图像)填充图形;
    描边,就是只在图形的边缘画线。

          是不是还漏点什么?没错,我画画的时候不可能只有一种颜色的笔吧。所以我要更改描边或者填充的属性,就要用到两个属性:fillStylestrokeStyle 

    自定义画笔属性

          fillStyle、strokeStyle这两个属性的值可以是字符串、渐变对象或模式对象,而且它们的默认值都是"#000000"。如果为它们指定表示颜色的字符串值,可以使用CSS中指定颜色值的任何格式,包括颜色名、十六进制码、 rgb、rgba、hsl 或hsla。

    var drawing=document.getElementById("myCanvas");
    var context=drawing.getContext("2d");
    
    //设置描边颜色、填充颜色
    context.strokeStyle = "#ff0000";
    context.fillStyle = "rgba(0,0,0,0.3)";
    
    //描边、填充(画一个矩形)    
    context.strokeRect(10, 10, 50, 50);
    context.fillRect(10, 10, 50, 50);
    
    //描边、填充(画第二个矩形)    
    context.strokeRect(35, 35, 50, 50);
    context.fillRect(35, 35, 50, 50);

              

          以上代码将fillStyle 通过rgba()格式设置为透明度为0.3的黑色,将stokeStyle 设置为红色,然后从(10,10)处开始绘制矩形,矩形的宽和高均为50像素。再在(35,35)画第二个矩形并描边。所以两个矩形有1/4是重合的。

          然后我现在想在第二个矩形的右下方挖一个矩形的洞出来,要怎么做。

    context.clearRect(60,60, 25, 25);

           效果如上右图。

          但是,只能画画矩形什么的也太弱了吧,我想要自己画一条路径。

    绘制路径

          要绘制路径,首先必须调用beginPath()方法,表示要开始绘制新路径。然后调用一些方法来绘制路径,最后调用stroke()方法来对路径进行描边。

          先举个栗子:

    context.beginPath();
    context.moveTo(85,35);
    context.lineTo(110,35);
    context.arc(85,35,25,0,2*Math.PI,false)
    context.stroke();

            

          来看看干了啥事,先调用了moveTo方法移动到了(85, 35),然后调用lineTo画了一条水平直线到(110,35),然后调用arc方法画一个圆心为(85, 35),半径为25,角度为(0,2PI),顺时针(false)的圆,最后调用stroke进行描边。

    注:
    1、moveTo函数会将点移动到指定位置,但是不绘画路径
    2、画圆的时候会以圆心向右半径的距离开始画,此时点应该在此处,否则将会从产生一个从所在点圆心向右半径距离点的路径线(理解上右图)
        context.moveTo(85,35);
        context.lineTo(120,75);
        context.arc(85,35,25,0,2*Math.PI,false)

           下面我们来看看绘制路径有哪些方法,以及如何使用这些方法:

    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()所绘制的独立的形状。

    阴影和渐变   

          要为元素绘制阴影,只需要指定以下四个属性:

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

          在绘制前为它们设置适当的值,就会产生阴 影。举个栗子:

        //设置阴影
        context.shadowOffsetX = -5;
        context.shadowOffsetY = 5;
        context.shadowBlur = 5;
        context.shadowColor = "rgba(0, 0, 0, 0.8)";
        
        context.beginPath();
        context.moveTo(85,35);
        context.lineTo(120,75);
        context.arc(85,35,25,0,2*Math.PI,false)
        context.closePath();
        context.stroke();    

        

          设置渐变的方法也很简单,调用createLinearGradient(start_x, start_y, end_x, end_y)方法,就能产生一个指定区域内的渐变,而你的图像必须和渐变坐标相符合,才能产生正确的渐变。例如:

      //设置渐变
        var gradient = context.createLinearGradient(140, 30, 190, 90);
        gradient.addColorStop(0, "white");
        gradient.addColorStop(1, "black");
        
        //绘制渐变矩形
        context.fillStyle = gradient;
        context.fillRect(140, 30, 50, 50);

    绘制文本

          除了画图外,我们可能还需要绘制一些必要的文字,Context也同样提供了两个方法:fillText()和strokeText() 和三个配置属性:font、textAlign、textBaseline。

          三个属性的说明如下:

    font:表示文本样式、大小及字体,用CSS 中指定字体的格式来指定,例如"10px Arial"。
    textAlign:表示文本对齐方式。可能的值有"start""end""left""right""center"。
    textBaseline:表示文本的基线。可能的值有"top""hanging""middle""alphabetic""ideographic""bottom"

      fillText()和strokeText()    接受字符串、x 坐标、y坐标和最大像素宽度(可选) 四个参数,举个栗子:

        // 写字
        context.fillStyle = "rgba(0,0,0,1)";
        context.font = "bold 14px Arial";
        context.textAlign = "center";
        context.textBaseline = "middle";
        context.fillText("嘻哈", 110, 100);
        
        //起点对齐
        context.textAlign = "start";
        context.fillText("嘻哈", 110, 120);
        //终点对齐
        context.textAlign = "end";
        context.fillText("嘻哈", 110, 140);     

          暂时先介绍到这里,下次我们就要这些学到的入门知识,实现一个帧动画试试吧!

          附上本节完整代码:

     1 <!DOCTYPE html>
     2 <html>
     3 <head> 
     4 <meta charset="utf-8"> 
     5 <title>canvas测试</title> 
     6 </head>
     7 <body>
     8 
     9 <canvas id="myCanvas" width="300" height="300" style="border:1px solid #c3c3c3;">
    10 您的浏览器不支持 HTML5 canvas 标签。
    11 </canvas>
    12 
    13 <script>
    14 
    15     //取得画笔
    16     var drawing=document.getElementById("myCanvas");
    17     var context=drawing.getContext("2d");
    18     
    19     //设置画笔属性
    20     context.strokeStyle = "#ff0000";
    21     context.fillStyle = "rgba(0,0,0,0.3)";
    22     
    23     //画矩形
    24     context.strokeRect(10, 10, 50, 50);
    25     context.fillRect(10, 10, 50, 50);
    26     
    27     //画第二个矩形
    28     context.strokeRect(35, 35, 50, 50);
    29     context.fillRect(35, 35, 50, 50);
    30     
    31     //挖空一个矩形
    32     context.clearRect(60,60, 25, 25);
    33     
    34     //设置阴影
    35     context.shadowOffsetX = -5;
    36     context.shadowOffsetY = 5;
    37     context.shadowBlur = 4;
    38     context.shadowColor = "rgba(0, 0, 0, 0.8)";
    39     
    40     //画直线、圆
    41     context.beginPath();
    42     context.moveTo(85,35);
    43     context.lineTo(120,75);
    44     context.arc(85,35,25,0,2*Math.PI,false)
    45     context.closePath();
    46     context.stroke();
    47     
    48     //设置渐变
    49     var gradient = context.createLinearGradient(140, 30, 190, 90);
    50     gradient.addColorStop(0, "white");
    51     gradient.addColorStop(1, "black");
    52     
    53     //绘制渐变矩形
    54     context.fillStyle = gradient;
    55     context.fillRect(140, 30, 50, 50);
    56     
    57     context.shadowColor = "rgba(0, 0, 0, 0)";
    58     
    59     // 写字
    60     context.fillStyle = "rgba(0,0,0,1)";
    61     context.font = "bold 14px Arial";
    62     context.textAlign = "center";
    63     context.textBaseline = "middle";
    64     context.fillText("嘻哈", 110, 100);
    65     
    66     //起点对齐
    67     context.textAlign = "start";
    68     context.fillText("嘻哈", 110, 120);
    69     //终点对齐
    70     context.textAlign = "end";
    71     context.fillText("嘻哈", 110, 140);
    72     
    73     
    74 </script>
    75 
    76 </body>
    77 </html>

     

  • 相关阅读:
    远程视频监控之应用篇(mjpg-streamer)
    C语言存储类型
    基于Qt的wifi智能小车的制作(一)
    libevent和基于libevent的网络编程
    fdisk 分区格式化为ext4格式分区
    Makefile 中:= ?= += =的区别
    【计算机网络】详解网络层(二)ARP和RARP
    Nginx 反向代理 负载均衡 虚拟主机配置
    C# 对文本文件的几种读写方法总结
    Visual Studio中Image Watch的使用
  • 原文地址:https://www.cnblogs.com/ljwTiey/p/7415298.html
Copyright © 2020-2023  润新知