HTML5权威指南笔记:36-使用canvas元素(2)

1 用路径绘图

基本路径方法:

名称 说明 返回
beginPath() 开始一条新路径 void
closePath() 尝试闭合现有路径,方法是绘制一条线,连接最后那条线的终点与初始坐标 void
fill() 填充用子路径描述的图形 void
isPointlnPath(x, y) 如果指定的点在当前路径所描述的图形之内则返回true 布尔值
lineTo(x, y) 绘制一条到指定坐标的子路径 void
moveTo(x, y) 移动到指定坐标而不绘制子路径 void
rect(x, y, w, h) 绘制一个矩形,其左上角位于(x,y), 宽度是w, 高度是h void
stroke() 给子路径描述的图形绘制轮廓线 void

绘制一条路径的基本顺序如下:

  1. 调用beginPath方法;
  2. 用moveTo方法移动到起点;
  3. 用arc和lineTo等方法绘制子路径;
  4. 调用closePath方法(可选) ;
  5. 调用fill或stoke方法。

1.1 用线条绘制路径


<html>
    <head>
        <title>Exampletitle>
        <style>
            canvas {border: thin solid black}
            body > * {float:left;}
        style>
    head>
    <body>
        <canvas id="canvas" width="500" height="140">
            Your browser doesn't support the <code>canvascode> element
        canvas>
        <script>
            var ctx = document.getElementById("canvas").getContext("2d");

            //定义画版属性
            ctx.fillStyle = "yellow";
            ctx.strokeStyle = "black";
            ctx.lineWidth = 4;

            //画直线
            ctx.beginPath();
            //使用lineCap来设置线条末端的样式,值有butt(默认值)、round和square。
            ctx.lineCap = "round";
            ctx.moveTo(10, 10);
            ctx.lineTo(110, 10);
            ctx.lineTo(110, 120);
            ctx.closePath();
            //填充图形和路径
            ctx.fill();
            ctx.stroke();
        script>
    body>
html>

1.2 绘制矩形


<html>
    <head>
        <title>Exampletitle>
        <style>
            canvas {border: thin solid black}
            body > * {float:left;}
        style>
    head>
    <body>
        <canvas id="canvas" width="500" height="140">
            Your browser doesn't support the <code>canvascode> element
        canvas>
        <script>
            var ctx = document.getElementById("canvas").getContext("2d");

            ctx.fillStyle = "yellow";
            ctx.strokeStyle = "black";
            ctx.lineWidth = 4;

            ctx.beginPath();
            //绘制矩形,相对于左边偏离110,距离上边偏离10,宽100,高90
            ctx.rect(110, 10, 100, 90);

            ctx.fill();
            ctx.stroke();           
        script>
    body>
html>

2 绘制圆弧

圆弧方法:

名称 说明 返回
arc(x,y,rad,startAngle,endAngle,direction) 绘制一段圆弧到(x, y),半径为rad,起始角度为startAngle,结束角度为end如gle 。可选参数direction指定了圆弧的方向。 void
arcTo(x1, y1, x2, y2,rad) 绘制一段半径为rad,经过(x1 ,y1), 直到(x2,y2)的圆弧 void

2.1 使用arcTo方法


<html>
    <head>
        <title>Exampletitle>
        <style>
            canvas {border: thin solid black}
            body > * {float:left;}
        style>
    head>
    <body>
        <canvas id="canvas" width="500" height="140">
            Your browser doesn't support the <code>canvascode> element
        canvas>
        <script>
            var ctx = document.getElementById("canvas").getContext("2d");

            var point1 = [100, 10];
            var point2 = [200, 10];
            var point3 = [200, 110];

            ctx.fillStyle = "yellow";
            ctx.strokeStyle = "black";
            ctx.lineWidth = 4;

            ctx.beginPath();
            ctx.moveTo(point1[0], point1[1]);
            ctx.arcTo(point2[0], point2[1], point3[0], point3[1], 100);
            ctx.stroke();

            drawPoint(point1[0], point1[1]);
            drawPoint(point2[0], point2[1]);
            drawPoint(point3[0], point3[1]);

            ctx.beginPath();
            ctx.moveTo(point1[0], point1[1]);
            ctx.lineTo(point2[0], point2[1]);
            ctx.lineTo(point3[0], point3[1]);
            ctx.stroke();

            function drawPoint(x, y) {
                ctx.lineWidth = 1;
                ctx.strokeStyle = "red";
                ctx.strokeRect(x -2, y-2, 4, 4);
            }
        script>
    body>
html>

2.2 使用arc方法


