应用办公生活信息教育商业
投稿投诉
商业财经
汽车智能
教育国际
房产环球
信息数码
热点科技
生活手机
晨报新闻
办公软件
科学动态
应用生物
体育时事

Canvas从入门到实战

  1、什么是Canvas?
  HTML5提供CanvasAPI,其本质上是一个DOM元素,可以看成是浏览器提供一块画布供我们在上面渲染2D或者3D图形。由于3D绘制上下文(webgl)目前在很多浏览器上兼容性较差,所以我们一般用于绘制2D图形。canvasidcanvascanvas
  2、为什么使用Canvas?
  Canvas是HTML5引入的标签,在此之前我们通常会使用SVG来绘制一些图形,那么两者之间有什么区别呢?SVG可缩放矢量图形(ScalableVectorGraphics)是基于可扩展标记语言XML描述的2D图形的语言,两者部分区别:
  SVG图像是使用各种元素创建的,这些元素分别应用于矢量图像的结构、绘制与布局;而Canvas本身并不描述图像,而是通过Javascript完成绘制;如上所述,SVG本身是DOM元素,每一个描述元素也是DOM元素,浏览器在进行渲染时需要进行大量计算以处理每一个元素;而在渲染Canvas的过程中,浏览器只需要渲染一张画布,其余的是通过Javascript引擎执行逻辑来绘制;SVG(矢量图)不依赖分辨率,放大不会失真;而Canvas(位图)依赖分辨率,放大会失真;
  由于Canvas是通过Javascript来完成绘制的,所以可控性很强,我们可以比较精确的控制图形渲染的每一帧;从另一方面来说,如果在高频率渲染中要处理过多的DOM元素就意味着性能一定不会太好,渲染速度会下降很多。Canvas的高性能能够保障复杂场景中图形的渲染效率,所以目前很多领域都会使用Canvas,例如动画、游戏图形、数据可视化、照片处理和实时视频处理等。
  3、Canvas的基本使用
  要使用Canvas,我们需要先获取Canvas元素的引用继而通过getContext()方法获取图形的绘制上下文。constcanvasdocument。getElementById(canvas)constctxcanvas。getContext(2d)
  获取到图形绘制上下文后,我们就能使用CanvasRenderingContext2D接口上的绘图API了,接下来我们可以了解一些比较常规的使用。
  3。1、画布属性:
  width、height:画布的宽度以及高度,默认大小为300x150;fillStyle:填充图形的样式,值可以是colorstring、CanvasGradient对象;strokeStyle:轮廓图形的样式,值可以是colorstring、CanvasGradient对象;lineWidth:绘制线条的宽度;globalAlpha:画布的透明度,01的偏移值;globalCompositeOperation:画布中新老图形重叠时的渲染方式,默认为sourceover,新图形覆盖老图形;。。。。。。ctx。width300ctx。height300ctx。fillStylefffctx。strokeStylebluectx。lineWidth5ctx。globalAlpha0。3ctx。globalCompositeOperationdestinationout新老图形重叠部分变透明。。。。。。
  3。2、绘制图形:
  。fillRect(x,y,width,height):绘制一个填充的矩形,矩形左上角的坐标为(x,y),高宽分别为width、height;。strokeRect(x,y,width,height):绘制一个矩形边框,矩形左上角的坐标为(x,y),高宽分别为width、height;。clearRect(x,y,width,height):清除指定矩形区域,让清除部分完全透明;ctx。fillStyleredctx。fillRect(100,100,100,100)ctx。strokeStylebluectx。strokeRect(200,200,100,100)ctx。clearRect(125,125,50,50)ctx。strokeRect(130,130,40,40)
  3。3、绘制路径:
  。beginPath():开始一段路径的绘制;。closePath():从起始点到当前点,结束路径的绘制,非必需;。fill():根据路径生成填充图形;。stroke():通过路径生成轮廓图形;。moveTo(x,y):声明一段路径的起始点;。lineTo(x,y):绘制一条从当前坐标到(x,y)的线;ctx。beginPath()ctx。moveTo(50,50)ctx。lineTo(100,100)ctx。lineTo(100,0)ctx。fill()ctx。beginPath()ctx。moveTo(110,100)ctx。lineTo(150,100)ctx。lineTo(150,200)ctx。lineTo(110,200)ctx。closePath()轮廓图形不会根据从当前坐标到起始坐标生成轮廓,所以需要闭合路径ctx。stroke()
  3。4、绘制圆弧:
  。arc(x,y,radius,startAngle,endAngle,anticlockwise):画一个以(x,y)为圆心的以radius为半径的圆弧(圆),从startAngle开始到endAngle结束,按照anticlockwise给定的方向(默认为顺时针,false)来生成;arcTo(x1,y1,x2,y2,radius):根据给定的两条切线中的一组切点坐标生成半径为radius的圆弧;
  注意:arc函数中的角度的单位是弧度而不是度,弧度(Math。PI180)度圆左上部分ctx。beginPath()ctx。arc(100,100,50,Math。PI,Math。PI32,false)ctx。strokeStyleff6700ctx。stroke()圆右上部分ctx。beginPath()ctx。arc(100,100,50,Math。PI32,0,false)ctx。strokeStyle6700ffctx。stroke()圆右下部分ctx。beginPath()ctx。arc(100,100,50,0,Math。PI2,false)ctx。strokeStyle00FFFFctx。stroke()圆左下部分ctx。beginPath()ctx。arc(100,100,50,Math。PI2,Math。PI,false)ctx。strokeStyle8B008Bctx。stroke()两条切线的交点坐标为(0,0)ctx。beginPath()ctx。moveTo(100,0)ctx。arcTo(0,0,0,100,100)ctx。fillStylebluectx。fill()
  3。5、渐变对象:
  。createLinearGradient(x1,y1,x2,y2):创建一个沿参数坐标指定的直线的渐变,开始坐标为(x1,y1),结束坐标为(x2,y2);。createRadialGradient(x1,y1,r1,x2,y2,r2):创建根据参数确定两个圆的坐标的放射性渐变,开始圆形圆心为(x1,y1),半径为r1;结束圆形圆心为(x2,y2),半径为r2;
  创建好渐变对象之后,可以通过渐变对象上的。addColorStop(offset,color)为每一个渐变阶段填充颜色,offset为01的偏移值。constgradientctx。createLinearGradient(50,50,250,50)gradient。addColorStop(0,blue)gradient。addColorStop(0。5,green)gradient。addColorStop(1,red)ctx。fillStylegradientctx。fillRect(0,0,300,90)constradialGradientctx。createRadialGradient(200,200,100,200,200,50);radialGradient。addColorStop(0,yellow);radialGradient。addColorStop(1,green);ctx。fillStyleradialGradient;ctx。fillRect(100,100,200,200);
  3。6、像素操作:
  。drawImage(image,x,y,width,height):image可以是image对象、canvas元素、video元素;。getImageData(x,y,width,height):获取坐标为(x,y)一定区域内图像的像素数据;constpdocument。querySelector(p)letmousedownfalse;functiongetRandom(){returnMath。round(255Math。random());}functiongetColor(){returnrgb({getRandom()},{getRandom()},{getRandom()});}constgradientctx。createLinearGradient(0,0,300,300);gradient。addColorStop(0,getColor());gradient。addColorStop(0。6,getColor());gradient。addColorStop(1,getColor());functionclear(){ctx。fillStylegradient;ctx。fillRect(0,0,canvas。width,canvas。height);}ctx。beginPath();ctx。fillStylegradient;ctx。fillRect(0,0,300,300);functionselector(x150,y150){clear();ctx。beginPath();ctx。arc(x,y,5,0,Math。PI2);ctx。strokeStylefff;ctx。stroke();const{data}ctx。getImageData(x,y,1,1);获取(x,y)点对应的imageDataconstcolorrgba({data〔0〕},{data〔1〕},{data〔2〕},{data〔3〕255})p。innerTextcolor:{color};p。style。backgroundColorcolor}functionhandleSelector(e){constxe。offsetX;constye。offsetY;selector(x,y);}canvas。addEventListener(mousedown,(e){mousedowntrue;handleSelector(e)});canvas。addEventListener(mouseup,(){mousedownfalse;});canvas。addEventListener(mousemove,(e){if(mousedown){handleSelector(e)}});selector();
  3。7、画布状态:
  。save():将当前画布的状态推入到栈中,例如fillStyle、2D转换等;。restore():将栈顶元素弹出,恢复上一次推入栈中画布的状态;
  当我们需要通过空间转换来绘制图形时,保存与恢复画布的状态是很关键的,因为我们是在同一块画布上绘制图形,而变换都是基于画布的,这与我们平时使用到的CSS2D转换截然不同,所以我们在下一步绘制时要确认此时画布的状态是否是我们的理想状态。ctx。save()保存画布初始状态ctx。translate(100,100)将画布原点转移至(100,100)ctx。fillStyleredctx。fillRect(0,0,50,50)ctx。restore()恢复画布状态,此时画布原点为(0,0)ctx。fillStylebluectx。fillRect(0,0,50,50)
  3。8、几何变化:
  。translate(x,y):画布默认的原点是(0,0),此方法可以切换原点到(x,y)而不需要手动更改绘制图形的坐标;。rotate(angle):将画布旋转一定的角度,angle单位为弧度;。scale(sx,sy):sx为水平方向的缩放比例,sy为竖直方向的缩放比例;。transform(a,b,c,d,e,f):依次为水平缩放、垂直倾斜、水平倾斜、垂直缩放、水平移动、垂直移动;
  constcolors〔red,orange,yellow,green,blue,purple〕;ctx。translate(150,150)for(leti0;i6;i){ctx。beginPath()ctx。fillStylecolors〔i〕ctx。moveTo(0,0)ctx。lineTo(100,0)ctx。lineTo(100,50)ctx。rotate(Math。PI3)ctx。fill()}
  4、综合实战
  constpMath。PI;functionclock(){constdatenewDate();consthourdate。getHours()constsdate。getSeconds();constmdate。getMinutes();consth!!(hour12)?hour12:12;ctx。clearRect(0,0,canvas。width,canvas。height);ctx。save();保存画布初始状态ctx。translate(150,150);ctx。rotate(p2);轮廓ctx。beginPath();ctx。lineWidth5;ctx。strokeStyle76b2ff;ctx。arc(0,0,80,0,p2);ctx。stroke();圆心ctx。beginPath();ctx。arc(0,0,2,0,p2);ctx。fill();分针、秒针刻度for(leti0;i60;i){ctx。beginPath();ctx。rotate(p30);ctx。moveTo(75,0);ctx。lineWidth4;ctx。strokeStyle89f086;ctx。lineTo(80,0);ctx。stroke();}时针刻度for(leti0;i12;i){ctx。beginPath()ctx。rotate(p6)ctx。moveTo(70,0)ctx。lineTo(80,0)ctx。stroke()}ctx。save();保存画布变换之后的状态秒针ctx。beginPath();ctx。rotate(s(p30));ctx。lineWidth2ctx。strokeStyleff6700ctx。moveTo(0,0);ctx。lineTo(80,0);ctx。stroke();恢复之前的状态再保存,时针、分针、秒针都是基于原点以及画布方向变换后绘制ctx。restore();ctx。save();分针ctx。beginPath();ctx。rotate(m(p30));ctx。lineWidth3;ctx。strokeStyle6700ffctx。moveTo(0,0);ctx。lineTo(70,0);ctx。stroke();ctx。restore();时针ctx。beginPath();ctx。rotate(h(p6));ctx。lineWidth4;ctx。moveTo(0,0);ctx。lineTo(60,0);ctx。stroke();ctx。restore();恢复画布最初状态document。querySelector(p)。innerTextNow:{h}:{m}:{s}{hour12?pm:am}window。requestAnimationFrame(clock);}clock();
  5、小结
  随着互联网的高速发展,用户对页面的视觉和交互有着越来越高的要求,传统的web开发无法得到满足,利用Canvas强大的绘图能力,可以让网页显示的内容更加的丰富多彩,也能给用户带来更好的视觉体验。
  作者:LLSFE团队
  来源:微信公众号:流利说技术团队
  出处:https:mp。weixin。qq。comsbvkx3wOeMvIUU64cktX6iA

