• 你不知道的Canvas(二)


    你不知道的Canvas(二)

    一、色彩Colors

    到目前为止,我们只看到过绘制内容的方法。如果我们想要给图形上色,有两个重要的属性可以做到:fillStylestrokeStyle。

    • fillStyle = color

      设置图形的填充颜色。

    • strokeStyle = color

      设置图形轮廓的颜色。

    color 可以是表示 CSS 颜色值的字符串,渐变对象或者图案对象。默认情况下,线条和填充颜色都是黑色(CSS 颜色值 #000000)。

    输入的应该是符合 CSS3 颜色值标准 的有效字符串。下面的例子都表示同一种颜色。

    // 这些 fillStyle 的值均为 '橙色'
    ctx.fillStyle = "orange";
    ctx.fillStyle = "#FFA500";
    ctx.fillStyle = "rgb(255,165,0)";
    ctx.fillStyle = "rgba(255,165,0,1)";
    

    1.fillStyle--调色板

    在本示例里,用两层 for 循环来绘制方格阵列,每个方格不同的颜色。结果如右图,但实现所用的代码却没那么绚丽。我用了两个变量 i 和 j 来为每一个方格产生唯一的 RGB 色彩值,其中仅修改红色和绿色通道的值,而保持蓝色通道的值不变。你可以通过修改这些颜色通道的值来产生各种各样的色板。通过增加渐变的频率,你还可以绘制出类似 Photoshop 里面的那样的调色板。

    <!DOCTYPE html>
    <!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
    <!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
    <!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
    <!--[if gt IE 8]><!-->
    <html class="no-js">
    <!--<![endif]-->
    
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title></title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="">
        <script type="text/javascript">
            function draw() {
                var ctx = document.getElementById('myCanvas').getContext('2d');
                for (var i = 0; i < 6; i++) {
                    for (var j = 0; j < 6; j++) {
                        ctx.fillStyle = 'rgb(' + Math.floor(255 - 42.5 * i) + ','
                            + Math.floor(255 - 42.5 * j) + ',0)';
                        ctx.fillRect(j * 25, i * 25, 25, 25)
                    }
                }
            }
        </script>
    </head>
    
    <body onload="draw();">
        <!--[if lt IE 7]>
                <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
            <![endif]-->
        <canvas id="myCanvas" width="150" height="150"></canvas>
        <script src="" async defer></script>
    </body>
    
    </html>
    

    效果如图所示:

    2. strokeStyle--arc多彩圆圈

    这个示例与上面的有点类似,但这次用到的是 strokeStyle 属性,画的不是方格,而是用 arc 方法来画圆。

    <!DOCTYPE html>
    <!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
    <!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
    <!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
    <!--[if gt IE 8]><!-->
    <html class="no-js">
    <!--<![endif]-->
    
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title></title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="">
        <script type="text/javascript">
            function draw() {
                var canvas = document.getElementById('myCanvas');
                if (canvas.getContext) {
                    var ctx = canvas.getContext('2d');
                    for (var i = 0; i < 6; i++) {
                        for (var j = 0; j < 6; j++) {
                            ctx.strokeStyle = 'rgb(0,' + Math.floor(255 - 42.5 * i) + ',' +
                                Math.floor(255 - 42.5 * j) + ')';
                            ctx.beginPath();
                            ctx.arc(12.5 + j * 25, 12.5 + i * 25, 10, 0, Math.PI * 2, true);
                            ctx.stroke();
                        }
                    }
                }
            }
        </script>
    </head>
    
    <body onload="draw()">
        <!--[if lt IE 7]>
                <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
            <![endif]-->
        <canvas id="myCanvas" width="150" height="150" style="margin: 100px 100px;"></canvas>
        <script src="" async defer></script>
    </body>
    
    </html>
    

    效果如图所示:

    二、透明度Transparency

    除了可以绘制实色图形,我们还可以用 canvas 来绘制半透明的图形。通过设置 globalAlpha 属性或者使用一个半透明颜色作为轮廓或填充的样式。

    • globalAlpha = transparencyValue

      这个属性影响到 canvas 里所有图形的透明度,有效的值范围是 0.0 (完全透明)到 1.0(完全不透明),默认是 1.0。

    globalAlpha 属性在需要绘制大量拥有相同透明度的图形时候相当高效。不过,我认为下面的方法可操作性更强一点。

    因为 strokeStylefillStyle 属性接受符合 CSS 3 规范的颜色值,那我们可以用下面的写法来设置具有透明度的颜色。

    // 指定透明颜色,用于描边和填充样式
    ctx.strokeStyle = "rgba(255,0,0,0.5)";
    ctx.fillStyle = "rgba(255,0,0,0.5)";
    

    rgba() 方法与 rgb() 方法类似,就多了一个用于设置色彩透明度的参数。它的有效范围是从 0.0(完全透明)到 1.0(完全不透明)。

    1. globalAlpha--辐射半透明圆四色格

    在这个例子里,将用四色格作为背景,设置 globalAlpha0.2 后,在上面画一系列半径递增的半透明圆。最终结果是一个径向渐变效果。圆叠加得越多,原先所画的圆的透明度会越低。通过增加循环次数,画更多的圆,从中心到边缘部分,背景图会呈现逐渐消失的效果。

    <!DOCTYPE html>
    <!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
    <!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
    <!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
    <!--[if gt IE 8]><!-->
    <html class="no-js">
    <!--<![endif]-->
    
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title></title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="">
        <script type="text/javascript">
            function draw() {
                var canvas = document.getElementById('myCanvas');
                if (canvas.getContext) {
                    var ctx = canvas.getContext('2d');
                    // 画背景
                    ctx.fillStyle = '#FD0';
                    ctx.fillRect(0, 0, 75, 75);
                    ctx.fillStyle = '#6C0';
                    ctx.fillRect(75, 0, 75, 75);
                    ctx.fillStyle = '#09F';
                    ctx.fillRect(0, 75, 75, 75);
                    ctx.fillStyle = '#F30';
                    ctx.fillRect(75, 75, 75, 75);
                    ctx.fillStyle = '#FFF';
    
                    // 设置透明度值
                    ctx.globalAlpha = 0.2;
    
                    // 画半透明圆
                    for (var i = 0; i < 7; i++) {
                        ctx.beginPath();
                        ctx.arc(75, 75, 10 + 10 * i, 0, Math.PI * 2, true);
                        ctx.fill();
                    }
                }
            }
        </script>
    </head>
    
    <body onload="draw();">
        <!--[if lt IE 7]>
                <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
            <![endif]-->
        <canvas id="myCanvas" width="150" height="150"></canvas>
        <script src="" async defer></script>
    </body>
    
    </html>
    

    效果如图所示:

    2. rgba--四色辐射矩形格

    <!DOCTYPE html>
    <!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
    <!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
    <!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
    <!--[if gt IE 8]><!-->
    <html class="no-js">
    <!--<![endif]-->
    
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title></title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="">
        <script type="text/javascript">
            function draw() {
                var canvas = document.getElementById('myCanvas');
                if (canvas.getContext) {
                    var ctx = canvas.getContext('2d');
                    // 画背景
                    ctx.fillStyle = 'rgb(255,221,0)';
                    ctx.fillRect(0, 0, 150, 37.5);
                    ctx.fillStyle = 'rgb(102,204,0)';
                    ctx.fillRect(0, 37.5, 150, 37.5);
                    ctx.fillStyle = 'rgb(0,153,255)';
                    ctx.fillRect(0, 75, 150, 37.5);
                    ctx.fillStyle = 'rgb(255,51,0)';
                    ctx.fillRect(0, 112.5, 150, 37.5);
    
                    // 画半透明矩形
                    for (var i = 0; i < 10; i++) {
                        ctx.fillStyle = 'rgba(255,255,255,' + (i + 1) / 10 + ')';
                        for (var j = 0; j < 4; j++) {
                            ctx.fillRect(5 + i * 14, 5 + j * 37.5, 14, 27.5)
                        }
                    }
                }
            }
        </script>
    </head>
    
    <body onload="draw();">
        <!--[if lt IE 7]>
                <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
            <![endif]-->
        <canvas id="myCanvas" width="150" height="150"></canvas>
        <script src="" async defer></script>
    </body>
    
    </html>
    

    效果如图所示:

    三、线型Line Style

    可以通过一系列属性来设置线的样式。

    • lineWidth = value

      设置线条宽度。

    • lineCap = type

      设置线条末端样式。

    • lineJoin = type

      设定线条与线条间接合处的样式。

    • miterLimit = value

      限制当两条线相交时交接处最大长度;所谓交接处长度(斜接长度)是指线条交接处内角顶点到外角顶点的长度。

    • getLineDash()

      返回一个包含当前虚线样式,长度为非负偶数的数组。

    • setLineDash(segments)

      设置当前虚线样式。

    • lineDashOffset = value

      设置虚线样式的起始偏移量。

    通过以下的样例可能会更加容易理解。

    1. lineWidth 属性的例子

    这个属性设置当前绘线的粗细。属性值必须为正数。默认值是1.0。

    线宽是指给定路径的中心到两边的粗细。换句话说就是在路径的两边各绘制线宽的一半。因为画布的坐标并不和像素直接对应,当需要获得精确的水平或垂直线的时候要特别注意。

    在下面的例子中,用递增的宽度绘制了10条直线。最左边的线宽1.0单位。并且,最左边的以及所有宽度为奇数的线并不能精确呈现,这就是因为路径的定位问题。

    <!DOCTYPE html>
    <!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
    <!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
    <!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
    <!--[if gt IE 8]><!-->
    <html class="no-js">
    <!--<![endif]-->
    
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title></title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="">
        <script type="text/javascript">
            function draw() {
                var ctx = document.getElementById('myCanvas').getContext('2d');
                for (var i = 0; i < 10; i++) {
                    ctx.beginPath();
                    ctx.lineWidth = 1 + i;
                    ctx.moveTo(5 + i * 14, 5);
                    ctx.lineTo(5 + i * 14, 140);
                    ctx.stroke();
                }
            }
        </script>
    </head>
    
    <body onload="draw();">
        <!--[if lt IE 7]>
                <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
            <![endif]-->
        <canvas id="myCanvas" width="150" height="150"></canvas>
        <script src="" async defer></script>
    </body>
    
    </html>
    

    效果如图所示:

    2. lineCap 属性的例子

    img属性 lineCap 的值决定了线段端点显示的样子。它可以为下面的三种的其中之一:buttroundsquare。默认是 butt。

    在这个例子里面,我绘制了三条直线,分别赋予不同的 lineCap 值。还有两条辅助线,为了可以看得更清楚它们之间的区别,三条线的起点终点都落在辅助线上。

    最左边的线用了默认的 butt 。可以注意到它是与辅助线齐平的。中间的是 round 的效果,端点处加上了半径为一半线宽的半圆。右边的是 square 的效果,端点处加上了等宽且高度为一半线宽的方块。

    <!DOCTYPE html>
    <!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
    <!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
    <!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
    <!--[if gt IE 8]><!-->
    <html class="no-js">
    <!--<![endif]-->
    
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title></title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="">
        <script type="text/javascript">
            function draw() {
                var ctx = document.getElementById('myCanvas').getContext('2d');
    
                var lineCap = ['butt', 'round', 'square'];
    
                // 创建路径
                ctx.strokeStyle = '#09f';
                ctx.beginPath();
                ctx.moveTo(10, 10);
                ctx.lineTo(140, 10);
                ctx.moveTo(10, 140);
                ctx.lineTo(140, 140);
                ctx.stroke();
    
                // 画线条
                ctx.strokeStyle = 'black';
                for (var i = 0; i < lineCap.length; i++) {
                    ctx.lineWidth = 15;
                    ctx.lineCap = lineCap[i];
                    ctx.beginPath();
                    ctx.moveTo(25 + i * 50, 10);
                    ctx.lineTo(25 + i * 50, 140);
                    ctx.stroke();
                }
            }
        </script>
    </head>
    
    <body onload="draw();">
        <!--[if lt IE 7]>
                <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
            <![endif]-->
        <canvas id="myCanvas" width="150" height="150"></canvas>
        <script src="" async defer></script>
    </body>
    
    </html>
    

    3. lineJoin属性的例子

    imglineJoin 的属性值决定了图形中两线段连接处所显示的样子。它可以是这三种之一:round, bevelmiter。默认是 miter``。

    这里我同样用三条折线来做例子,分别设置不同的 lineJoin 值。最上面一条是 round 的效果,边角处被磨圆了,圆的半径等于线宽。中间和最下面一条分别是 bevel 和 miter 的效果。当值是 miter 的时候,线段会在连接处外侧延伸直至交于一点,延伸效果受到下面将要介绍的 miterLimit 属性的制约。

    <!DOCTYPE html>
    <!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
    <!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
    <!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
    <!--[if gt IE 8]><!-->
    <html class="no-js">
    <!--<![endif]-->
    
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title></title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="">
        <script type="text/javascript">
            function draw() {
                var ctx = document.getElementById('myCanvas').getContext('2d');
                var lineJoin = ['round', 'bevel', 'miter'];
                ctx.lineWidth = 10;
                for (var i = 0; i < lineJoin.length; i++) {
                    ctx.lineJoin = lineJoin[i];
                    ctx.beginPath();
                    ctx.moveTo(-5, 5 + i * 40);
                    ctx.lineTo(35, 45 + i * 40);
                    ctx.lineTo(75, 5 + i * 40);
                    ctx.lineTo(115, 45 + i * 40);
                    ctx.lineTo(155, 5 + i * 40);
                    ctx.stroke();
                }
            }
        </script>
    </head>
    
    <body onload="draw();">
        <!--[if lt IE 7]>
                <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
            <![endif]-->
        <canvas id="myCanvas" width="150" height="150"></canvas>
        <script src="" async defer></script>
    </body>
    
    </html>
    

    效果如图所示:

    4. 使用虚线

    setLineDash 方法和 lineDashOffset 属性来制定虚线样式. setLineDash 方法接受一个数组,来指定线段与间隙的交替;lineDashOffset 属性设置起始偏移量.

    在这个例子中,我们要创建一个蚂蚁线的效果。它往往应用在计算机图形程序选区工具动效中。它可以帮助用户通过动画的边界来区分图像背景选区边框。

    四、渐变Gradients

    就好像一般的绘图软件一样,我们可以用线性或者径向的渐变来填充或描边。我们用下面的方法新建一个 canvasGradient 对象,并且赋给图形的 fillStylestrokeStyle 属性。

    • createLinearGradient(x1, y1, x2, y2)

      createLinearGradient 方法接受 4 个参数,表示渐变的起点 (x1,y1) 与终点 (x2,y2)。

    • createRadialGradient(x1, y1, r1, x2, y2, r2)

      createRadialGradient 方法接受 6 个参数,前三个定义一个以 (x1,y1) 为原点,半径为 r1 的圆,后三个参数则定义另一个以 (x2,y2) 为原点,半径为 r2 的圆。

    var lineargradient = ctx.createLinearGradient(0,0,150,150);
    var radialgradient = ctx.createRadialGradient(75,75,0,75,75,100);
    

    创建出 canvasGradient 对象后,我们就可以用 addColorStop 方法给它上色了。

    • gradient.addColorStop(position, color)

      addColorStop 方法接受 2 个参数,position 参数必须是一个 0.0 与 1.0 之间的数值,表示渐变中颜色所在的相对位置。例如,0.5 表示颜色会出现在正中间。color 参数必须是一个有效的 CSS 颜色值(如 #FFF, rgba(0,0,0,1),等等)。

    你可以根据需要添加任意多个色标(color stops)。下面是最简单的线性黑白渐变的例子。

    var lineargradient = ctx.createLinearGradient(0,0,150,150);
    lineargradient.addColorStop(0,'white');
    lineargradient.addColorStop(1,'black');
    

    1.createLinearGradient 的例子

    img

    本例中,有两种不同的渐变。第一种是背景色渐变,你会发现,我给同一位置设置了两种颜色,你也可以用这来实现突变的效果,就像这里从白色到绿色的突变。一般情况下,色标的定义是无所谓顺序的,但是色标位置重复时,顺序就变得非常重要了。所以,保持色标定义顺序和它理想的顺序一致,结果应该没什么大问题。

    第二种渐变,我并不是从 0.0 位置开始定义色标,因为那并不是那么严格的。在 0.5 处设一黑色色标,渐变会默认认为从起点到色标之间都是黑色。

    你会发现,strokeStylefillStyle 属性都可以接受 canvasGradient 对象。

    2. createRadialGradient的例子

    这个例子,我定义了 4 个不同的径向渐变。由于可以控制渐变的起始与结束点,所以我们可以实现一些比(如在 Photoshop 中所见的)经典的径向渐变更为复杂的效果。(经典的径向渐变是只有一个中心点,简单地由中心点向外围的圆形扩张)

    <!DOCTYPE html>
    <!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
    <!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
    <!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
    <!--[if gt IE 8]><!-->
    <html class="no-js">
    <!--<![endif]-->
    
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title></title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="">
        <script type="text/javascript">
            function draw() {
                var canvas = document.getElementById('myCanvas');
                var ctx = canvas.getContext('2d');
                // 创建渐变
                var radgrad = ctx.createRadialGradient(45, 45, 10, 52, 50, 30);
                radgrad.addColorStop(0, '#A7D30C');
                radgrad.addColorStop(0.9, '#019F62');
                radgrad.addColorStop(1, 'rgba(1,159,98,0)');
    
                var radgrad2 = ctx.createRadialGradient(105, 105, 20, 112, 120, 50);
                radgrad2.addColorStop(0, '#FF5F98');
                radgrad2.addColorStop(0.75, '#FF0188');
                radgrad2.addColorStop(1, 'rgba(255,1,136,0)');
    
                var radgrad3 = ctx.createRadialGradient(95, 15, 15, 102, 20, 40);
                radgrad3.addColorStop(0, '#00C9FF');
                radgrad3.addColorStop(0.8, '#00B5E2');
                radgrad3.addColorStop(1, 'rgba(0,201,255,0)');
    
                var radgrad4 = ctx.createRadialGradient(0, 150, 50, 0, 140, 90);
                radgrad4.addColorStop(0, '#F4F201');
                radgrad4.addColorStop(0.8, '#E4C700');
                radgrad4.addColorStop(1, 'rgba(228,199,0,0)');
    
                // 画图形
                ctx.fillStyle = radgrad4;
                ctx.fillRect(0, 0, 150, 150);
                ctx.fillStyle = radgrad3;
                ctx.fillRect(0, 0, 150, 150);
                ctx.fillStyle = radgrad2;
                ctx.fillRect(0, 0, 150, 150);
                ctx.fillStyle = radgrad;
                ctx.fillRect(0, 0, 150, 150);
            }
        </script>
    </head>
    
    <body onload="draw();">
        <!--[if lt IE 7]>
                <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
            <![endif]-->
        <canvas id="myCanvas" width="150" height="150"></canvas>
        <script src="" async defer></script>
    </body>
    
    </html>
    

    效果如图所示:

    这里,我让起点稍微偏离终点,这样可以达到一种球状 3D 效果。但最好不要让里圆与外圆部分交叠,那样会产生什么效果就真是不得而知了。

    4 个径向渐变效果的最后一个色标都是透明色。如果想要两色标直接的过渡柔和一些,只要两个颜色值一致就可以了。代码里面看不出来,是因为我用了两种不同的颜色表示方法,但其实是相同的,#019F62 = rgba(1,159,98,1)。

    五、图案样式Patterns

    上面的一个例子里面,我用了循环来实现图案的效果。其实,有一个更加简单的方法:createPattern。

    • createPattern(image, type)

      该方法接受两个参数。Image 可以是一个 Image 对象的引用,或者另一个 canvas 对象。Type 必须是下面的字符串值之一:repeatrepeat-xrepeat-yno-repeat

    注意: 用 canvas 对象作为 Image 参数在 Firefox 1.5 (Gecko 1.8) 中是无效的。

    图案的应用跟渐变很类似的,创建出一个 pattern 之后,赋给 fillStylestrokeStyle 属性即可。

    var img = new Image();
    img.src = 'someimage.png';
    var ptrn = ctx.createPattern(img,'repeat');
    

    注意:与 drawImage 有点不同,你需要确认 image 对象已经装载完毕,否则图案可能效果不对的。

    1. createPattern的例子

    在最后的例子中,我创建一个图案然后赋给了 fillStyle 属性。唯一要注意的是,使用 Image 对象的 onload handler 来确保设置图案之前图像已经装载完毕。

    <!DOCTYPE html>
    <!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
    <!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
    <!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
    <!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
        <head>
            <meta charset="utf-8">
            <meta http-equiv="X-UA-Compatible" content="IE=edge">
            <title></title>
            <meta name="description" content="">
            <meta name="viewport" content="width=device-width, initial-scale=1">
            <link rel="stylesheet" href="">
            <script type="text/javascript">
                function draw() {
                    var canvas = document.getElementById('myCanvas');
                    var ctx = canvas.getContext('2d');
    
                    //创建新Image对象,用做图案
                    var img = new Image();
                    img.src = 'https://pic.cnblogs.com/avatar/1489272/20190625145401.png';
                    img.onload = function() {
    
                        //创建图案
                        var pattern = ctx.createPattern(img, "repeat");
                        ctx.fillStyle = pattern;
                        ctx.fillRect(0, 0, 150, 150);
                    }
                }
            </script>
        </head>
        <body onload="draw();">
            <!--[if lt IE 7]>
                <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
            <![endif]-->
            <canvas id="myCanvas" width="150" height="150">
    
            </canvas>
            <script src="" async defer></script>
        </body>
    </html>
    

    效果如图所示:

    六、阴影Shadows

    shadowOffsetX = float

    shadowOffsetXshadowOffsetY 用来设定阴影在 X 和 Y 轴的延伸距离,它们是不受变换矩阵所影响的。负值表示阴影会往上或左延伸,正值则表示会往下或右延伸,它们默认都为 0

    shadowOffsetY = float

    shadowOffsetX 和 shadowOffsetY 用来设定阴影在 X 和 Y 轴的延伸距离,它们是不受变换矩阵所影响的。负值表示阴影会往上或左延伸,正值则表示会往下或右延伸,它们默认都为 0

    shadowBlur = float

    shadowBlur 用于设定阴影的模糊程度,其数值并不跟像素数量挂钩,也不受变换矩阵的影响,默认为 0

    shadowColor = color

    shadowColor 是标准的 CSS 颜色值,用于设定阴影颜色效果,默认是全透明的黑色。

    1. 文字阴影的例子

    <!DOCTYPE html>
    <!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
    <!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
    <!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
    <!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
        <head>
            <meta charset="utf-8">
            <meta http-equiv="X-UA-Compatible" content="IE=edge">
            <title></title>
            <meta name="description" content="">
            <meta name="viewport" content="width=device-width, initial-scale=1">
            <link rel="stylesheet" href="">
            <script type="text/javascript">
                function draw() {
                    var canvas = document.getElementById('myCanvas');
                    var ctx = canvas.getContext('2d');
    
                    ctx.shadowOffsetX = 2;
                    ctx.shadowOffestY = 2;
                    ctx.shadowBlur = 2;
                    ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';
    
                    ctx.font = '20px Times New Roman';
                    ctx.fillStyle = 'red';
                    ctx.fillText("Hello, World!", 5, 30);
                }
            </script>
        </head>
        <body onload="draw();">
            <!--[if lt IE 7]>
                <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
            <![endif]-->
            <canvas id="myCanvas" width="150" height="150"></canvas>
            <script src="" async defer></script>
        </body>
    </html>
    

    效果如图所示:

    七、Canvas填充规则

    当我们用到 fill(或者 clipisPointinPath)你可以选择一个填充规则,该填充规则根据某处在路径的外面或者里面来决定该处是否被填充,这对于自己与自己路径相交或者路径被嵌套的时候是有用的。

    两个可能的值:

    • **"nonzero**": non-zero winding rule, 默认值.
    • **"evenodd"**: even-odd winding rule.

    这个例子,我们用填充规则 evenodd

    <!DOCTYPE html>
    <!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
    <!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
    <!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
    <!--[if gt IE 8]><!-->
    <html class="no-js">
    <!--<![endif]-->
    
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title></title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="">
        <script type="text/javascript">
            function draw() {
                var canvas = document.getElementById('myCanvas');
                var ctx = canvas.getContext('2d');
                ctx.beginPath();
                ctx.arc(50, 50, 30, 0, Math.PI * 2, true);
                ctx.arc(50, 50, 15, 0, Math.PI * 2, true);
                ctx.fill("evenodd");
            }
        </script>
    </head>
    
    <body onload="draw();">
        <!--[if lt IE 7]>
                <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
            <![endif]-->
        <canvas id="myCanvas" width="150" height="150"></canvas>
        <script src="" async defer></script>
    </body>
    
    </html>
    

    效果如图所示:

  • 相关阅读:
    118. Pascal's Triangle
    697. Degree of an Array
    1013. Partition Array Into Three Parts With Equal Sum
    167. Two Sum II
    ol7 禁用mysql 自启动
    pgsql常用命令
    清空history 命令记录
    pgsql启动报错
    在rhel 7.4中安装glibc-devel-2.17-196.el7.i686包的过程详录
    postgresql-9.2 install
  • 原文地址:https://www.cnblogs.com/ktddcn/p/11797769.html
Copyright © 2020-2023  润新知