<html>
    <head>
        <title>Exampletitle>
        <style>
            canvas {border: thin solid black}
            body > * {float:left;}
        style>
    head>
    <body>
        <canvas id="canvas" width="500" height="140">
            Your browser doesn't support the <code>canvascode> element
        canvas>
        <script>
            var ctx = document.getElementById("canvas").getContext("2d");
            ctx.fillStyle = "yellow";
            ctx.lineWidth = "3";

            ctx.beginPath();
            //用前两个方法参数在画布上指定一个点。
            //用第三个参数指定圆弧的半径,然后指定圆弧的起始和结束角度。
            //最后一个参数指定绘制圆弧时是按顺时针还是逆时针方向
            ctx.arc(70, 70, 60, 0, Math.PI * 2, true);
            ctx.stroke();

            ctx.beginPath();
            ctx.arc(200, 70, 60, Math.PI/2, Math.PI, true);
            ctx.fill();
            ctx.stroke();

            ctx.beginPath();
            var val = 0;
            for (var i = 0; i < 4; i++) {
                ctx.arc(350, 70, 60, val, val + Math.PI/4, false);
                val+= Math.PI/2;
            }
            ctx.closePath();
            ctx.fill();
            ctx.stroke();
        script>
    body>
html>

3 绘制贝塞尔曲线

名称 说明 返回
bezierCurveTo(cx1, cy1, cx2, cy2, x, y) 绘制一段贝塞尔曲线到点(x, y), 控制点为(ex1, cy1)和(cx2,cy2)。 void
quadraticCurveTo(cx, xy, x, y) 绘制一段二次贝塞尔曲线到点(x,y), 控制点为(ex, cy) void

3.1 绘制三次贝塞尔曲线

bezierCurveTo方法会绘制一条曲线,范围是从上一条子路径的终点到第五个与第六个方法参数所指定的点。控制点有两个,它们由前四个参数指定。

例子:


<html>
    <head>
        <title>Exampletitle>
        <style>
            canvas {border: thin solid black}
            body > * {float:left;}
        style>
    head>
    <body>
        <canvas id="canvas" width="500" height="140">
            Your browser doesn't support the <code>canvascode> element
        canvas>
        <script>
            var canvasElem = document.getElementById("canvas");
            var ctx = canvasElem.getContext("2d");

            var startPoint = [50, 100];
            var endPoint = [400, 100];
            var cp1 = [250, 50];
            var cp2 = [350, 50];

            canvasElem.onmousemove = function(e) {
                if (e.shiftKey) {
                    cp1 = [e.clientX, e.clientY];
                } else if (e.ctrlKey) {
                    cp2 = [e.clientX, e.clientY];
                }
                ctx.clearRect(0, 0, 500, 140);
                draw();
            }

            draw();

            function draw() {
                ctx.lineWidth = 3;
                ctx.strokeStyle = "black";                  
                ctx.beginPath();
                ctx.moveTo(startPoint[0], startPoint[1]);
                ctx.bezierCurveTo(cp1[0], cp1[1], cp2[0], cp2[1], 
                    endPoint[0], endPoint[1]);
                ctx.stroke();

                ctx.lineWidth = 1;
                ctx.strokeStyle = "red";            
                var points = [startPoint, endPoint, cp1, cp2];
                for (var i = 0; i < points.length; i++) {
                    drawPoint(points[i]);    
                }
                drawLine(startPoint, cp1);
                drawLine(endPoint, cp2);
            }

            function drawPoint(point) {
                ctx.beginPath();

                ctx.strokeRect(point[0] -2, point[1] -2, 4, 4);
            }

            function drawLine(from, to) {
                ctx.beginPath();
                ctx.moveTo(from[0], from[1]);
                ctx.lineTo(to[0], to[1]);
                ctx.stroke();
            }
        script>
    body>
html>

3.2 绘制二次贝塞尔曲线

二次贝塞尔曲线只有一个控制点,因此quadraticCurveTo方法的参数bezierCurveTo方法要少两个。

例子:


<html>
    <head>
        <title>Exampletitle>
        <style>
            canvas {border: thin solid black}
            body > * {float:left;}
        style>
    head>
    <body>
        <canvas id="canvas" width="500" height="140">
            Your browser doesn't support the <code>canvascode> element
        canvas>
        <script>
            var canvasElem = document.getElementById("canvas");
            var ctx = canvasElem.getContext("2d");

            var startPoint = [50, 100];
            var endPoint = [400, 100];
            var cp1 = [250, 50];

            canvasElem.onmousemove = function(e) {
                if (e.shiftKey) {
                    cp1 = [e.clientX, e.clientY];
                }
                ctx.clearRect(0, 0, 500, 140);
                draw();
            }

            draw();

            function draw() {
                ctx.lineWidth = 3;
                ctx.strokeStyle = "black";                  
                ctx.beginPath();
                ctx.moveTo(startPoint[0], startPoint[1]);
                ctx.quadraticCurveTo(cp1[0], cp1[1], endPoint[0], endPoint[1]);
                ctx.stroke();

                ctx.lineWidth = 1;
                ctx.strokeStyle = "red";            
                var points = [startPoint, endPoint, cp1];
                for (var i = 0; i < points.length; i++) {
                    drawPoint(points[i]);    
                }
                drawLine(startPoint, cp1);
                drawLine(endPoint, cp1);
            }

            function drawPoint(point) {
                ctx.beginPath();

                ctx.strokeRect(point[0] -2, point[1] -2, 4, 4);
            }

            function drawLine(from, to) {
                ctx.beginPath();
                ctx.moveTo(from[0], from[1]);
                ctx.lineTo(to[0], to[1]);
                ctx.stroke();
            }
        script>
    body>
