• 【canvas学习笔记三】样式和颜色


    上一节我们学习了如何用路径绘制各种形状,但我们只能用默认的颜色和线条。这节就来学习设置不同的颜色和线条样式。

    颜色

    设置颜色主要有两个属性:

    fillStyle = color
    设置填充颜色
    strokeStyle = color
    设置描边颜色

    颜色值可以用十六进制也可以用一些内置的颜色字符,还可以用rgb和rgba格式。

    例子:

    // these all set the fillStyle to 'orange'
    
    ctx.fillStyle = 'orange';
    ctx.fillStyle = '#FFA500';
    ctx.fillStyle = 'rgb(255, 165, 0)';
    ctx.fillStyle = 'rgba(255, 165, 0, 1)';
    

    下面来看看一个填充颜色的例子和一个描边颜色的例子:

    填充颜色示例

    在下面这个例子中,我们创建了6X6的方块,每个方块都填充了不同的颜色。根据i、j的值,生成R通道和G通道的值,而B通道的值为固定值0。

    function draw() {
      var ctx = document.getElementById('canvas').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);
        }
      }
    }
    

    效果

    image

    描边颜色示例

    这个例子和上一个例子类似。在这个例子中,R通道的值固定,G和B通道的值根据i、j的值变化。

    function draw() {
        var ctx = document.getElementById('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();
          }
        }
      }
    

    效果

    image

    Tips:

    如果没有设置fillStyle或strokeStyle,则默认的fillStyle或strokeStyle是黑色,如果设置了fillStyle或strokeStyle,则默认的颜色就变成设置的颜色。

    透明

    我们可以直接通过rgba的方式设置颜色从而实现透明的效果,如下:

    // Assigning transparent colors to stroke and fill style
    
    ctx.strokeStyle = 'rgba(255, 0, 0, 0.5)';
    ctx.fillStyle = 'rgba(255, 0, 0, 0.5)';
    

    我们还可以设置全局的透明度,设置了全局透明度,之后绘制的图形都会是这个透明度。全局透明度的值是0~1。

    globalAlpha = transparencyValue

    例子

    function draw() {
      var ctx = document.getElementById('canvas').getContext('2d');
      // draw background
      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';
    
      // set global transparency value
      ctx.globalAlpha = 0.2;
    
      // Draw semi transparent circles
      for (i = 0; i < 7; i++) {
        ctx.beginPath();
        ctx.arc(75, 75, 10 + 10 * i, 0, Math.PI * 2, true);
        ctx.fill();
      }
    }
    

    效果

    image

    线条样式

    有很多属性和API可以设置线条的样式。

    lineWidth = value
    设置线条的宽度。
    lineCap = type
    设置线条端点的样式。
    lineJoin = type
    设置线条连接处的样式。
    miterLimit = value
    设置或返回最大斜接长度。
    getLineDash()
    获取当前虚线的样式,返回设置虚线的线宽数组。
    setLineDash(segments)
    设置当前虚线样式。
    lineDashOffset = value
    确定一条线从哪里开始是虚线。

    lineWidth

    线宽这个属性就是设置线的粗细。它的值不能是负数,单位是像素。默认值是1像素。
    下面我们先来看一个例子:

    function draw() {
      var ctx = document.getElementById('canvas').getContext('2d');
      for (var i = 0; i < 10; i++) {
        ctx.lineWidth = 1 + i;
        ctx.beginPath();
        ctx.moveTo(5 + i * 14, 5);
        ctx.lineTo(5 + i * 14, 140);
        ctx.stroke();
      }
    }
    

    效果:
    image
    注意看的话会发现,奇数位置的线条边缘有些模糊,这是因为位置不对,这就需要了解线生成的机制。
    image
    如图,图中一个方格表示一个像素。如果要在坐标(3,1)到坐标(3,5)之间画一条1像素宽的直线,那么线的宽度将会如图中第一张图的深蓝部分所示,左右的宽度只占半个像素。半个像素是无法绘制的,所以实际绘制的线条是第二章图所示的内容。它实际的位置并不正确。

    lineCap

    lineCap属性设置了线段端点的样式。它的值有三种:

    butt (默认值)
    端点是方的。
    round
    端点是圆的。
    square
    端点多出一个宽度和线宽一样,长度是线宽一般的方块。

    三种样式从左到右如图:
    image

    lineJoin

    这个属性设置了线段连接处的样式。
    它的值有三种:

    round
    连接处是圆的。
    bevel
    连接处是一个三角形。
    miter(默认值)
    连接处是一个菱形。

    从上到下效果如图:
    image

    miterLimit

    miterlimit属性就是对上文miter作控制的一个属性。简单的说,miterlimit属性就是控制miter的大小的。
    下面来简单说明一下它的效果:
    image
    image
    image
    上面三张图分别是miterlimit属性值为1、5、10时的效果。miterlimit属性实际上久时hi限制了连接处菱形的大小。

    setLineDash(segments) && lineDashOffset

    利用setLineDash(segments)方法和lineDashOffset属性就可以自己设置虚线的样式。
    setLineDash(segments)接受一个数组作参数,数组的第一个元素规定了虚线中每一小段虚线的长度,第二个参数规定了虚线中每一小段虚线之间的间隔距离。
    lineDashOffset设置了虚线样式是从哪里开始的。
    下面用一个蚂蚁线的动画例子来说明一下它们的用法:

    var ctx = document.getElementById('canvas').getContext('2d');
    var offset = 0;
    
    function draw() {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      ctx.setLineDash([4, 2]);
      ctx.lineDashOffset = -offset;
      ctx.strokeRect(10, 10, 100, 100);
    }
    
    function march() {
      offset++;
      if (offset > 16) {
        offset = 0;
      }
      draw();
      setTimeout(march, 20);
    }
    
    march();
    

    效果

    image
    通过间隔一段时间增加lineDashOffset的方法达到虚线移动的效果。这个效果经常用来表示选中。

    渐变

    canvas可以创建渐变对象,将渐变对象赋值给strokeStyle或fillStyle,就可以画出渐变的颜色。
    有两种渐变对象,一种是线性渐变,一种是径向渐变:

    createLinearGradient(x1, y1, x2, y2)
    创建线性渐变对象,从点(x1, y1)开始,至点(x2, y2)结束。
    createRadialGradient(x1, y1, r1, x2, y2, r2)
    创建径向渐变对象,参数是两个圆,一个圆圆心是(x1, y1),半径是r1,另一个圆圆心是(x2, y2),半径是r2。

    例子:

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

    这样就创建了渐变对象。然后用addColorStop方法添加颜色:

    gradient.addColorStop(position, color)
    position的值是0~1,这决定了颜色相对于渐变对象的位置,color是表示颜色的字符串,只要CSS中用来表示的颜色的方法都可以,比如十六进制、rgb或rgba。

    线性渐变例子

    function draw() {
      var ctx = document.getElementById('canvas').getContext('2d');
    
      // Create gradients
      var lingrad = ctx.createLinearGradient(0, 0, 0, 150);
      lingrad.addColorStop(0, '#00ABEB');
      lingrad.addColorStop(0.5, '#fff');
      lingrad.addColorStop(0.5, '#26C000');
      lingrad.addColorStop(1, '#fff');
    
      var lingrad2 = ctx.createLinearGradient(0, 50, 0, 95);
      lingrad2.addColorStop(0.5, '#000');
      lingrad2.addColorStop(1, 'rgba(0, 0, 0, 0)');
    
      // assign gradients to fill and stroke styles
      ctx.fillStyle = lingrad;
      ctx.strokeStyle = lingrad2;
      
      // draw shapes
      ctx.fillRect(10, 10, 130, 130);
      ctx.strokeRect(50, 50, 50, 50);
    
    }
    

    效果

    image

    径向渐变例子

    function draw() {
      var ctx = document.getElementById('canvas').getContext('2d');
    
      // Create gradients
      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)');
      
      // draw shapes
      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);
    }
    

    效果

    image

    图案

    现在介绍的这个方法可以用图片去填充图形。

    createPattern(image, type)  
    这个方法创建并返回了一个pattern对象,image参数是CanvasImageSource,HTML图片元素、canvas或

    type参数有如下几种值:

    repeat
    在垂直和水平方向上重复平铺图片。
    repeat-x
    水平平铺图片。
    repeat-y
    垂直平铺图片。
    no-repeat
    不平铺重复图片。

    pattern对象的创建方法和渐变对象类似:

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

    注意

    这个方法和drawImage类似,要确保图片加载完,否则图片不能显示。
    

    例子

    function draw() {
      var ctx = document.getElementById('canvas').getContext('2d');
    
      // create new image object to use as pattern
      var img = new Image();
      img.src = 'https://mdn.mozillademos.org/files/222/Canvas_createpattern.png';
      img.onload = function() {
    
        // create pattern
        var ptrn = ctx.createPattern(img, 'repeat');
        ctx.fillStyle = ptrn;
        ctx.fillRect(0, 0, 150, 150);
    
      }
    }
    

    效果

    image

    阴影

    阴影涉及四个属性:

    shadowOffsetX = float
    阴影水平方向距离。默认值为0。不受transform变换矩阵影响。
    shadowOffsetY = float
    阴影垂直方向距离。默认值为0。不受transform变换矩阵影响。
    shadowBlur = float
    阴影模糊大小。默认值为0。模糊数值并不是模糊的像素的大小,是模糊的程度。不受transform变换矩阵影响。
    shadowColor = color
    阴影颜色。默认值是全透明黑色。

    例子

    function draw() {
      var ctx = document.getElementById('canvas').getContext('2d');
    
      ctx.shadowOffsetX = 2;
      ctx.shadowOffsetY = 2;
      ctx.shadowBlur = 2;
      ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';
     
      ctx.font = '20px Times New Roman';
      ctx.fillStyle = 'Black';
      ctx.fillText('Sample String', 5, 30);  // 后面两个参数是x, y坐标
    }
    

    效果

    image

    Canvas填充规则

    如果两个路径交叉或重叠,我们可以设置填充的方式。
    参数有两种:

    "nonzero": 默认值,按照non-zero winding rule规则填充。
    "evenodd": 按照even-odd winding rule规则填充。

    例子

    function draw() {
      var ctx = document.getElementById('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');
    }
    

    效果

    image

  • 相关阅读:
    Eclipse运行单个Junit 单元测试
    梯形法求定积分(一)设计梯形法求积分的类模板,梯形法
    写一个顺序表模板,包括顺序表的基本功能,例如查找,插
    对于静态成员函数和静态成员变量的练习
    梯形法求定积分(二)设计一个函数模板,独立的非成员函
    各位高手帮我看看这个清屏程序
    对于静态成员函数和静态成员变量的练习
    二分法的递归算法和迭代算法,算法作为有序表模板类的成
    梯形法求定积分(一)设计梯形法求积分的类模板,梯形法
    二分法的递归算法和迭代算法,算法作为有序表模板类的成
  • 原文地址:https://www.cnblogs.com/-867259206/p/7275864.html
Copyright © 2020-2023  润新知