HTML Canvas基本概念

Canvas

Canvas元素是HTML5新家的元素,这个元素负责在页面中设定一个区域,然后就可以通过Javascript动态地在这个区域中绘制图形

基本用法

使用canvas元素时,必须先设置其width属性和height属性,指定绘图区域的大小。出现在canvas标签中的内容是后备信息,如果浏览器不支持canvas元素,就会显示这些信息。

<canvas id="canvas" width="300" height="200">
您的浏览器不支持Canvas
</canvas>

要在这块画布上绘图,就需要获得其绘图上下文,取得绘图上下文对象的引用,需要调用getContext()方法,这个方法接收一个参数,即上下文的名字,传入2d,就可以获得2D上下文对象,也可以传入webgl获得webgl上下文的对象。

var canvas = document.getElementById("canvas");
if (canvas.getContext) {
    var ctx = canvas.getContext('2d');
}
//在使用canvas元素之前,首先要检测是否有getContext()方法,有些浏览器会将HTML规范之外的元素创建为默认的HTML元素对象,这种情况下,即使获取了id为canvas的元素,也不一定是canvas元素,没有getContext()方法。

使用toDataURL()方法,可以将canvas元素上绘制的图像导出,这个方法接收一个参数,即图像的MIME类型,而且适用于创建图像的任何上下文。

var canvas = document.getElementById('canvas');
if (canvas.getContext) {
    //获取图像的数据URI
    var imgURL = canvas.toDataURL('img/png');

    //显示图像
    var image = document.createElement('img');
    image.src = imgURL;
    document.body.appendChild(image);
}

2D上下文

使用2D绘图上下文提供的方法。可以绘制简单的2D图形,如矩形、弧线和路径。2D上下文的坐标开始于canvas元素的左上角,坐标原点是(0,0),水平方向代表x轴,向右为正,竖直方向表示y轴,向下为正。

填充和描边

填充就是用指定的样式(颜色、渐变或图像)填充图形,这个操作可以使用strokeStyle属性来指定样式。
描边就是在图形的边缘划线,这个操作使用fillStyle属性来指定样式。
fillStylestrokeStyle属性的值可以是字符串、渐变对象或模式对象,其默认值是#000000,如果使用表示颜色的字符串值,可以使用CSS中指定颜色值的任何形式,十六进制码、rgb、rgba、hsl、hsla等。

ctx.strokeStyle = "red"; //指定描边颜色
ctx.fillStyle = "#0000ff"; //指定填充颜色

绘制矩形

2D上下文对象可以直接绘制矩形,其方法有:

  • fillRect(x, y, width, height):绘制左上角坐标为(x,y), 宽为width,高为height的矩形,并按fillStyle指定的模式填充
  • strokeRect(x, y, width, height):绘制左上角坐标为(x, y), 宽为width,高为height的矩形,并按strokeStyle指定的模式描边
  • clearRect(x, y, width, height):清除矩形区域,实际上是把一部分区域变得透明。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>绘制矩形</title>
</head>
<body>
    <canvas id="canvas" height="600" width="1200"></canvas>
</body>
<script type="text/javascript">
    var canvas = document.getElementById("canvas")
    if (canvas.getContext) {
        var ctx = canvas.getContext('2d')

        ctx.fillStyle = "#ff0000"
        ctx.strokeStyle = "#00ff00"
        ctx.fillRect(10,10,50,50)
        ctx.strokeRect(70,70,50,50)

        ctx.fillRect(200,200,300,300)
        ctx.fillStyle = "#0000ff"
        ctx.fillRect(300,300,300,300)
        ctx.clearRect(350,350,100,100)
    }
</script>
</html>

运行效果:
HTML Canvas基本概念
描边线条的宽度可以使用lineWidth属性来控制,其属性值可以为任意的额整数,还可以使用lineCap属性控制线条末端的形状是平头(butt)、圆头(round)还是方头(square),lineJoin属性可以控制萧条相交的方式是圆交(round)、斜交(bevel)还是斜接(miter)。

绘制路径

canvas使用一种基于状态的方式来绘图,意思就是,你绘图的结果取决于你当前设置的状态,我们上面使用了strokeStylefillStyle规定了描边和填充的颜色,当我们再次给这两个属性赋予了新的值之后,再绘制的图形的填充颜色和描边颜色就会跟着发生改变。在绘制路径时,可以先设置好一段路径的属性,比如上面提的strokeStylefillStylelineWidth等,然后开始绘制路线,最后决定以填充方式或者描线方式绘制该路径,然后在规定新的路径的属性。
要绘制路径,首先要调用beginPath()方法,表示开始绘制新路径,然后使用下面的方法绘制该路径:

  • arc(x, y, radius, startAngle, endAngle, counterclockwise):以(x,y)为圆心绘制一条弧线,弧线的半径为radius,其实角度(用弧度表示)分别为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。