html>

4 创建剪辑区域

使用clip()可以创建新的裁剪区域,返回值是void。

例子:


<html>
    <head>
        <title>Exampletitle>
        <style>
            canvas {border: thin solid black}
            body > * {float:left;}
        style>
    head>
    <body>
        <canvas id="canvas" width="500" height="140">
            Your browser doesn't support the <code>canvascode> element
        canvas>
        <script>
            var ctx = document.getElementById("canvas").getContext("2d");

            ctx.fillStyle = "yellow";
            ctx.beginPath();
            ctx.rect(0, 0, 500, 140);
            ctx.fill();

            //进行裁剪
            ctx.beginPath();
            ctx.rect(100, 20, 300, 100);
            ctx.clip();

            ctx.fillStyle = "red";
            ctx.beginPath();
            ctx.rect(0, 0, 500, 140);
            ctx.fill();

        script>
    body>
html>

5 绘制文本

文本方法:

名称 说明 返回
fillText(, x, y, width) 在位置(x, y)上绘制并填充指定文本。宽度参数是可选的, 它设置了文本宽度的上限 void
strokeText(, x, y, width) 在位置(x, y)上绘制并描边指定文本。宽度参数是可选的, 它设置了文本宽度的上限 void

文本绘制状态属性:

名称 说明 返回
font 设置绘制文本时使用的字体 字符串
textAlign 设笠文本的对齐方式:start、end、left、weight、center 字符串
textBaseline 设牲文本的基线:top、hanging、middle、alphabetic、ideographic、bottom 字符串

例子:


<html>
    <head>
        <title>Exampletitle>
        <style>
            canvas {border: thin solid black}
            body > * {float:left;}
        style>
    head>
    <body>
        <canvas id="canvas" width="350" height="140">
            Your browser doesn't support the <code>canvascode> element
        canvas>
        <script>
            var ctx = document.getElementById("canvas").getContext("2d");

            ctx.fillStyle = "lightgrey";
            ctx.strokeStyle = "black";
            ctx.lineWidth = 3;

            //绘制文本
            ctx.font = "100px sans-serif";
            ctx.fillText("Hello", 50, 100);
            ctx.strokeText("Hello", 50, 100);
        script>
    body>
html>

6 使用特效和变换

6.1 使用阴影

阴影属性:

名称 说明 返回
shadowBlur 设置阴影的模糊程度 数值
shadowColor 设置阴影的颜色 字符串
shadowOffsetx 设置阴影的水平偏移量 数值
shadowOffsety 设置阴影的垂直偏移量 数值

例子:


<html>
    <head>
        <title>Exampletitle>
        <style>
            canvas {border: thin solid black}
            body > * {float:left;}
        style>
    head>
    <body>
        <canvas id="canvas" width="500" height="140">
            Your browser doesn't support the <code>canvascode> element
        canvas>
        <script>
            var ctx = document.getElementById("canvas").getContext("2d");

            ctx.fillStyle = "lightgrey";
            ctx.strokeStyle = "black";
            ctx.lineWidth = 3;

            //设置阴影
            ctx.shadowOffsetX = 5;
            ctx.shadowOffsetY = 5;
            ctx.shadowBlur = 5;
            ctx.shadowColor = "grey";

            ctx.strokeRect(250, 20, 100, 100);

            ctx.beginPath();
            ctx.arc(420, 70, 50, 0, Math.PI, true);
            ctx.stroke();

            ctx.beginPath();
            ctx.arc(420, 80, 40, 0, Math.PI, false);
            ctx.fill();

            ctx.font = "100px sans-serif";
            ctx.fillText("Hello", 10, 100);
            ctx.strokeText("Hello", 10, 100);
        script>
    body>
html>

6.2 使用透明度

使用globalAlpha属性设置透明度
例子:


