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, 高度是hvoid
stroke()给子路径描述的图形绘制轮廓线void

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

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

1.1 用线条绘制路径

<!DOCTYPE HTML>
<html>
    <head>
        <title>Example</title>
        <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>canvas</code> 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 绘制矩形

<!DOCTYPE HTML>
<html>
    <head>
        <title>Example</title>
        <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>canvas</code> 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方法

<!DOCTYPE HTML>
<html>
    <head>
        <title>Example</title>
        <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>canvas</code> 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方法

<!DOCTYPE HTML>
<html>
    <head>
        <title>Example</title>
        <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>canvas</code> 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方法会绘制一条曲线,范围是从上一条子路径的终点到第五个与第六个方法参数所指定的点。控制点有两个,它们由前四个参数指定。

例子:

<!DOCTYPE HTML>
<html>
    <head>
        <title>Example</title>
        <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>canvas</code> 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方法要少两个。

例子:

<!DOCTYPE HTML>
<html>
    <head>
        <title>Example</title>
        <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>canvas</code> 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。

例子:

<!DOCTYPE HTML>
<html>
    <head>
        <title>Example</title>
        <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>canvas</code> 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(<text>, x, y, width)在位置(x, y)上绘制并填充指定文本。宽度参数是可选的, 它设置了文本宽度的上限void
strokeText(<text>, x, y, width)在位置(x, y)上绘制并描边指定文本。宽度参数是可选的, 它设置了文本宽度的上限void

文本绘制状态属性:

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

例子:

<!DOCTYPE HTML>
<html>
    <head>
        <title>Example</title>
        <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>canvas</code> 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设置阴影的垂直偏移量数值

例子:

<!DOCTYPE HTML>
<html>
    <head>
        <title>Example</title>
        <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>canvas</code> 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属性设置透明度
例子:

<!DOCTYPE HTML>
<html>
    <head>
        <title>Example</title>
        <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>canvas</code> 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:对来源图像和目标图像执行异或运算。

例子:

<!DOCTYPE HTML>
<html>
    <head>
        <title>Example</title>
        <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>canvas</code> element
        </canvas>
        <label>Composition Value:</label><select id="list">
            <option>copy</option>
            <option>destination-atop</option><option>destination-in</option>
            <option>destination-over</option><option>distination-out</option>
            <option>lighter</option><option>source-atop</option>
            <option>source-in</option><option>source-out</option>
            <option>source-over</option><option>xor</option>
        </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(<xScale>, <yScale>)沿X轴缩放画布xScale倍, 沿Y轴yScale倍void
rotate(<angle>)使画布围绕点(0, 0)顺时针旋转指定的弧度数void
translate(<x>, <y>)重映射画布坐标为沿X轴x,沿Y轴yvoid
transform(a, b, c, d, e, f)合并现有的变换和a~f所指定的矩阵void
setTransform(a, b, c, d, e, f)用a~f值所指定的矩阵替换现有的变换void

例子:

<!DOCTYPE HTML>
<html>
    <head>
        <title>Example</title>
        <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>canvas</code> 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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值