canvas学习总结(三)

上篇文档中介绍了canvas图形绘制技巧并制作了几个典型的案例。本文档主要在上篇基础上继续扩展讲述Canvas的图形样式渲染技巧。本篇资料参考来自:dev.w3c.org

1 线风格

正如前面所讲,线也有风格,我们经常设置的是线宽(lineWidth);

context.lineWidth [=value];// 返回或设置线宽,value以像素为单位。

还有几个其他的线风格:

线帽(lineCap):

context.lineCap[=value];//value:butt/round/square

butt:默认值,不做任何处理;

round:头尾增加半圆形的箭头;

square:头尾增加长方形,长为线宽1/2,高位线宽;

连接方式(lineJoin):

context.lineJoin[=value];//value:miter/round/bevel

miter:默认值,外延交于一点,外延的斜率可以由miterLimit属性显示定义;

round:连接外延为以内侧交点为圆心,以线宽为半径的圆角;

bevel:斜角连接 

斜角斜率(miterLimit):

context.miterLimit[=value];//value:默认值为10.0

miterLimit表示斜接长度:如下图示:

 

我们发现,边角角度越小,斜接长度越大,为了避免斜接长度过大,我们使用miterLimit属性进行限制,且只有当lineJoin=‘miter’时,该属性才有效;

记斜接长度为l,则有下列结论:

  1. l<=0,忽略;
  2. 0<l<=value,尖角显示;
  3. l>value,边角以bevel类型显示(以连接线垂直方向截断);

 

下面是关于lineJoin属性的演示:

  

 

2 字体样式

context.font[=value];//获得或设置文字类型

   eg: context.font = '10px sans-serif';

  上面是font的默认值。font可以设置的属性按顺序排列如下:

  font-style:normal/italic/oblique//字体样式

  font-variant:normal/small-caps//字体变体

  font-weight:normal/bold/bolder/lighter/100…900//字体粗细,默认400

  font-size/line-height:规定字号和行高,以像素计,默认:10px/2

  font-family:规定字型,默认sans-serif

  文字对齐:

  context.textAlign[=value];//获取或设置文字对齐方式。

  value可取值:start(默认)/end/left/right/center

  设置文字的对齐基线:

  context.textBaseline[=value];//获取或设置文字的对齐基线

  value可取值:alphabetic(默认)/top/bottom/middle/hanging/ideographic

 

3 颜色及渐变

正如前面所述canvas中通过设置context.fillStyle和context.strokeStyle两个属性值设置绘制的颜色。前者表示填充颜色,后者表示路径颜色。色值均通过RGB属性获得:

fillStyle = “#F00”;//#FF0000的简写

fillStyle = “red”;//用自然语言描述

fillStyle = “rgb(255,0,0)”;//显示定义rgb的值(0~255)

fillStyle = “rgba(255,0,0,0.6)”;//带透明度的颜色设置,0~10表示完全透明

canvas除了可以定义纯色,还可以自定义颜色渐变。canvas定义了CanvasGradient接口:

 

addColorStop方法规定gradient对象中的颜色和位置,偏移量(offset)取0~ 1.0,color为一个DOM字符串,用法如下:

gradient.addColorStop(0,’rgba(200,0,0,0.7));

当需要使用多个渐变的混合效果时可以多次调用此方法。

 

利用canvas对象可以为此接口生成gradient对象。

1.0规范规定了两类渐变类型:线性渐变和径向渐变:

 

两个方法都返回CanvasGradient对象。具体参数的含义如下:

线性渐变的参数较简单,分别表示2个点的坐标,下面是一个简单的黑白渐变:

 

代码展示:

 

下面是多个线性渐变混合的效果:

 

代码展示:

 

 

径向渐变前3个参数和后3个参数分别表示开始圆和结束圆。

把它想象成手电筒照出的光柱,光柱外都以透明黑填充,光柱开始圆至向外延伸的部分以偏移量为0的纯色填充;光柱结束圆至向外延伸的部分以偏移量为1的纯色填充。显然如果两个圆半径相等则两端向外无限延伸,否则总会在某端聚焦于一点,而中间区域会以(x1,y1)为圆心,以半径为r1+w的范围内变化,且同一半径下圆弧上点的色值相等。下面是该效果的示意图:

  

 

