使用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可画简单便捷的拖拽功能和丰富的模板,创造精彩纷呈的设计 Canva可画(www.canva.cn?)是全球领先的视觉传播平台,2013年诞生于澳大利亚,2018年正式进入中国市场,隶属于北京咖瓦信息技术有限公司。公司估值400亿美金,是视觉传播领域唯一独角兽公司,投资者包括互联网女王玛丽·米克尔 (Mary Meeker) 主导的Bond Caphttps://canva.cn/about
2.可画简介可画在线设计电话:400-808-2776 北京咖瓦信息技术有限公司 创立时间:2013年 发源地:澳大利亚 邮箱:cnsupport@canva.com 信用指数:829 关注度:3529 品牌评论:0 品牌点赞:0 品牌分享:0 品牌企业介绍 Canva可画(www.canva.cn)是全球领先的视觉传播平台,2013年诞生于澳大利亚,2018年正式进入中国市场,隶属于北京咖瓦信息技术有限公https://www.cnpp.cn/pinpai/104792.html
3.微博正文Canva可画:网页端:点击首页右下角问号。app端:首页右下角菜单-帮助中心。或者也可拨打电话:400-808-2776 2022-9-15 来自河南 串串在上幼儿园 为什么ipad下载完全打不开 2022-9-16 来自浙江 章鱼哥来一个 你好,请问今晚这个最晚几点修好,网站崩坏 2022-9-29 来自辽宁 杞十一 我也绑不了之前还行今天突https://m.weibo.cn/status/4811450990723153
4.Canva官网Canva产品价格标准Canva用户口碑评价评分咨询电话:15073104040 文章Canva产品怎么收费? Canva可画是一款在线平面设计工具,它支持多平台使用,包括网页端、iPhone、iPad及Android端。用户可以利用Canva提供的丰富的版权图片、原创插画以及各类优质设计模板,通过简单的修改,在几分钟内创建出海报、简历、Banner https://www.saasruanjian.com/t_19319.html
5.Canva官网版下载app可画canvas官网下载2.238.0安卓版Canva官网版下载app软件简介 Canva官网版下载app是一款非常好用的都美图修图剪辑app,提供了超级丰富的精美贴图和美图模版供用户使用,更有非常好玩的细节功能等你来体验,软件支持一键共享照片,能够让你的照片获得更多的赞美,让美图变得更加的简单!让每个人都可以通过这款软件,用很简单的手段来制作出各种精美的图片! https://wfdown.com/soft/10015.htm
6.可画无故收费按钮 2、官方公众号“Canva可画“(ID: canvachina) 3、邮箱:cnsupp***@canva.com 我们将在核实您的具体情况后,提供进一步协助。黑猫消费者服务平台 自动完成 2022-12-16 16:01:02 距离商家最新回复已经30个自然日,期间用户未做进一步操作,系统已自动变更为“已完成”状态。如对企业处理结果有异议,可重新https://tousu.sina.cn/complaint/view/17362861952/
7.canva可画官网,全能在线设计工具,海报,简历,电商,PPT,H5页面,UI?>1.免费ai视频生成+写作(可联网)?>2.超强免费ai视频神器3.免费ai写作绘画 canva可画官网,全能在线设计工具,海报,简历,电商,PPT,H5页面,UI设计 简介 Canva是一款在线设计工具,可以帮助用户进行各种设计工作,包括海报、简历、电商设计、PPT、H5页面、UI设计等。 https://feizhuke.com/sites/canva.html
8.Canva可画在线www.canva.cn2024-12-24,Canva可画在线网站世界排名0位,浏览人数已经达到1次,网站关注度2。如果需要了解该站的相关权重信息,可以使用"爱站工具""Chinaz站长工具"查询,本页的网站数据不是实时更新、仅供参考,建议大家以爱站查询数据为准。关于Canva可画在线网站价值评估:如访问速度、搜索引擎收录情况以及索引量、用户体验等;当然https://top.080210.com/siteinfo/53730.html
9.canva可画客服售后投诉维权中心canva可画 0 % 解决率 6026 访问量 企业名称: - 官网: - 分享 纠错 举报 客服电话: - 售后政策: - 品牌简介: - 数据概览 投诉内容 Canva可画未经通知自动扣取年费 我于2024年10月2日被扣款298的年费。在被扣款前,没有收到任何一条电话或者信息通知,我于10月9号才在支付宝上发现被扣款。https://www.xfb315.com/brands/47027
10.可画官网介绍(www.canva.cn)可画(Canva)是全球领先的视觉传播平台,2013年诞生于澳大利亚,2018年正式进入中国市场。可画(Canva)为用户提供零门槛的设计编辑工具,海量免费精美设计模板和千万级版权素材内容。【查看详情】 微信扫码,关注网谋 访问官网 客服电话 您可能感兴趣https://www.igfwz.com/amp/3137313230/
11.Canva可画StatusWelcome to Canva可画's home for real-time and historical data on system performance.https://www.canvastatus.cn/
12.Canvas可画通过苹果支持自动扣费298元本人并不需要付费服务已分配商家 Apple支持 黑猫消费者服务平台审核通过12-13 16:42:55 机灵喵发起投诉12-13 15:52:52 名为:“canva可画”软件的订阅服务,导致扣费298元,申请两次了退款告诉不符合要求,拒绝退款。具体原由并未告知。并且本人不需要该软件的付费服务,请求退款。https://tousu.sina.com.cn/complaint/view/17363696623/
13.使用canvas来绘制图形既然我们已经设置了 canvas 环境,我们可以深入了解如何在 canvas 上绘制。到本文的最后,你将学会如何绘制矩形,三角形,直线,圆弧和曲线,变得熟悉这些基本的形状。绘制物体到 Canvas 前,需掌握路径,我们看看到底怎么做。http://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes
14.使用画布绘制自定义图形(Canvas)显示图形onReady(event: () => void)是Canvas组件初始化完成时的事件回调,调用该事件后,可获取Canvas组件的确定宽高,进一步使用CanvasRenderingContext2D对象和OffscreenCanvasRenderingContext2D对象调用相关API进行图形绘制。 Canvas(this.context) .width('100%') .height('100%') .backgroundColor('#https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/arkts-drawing-customization-on-canvas-0000001453684976-V2
15.联系我们Pro地址/电话/传真 请联系Pro-face当地分支机构。? 中国分支机构 全球分支机构 ? 在线技术支持(微信客服) 微信扫一扫下方二维码,即可通过微信在线联系我们的技术专家,响应更迅速,处理更便捷。? ? 在线咨询 关于询价、示例、技术等问题可以通过“在线咨询表”进行咨询。 在线咨询表 客户通过E-mail进行咨询https://www.proface.com/zh-hans/contact
16.#可画变形课,开课喽#哈喽,这里是最最最富来自Canca可画#可画变形课,开课喽#哈喽,这里是最最最富有创造力的可画魔法学院。快来快来!可画魔法学院为大家邀请了优秀的太太@蝴蜜_humi 带来精彩纷呈的变形课,用原创的魔法素材鼓励大家激发创造力,用可画将脑海中的小灵感实现在平面之间!如何将单调的画面变得生动起来?这节变形课将给你答案。海量的素材,丰富的贴纸可https://weibo.com/7632264752/N4I1ceJZm
17.微信小程序canvas画图使用百分比适配不同机型屏幕达到任何屏幕比例皆然后根据自己所需要将canvas图绘制完成。绘制的时候直接使用固定的px数值即可。 例如:一段文字的xy和大小 ctx.setFontSize(14)//设置字体大小 ctx.fillText('张三',40,66);//设置文字,并指定坐标 只要能达到自己想要的绘制效果就可以了。此时绘制完成,第二步就完成了 https://blog.csdn.net/Qensq/article/details/139309191