使用canvas

了解如何正确使用canvas画布,以及通过canvas绘制图形及动画。

通过本节,你将学会:

快应用的canvas功能由两部分组成,canvas组件和渲染脚本。

canvas组件中,用于绘制图形的部分,称之为画布。

和其他组件一样,在快应用template中添加即可。同时可为其添加需要的样式。

这里需要注意,与HTML中canvas不同的是:

单独的canvas组件仅仅是一个透明矩形,我们需要通过渲染脚本来进一步操作。

首先通过$element和id来获取canvas组件节点,再通过getContext方法创建canvas绘图上下文。

getContext方法的参数目前仅支持'2d',创建的canvas绘图上下文是一个CanvasRenderingContext2D对象。

在后续脚本中操作该对象即可绘制图形。

完整示例代码如下:

如果你想进入页面即渲染canvas,只能在onShow中获取canvas组件节点,绘制图形。

输出效果如图

开始画图之前,需要了解一下画布的坐标系。

如下图所示,坐标系原点为左上角(坐标为(0,0))。所有元素的位置都相对于原点定位。x轴向右递增,y轴向下递增。

canvas绘图的基本绘制方式之一是填充绘制。

填充是指用指定的内容填满所要绘制的图形,最终生成一个实心的图案。

canvas绘图的另一种基本绘制方式是描边绘制。

描边绘制是指,沿着所要绘制的图形边缘,使用指定的内容进行描绘,最终生成的是空心的图案。

如果既要填充又要描边,则需要分别绘制两次完成最终图案。

矩形,是最基础的形状。canvas提供了三种方法绘制矩形:

与绘制矩形的直接绘制不同,绘制路径需要一些额外的步骤。

为此,我们需要了解以下一些基本方法。

开始一条新路径,这是生成路径的第一步操作。

一条路径本质上是由多段子路径(直线、弧形、等等)组成。而每次调用beginPath之后,子路径清空重置,然后就可以重新绘制新的图形。

闭合当前路径。

closePath()不是必须的操作,相当于绘制一条当前位置到路径起始位置的直线子路径。

描边绘制当前路径。

填充绘制当前路径。

当调用fill()时,当前没有闭合的路径会自动闭合,不需要手动调用closePath()函数。调用stroke()时不会自动闭合。

移动笔触。将当前路径绘制的笔触移动到某个坐标点。

相当于绘制一条真正不可见的子路径。通常用于绘制不连续的路径。

调用beginPath()之后,或者canvas刚创建的时候,当前路径为空,第一条路径绘制命令无论实际上是什么,通常都会被视为moveTo。因此,在开始新路径之后建议通过moveTo指定起始位置。

路径绘制命令是实际绘制路径线条的一些命令。包括有:

这里,我们展示一个组合使用的效果,绘制一个快应用的logo。

drawCanvas(){constcanvas=this.$element('newCanvas')constctx=canvas.getContext('2d')constr=20consth=380constp=Math.PIctx.beginPath()ctx.moveTo(r*2,r)ctx.arc(r*2,r*2,r,-p/2,-p,true)ctx.lineTo(r,h-r*2)ctx.arc(r*2,h-r*2,r,p,p/2,true)ctx.lineTo(h-r*2,h-r)ctx.arc(h-r*2,h-r*2,r,p/2,0,true)ctx.lineTo(h-r,r*2)ctx.arc(h-r*2,r*2,r,0,-p/2,true)ctx.closePath()ctx.stroke()consts=60ctx.beginPath()ctx.moveTo(h/2+s,h/2)ctx.arc(h/2,h/2,s,0,-p/2*3,true)ctx.arc(h/2,h/2+s+s/2,s/2,-p/2,p/2,false)ctx.arc(h/2,h/2,s*2,-p/2*3,0,false)ctx.arc(h/2+s+s/2,h/2,s/2,0,p,false)ctx.moveTo(h/2+s*2,h/2+s+s/2)ctx.arc(h/2+s+s/2,h/2+s+s/2,s/2,0,p*2,false)ctx.moveTo(h/2+s/4*3,h/2+s/2)ctx.arc(h/2+s/2,h/2+s/2,s/4,0,p*2,false)ctx.fill()}实现效果如下

通过刚才的例子,我们学会了绘制图形。