代码展示:

 

4 图案平铺

 

通常页面上的一些底纹效果是通过图案平铺效果展示出来的。在canvas画布里也可以轻松实现图案平铺。我们可以使用下面这张小图片(96*96)实现画布背景平铺效果:

 

 

canvas1.0定义了CanvasPattern接口:

 

通过canvas上下文对象可以创建CanvasPattern对象,方法定义如下:

 

这个方法第一个参数:image指的是Html中的image,canvas或video元素;第二个参数repetition指的是重复方式,其值有:

repeat:默认值,水平和垂直方向重复;

repeat-x:只在水平方向重复;

repeat-y:只在垂直方向重复;

no-repeat:不重复;

被重复的元素可以用于绘制/填充矩形、圆形或线条等等。

下面是上面例子的代码:

 

除了可以用图案进行平铺还可以用图案进行绘制,就像ps里的画刷一样,只要指定strokeStyle=pattern即可。

 

5 阴影

关于阴影设置有四个全局的属性:

context.shadowBlur[=value];//获取或设置阴影的模糊等级,value>0,相当于PS里羽化效果;

context.shadowColor[=value];//获取或设置阴影的颜色;

context.shadowOffsetX[=value];//获取或设置阴影横向偏移;

context.shadowOffsetY[=value];//获取或设置阴影纵向偏移;

下图是一个带阴影的圆形按钮:

 

代码展示:

 

 

 

 

6 滤镜特效

如果说canvas的渲染能力有多强,必须要提到canvas所能展现的各种滤镜特效。

玩过ps的人应该都知道用过滤镜。通过滤镜设置可以展现出各种特效,比如反色、分层云彩、浮雕、影印等。

canvas之所以能实现各种滤镜效果,是因为canvas支持对图像进行像素级操作,通过一定的算法对像素的rgb值进行变换,从而达到特殊的效果。

首先,介绍下w3c canvas 1.0里的一些规范。

canvas 1.0里定义了ImageData接口:

 

ImageData里封装了图像的像素值:width、height、data。width和height表示像素的长宽比,data是个Uint8ClampedArray对象。

下图是对该对象的官方解释:

 

canvas提供的像素级操作的方法主要有以下几种:

createImageData、getImageData、putImageData,方法定义如下:

 

参数含义如下:

createImageData可以通过指定css像素宽高或从一个ImageData中获取宽高的的ImageData对象,所有像素为透明黑(transparent black);

getImageData通过给定的画布上矩形区域返回该区域内的图像,对于区域外的部分返回透明黑;

putImageData在当前画布上绘制ImageData对象,如果指定了脏矩形(dirty rectangle1)则只有脏矩形上的数据被绘制。

好了,来进行实战演练吧。

下面我们实现ps里溶图的效果(2):

 

上图的第三张图是第一张图和第二张图叠加的结果。

代码展示:

 

我们将融合效果封装到Effectsblend方法中。其算法如下:

 

blend通过调用底层方法:_darken实现像素变暗的效果,这是整个算法的核心:

 

每种效果都有一个核心算法,这个算法可以在网上找到。当然你也可以创造特定的算法。

其实,滤镜特效的展现属于像素化操作(pixel manipulation)。通过js就可以随心所欲地控制图像像素,甚至可以对特定的像素块进行循环变换,从而产生动画效果,甚至比用一般2d游戏做出来的效果更加细腻!

本篇展示的渲染均是静态渲染,后续会做些简单的动态渲染以及简单的小动画。

 

7 综合演示

优化钟表样式

上篇最后我们绘制了一个钟表,现在我们优化下钟表样子: 

第一步:给矩形表面添加纹理

 

代码展示:

 

第二步:给圆盘添加渐变

 

代码展示:

 

第三步:添加阴影

 

代码展示:

 

 

注解:

1:脏矩形是二维图像引擎里的一个专用术语。2d游戏中把只进行局部更新的区域为“脏矩形”。具体解释请进行百度或google搜索。

2:此例引自http://www.w3cfuns.com/。里面有很多好的例子。

posted @ 2019-01-14 13:29  微观link  阅读(257)  评论(0)    收藏  举报