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

颜色

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

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);
}
}
}

效果

描边颜色示例

这个例子和上一个例子类似。在这个例子中,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();
}
}
}

效果

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();
}
}

效果

线条样式

有很多属性和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();
}
}

效果:



注意看的话会发现,奇数位置的线条边缘有些模糊,这是因为位置不对,这就需要了解线生成的机制。



如图,图中一个方格表示一个像素。如果要在坐标(3,1)到坐标(3,5)之间画一条1像素宽的直线,那么线的宽度将会如图中第一张图的深蓝部分所示,左右的宽度只占半个像素。半个像素是无法绘制的,所以实际绘制的线条是第二章图所示的内容。它实际的位置并不正确。

lineCap

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

butt (默认值)

端点是方的。

round

端点是圆的。

square

端点多出一个宽度和线宽一样,长度是线宽一般的方块。

三种样式从左到右如图:

lineJoin

这个属性设置了线段连接处的样式。

它的值有三种:

round

连接处是圆的。

bevel

连接处是一个三角形。

miter(默认值)

连接处是一个菱形。

从上到下效果如图:

miterLimit

miterlimit属性就是对上文miter作控制的一个属性。简单的说,miterlimit属性就是控制miter的大小的。

下面来简单说明一下它的效果:







上面三张图分别是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();

效果



通过间隔一段时间增加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); }

效果

径向渐变例子

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);
}

效果

图案

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

createPattern(image, type)  

这个方法创建并返回了一个pattern对象,image参数是CanvasImageSource,HTML图片元素、canvas或元素等等。type参数是一个字符串,决定了图片的使用方式。

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); }
}

效果

阴影

阴影涉及四个属性:

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坐标
}

效果

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');
}

效果

【canvas学习笔记三】样式和颜色的更多相关文章

  1. 学习笔记(三)--->《Java 8编程官方参考教程(第9版).pdf》:第十章到十二章学习笔记

    回到顶部 注:本文声明事项. 本博文整理者:刘军 本博文出自于: <Java8 编程官方参考教程>一书 声明:1:转载请标注出处.本文不得作为商业活动.若有违本之,则本人不负法律责任.违法 ...

  2. angular学习笔记(三十)-指令(2)-restrice,replace,template

    本篇主要讲解指令中的 restrict属性, replace属性, template属性 这三个属性 一. restrict: 字符串.定义指令在视图中的使用方式,一共有四种使用方式: 1. 元素: ...

  3. Oracle学习笔记三 SQL命令

    SQL简介 SQL 支持下列类别的命令: 1.数据定义语言(DDL) 2.数据操纵语言(DML) 3.事务控制语言(TCL) 4.数据控制语言(DCL)  

  4. [Firefly引擎][学习笔记三][已完结]所需模块封装

    原地址:http://www.9miao.com/question-15-54671.html 学习笔记一传送门学习笔记二传送门 学习笔记三导读:        笔记三主要就是各个模块的封装了,这里贴 ...

  5. JSP学习笔记(三):简单的Tomcat Web服务器

    注意:每次对Tomcat配置文件进行修改后,必须重启Tomcat 在E盘的DATA文件夹中创建TomcatDemo文件夹,并将Tomcat安装路径下的webapps/ROOT中的WEB-INF文件夹复 ...

  6. java之jvm学习笔记三(Class文件检验器)

    java之jvm学习笔记三(Class文件检验器) 前面的学习我们知道了class文件被类装载器所装载,但是在装载class文件之前或之后,class文件实际上还需要被校验,这就是今天的学习主题,cl ...

  7. VSTO学习笔记(三) 开发Office 2010 64位COM加载项

    原文:VSTO学习笔记(三) 开发Office 2010 64位COM加载项 一.加载项简介 Office提供了多种用于扩展Office应用程序功能的模式,常见的有: 1.Office 自动化程序(A ...

  8. Java IO学习笔记三

    Java IO学习笔记三 在整个IO包中,实际上就是分为字节流和字符流,但是除了这两个流之外,还存在了一组字节流-字符流的转换类. OutputStreamWriter:是Writer的子类,将输出的 ...

  9. NumPy学习笔记 三 股票价格

    NumPy学习笔记 三 股票价格 <NumPy学习笔记>系列将记录学习NumPy过程中的动手笔记,前期的参考书是<Python数据分析基础教程 NumPy学习指南>第二版.&l ...

随机推荐

  1. C++ string 详细用法

    string不是STL的容器(知道这一点的时候我也很吃惊),但是它与STL容器有着很多相似的操作,不需要担心长度问题,还封装了多种多样的方法,十分好用. 用到的库 #include <strin ...

  2. Django框架中使用Echart进行统计的SQL语句

    最近想用Echart做数据统计的图形显示,数据来源是MySQL数据库,自然需要根据不同的搜索条件筛选出表中的数据,用比较多的就是时间的参数吧! 常用的mysql时间的条件进行检索的SQL语句: 数据表 ...

  3. Python爬虫之简单的爬取百度贴吧数据

    首先要使用的第类库有 urllib下的request  以及urllib下的parse  以及 time包  random包 之后我们定义一个名叫BaiduSpider类用来爬取信息 属性有 url: ...

  4. php多域名单站点路由

    能够使多域名但是只有一个站点的小站,通过路由访问到各个指定目录 <?php //域名跳转路由 //默认跳转 $default = "http://www.stanwind.com/in ...

  5. Codeforces 1215D. Ticket Game

    传送门 博弈,发现情况有点多,分析一下把有用的状态提取出来 显然各个位置的数字是没用的,我们只要知道两边的数字和分别是多少 并且状态显然和左右两边的 "?" 数量有关 因为最终我们 ...

  6. KVM虚拟化网卡管理

    brctl常用命令 查看当前虚拟网桥状态 brctl show 添加一个网桥 addbr 删除一个网桥 delbr 添加网口 addif 删除网口 delif VALN LAN 表示 Local Ar ...

  7. spring中spEL常用应用场景

    spEL表达式表示:#{} 一.基本类型值运算操作 {}可以放置数字,字符串,布尔型,表达式(运算,正则,逻辑).这个应用场景和EL表达式一样的,实际中用的也不多. 注意:在XML中表示==,> ...

  8. SpringBootMVC01——A simple SpringBootMVC Sample

    不带数据库的SpringBootMVC案例 1.创建一个SpringBoot项目,添加thymeleaf,webstarter 2.目录层级 3.启动器代码 package com.littlepag ...

  9. uwsgi_response_write_body报错的几种情况

    1.uwsgi_response_write_body_do(): Broken pipe 出现这种情况一般是由于客户端无法等到服务端的回应而关闭了连接,常出现与nginx + uwsgi的情况,当u ...

  10. 格兰杰因果 Granger causality

    格兰杰因果关系(Granger causality )是基于预测的因果关系统计概念.根据格兰杰因果关系,如果信号X1“格兰杰Causes”(或“G-Causes”)信号X2,则X1的过去值应该包含有助 ...