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

摘要:
在上一节中,我们学习了如何使用路径绘制各种形状,但我们只能使用默认的颜色和线条。Functiondraw(){varctx=document.getElementById.getContext;for{for{ctx.fillStyle='rgb';ctx.fill Rect;}}}}效果笔划颜色的示例与前面的示例类似。GlobalAlpha=透明度值示例函数draw(){varctx=document.getElementById.getContext;//drawbackgroundctx.fillStyle=“#FD0”;ctx.fill Rect;ctx.fillStyle=“#6C0”;ctx.fillRect;ctx.fillStyle=“#09F”;ctx.fillRect;ct x.fillStyle=‘#F30’;ctx.fillRec{ctx.beginPath()的透明圆; ctx。弧ctx。fill();}}效果线样式有许多属性和API来设置线样式。LineCap=type设置线端点的样式。MiterLimit=值设置或返回最大斜接长度。GetLineDash()获取当前虚线的样式,并返回设置的虚线的线宽数组。SetLineDash设置当前虚线样式。斜面连接是一个三角形。

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

颜色

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

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 = 'http://t.zoukankan.com/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

免责声明:文章转载自《【canvas学习笔记三】样式和颜色》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇MySQL-binlog解析工具新认知之WinForm窗体程序下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

H5动画开发快车道

前言 以往做一些H5的运营项目,都是动画设计师使用Animate cc(原来的Flash)先设计好动画原型,然后交给我们UI开发来实现。做过动画开发的童鞋都知道动画开发都是比较耗费时间精力的,而且还要高质量的还原动画设计师设计好的动画,来回沟通成本也非常高。 那有没有一种高效的方法来改善这种流程,提高开发效率的同时还能完成高品质的动画呢? 经过一段时间的摸...

H5开发:横屏适配

平常我们做过的需求里,主要是以竖屏式为主,而横屏式较少。对于竖屏式场景来说,大家的经验会比较丰富,因此,此次主要式探讨下横屏式场景下的一些需要注意的点,特别是怎样去做横屏适配。 对于 H5 横屏页面来说,要实现横屏的话,主要是解决两点:1.无论用户手持方向如何,都需要保证屏幕横向显示。2.由于屏幕分辨率的多样化,因此就算是横屏下也是需要进行横屏适配,保证页...

canvas实现平铺水印

欲实现的水印平铺的效果图如下: 从图上看,应该做到以下几点: 文字在X和Y方向上进行平铺; 文字进行了一定的角度的旋转; 水印作为背景,其z-index位置应位于页面内容底部, 即不能覆盖页面主内容; 平铺的水印应能随窗口大小改变进行自适应。 思路: 首先我们先在canvas上绘制如下图所示一小块画布: var tpl = '<canvas...

Android Graphics专题(1)--- Canvas基础

作为Android Graphics专题的开篇。毫无疑问,我们将讨论Android UI技术的核心概念——Canvas。 Canvas是Android UI框架的基础,在Android的控件体系中。全部容器类、控件类在实现上都依赖于Canvas。界面的绘制实质上都是Canvas绘制的。本文将讨论Canvs的由来。并通过实例展示Canvas的基础使用方法。...

使用canvas实现对图片的批量打码

最近有个需求,利用h5的canvas对图片一些涉及个人隐私的地方进行打码再上传,而且最好能实现批量打码.意思是在一张图片上对哪些地方做了打码,后续的所有图片都在同样的地方也可以自动打上码,不用人工一张一张进行图片涂抹了. 例如: 首先想到的是利用canvas的drawImage方法将图片加载进来,然后在利用鼠标的点击移动事件在画布上面划线,很容易就实现了...

html5与EmguCV前后端实现——人脸识别篇(一)

  上个月因为出差的关系,断更了很久,为了补偿大家长久的等待,送上一个新的系列,之前几个系列也会抽空继续更新。   大概半年多前吧,因为工作需要,我开始研究图像识别技术。OpenCV在这方面已经有了很多技术积累,在html5领域也很早就有了这方面的Demo。但是一番学习下来,我发现基本上这方面的文章大都比较零散片面,而且很多关键的代码可能已经老化不能正常使...