玉米山东涨不停,东北跌未止!何时现转机?10月21日最新价格国内玉米市场还是在走地区间分化行情,山东玉米价格小碎步走高,东北企业仍以跌价为主。山东深加工企业早间未卸车量321辆,继续处于供需均衡值下方,企业仍以小幅度涨价为主。今日……一加AcePro对比一加Ace,究竟Pro在了哪里,一眼看懂一加Ace一加AcePro性能天玑8100MAXLPDDR5UFS3。1骁龙8Gen1LPDDR5UFS3。1屏幕6。7英寸12……这几种食物被称为强肝王,建议春季养肝正当时,可适当多吃冬去春来,万物复苏,俗话讲一日之计在于晨,一年之计在于春,春天是万物复苏的季节,同时也是机体肝胆静脉最开始旺盛以及活跃的季节,在这个时间内,如果可以较为良好的调理肝脏健康,可以……幼小衔接到底要不要上?过来人这么说近日,各中小学报名系统陆续打开,意味着又一波孩子即将上小学和中学。相比小中衔接,幼小衔接更为关键和复杂。小学和幼儿园有哪些不同?幼小衔接到底要不要上呢?高躰亲子时光小组询问了多……谢娜最大的悲哀,是错把平台当本事关于谢娜的争议,就没有停下来过。从进入快本到结婚生子再到快本停播,骂谢娜的人,只多不少。可以说,这么多年,她湖南一姐的地位是被大家骂出来的。有人说,谢娜没有什……被忽视的吉林队功臣,老将钟诚4月4日结束的季后赛中有一场冷门引起了许多球迷朋友的关注,那就是只有单外援的吉林队战胜了四外援的北京队。这几天很多球迷朋友都在讨论吉林队的功臣琼斯与姜宇星,但是笔者认为钟诚是被……57万元起售,对标ModelX,高合HiPhiX长续航版上市各位老司机们,大家好!请点击关注【汽车行业情报站】,第一时间了解最新的汽车资讯,在这里轻松读懂汽车!近日,情报君从相关渠道获悉,2022款高合HiPhiX长续航版车型正式……这届冬奥会,网友是这样追星的我们要第一,也爱这烟火气。谷爱凌比赛间隙又吃了啥?任子威微博简介每年都改生日频频登上热搜的冬奥花絮,是网友对冬奥选手的考古热情。再往后看,是我们追星奥运选手不再沉迷……150女生必看!小个子夏天这样穿,真的巨显高我最近又发现了一部宝藏旅行综艺《属于我们的夏天》!沈月吴宣仪翟子路丁冠霖利晴天嘉宾之间没有相互猜忌,节目组也没有搞事情限制,一行人愉快地开启了云南度假模式。白……好听的男孩名字怎么取?取名是一件大事,很多家长都为取名犯难,想取一个好听又有特点的男孩名字,但是又不知道如何取。对于孩子,父母们的都希望给予他们最好的。起名就是其中的一项,可以说为了能给孩子起个好名……生完孩子坐月子为啥容易便秘?如何缓解和预防?一篇文章告诉你一个顺转剖的妈妈产后跟朋友聊到生产时,什么最难受:生孩子的时候顺产疼,结果顺产宫口已经开了三指了因为羊水混浊又拖到手术室去,紧急剖宫产。剖宫产之后护士要来帮压肚子,压肚子……为什么我不发朋友圈了有时浏览朋友圈,会发现有些人已经很久没发过个人动态了。我以前也是喜欢刷屏朋友圈的人之一,有时候还会被人嫌弃。没想到现在就变成,你怎么也把朋友圈关了。朋友圈里张三在秀……
汤尤杯兵败!国羽掌门公开道歉,宣布做重大调整,男单换帅在即北京时间5月15日消息,国羽在本届汤尤杯赛事中发挥惨淡,女团在尤伯杯决赛中23遭到韩国逆转,无缘第16冠。而男团更是止步汤姆斯杯8强,追平历史最差战绩。针对这样的表现,中国羽协……好消息!女排又一冠军成员实现转型,将进入教练组工作,未来可期转眼间,新一届女排世界联赛已结束前两周的争夺,中国女排暂时取得了5胜3负的成绩,排在了积分榜的第6位。对于这样的成绩单,并不能让人称得上满意,因为输掉的三场比赛里,有两场是输给……预售供不应求,如今降价清仓!2022年这3款老机型轻松用到2去年的手机圈内卷带动了很多新机的发布,虽然现在已经是2021年,但是丝毫不影响去年那些老机型的优秀。今天就来盘点一下去年那些发售的时候很火爆,如今却需要降价清仓的优秀老机型!……励志语录别总是羡慕别人的成功,自己却不敢开始励志语录Mar26(1)不想认命,就去拼命相信付出就会有收获或大或小,或迟或早所有的梦想,始终不会辜负你的努力有一种落差是你总是羡慕别……翼龙又盯上郭艾伦,CBA高管施压姚明,一招完美解决球员流失近日,CBA球员转会的问题又被吹上了风口浪尖,此前周琦就是因为不愿意继续为新疆男篮效力,所以才无奈背井离乡加盟NBL联赛,如今又换成了郭艾伦,他将面临和周琦一样的处境,目前可以……双胞胎姐妹刚刚满月丢失,2021年33岁再相逢差别巨大俗话说,孩子是父母的心头宝。自打一个孩子出生之后,他们的一举一动就牵动着父母的心,是父母目光所凝聚之处。但是世事难料,偶尔天有不测风云,有些父母还没有亲眼目睹孩子成长起来……电竞产业快速扩张日前,上海交通大学发布《全球电竞之都评价报告》,对全球15个致力于发展电竞之都的城市进行评价,上海作为中国城市电竞发展的排头兵,其拥有众多优质电竞企业及完整产业集群,因此排名第……夏天适合用滋润的还是清爽的护肤品,你要的清单在这里才4月,小编是真切地感受到夏天来临了。。。天气越来越热,皮肤出油都明显变多了!对很多人来说,炎热的夏季,一边出油一边长痘,还悄悄长黑头的皮肤,简直就是场灾难。而秋冬……年轻旅行者被认为不务正业在路上经常被陌生人劝解回家结婚生子今天聊一下在路上几年听到一些陌生人意见:生活选择该如何算是正确方式。如今旅行已经成为一个大众化的生活方式,在以往时间:80年代、90年代,能出去旅游的人,那么一定是家境殷……孙杨张豆豆领证结婚,女方年龄小他5岁,来头不小7月6日下午,一则消息突然炸响各大社交平台:泳坛名将孙杨,于日前和素有体坛女神之称的张豆豆,喜结连理,低调完婚。消息一出,两人立即冲上了热搜,也引来了众多网友的议论……房车越卷越热,上汽大通真把旅行玩明白了文拎壶冲当你开车在独库公路上体验堵哭,说走就走抢到机票却订不到酒店,露营遇到暴雨摧残着你的帐篷,梦想中的亲子游变成了噩梦的时候,你一定会想要拥有一台房车,一个夜晚亮着灯的……游党西清真寺今天骑车去赶党东大集,信马由缰竟然路过党西村清真寺。恰好有位回民从里面出来,说允许参观,我们这才敢进去。凡是回民,一般都在大门匾额上有道伊斯兰文字横批原来是:万物非主,唯有安拉……
友情链接:快好找快生活快百科快传网中准网文好找聚热点快软网