zoukankan      html  css  js  c++  java
  • 你不知道的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>
    

    效果如图所示:

  • 相关阅读:
    HDU 1495 非常可乐
    ja
    Codeforces Good Bye 2016 E. New Year and Old Subsequence
    The 2019 Asia Nanchang First Round Online Programming Contest
    Educational Codeforces Round 72 (Rated for Div. 2)
    Codeforces Round #583 (Div. 1 + Div. 2, based on Olympiad of Metropolises)
    AtCoder Regular Contest 102
    AtCoder Regular Contest 103
    POJ1741 Tree(点分治)
    洛谷P2634 [国家集训队]聪聪可可(点分治)
  • 原文地址:https://www.cnblogs.com/ktddcn/p/11797769.html
Copyright © 2011-2022 走看看