canvas 绘制直线 并选中_canvas用法整理

41970dd5d41ef0d407173d350f2a8e7d.png

Canvas基本知识

用<canvas>标签,指定width和height属性,一般还要指定id属性以供js使用。

<

默认的width是300,height是150

注意canvas的css里的width和height和标签上的width以及height是不同的,浏览器会把标签上的大小缩放到css里设置的大小上,所以一般不需要设置css里的width和height。

canvas也就三个方法

  • getContext - 一般就传入'2d'参数
  • toDataURL(type, quality) - type默认为image/png,也可以指定别的格式,quality是一个0~1.0的数值,用在JPEG格式上,得到的结果是一个data:image/png;base64 xxxx这样的字符串,可以直接置给<img>的src
  • toBlob(callback, type, quality) - 创建canvas元素图像文件的Blob对象,type默认也是image/png,最后一个也是quality,跟上一个方法一样

getContext获得的是一个CanvasRenderingContext2D对象,以下简称context,含有如下的属性

  • canvas
  • fillStyle
  • font
  • globalAlpha
  • globalCompsiteOperation
  • lineCap
  • lineWidth
  • lineJoin
  • miterLimit
  • shadowBlur
  • shadowColor
  • shadowOffsetX
  • shadowOffsetY
  • strokeStyle
  • textAlign
  • textBaseline

context含有两个方法save( )和restore( ),用来保存和恢复绘制时设置的上述属性,它是一个栈的数据结构。绝大多数情况下,对context的设置都要包裹在save()和restore()之间。

如果想要对context进行方法功能增强,那就在CanvasRenderingContext2D.prototype上添加方法。

canvas的原点坐标在左上角。

canvas的事件处理没有什么特别的,因为往下不存在DOM了,所以事件都要挂在canvas上,以下一段代码常用来进行事件坐标和canvas坐标的转换,同时考虑了CSS设置width和height的情况。

function 

下面是一个根据鼠标移动画辅助线的例子,用到上面的方法

let 

a04eb6eded518053b74eb97cc1c98493.png

PS:请复习一下中学数学,特别关于三角函数和向量的知识

矩形绘制

  • clearRect(x, y, width, height)
  • strokeRect(x, y, width, height)
  • fillRect(x, y, width, height)

跟strokeRect有关的属性有

  • strokeStyle
  • lineWidth
  • lineJoin
  • miterLimit

跟fillRect有关的属性有

  • fillStyle

渐变

  • createLinearGradient(x0, y0, x1, y1) - 从(x0, y0)到(x1, y1)的线性渐变,用返回对象的addColorStop( )方法来增加颜色
  • createRadialGradient(x0, y0, r0, x1, y1, r1) - 从(x0, y0)点周围r0宽度向(x1, y1)周围r1宽度放射渐变,也用返回对象的addColorStop( )方法来增加颜色

注意放射渐变可以不是一个矩形

var 

0bedf150dc91cfa63860a445b591312f.png

渐变也可以用在stroke方法里,比如这种效果

a431eca6b8903e7f7df03b3d19b97ed0.png

图案

  • createPattern(image, repeat) - repeat可以取repeat repeat-x repeat-y no-repeat
let 

553ada9a381acbfb899cf4a99d833ff9.png

阴影

指定shadowColor, shadowOffsetX, shadowOffsetY, shadowBlur这几个属性

context

效果如下图

b6d5f40a7605cabb634e260b8808fcdb.png

路径

想要画出任意图像就需要使用路径

beginPath( )用来清除之前的路径并开启新路径

closePath( )用来封闭路径

arc( )用来增加圆弧路径

141d258070bc958636dc34bf5d1ff926.png

arcTo(x1, y1, x2, y2, radius)用来增加从x点到y点相切的一条圆弧路径,一般用来做圆角矩形

fill( )用来对路径填充

stroke( )用来对路径描边

rect( )用来生成矩形路径,它自然是封闭的

moveTo( )移动路径的点

lineTo( )生成直线的路径

quadraticCurveTo(cpx, cpy, x, y)用来增加二次方贝塞尔曲线路径

9bb5605867e0fae7957f324d87406aa1.png

bezierCurveTo(cpx, cpy, cp2x, cp2y, x, y)用来增加三次方贝塞尔曲线路径

011ffd024e5fb43b9b5ee84faf72ba05.png
  1. 注意beginPath( )方法会清除上一次的路径,就是指从beginPath( )之后增加的路径开始画,如果不清除的话,之后的stroke( ) fill( )都会把之前的路径又画一遍。
ctx

2. 注意线段的绘制要画在0.5位置上,以一像素为例,只有画在0.5位置上才是真正的一像素宽度

6c61a7350251c2dc0c437567a8e110a6.png

f7815566ad38e9a71984b73fc722d13c.png
for 

8dd32b968610255292be74cd384baffc.png

