城市直播房产教育博客汽车
快传网
汽车报价
买车新车
博客专栏
专题精品
教育留学
高考读书
房产家居
彩票视频
直播黑猫
投资微博
城市上海
政务旅游

Canvas上下文详解

9月9日 尘世客投稿
  本部分重点讲解了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后再进行绘制,最后结果如何呢?imgidtulipsrcc2021imgdataimg。jpgdatasrcimgq01。71396。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旋转。请看下例:imgidtulipsrcc2021imgdataimg。jpgdatasrcimgq01。71396。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
投诉 评论 转载

使命召唤10幽灵重制版现已推出可能是动视IW组最可惜的一部COD,《使命召唤10:幽灵》虽然剧情略显俗套。但其中创新的多人模式和许多的小众武器,都让人印象深刻。用这款全新的滤镜设置,来提升游戏的……(漫画)普通人的一生我们到底还是活成了别人的样子(漫画)普通人的一生:我们到底还是活成了别人的样子我们都知道一个人小的时候真的是非常的天真,比如说有些人小的时候想要当科学家,有的人小的时候想要当宇航员,但是像这样的梦想……魏晋风流好男风?头条创作挑战赛据史料记载,好男风一开始是君王贵族的特殊癖好,但是到了魏晋南北朝时期,这种风气渐渐在士大夫以及社会民众间盛行起来,到了唐朝和五代十国时期逐渐衰弱。但到了宋朝又兴盛……挖掘遗产多重价值向世界讲好中国珍珠故事来源:农民日报为系统总结农业文化遗产核心价值与已有成果,助推德清县全面乡村振兴和可持续发展,近日中科院地理资源所自然与文化遗产研究中心、浙江德清县委、县政府联合以线上与线……Canvas上下文详解本部分重点讲解了Canvas中心点的内容,在Canvas中所有内容的绘制都是基于上下文变换后的新坐标系中心点来完成的,对于坐标系中心点的理解是正确完成内容绘制的前提。同时,本章……巨轮智能2022年前三季度净利润722。38万元同比下降32中证智能财讯巨轮智能(002031)10月29日披露2022年第三季度报告。2022年前三季度,公司实现营业总收入7。47亿元,同比下降54。42;归母净利润722。38万元,……舟山帮舟山市机关事务管理中心招聘编外人员部分航班调整招聘公告舟山市机关事务管理中心招聘编外人员公告因工作需要,市机关事务管理中心面向社会公开招聘综合文字岗位工作人员(编外劳务派遣人员),具体要求如下:一、招聘计……山鹰国际公司及子公司预计对外担保额度不超过358亿元北京商报讯(记者张君花)1月5日,山鹰国际发布公告称,为满足公司合并报表范围内子公司的日常生产经营及业务发展需要,公司董事会审议通过《关于2022年度担保计划的议案》,同意20……又炒中美太空竞赛,NASA局长发警告留给美国时间已经不多了【环球时报报道记者林泽宇陈子帅】美国国家航空航天局(NASA)局长比尔尼尔森宣称中美正处于一场太空竞赛。中国专家认为,美国将太空竞争者的帽子扣在中国头上,企图破坏中国航天的实力……民间故事伙计偷东家东西被小姐发现,小姐陪陪我,我帮你偷山西最南端的黄河岸边有个清河镇,镇上有个李员外李有财,清河镇的首富,乡下有良田五百多亩,镇上开了一个钱庄,一个油坊,一个豆腐坊,牛马成群,长工、短工、家丁、佣人近百号。李……中央网信办加强网络暴力治理强化网暴当事人保护中央网信办印发《关于切实加强网络暴力治理的通知》。内容如下:关于切实加强网络暴力治理的通知各省、自治区、直辖市党委网信办,新疆生产建设兵团党委网信办:网络暴力……断舍离是让东西去往最合适的地方断舍离是让东西去往最合适的地方断舍离并不是要大家不分青红皂白把东西乱扔一气,而是要有效地利用资源回收。要知道,断舍离最终的目标是必要的时间、必要的地点、必要的限度,所以对……
沈阳今年的供热是不是不好?全国第一波感染高峰时间表,看看你的家乡在哪里?内蒙女局长因妆容被调查,冤吗?外援不限人数,新赛季中国排超联赛即将揭幕许世友19般武艺,被授上将时心怀不满,周总理提这2人让他住嘴唐山打人第62天后,案情进展没有及时公布,导致谣言和蝴蝶效应湖北佛教圣地当阳铁塔,千年未生锈,为什么近年来却生锈了?芙蓉国评论丨全力走好中国式现代化之路为什么有的女人身上香香的?教你一招,衣服持久留香蚌埠有哪些厂?黑马摩洛哥可能拿冠军为男足指明出路将归化到底,归化日韩球员对于教师违规补课你怎么看?
迷人湖之谜,让你呼风唤雨的仙境(真的太美了)陌陌科技唐岩我们不愁没钱赚谈盈利还太早12条厨房清洁技巧超级实用案例设置是查看还是修改1983年国家严打,朱德孙子被枪毙,他究竟犯了什么法?我家的小乌龟闭口是怎么形成的想不到吧,北京这些地方赏月更浪漫?这也太美了吧出口商品打一俗语的答案兰芝水凝透润精华水怎么样分分钟秒杀一切的精华水魁梧的拼音魁梧的拼音怎样读女儿遇到情绪问题,妈妈在她平静后,就帮她抚平情绪不留心结

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找江西南阳嘉兴昆明铜陵滨州广东西昌常德梅州兰州阳江运城金华广西萍乡大理重庆诸暨泉州安庆南充武汉辽宁