但是我们看到,不管是填充还是描边,画出来的都是简单的黑白图形。如果想要指定描绘的内容,画出更丰富的效果应该如何操作呢?

有两个重要的属性可以做到,fillStyle和strokeStyle。顾名思义,分别是为填充和描边指定样式。

在本章节最初的例子里,其实已经看到上色的基本方法,就是直接用颜色作为指定样式。

ctx.fillStyle='rgb(200,0,0)'ctx.fillRect(20,20,200,200)一旦设置了fillStyle或者strokeStyle的值,新值就会成为新绘制的图形的默认值。如果你要给每个图形上不同的颜色,需要画完一种样式的图形后,重新设置fillStyle或strokeStyle的值。

//填充绘制一个矩形,颜色为暗红色ctx.fillStyle='rgb(200,0,0)'ctx.fillRect(20,20,200,200)//描边绘制另一个矩形,边框颜色为半透明蓝色ctx.strokeStyle='rgba(0,0,200,0.5)'ctx.strokeRect(80,80,200,200)canvas的颜色支持各种CSS色彩值。

渐变色对象可以使用createLinearGradient创建线性渐变,然后使用addColorStop上色。

这里要注意的是,渐变色对象的坐标尺寸都是相对画布的。应用了渐变色的图形实际起到的是类似“蒙版”的效果。

线型可设置的项目包括:

顾名思义,线宽就是描边线条的宽度,单位是像素。

这里要注意两点:

线条的宽度会向图形的内部及外部同时延伸,会侵占图形的内部空间。在使用较宽线条时特别需要注意图形内部填充部分是否被过度挤压。常用解决方法可以尝试先描边后填充。

可能会出现的半渲染像素点。例如,绘制一条(1,1)到(1,3),线宽为1px的线段,是在x=1的位置,向左右各延伸0.5px进行绘制。但是由于实际最小绘制单位是一个像素点,那么最终绘制出来的效果将是线宽2px,但是颜色减半的线段,视觉上看就会模糊。常用解决方法,一种是改用偶数的线宽绘制;另一种可以将线段绘制的起始点做适当偏移,例如偏移至(1.5,1)到(1.5,3),左右各延伸0.5px后,正好布满一个像素点,不会出现半像素渲染了。

端点样式决定了线段端点显示的样子。从上至下依次为butt,round和square,其中butt为默认值。

这里要注意的是,round和square会使得线段描绘出来的视觉长度,两端各多出半个线宽,可参考蓝色辅助线。

交点样式决定了图形中两线段连接处所显示的样子。从上至下依次为miter,bevel和round,miter为默认值。

在上图交点样式为miter的展示中,线段的外侧边缘会延伸交汇于一点上。线段直接夹角比较大的,交点不会太远,但当夹角减少时,交点距离会呈指数级增大。

miterLimit属性就是用来设定外延交点与连接点的最大距离,如果交点距离大于此值,交点样式会自动变成了bevel。