路径绘制结束后,使用closePath()方法结束绘制路径。然后用stroke()fill()方法绘制线或者填充,也可以用'clip()'方法创建一个剪切区域。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>绘制路径</title>
</head>
<body>
    <canvas id="canvas" width="1200" height="600"></canvas>
</body>
<script type="text/javascript">
    var canvas = document.getElementById('canvas')

    if (canvas.getContext) {
        var ctx = canvas.getContext('2d')

        ctx.strokeStyle = 'red'
        ctx.beginPath()
        ctx.arc(100, 100, 100, 0, Math.PI / 2,true)
        ctx.stroke()
        ctx.closePath()

        ctx.strokeStyle = 'green'
        ctx.beginPath()
        ctx.moveTo(100,200)
        ctx.arcTo(200,300,100,400,100)
        ctx.stroke()
        ctx.closePath()

        ctx.strokeStyle = "yellow"
        ctx.beginPath()
        ctx.bezierCurveTo(100,200,300,200,400,400)
        ctx.stroke()
        ctx.closePath()

        ctx.strokeStyle = "blue"
        ctx.beginPath()
        ctx.moveTo(500,200)
        ctx.quadraticCurveTo(100,300,600,600)
        ctx.stroke()
        ctx.closePath()

        ctx.strokeStyle = "orange"
        ctx.beginPath()
        ctx.rect(200,200,200,300)
        ctx.stroke()
        ctx.closePath()
    }
</script>
</html>

结果:
HTML Canvas基本概念
*在这注意,arc()方法中,x的正方向,即水平向右方向的角度为0,然后顺时针方向增加,y正方向,即垂直向下方向为90度,水平左方向为180度,垂直向上方向为270度,再次到水平向右方向时,是360度,所以,想创建一个整圆,可以这么写:`ctx.arc(100,100,100,0,Math.PI 2,true)`**

扫描二维码关注公众号,回复: 212510 查看本文章

关于closePath(),还有另一作用,如果调用了closePath()之后再执行stroke(),图形将自动闭合,否则不会闭合。如下面的例子所示:

ctx.beginPath()
ctx.arc(100,100,100,0,Math.PI / 2, true);
ctx.closePath()
ctx.stroke()

结果:
HTML Canvas基本概念

绘制文本

2D上下文也提供了绘制文本的方法,绘制文本主要有两个方法:

  • fillText(str, x, y, ?width)
  • strokeText(str, x, y, ?width)

这两个方法都有四个参数:要绘制的文本的字符串,x坐标,y坐标,可选的参数,最大像素宽度。这两个方法都以下面三个属性为基础:

  • font:表示文本样式、大小及字体,可以使用css中指定字体的格式来指定,如"10px Arial"
  • textAlign:表示文本的对齐方式,可能的值有"start","end","left","right"和"center",其中"start"和"left","end"和"right"的效果一样,但是建议前者。
  • textBaseline:表示文本的基线,可能的值有"top",“hanging”,"middle","alphabetic","ideographic"和"bottom"

实际上,textAligntextBaseline分别决定了文本的水平对齐方式和竖直对齐方式。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>绘制文本</title>
</head>
<body>
    <canvas id="canvas" width="300" height="300"></canvas>
</body>
<script type="text/javascript">
    var canvas = document.getElementById('canvas')

    if (canvas.getContext){
        var ctx = canvas.getContext('2d')

        ctx.beginPath()
        ctx.moveTo(100,0)
        ctx.lineTo(100,100)
        ctx.closePath()
        ctx.stroke()

        ctx.font = "20px Times New Roman"
        ctx.textAlign = "start"
        ctx.textBaseline = "middle"
        ctx.fillText("canvas",100,10)

        ctx.textAlign = "end"
        ctx.fillText("canvas",100,25)

        ctx.textAlign = "center"
        ctx.fillText("canvas",100,40)
    }
</script>
</html>

运行结果:
HTML Canvas基本概念

变换