尝试用鼠标操作绘制线段,这个例子使用image data来保存恢复图像,还可以使用线段数据数组的方式来存储线段数据,每次重绘的时候把数组里的线段都再绘制一遍(其实我更倾向于后者)

let 

3. 线段端点属性lineCap和线段连接点lineJoin属性

4ae6022bf8e6894062b7f9ad93928574.png

c4b93754f33a0c29a47ea25dc209b8c0.png

miterLimit是斜接线商都与二分之一线宽的比值,如果斜接线长度超过该值,浏览器以bevel方式来绘制

241463acd026352e024f1e7956190a54.png

4. context有个方法isPointInPath( )用来判断点是否在当前路径中,在使用前可以用beginPath( )等方法创建出路径来,然后进行判断。同理还有isPointInStroke( )。

5. scrollPathIntoView( )是一个实验中的方法,让给定的路径滚动到窗口

6. 通过context的lineDashOffset或者setLineDash( )方法可以设置绘制虚线的规格

坐标变换

通过rotate( ) scale( ) translate( ) transform( ) setTransform( )等方法来进行坐标轴的变换,其中transform( )和setTransform( )的区别在于transform( )会叠加效果而setTransform( )会清除之前的效果。

比如画一个左右对称图形

context

2c44d9daf0330eda5c9e2d102992af6a.png

图像合成

设置context的globalCompositeOperation属性,可以取如下的值,注意一下在不同浏览器上的行为是否一致

91787114a07e6772a0afe5cbab2a40bf.png

下图就是一个橙色圆形和文字在合成属性设为xor的情况下的效果

4cb1ec4a301558aca1d631d698b7832d.png

区域剪辑

使用context的clip( )方法把当前路径与剪辑区域的交集绘制出来,记得放在save( )和restore( )之间,否则剪辑区域会越变越小。

const 

f0dbe5d1bc11fb65e98254cebacf436a.png

文本

绘制文本主要通过以下三个方法

  1. strokeText(text, x, y)
  2. fillText(text, x, y)
  3. measureText(text)

跟文本有关的context属性有

  1. font
  2. textAlign
  3. textBaseline

但其他的fillStyle等属性也是适用于文本绘制的。

font的属性是一个字符串,注意如下次序不能乱,不然canvas不认

  1. font-style 包含normal italic oblique
  2. font-variant 包含normal small-caps
  3. font-weight 跟css里设置该值属性一样
  4. font-size 跟css里一样
  5. line-height 只能是normal,其他值会被忽略
  6. font-family 字体

textAlign可以取值

  • start
  • center
  • end
  • left
  • right

textBaseline可以取值

  • top
  • bottom
  • middle
  • alphabetic
  • ideographic
  • hanging

下图是各属性的效果,如果要将文本基于某个点居中,那就设成center middle,在坐标轴标签绘制的情况下注意设置合理的属性

17c116b7bc2e7e472d6d071d8b0c6e0e.png

环形文本绘制效果可以参见之前我做的一个神盾局logo的绘制

Anli Li:用canvas画神盾局Logo​zhuanlan.zhihu.com
ec1c80c0412d039f622d0a6f5979b2f6.png

图像

跟图像绘制有关的方法

  • drawImage(image, dx, dy) / drawImage(image, dx, dy, dw, dh) / drawImage(image,sx, sy, sw, sh, dx, dy, dw, dh)
  • getImageData( x, y, width, height)
  • putImageData( )
  • createImageData(width, height)

下面一个例子是通过鼠标操作缩放图像部分。

let 

0f961a7c00f7f07df6e0aeab3395c350.png

一个增加效率的绘图方法,创建一个canvas元素但不显示,在这个canvas进行绘制,然后把它的一部分内容复制到正在显示的canvas中,由于绘制是发生在离线情况下,用户不会感受到绘制时的变化,只注意到最后的结果,这种方式叫离线canvas。

getImageData( )会有跨域的限制,它返回的是这样一个对象

bec72bac8e66cdd7e32c8904623f1670.png

其中data是一个4×width×height个整数值的数组,每四个整数值代表一个像素,分别表示红、绿、蓝和透明度(最高255)。这里的宽度和高度是canvas的宽高而不是图像本身的宽高。

putImageData(ImageData imagedata, dx, dy, optional dirtyX, dirtyY, dirtyWidth, dirtyHeight )用法如下图

16b80a9c25321940994556c771113a14.png

拿到了像素数据后就可以进行图像处理,比如取反或黑白等,如果计算量大可以考虑使用web worker。

canvas

a10d828aa57fb6065efea886ebb5ee6b.png

考虑优化性能,可以只重绘部分区域或者先绘制到离屏的canvas上再把部分区域绘制到屏幕上。

关于canvas的用法暂时整理到这里,其他的一些高级应用会另写文章来讨论。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值