纠纷奇闻社交美文家庭
投稿投诉
家庭城市
爱好生活
创业男女
能力餐饮
美文职业
心理周易
母婴奇趣
两性技能
社交传统
新闻范文
工作个人
思考社会
作文职场
家居中考
兴趣安全
解密魅力
奇闻笑话
写作笔记
阅读企业
饮食时事
纠纷案例
初中历史
说说童话
乐趣治疗

Canvas上下文详解

1月25日 辞凤阙投稿
  本部分重点讲解了Canvas中心点的内容,在Canvas中所有内容的绘制都是基于上下文变换后的新坐标系中心点来完成的,对于坐标系中心点的理解是正确完成内容绘制的前提。同时,本章节也将重点讲述Canvas绘图状态相关的两个方法save和restore。1。Canvas与CSS3坐标变换1。1CSS3matrix2D矩阵和Canvastransform2D矩阵
  2D矩阵指的是元素在2D平面内发生诸如缩放、平移、旋转、拉伸四种变化,在CSS3中对应4个方法分别是scale()、translate()、rotate()和skew(),这4个方法是CSS3矩阵matrix的快捷方式,其本质都是由matrix()实现的。
  类似地,在Canvas中与CSS3对应的3个方法分别是scale()、translate()、rotate(),而Canvas对象没有skew方法,CSS3中的矩阵和Canvas矩阵原理是相通的。matrix方法有六个参数matrix(a,b,c,d,x,y),六个参数默认值是:matrix(1,0,0,1,0,0)
  这六个参数分别控制不同的变换
  a水平缩放
  b水平拉伸
  c垂直拉伸
  d垂直缩放
  x水平位移
  y垂直位移
  关于matrix的各种变换在后面章节会有更加详细的说明,在这里只需知道Canvas和CSS3中矩阵变换的规则是一致的。1。2Canvas与CSS3坐标变换中心点差异
  1。1部分讲过,在Canvas中也存在CSS32D变换的功能,如translate()、rotate()、scale()等。虽然两者看起来差不多,但是CSS3中元素变换中心点都是针对DOM元素,而在Canvas中并非针对DOM元素的变换,而是虚拟画布区域。
  默认情况下,Canvas中心点是左上角,即坐标(0,0)。就像可以通过transformorigin来改变CSS3元素变换的中心点一样,Canvas也可以改变默认中心点,只不过需要通过translate()方法平移内部的2D绘图环境。p2{transform:rotate(45deg);transformorigin:2040;}
  总之,对于中心点而言,CSS3是针对元素本身,即DOM元素,而Canvas针对的是整个Canvas绘图环境,即虚拟画布区域2。Canvas上下文变换2。1Canvas上下文变换基础
  首先来看下在不改变中心点情况下,Canvas旋转前后的变化:canvasidcanvaswidth200height200canvas!真实的画布就是200x200varcanvasdocument。getElementById(canvas);ctxcanvas。getContext(2d);ctx。save();ctx。fillSctx。fillRect(20,20,100,100);旋转前绘制ctx。rotate((Math。PI180)30);ctx。fillSctx。fillRect(20,20,100,100);旋转后绘制ctx。restore();
  由上面的代码可以看到,在旋转画布前,我们在坐标(20,20)处绘制了一个100100的黑色矩形,而在旋转之后,又在坐标(20,20)处绘制了一个100100的蓝色矩形。最后得到的效果如下:
  需要注意的是,Canvas旋转前绘制的元素没有旋转效果,而这种旋转效果只会出现在Canvas旋转后绘制的元素。因此,如果要对Canvas里的某些图形进行旋转处理,就必须在绘图环境旋转后再进行绘制。
  那么如果将Canvas旋转180后再进行绘制,最后结果如何呢?imgidtulipsrca2020imgdataimg。jpgdatasrcimg02。bs178。combjth7c7b07d3cb9f6a74。jpgaltTheTulipcanvasidmyCanvaswidth500height300styleborder:1pxsolidd3d3d3;background:YourbrowserdoesnotsupporttheHTML5canvastag。canvaswindow。onloadfunction(){varcdocument。getElementById(myCanvas);varctxc。getContext(2d);ctx。rotate((Math。PI180)180);varimgdocument。getElementById(tulip);ctx。drawImage(img,10,10);};
  运行完上述代码,你会发现什么也看不到。因为Canvas的中心点是左上角(0,0),当将Canvas绘图环境旋转180弧度后,你会发现图形已经在Canvas可视区域外,这显然是不可行的。那需要如何做呢?2。2Canvas上下文变换原理
  下面将以图解的方式进一步讲述Canvas上下文变换的原理,通过分析你也能进一步深入理解上文旋转180的例子,即绘制的元素为啥会莫名消失。
  下面分步对该图进行讲解:
  第一步:不做任何原点移动的绘制varcdocument。getElementById(myCanvas);varctxc。getContext(2d);varimgdocument。getElementById(tulip);ctx。drawImage(img,10,10);
  此时通过X,Y轴指定了绘制的方向,整个图以O(0,0)为中心进行绘制。第二步:移动了绘制原点
  ctx。translate(w2,h2);
  绘制原点移动到O(12w,12h),而X和Y指定了最新绘制的方向。此时需要注意的是:整个Canvas在页面中展示区域依然是w,h指定的位置,只是绘图的原点发生了改变而已。所以,在Canvas中灰色区域是整个w,h指定的唯一有图像的区域,而其他区域都是空的,因为Context压根就没有在这些位置进行绘制。
  第三步:上下文进行旋转ctx。translate(w2,h2);ctx。rotate(Math。PI);ctx。drawImage(img,0,0);
  通过这一步,X轴,Y轴的方向方向再次发生了变化,分别为X和Y,但是原点依然对应于O(12w,12h),因为Context没有做类似translate方法来改变中心点位置。这一步需要注意的是绘制的方向,由X和Y的指向来看,此时的绘图方向已经转化为向上和向右绘制。和第二步分析一致,黄色区域是唯一能看到图像的区域。到这一步,你应该明白了,现在依然没有实现元素在指定位置的180旋转。请看下例:imgidtulipsrca2020imgdataimg。jpgdatasrcimg02。bs178。combjth45b6b0800585c6cd。jpgaltTheTulipcanvasidmyCanvaswidth500height300styleborder:1pxsolidd3d3d3;background:YourbrowserdoesnotsupporttheHTML5canvastag。canvaswindow。onloadfunction(){varcdocument。getElementById(myCanvas);varctxc。getContext(2d);ctx。translate(5002,3002);ctx。rotate(Math。PI);varimgdocument。getElementById(tulip);ctx。drawImage(img,10,10);};
  原图为:
  代码执行后的效果为:
  图片具体表现可以通过上面的分析看出来,很显然现在绘制出来的图片只是原图的一部分,而不是完整的图片。究其原因主要是当图片尺寸超过0。5w,0。5h的时候,黄色区域没法完全容纳整张图片的绘制。而造成该问题的本质原因在于上下文移动的0。5w,0。5h距离。下面部分讲解具体的解决方法:2。3Canvas上元素旋转180的方法
  通过上面2。2的分析不难看出具体的解决方法。第一种途径是在rotate后继续改变绘图环境的中心点,将中心点平移到作图区域(w2,h2)。之所以为负数,是因为X和Y指定了新的坐标方向与原点要移动的位置相反。代码有:ctx。translate(w2,h2);ctx。rotate(Math。PI);ctx。translate(w2,h2);ctx。drawImage(img,0,0);
  最终效果如下:
  第二种途径是改变绘制图片的坐标,将图片绘制到(w2,h2),代码有:ctx。translate(w2,h2);ctx。rotate(Math。PI);ctx。drawImage(img,w2,h2);
  具体效果与上图相同。3。Canvas上下文状态保存
  在上面第2部分讲过上下文变换设置只会影响到之后的内容绘制,接下来重点讲述下Canvas上下文状态相关的两个主要方法,save()和restore()。3。1save()和restore()方法详解
  CanvasContext维持着绘制状态的堆栈,绘制状态主要包括以下几个维度:1。上下文矩阵变换:例如:平移translate(),缩放scale(),以及旋转rotate()等2。剪切区域:clip()3。特殊属性值设置:strokeStyle,fillStyle,globalAlpha,lineWidth,lineCap,lineJoin,miterLimit,shadowOffsetX,shadowOffsetY,shadowBlur,shadowColor,globalCompositeOperation,font,textAlign,textBaseline等
  需要注意的是:当前绘制路径、画布内容本身不属于绘图状态。绘制路径是持久的,只能使用beginPath()方法重置,而画布内容是画布的属性,而非上下文。save()和restore()的出现提供了用来操作绘制状态的快捷方法。1。Context。save()方法将当前绘制状态压入堆栈2。Context。restore()弹出堆栈上的状态,将上下文恢复到该状态。3。2save()和restore()方法示例
  当前示例的完整代码可以查看这里,将代码复制在任何编辑器中以。html为文件后缀,用浏览器打开即可看到完整示例效果,下面对核心代码进行说明。
  第一步:首先设置了Canvas绘制的fillStyle、shadow属性,然后在(0,0)处绘制了一个15x150的矩形。接着调用了ctx。save()方法将当前绘制状态压入堆栈。ctx。fillStyleFA6900;ctx。shadowOffsetX5;ctx。shadowOffsetY5;ctx。shadowBlur4;ctx。shadowColorrgba(204,204,204,0。5);ctx。fillRect(0,0,15,150);ctx。save();
  当前画布及堆栈的状态如下:
  第二步:重新设置fillStyle、shadow属性,然后在坐标(30,0)处绘制一个30x150的矩阵。接着调用ctx。save()方法将当前绘制状态压入堆栈。ctx。fillStyleE0E4CD;ctx。shadowOffsetX10;ctx。shadowOffsetY10;ctx。shadowBlur4;ctx。shadowColorrgba(204,204,204,0。5);ctx。fillRect(30,0,30,150);ctx。save();
  当前画布以及堆栈的完整状态如下:
  第三步:再次重新设置fillStyle、shadow属性,然后在坐标(90,0)处绘制一个45x150的矩阵。接着调用ctx。save()方法将当前绘制状态压入堆栈。ctx。fillStyleA7DBD7;ctx。shadowOffsetX15;ctx。shadowOffsetY15;ctx。shadowBlur4;ctx。shadowColorrgba(204,204,204,0。5);ctx。fillRect(90,0,45,150);ctx。save();
  当前画布以及堆栈的完整状态如下:
  第四步:调用ctx。restore()获取堆栈的最新状态,然后使用该状态绘制一个圆形。ctx。restore();ctx。beginPath();ctx。arc(185,75,22,0,Math。PI2,true);ctx。closePath();ctx。fill();
  当前画布以及堆栈的完整状态如下:
  第五步:继续调用ctx。restore()获取堆栈的最新状态,然后使用该状态绘制一个圆形。ctx。restore();ctx。beginPath();ctx。arc(260,75,15,0,Math。PI2,true);ctx。closePath();ctx。fill();
  当前画布以及堆栈的完整状态如下:
  第六步:继续调用ctx。restore()获取堆栈的最新状态,然后使用该状态绘制一个圆形。ctx。restore();ctx。beginPath();ctx。arc(305,75,8,0,Math。PI2,true);ctx。closePath();ctx。fill();
  当前画布以及堆栈的完整状态如下:
  4。本章小结
  本章节以图解的方式讲解了Canvas中心点在绘图中的作用,主要通过一个常见的元素180旋转的真实例子展开。同时,重点介绍了两个Canvas绘图状态设置的save()和restore()方法。通过本章节的学习,应该会对Canvas绘制的上下文相关内容有一个比较深入的理解了。参考资料
  Understandingsave()andrestore()fortheCanvasContext