通过上下文的变换,可以将处理后的图像绘制到画布上,创建绘制上下文时,会以默认值初始化变换矩阵,使用变换时,会使用不同的变换矩阵来做处理,产生不同的效果。
可以使用以下方法来修改变换矩阵:

  • 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):直接修改变换矩阵,方式是乘以以下矩阵:\begin{bmatrix} m1_1 & m1_2 & dx\m2_1 & m2_2 & dy \ 0 & 0 & 1 \end{bmatrix}
  • setTranform(m1_1,m1_2,m2_1,m2_2,dx,dy):将变换矩阵重置为默认值,然后调用transform()
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>变换</title>
</head>
<body>
    <canvas id="canvas" width="1200" height="600"></canvas>
</body>
<script type="text/javascript">
    var canvas = document.getElementById("canvas")

    if (canvas.getContext) {
        var ctx = canvas.getContext('2d')

        ctx.strokeStyle = "red"
        ctx.rotate(-Math.PI/6)
        ctx.beginPath()
        ctx.rect(200,400,200,100)
        ctx.stroke()
        ctx.closePath()

        ctx.strokeStyle = "blue"
        ctx.rotate(Math.PI/6)//将上面的30度恢复原状
        ctx.scale(1,2)
        ctx.beginPath()
        ctx.rect(100,100,200,100)
        ctx.stroke()
        ctx.closePath()

        ctx.strokeStyle = "green"
        ctx.setTransform(1,0,2,1,0,0)//对-45度对称
        ctx.beginPath()
        ctx.rect(100,100,100,100)
        ctx.stroke()
        ctx.closePath()
    }
</script>
</html>

运行结果:
HTML Canvas基本概念

绘制图像

2D上下文对象提供了对图像的支持,如果想在画布上绘制一幅图像,可以使用drawImage()方法,这个方法的参数根据需要,有几种可能。

  1. 传入一个<img>元素,以及绘制该图像的起点的x和y坐标

    var image = document.images[0]
    ctx.drawImage(image,10,10)
  2. img元素,图像起点x,y,目标图像宽度和高度
    ctx.drawImage(image, 50, 10 20 30)

  3. 要绘制的图像、源图像的x坐标、源图像的y坐标、源图像的宽度、源图像的高度、目标图像的x坐标、目标图像的y坐标、目标图像的宽度、目标图像的高度。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>绘制图像</title>
<style type="text/css">
    img{display: block; padding: 5px;border: 1px solid black;margin-bottom: 15px;}
</style>
</head>
<body>
    <img src="cat.jpg">
    <canvas id="canvas" width="600" height="600"></canvas>
</body>
<script type="text/javascript">
    var img = document.images[0]
    var canvas = document.getElementById("canvas")

    if (canvas.getContext) {
        var ctx = canvas.getContext('2d')

        ctx.drawImage(img, 0, 0)
        ctx.drawImage(img, 300, 0, 120, 100)
        ctx.drawImage(img,40,40,150,150,450,0,160,80)
    }
</script>
</html>

运行结果:
HTML Canvas基本概念

阴影

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

  • shadowColor:用CSS颜色格式表示的阴影颜色,默认为黑色
  • shadowOffsetX:形状或路径x轴方向的阴影偏移量,默认为0
  • shadowOffsetY:形状或路径y轴方向的阴影偏移量,默认为0
  • shadowBlur:模糊的像素数,默认为0
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>阴影</title>
</head>
<body>
    <canvas id="canvas" width="1200" height="600"></canvas>
</body>
<script type="text/javascript">
    var canvas = document.getElementById("canvas")

    if (canvas.getContext) {
        var ctx = canvas.getContext('2d')

        ctx.shadowOffsetX = 5
        ctx.shadowOffsetY = 5
        ctx.shadowBlur    = 5
        ctx.shadowColor   = "rgba(0,0,0,0.5)"

        ctx.fillStyle = "#ff0000"
        ctx.fillRect(10,10,50,50)
    }
</script>
</html>

运行结果
HTML Canvas基本概念

渐变

渐变由CanvasGradient实例表示,可以通过2D上下文来创建和修改。
创建线性渐变可以使用createLinearGradient()方法,这个方法有四个参数:起点的x坐标、起点的y坐标、终点的x坐标、终点的y坐标。
创建了渐变对象之后,可以使用addColorStop()方法来指定色标,这个方法接收两个参数:色标位置和CSS颜色值,色标位置是一个0(开始的颜色)-1(结束的颜色)之间的数字。
最后,将fillStyle或strokeStyle设置为这个对象,从而使用渐变色来绘制形状或描边。
创建径向渐变时,可以使用createRadialGradient()方法,这个方法接收6个参数,对应着两个圆的圆心即半径。前三个参数指定的是起点圆的圆心坐标x,y和半径,后三个参数指终点圆的圆心坐标x,y即半径。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>渐变</title>
</head>
<body>
    <canvas id="canvas" width="1200" height="600"></canvas>