<html>
    <head>
        <title>Exampletitle>
        <style>
            canvas {border: thin solid black}
            body > * {float:left;}
        style>
    head>
    <body>
        <canvas id="canvas" width="300" height="120">
            Your browser doesn't support the <code>canvascode> element
        canvas>
        <script>
            var ctx = document.getElementById("canvas").getContext("2d");

            ctx.fillStyle = "lightgrey";
            ctx.strokeStyle = "black";
            ctx.lineWidth = 3;

            ctx.font = "100px sans-serif";
            ctx.fillText("Hello", 10, 100);
            ctx.strokeText("Hello", 10, 100);       

            ctx.fillStyle = "red";
            //设置透明度值可以从0 (完全透明)到l (完全不透明,这是默认值)
            ctx.globalAlpha = 0.5;
            ctx.fillRect(100, 10, 150, 100);
        script>
    body>
html>

6.3 使用合成

globalCompositeOperation 允许的值:

  1. copy:将来源绘制于目标之上,忽略一切透明度设置。
  2. destination-atop:与source-atop相同,但用目标图像替代来源图像,反之亦然。
  3. destination-in:与source- in相同,但用目标图像替代来源图像,反之亦然。
  4. destination-over:与source -over相同, 但用目标图像替代来源图像,反之亦然。
  5. distination-out:与source-ou讨目同,但用目标图像替代来源图像,反之亦然。
  6. lighter:显示来源图像与目标图像的总和,颜色值限制最高255 ( 100%)。
  7. source-atop:在两个图像都不透明处显示来源图像。目标图像不透明但来源图像透明处显示目标图像。其他位置显示为透明。
  8. source-in:来源图像和目标图像都不透明处显示来源图像。其他位置显示为透明。
  9. source-out:来源图像不透明但目标图像透明处显示来源图像。其他位置显示为透明。
  10. source-over:来源图像不透明处显示来源图像。其他位置显示目标图像。
  11. xor:对来源图像和目标图像执行异或运算。

例子:


<html>
    <head>
        <title>Exampletitle>
        <style>
            canvas {border: thin solid black; margin: 4px;}
            body > * {float:left;}
        style>
    head>
    <body>
        <canvas id="canvas" width="300" height="120">
            Your browser doesn't support the <code>canvascode> element
        canvas>
        <label>Composition Value:label><select id="list">
            <option>copyoption>
            <option>destination-atopoption><option>destination-inoption>
            <option>destination-overoption><option>distination-outoption>
            <option>lighteroption><option>source-atopoption>
            <option>source-inoption><option>source-outoption>
            <option>source-overoption><option>xoroption>
        select>
        <script>
            var ctx = document.getElementById("canvas").getContext("2d");

            ctx.fillStyle = "lightgrey";
            ctx.strokeStyle = "black";
            ctx.lineWidth = 3;

            var compVal = "copy";

            document.getElementById("list").onchange = function(e) {
                compVal = e.target.value;
                draw();
            }

            draw();

            function draw() {
                ctx.clearRect(0, 0, 300, 120);

                ctx.globalAlpha = 1.0;
                ctx.font = "100px sans-serif";
                ctx.fillText("Hello", 10, 100);
                ctx.strokeText("Hello", 10, 100);       

                ctx.globalCompositeOperation = compVal;

                ctx.fillStyle = "red";
                ctx.globalAlpha = 0.5;
                ctx.fillRect(100, 10, 150, 100);
            }
        script>
    body>
html>

6.4 使用变换

变换属性:

成员 说明 返回
scale(, ) 沿X轴缩放画布xScale倍, 沿Y轴yScale倍 void
rotate() 使画布围绕点(0, 0)顺时针旋转指定的弧度数 void
translate(, ) 重映射画布坐标为沿X轴x,沿Y轴y void
transform(a, b, c, d, e, f) 合并现有的变换和a~f所指定的矩阵 void
setTransform(a, b, c, d, e, f) 用a~f值所指定的矩阵替换现有的变换 void

例子:


<html>
    <head>
        <title>Exampletitle>
        <style>
            canvas {border: thin solid black; margin: 4px;}
            body > * {float:left;}
        style>
    head>
    <body>
        <canvas id="canvas" width="400" height="200">
            Your browser doesn't support the <code>canvascode> element
        canvas>
        <script>
            var ctx = document.getElementById("canvas").getContext("2d");

            ctx.fillStyle = "lightgrey";
            ctx.strokeStyle = "black";
            ctx.lineWidth = 3;

            ctx.clearRect(0, 0, 300, 120);
            ctx.globalAlpha = 1.0;
            ctx.font = "100px sans-serif";
            ctx.fillText("Hello", 10, 100);
            ctx.strokeText("Hello", 10, 100);       

            //使用缩放、旋转和坐标重映射
            ctx.scale(1.3, 1.3);
            ctx.translate(100, -50);
            ctx.rotate(0.5);                            

            ctx.fillStyle = "red";
            ctx.globalAlpha = 0.5;
            ctx.fillRect(100, 10, 150, 100);

            ctx.strokeRect(0, 0, 300, 200);
        script>
    body>
html>

你可能感兴趣的:(HTML5)