drawLineDashCanvas(){constcanvas=this.$element('linedash-canvas')constctx=canvas.getContext('2d')letoffset=0//绘制蚂蚁线setInterval(()=>{offset++if(offset>16){offset=0}ctx.clearRect(0,0,300,300)//设置虚线线段和间隙长度分别为4px2pxctx.setLineDash([4,2])//设置虚线的起始偏移量ctx.lineDashOffset=-offsetctx.strokeRect(10,10,200,200)},20)}运行效果如下

通过学习,我们为刚才绘制的快应用logo添加颜色和样式。

和绘制图形类似,快应用canvas也提供fillText和strokeText两种方法来绘制文字。

可以直接使用符合CSSfont语法的字符串作为文字样式的字体属性。默认值为'10pxsans-serif'。

要注意的是,不同于web,目前快应用还无法引入外部字体文件,对于字体的选择,仅限serif、sans-serif和monosapce。

这两个属性控制了文体相对与绘制定位点的对齐方式。

为了能够在canvas中使用图片,需要使用图像对象来加载图片。

src既可以使用URI来加载本地图片,也使用URL加载网络图片。

为避免图片未加载完成或加载失败导致填充错误,建议在加载成功的回调中进行图片填充操作。

img.onload=()=>{ctx.drawImage(img,0,0)}使用drawImage绘制图片也有3种不同的基本形式,通过不同的参数来控制。

drawImage(image,x,y)其中image是加载的图像对象,x和y是其在目标canvas里的起始坐标。

这种方法会将图片原封不动的绘制在画布上,是最基本的绘制方法。

drawImage(image,x,y,width,height)相对基础方法,多了两个width、height参数,指定了绘制的尺寸。

这种方法会将图片缩放成指定的尺寸后,绘制在画布上。

drawImage(image,sx,sy,sWidth,sHeight,dx,dy,dWidth,dHeight)其中image与基础方法一样,是加载的图像对象。

其它8个参数可以参照下方的图解,前4个是定义图源的切片位置和尺寸,后4个则是定义切片的目标绘制位置和尺寸。

图片不仅仅可以直接绘制在画布中,还可以将图片像渐变色一样,作为绘制图形的样式,在填充和描边绘制中使用。

首先,需要通过createPattern创建图元对象,然后就可以将图元对象作为样式用在图形的绘制中了。

同样,为避免图片未加载完成或加载失败导致填充错误,建议在加载成功的回调中进行操作。

我们不仅可以在已有图形后面再画新图形,还可以用来遮盖指定区域,清除画布中的某些部分(清除区域不仅限于矩形,像clearRect()方法做的那样)以及更多其他操作。

globalCompositeOperation=type

这个属性设定了在画新图形时采用的遮盖策略,其值是一个用于标识不同遮盖方式的字符串。

这是默认设置,并在现有画布上下文之上绘制新图形。

新图形只在与现有画布内容重叠的地方绘制。

新图形只在新图形和目标画布重叠的地方绘制。其他的都是透明的。

在不与现有画布内容重叠的地方绘制新图形。

在现有的画布内容后面绘制新的图形。

现有的画布只保留与新图形重叠的部分,新的图形是在画布内容后面绘制的。

现有的画布内容保持在新图形和现有画布内容重叠的位置。其他的都是透明的。

现有内容保持在新图形不重叠的地方。

两个重叠图形的颜色是通过颜色值相加来确定的。

只显示新图形。

图像中,那些重叠和正常绘制之外的其他地方是透明的。

已有的内容不受影响。

要取消裁切路径的效果,可以绘制一个和画布等大的矩形裁切路径。

//绘制一个红色矩形ctx.fillStyle='rgb(200,0,0)'ctx.fillRect(20,20,200,200)//使用裁切路径绘制一个圆ctx.beginPath()ctx.arc(120,120,120,0,Math.PI*2,true)ctx.clip()//绘制一个蓝色矩形,超出圆形裁切路径之外的部分无法绘制ctx.fillStyle='rgba(0,0,200)'ctx.fillRect(80,80,200,200)运行效果如下

到目前位置,我们所有的绘制,都是基于标准坐标系来绘制的。

标准坐标系的特点是:

现在介绍的变形,就是改变标准坐标系的方法。

for(leti=0;i<6;i++){ctx.fillRect(0,0,40,40)ctx.translate(50,0)}运行效果如图。

可以看到,虽然每次fillRect绘制的参数没有变化,但是因为坐标系变了,最终绘制出来的就是位置不同的图形。

通过前面的学习,我可以看到,每次图形绘制其实都带着非常丰富的状态。

在绘制复杂图形的时候,就会带来重复获取样式的问题。

如何优化呢?

ctx.save()//保存ctx.restore()//恢复canvas状态就是当前所有样式的一个快照。

save和restore方法是用来保存和恢复canvas状态的。

canvas状态存储在栈中,每次save的时候,当前的状态就被推送到栈中保存。

一个canvas状态包括:

你可以调用任意多次save方法。

每一次调用restore方法,上一个保存的状态就从栈中弹出,所有设定都恢复。

ctx.fillRect(20,20,200,200)//使用默认设置,即黑色样式,绘制一个矩形ctx.save()//保存当前黑色样式的状态ctx.fillStyle='#ff0000'//设置一个填充样式,红色ctx.fillRect(30,30,200,200)//使用红色样式绘制一个矩形ctx.save()//保存当前红色样式的状态ctx.fillStyle='#00ff00'//设置一个新的填充样式,绿色ctx.fillRect(40,40,200,200)//使用绿色样式绘制一个矩形ctx.restore()//取出栈顶的红色样式状态,恢复ctx.fillRect(50,50,200,200)//此时状态为红色样式,绘制一个矩形ctx.restore()//取出栈顶的黑色样式状态,恢复ctx.fillRect(60,60,200,200)//此时状态为黑色样式,绘制一个矩形运行效果如下:

之前我们介绍都是静态图像的绘制,接下来介绍动画的绘制方法。

canvas动画的基本原理并不复杂,就是利用setInterval和setTimeout来逐帧的在画布上绘制图形。

在每一帧绘制的过程中,基本遵循以下步骤。

到目前为止,我们尚未深入了解canvas画布真实像素的原理,事实上,你可以直接通过ImageData对象操纵像素数据,直接读取或将数据数组写入该对象中。

在快应用中ImageData对象是一个普通对象,其中存储着canvas对象真实的像素数据,它包含以下几个属性

data属性返回一个Uint8ClampedArray,它可以被使用作为查看初始像素数据。每个像素用4个1bytes值(按照红,绿,蓝和透明值的顺序;这就是"RGBA"格式)来代表。每个颜色值部份用0至255来代表。每个部份被分配到一个在数组内连续的索引,左上角像素的红色部份在数组的索引0位置。像素从左到右被处理,然后往下,遍历整个数组。

Uint8ClampedArray包含高度×宽度×4bytes数据,索引值从0到(高度×宽度×4)-1

例如,要读取图片中位于第50行,第200列的像素的蓝色部份,你会写以下代码:

constblueComponent=imageData.data[50*(imageData.width*4)+200*4+2]你可能用会使用Uint8ClampedArray.length属性来读取像素数组的大小(以bytes为单位):

constmyImageData=ctx.createImageData(width,height)上面代码创建了一个新的具体特定尺寸的ImageData对象。所有像素被预设为透明黑。

你也可以创建一个被anotherImageData对象指定的相同像素的ImageData对象。这个新的对象像素全部被预设为透明黑。这个并非复制了图片数据。

constmyImageData=ctx.getImageData(left,top,width,height)这个方法会返回一个ImageData对象,它代表了画布区域的对象数据,此画布的四个角落分别表示为(left,top),(left+width,top),(left,top+height),以及(left+width,top+height)四个点。这些坐标点被设定为画布坐标空间元素。

你可以用putImageData()方法去对场景进行像素数据的写入。

ctx.putImageData(myImageData,dx,dy)dx和dy参数表示你希望在场景内左上角绘制的像素数据所得到的设备坐标。

例如,为了在场景内左上角绘制myImageData代表的图片,你可以写如下的代码:

setGray(){constcanvas=this.$element('new-canvas')constctx=canvas.getContext('2d')constcanvasW=380constcanvasH=380//得到场景像素数据constimageData=ctx.getImageData(0,0,380,380)constdata=imageData.datafor(leti=0;i

了解canvas的特点,现在就可以实现基本组件无法实现的视觉效果。

THE END
1.Canva可画在线设计协作平台平面设计作图软件在线设计协作平台Canva可画提供了海量的设计模板,涵盖海报、简历、名片、Logo、PPT、手抄报、二维码、Banner等数十种平面设计场景,更有千款中英文字体及千万张正版图片素材可供使用。精彩设计,随时随地!https://www.canva.cn/
2.Canva可画在线设计协作平台平面设计作图软件在线设计协作平台Canva可画提供了海量的设计模板,涵盖海报、简历、名片、Logo、PPT、手抄报、二维码、Banner等数十种平面设计场景,更有千款中英文字体及千万张正版图片素材可供使用。精彩设计,随时随地!http://www.canva.co/
3.Canva可画在线设计协作平台平面设计作图软件在线设计协作平台Canva可画提供了海量的设计模板,涵盖海报、简历、名片、Logo、PPT、手抄报、二维码、Banner等数十种平面设计场景,更有千款中英文字体及千万张正版图片素材可供使用。精彩设计,随时随地!http://canva.me/
4.Canva官网版下载app可画canvas官网下载2.238.0安卓版Canva官网版下载app软件简介 Canva官网版下载app是一款非常好用的都美图修图剪辑app,提供了超级丰富的精美贴图和美图模版供用户使用,更有非常好玩的细节功能等你来体验,软件支持一键共享照片,能够让你的照片获得更多的赞美,让美图变得更加的简单!让每个人都可以通过这款软件,用很简单的手段来制作出各种精美的图片! https://wfdown.com/soft/10015.htm
5.Canva可画StatusWelcome to Canva可画's home for real-time and historical data on system performance.https://www.canvastatus.cn/
6.可画优聚集Canva在线平面设计平台标签:在线作图 获取网址手机查看精彩首页 canva可画,在线平面设计平台,提供了海量的免费设计模板,涵盖PPT模板、简历、手抄报、名片、海报、代金券、课程表、宣传单、宣传册、邀请函、等数十种设计场景,您只需选择喜欢的模板,即可轻松在线设计制作。 Canva 可画,人人可画,可画万物。 可画的功能https://www.youjuji.com/websites/1231.html
7.Canvas在线画图—简单制作一个画板使用了canvas和自定义右键菜单 画图工具有很多bug,比如画矩形的时候不显示轨迹 重绘路径时也有些bug,还有使用火狐保存图片时保存不了 等等bug 最好用谷歌打开 原码如下: <!DOCTYPE html> <htmllang="en"> <head><metacharset="UTF-8"><title>画图工具</title><style>*{ https://www.sohu.com/a/204432197_661296
8.Canvas简历编辑器选中绘制与拖拽多选交互设计canvas拖拽在线编辑:https://windrunnermax.github.io/CanvasEditor 开源地址:https://github.com/WindrunnerMax/CanvasEditor 关于简历编辑器项目的相关文章: 选中绘制 我们先来聊一聊最基本的节点点击选中以及拖拽的交互,而在聊具体的代码实现之前,我们先来看一下对于图形的绘制问题。在Canvas中我们绘制路径的话,我们可以通过filhttps://blog.csdn.net/qq_40413670/article/details/143280807
9.Canva可画下载最新pc版Canva可画电脑版官方免费下载安装Canva可画注重团队协作,用户可邀请他人共同编辑,或组建团队共同管理品牌资源。此外,白板功能助力头脑风暴,审批流程确保项目顺利进行,文档工具扩展内容创作,全方位满足团队协作需求。 3. 便捷分享机制 无论是新建网站还是印刷海报,Canva可画都能让您的创意大放异彩。我们提供一键发布、下载及分享功能,让您的作品轻松触达https://m.onlinedown.net/soft/10069318.htm
10.Canvas在线画图插件canvas可编辑拖拽画板。Canvas在线画图插件网页特效,js特效Canvas在线画图插件源码,实用的前端网页js插件,jquery特效,jquery插件下载Canvas在线画图插件网页特效,网页小部件js代码就上bootstrap模板库https://www.bootstrapmb.com/tag/zaixianhuatu
11.html5canvas仿ps在线编辑涂鸦画板功能html5 canvas实现在线编辑涂鸦画板功能 相关标签 html5 canvashtml5绘制图形jquery涂鸦在线客服在线qq功能图标在线拍照在线搜索手写功能可编辑图片编辑在线选座功能介绍页新功能介绍新功能引导在线生成编辑器qq在线客服多功能插件功能完善聊天功能功能模块增删改查 https://www.17sucai.com/pins/18913.html
12.在线图形设计平台canva.com本站收录的"在线图形设计平台“数据均来源网站“canva.com”及互联网,以上数据具有时效性,因网站域名、网站名称及内容会受域名过期、网站服务器故障、域名所有者更替或内容变化,而存在以上内容失效、错误等情况,请多谅解。访问者分布(%) & 网站排名变化曲线 1 United States(21.4%) 2 India(19.1%) 3 Mexico(http://www.948v.com/prodetail923276.html
13.画板在线画板工具在线画板利用HTML5的Canvas来制作一个画板,可以用来在线画图,可以将自己手绘的内容保存成图片,同时可以撤销和重做,非常方便,并且完全免费使用,让您体验绘画的乐趣!https://www.enbus.cn/tools/huatuban/
14.canva可画怎么导入图片canva可画添加图片方法当我们在使用canva可画设计一些图片或者其他东西的时候,经常需要添加图片来增加设计感,那么该怎么添加图片呢?可能有的小伙伴还不太清楚。下面就给大家带来具体的操作步骤,不知道的小伙伴可以跟小编一起来看看哦! canva可画怎么导入图片? 1、首先打开软件,在创建设计这里点击你要设计的图片。 https://shouyou.3dmgame.com/gl/451136.html