</body>
<script type="text/javascript">
    var canvas = document.getElementById("canvas")
    if (canvas.getContext) {
        var ctx = canvas.getContext('2d')
        var linearGardient = ctx.createLinearGradient(30,30,70,70)
        var radialGardient = ctx.createRadialGradient(155,155,10,150,150,30)
        linearGardient.addColorStop(0,"red")
        linearGardient.addColorStop(1,"yellow")
        radialGardient.addColorStop(0,"blue")
        radialGardient.addColorStop(1,"green")

        ctx.fillStyle = "#ff0000"
        ctx.fillRect(10,10,50,50)
        ctx.fillStyle = linearGardient
        ctx.fillRect(30,30,50,50)
        ctx.fillRect(50,50,50,50)
        ctx.fillStyle = "#0000ff"
        ctx.fillRect(110,110,50,50)
        ctx.fillStyle = radialGardient
        ctx.fillRect(130,130,50,50)

    }
</script>
</html>

运行结果:
HTML Canvas基本概念

模式

模式就是重复的图像,可以用来填充或者描边推行。
创建新模式:createPattern(),参数有两个:一个img元素,一个表示如何重复图像的字符串,其中,第二个参数的值与css的background-repeat属性值相同,包括repeatrepeat-xrepeat-yno-repeat

var image = document.images[0],
    pattern = ctx.createPattern(image, "repeat")

ctx.fillStyle = pattern
ctx.fillRect(10,10,150,150)

使用图像数据

2D上下文可以使用getImageData()取得原始图像的数据,这个方法接收4个参数:要取得其数据的画图区域的x和y坐标,以及该区域像素的高度和宽度。
var imageData = context.getImageData(10,5,150,150)
其返回对象是ImageData的实例,每个ImageData对象都有三个属性:width,height和data,data是一个数组,保存着图像中每一个像素的数据,在data数组中,每一个像素用4个元素来保存,分别表示红绿蓝和透明度值。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>获取图像数据</title>
<style type="text/css">
    img{border:1px solid black; display: block;margin-bottom: 15px;}
</style>
</head>
<body>
    <img src="cat.jpg">
    <canvas id="canvas" width="1200" height="600"></canvas>
</body>
<script type="text/javascript">
    var canvas = document.getElementById("canvas")
    if (canvas.getContext) {
        var ctx = canvas.getContext('2d'),
            image = document.images[0],
            imageData, data,
            i, len, average,
            red, green, blue, alpha

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

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

        for (i = 0, len = data.length; i < len; 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] = average
            data[i + 1] = average
            data[i + 2] = average
        }

        imageData.data = data
        ctx.putImageData(imageData,300,0)
    }
</script>
</html>

运行结果
HTML Canvas基本概念

合成

还有两个会应用到2D上下文中所有绘制操作的属性

  • globalAlpha:一个介于0-1的值,用于指定所有绘制的透明度,默认为0,如果所有后续操作都要基于相同的透明度,就可以先把globalAlpha设置为适当的值,然后绘制,最后再把它设置成默认值0
  • globalCompositionOpreation:表示后绘制的图形怎样与先绘制的图形结合,这个属性的值是字符串,可能的值如下:
    • source-over:默认值,后绘制的图形位于先绘制的图形上方
    • source-in:后绘制的图形与先绘制的图形重叠部分课件,两者其他部分全部透明
    • source-out:后绘制的图形与先绘制的图形不重叠的部分课件,两者其他部分完全透明
    • source-atop:后绘制的图形与先绘制的图形重复部分可见,先绘制图形不受影响
    • destination-over:后绘制的图形位于先绘制的图形下方,只有之前透明像素下的部分才可见
    • destination-in:后绘制的图形位于先绘制的图形下方,两者不重叠的部分完全透明
    • destination-out:后绘制的图形擦除与先绘制的图形的重叠部分
    • destionation-atop:后绘制的图形位于先绘制的图形下方,两个不重叠的地方,先绘制的图形会完全透明
    • lighter:后绘制的图形与先绘制的图形重叠部分的值相加,使该部分变亮
    • copy:后绘制的图形完全替代与之重叠的先绘制图形
    • xor:后绘制的图形与先绘制的图形重叠的部分执行“异或”操作

猜你喜欢

转载自blog.51cto.com/13175080/2114363
今日推荐