投诉 评论 转载

沉浸式声音剧场声探世界完全体解锁,全新番外篇今日开票听,黑暗之中传来的神秘之声,带你走进一场惊心动魄的破案之旅。全新沉浸式游戏剧场《声探世界》番外篇CanYouHearMe(它在身后)于今天(10月21日)中午12点正式开票!……3场比赛2次犯满,正负值45和杜欧并称三巨头,西蒙斯你也配?在篮网客场挑战灰熊的比赛开打前,贾莫兰特在NBA个人得分榜上高居第一,而篮网自从开季之后在防守端的表现,暂时位列联盟后半段。所以,这场比赛最终的结果,也如赛前这两项数据所展现出……黑色连体裤搭配小黑包,不仅时髦还很实用黑色连体裤是很多人选择的时尚单品之一,它不仅时髦还很实用。搭配上小黑包,整体造型会更加时尚。1:选择合适的黑色连体裤黑色连体裤是一种很流行的服装,它通常搭配小黑包,……BR记者如猛龙选择在截止日前交易范弗里特湖人快船等队有意直播吧1月26日讯据美媒露天看台记者EricPincus报道,消息人士透露,猛龙还未决定与范弗里特的未来,如他们选择在交易截止日前将他送走,许多季后赛竞争者球队会对其有意。……见识过清明上河图,再逛清明上河园,究竟是一种怎样的体验?头条创造挑战赛旅游作者:青侠《清明上河图》难得展出,我却留有遗憾2015年,一听说故宫将举办石渠宝笈特展,我和好朋友艳艳就相约要一起去看。可谁知,当天我去的早……四个月的宝宝为什么会厌奶?其实造成宝宝厌奶的原因有很多,如果宝妈采取的治疗措施却不是十分正确,那么四个月的宝宝为什么会厌奶?一、消化不良宝宝如果患了消化不良的情况,会出现消化不良、腹胀、便秘等的情况,而……2022年,我选择了无为!2022年,我们过得都不容易,很辛苦,因为要面对一波三折的疫情,每个人的身心都面临着巨大的挑战。面对无常,我选择了无为。这个选择,并不是年初做计划的时候就明确好的,……保温杯里泡两宝,一味补阳,一味养阴,阴阳同补元气足有一种虚,叫做阴阳两虚。现在生活压力大,很多人都处于一种亚健康的状态,比如阳气不足,总是怕冷,手脚发凉,同时又阴液不足,晚上失眠多梦,经常口干,嗓子干。这种情况,我们应该……Canvas上下文详解本部分重点讲解了Canvas中心点的内容,在Canvas中所有内容的绘制都是基于上下文变换后的新坐标系中心点来完成的,对于坐标系中心点的理解是正确完成内容绘制的前提。同时,本章……传奇单职业1。76御天战神强势来袭大家好,我是小雷说游戏。很多人都在问我什么是单职业,什么是三职业。其实很好分辨的,单职业的话就是单一职业的传奇,三职业就是三个职业,战法的传奇。现在大部分的网页传奇和手游……讲究拍照的效果,两台旗舰定位一致,却打造不同的拍照需求看文章听音乐是种享受,想听什么留言告知(都是付费无损包)要说目前手机市场,呈现着怎样的现象发展,想必很多人都会异口同声地回答多元化,那么何谓手机市场的多元化?其实答案很简……香港今起经机场出境海外乘客无需接受体温筛查北京日报客户端香港特区政府9日晚宣布:自10日起,经香港国际机场出境或过境前往海外或台湾的乘客无需接受体温筛查;但抵港入境及离港出境赴内地或澳门的人士仍须测体温。香……
拥有三星GalaxyZFold4,告别局限性办公,SPen提申花前场引援锁定南美豪门核心,已得到媒体确认,未来将挑起大梁法国游客到贵州旅游,看到梵净山被围起来收费!直言看不明白THEGOODLIFE欠债女王与世界第一幸福的小镇中文支持首太白穴,是调理胃的重要穴位走上全球舞台,助力中国智造云南工商学院学子在华为ICT大赛中牙齿丑,也不影响成为美人的8大女星,现代人为何不能容忍瑕疵了iPhone14系列价格曝光,Pro被曝涨价100美元?60岁之后,坚持做这三件事情,多半都会长寿走下坡路的红魔曼联跟如今中国足球一样一丢球心态就崩了LegacyofThievesCollection本周在PC被误会的5种野菜,浑身是宝,营养极高,春季易上火的要多吃
明星脑洞有多大?沈腾给新公司起名字太别出心裁了图黄果树瀑布离贵阳有多远带你领略一级风景死亡的骆驼人生哲理乳癌患者能不能喝豆浆女性什么样的乳房最容易得癌女人敏感部位的清洗方式周里京妻子和邻居儿子同时被害,隐退后再遇真爱,今渐渐释怀新学期学习计划小学课改教学工作总结上海人都在郊游!快来打卡春日限定烂漫人教版六年级数学下册第一单元负数的教学反思外国来客亮剑一个营的装备被李云龙抢走,长官为什么没有继续追究?

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找美丽时装彩妆资讯历史明星乐活安卓数码常识驾车健康苹果问答网络发型电视车载室内电影游戏科学音乐整形