当前位置: 首页 > Web前端 > HTML5

【极致用户体验】如何实现响应式画布?保持画布比例?教你让canvas自适应屏幕宽度!

时间:2023-04-05 16:31:27 HTML5

我是公众号线下派对游戏的作者HullQin(欢迎关注公众号,发加微信,交友),转载本文需作者HullQin授权。我独立开发了《联机桌游合集》,这是一个网页,在这里你可以轻松地和朋友一起玩网络游戏,五子棋等游戏,不收费,也没有广告。还为GameJam2022开发了《Dice Crush》,喜欢的话可以关注我HullQin哦~有空我会分享制作游戏的相关技术。背景画布是前端经常用到的东西,尤其是游戏开发者和图表开发者。响应式设计(网页元素可以适应各种屏幕宽度的设计)也是前端非常重要的基本功之一。前端开发者实现响应式设计的解决方案有很多,在之前的文章:《2行代码,让你的UI适配移动端、PC端,快来收藏》中已经列出。本文主要介绍的方法是利用width=device-width的viewport结合min-width来实现的。这个想法相当牛逼,因为它也适用于canvas。强烈建议没看过的同学看看,这个思路真的超级实用。什么是极致的用户体验1、一屏显示所有画布但是本文要讲的响应式画布,为了追求极致的用户体验,提出了更严格的限制:要求一屏显示整个画布.为什么会有这样的限制?尤其是游戏开发,无论PC端还是移动端,用户都不希望用户上下滚动才能看到全屏。甚至很多手游的交互都需要用户手指滑动,这就需要canvas监听用户的滑动操作,而用户无法通过滑动来上下滚动页面,导致无法看到部分网页。所以这个限制是完全合理的,充分照顾了最终的用户体验。2.画布比例与页面初始比例一致。画布比例要求与页面初始比例保持一致,这样用户才不会感到空洞。但如果用户稍后缩放浏览器,则要求画布比例保持不变(这实际上是技术上不得不做出的妥协)。为什么只要求与页面初始比例相同?因为canvas绘制后需要修改比例,那么内部所有元素的坐标都需要重新绘制,很多物理引擎的计算需要重做,对性能影响很大;而且开发成本也相当高。Canvas不像Dom。页面宽度发生变化后,浏览器可以自动计算出新的布局。要更改画布的布局,开发人员需要手动计算每个元素的新位置。页面的初始比例确定后,很大概率不会修改页面的比例。特别是在移动端,用户几乎无法修改页面大小(小浏览器窗口的情况不多)。根据以上3点得出结论,动态改变画布比例开发成本极高,收益极低(用户使用次数很少),即ROI很低,所以没必要动态改变修改画布比例,只需要保持画布比例。初始比例可以达到良好的用户体验。此外,画布比例通常有一些限制值。如果屏幕比例超过画布比例限制值,则应保持在限制值。例如,如果要求屏幕的纵横比为1:1到1:2,那么当屏幕太宽时,只能将画布比例设置到1:1的极限;当屏幕太窄时,只能将画布比例设置为1.:2的极限。直接看例子:比如屏幕太宽,超过canvasratio的限制值,高度会填充,宽度会留白。比如屏幕太窄,会超过canvasratio的限制值,宽度会填充,高度会留空:比如屏幕比例在两个限制值之间canvasratio,那么高宽就满了:上面的效果在实际体验中你可能不太清楚,我直接给你一个案例,看看什么是极致的用户体验。:参考我之前的文章《 合 成 大 西 瓜 》翻拍!(网络版正在做中)”,我复现了《合成大西瓜》游戏,??并用canvas实现。实现了以上两条规则,追求极致的用户体验。体验地址:https://game.hullqin.cn/dxg解决方案建议不要使用transform的scale来改变canvas的宽高,容易混淆canvas内部的宽高属性和CSS的宽高!如下图所示:两个红框里的属性有不同的作用,我们直接修改transform的scale属性,这样就可以实现比例缩放,完全不影响内部布局!但是修改了scale之后,元素看起来变小了,其实还是占了多少宽高,还是会出现滚动条,最简单的解决办法:给它的父元素设置overflow:hidden。设置画布的初始比例并使其保持在限制值之间。我们直接上传代码,在注释中说明:exportconstHeight=1408;//要求屏幕高度固定,宽度按比例放大缩小letwidth=704;//如果屏幕过大width],会使用这个宽度const{innerWidth,innerHeight}=window;//获取初始页面大小if(innerHeight>innerWidth*1.3){//如果初始页面大小不是[太宽]width=Height*innerWidth/innerHeight//导出计算出的画布最终宽度以监控resize,并动态设置画布比例接下来需要设置画布的初始比例和动态设置比例。//注意:变量canvas是画布的一个dom元素,变量root是画布的父元素。constresetSize=()=>{const{innerWidth,innerHeight}=window;if(innerWidth/innerHeight>Width/Height){//如果屏幕[width]缩放,使用屏幕高度计算缩放root.style.height=`${innerHeight}px`;//全高root.style.width=`${innerHeight/Height*Width}px`;//设置新计算的比例canvas.style.transform=`scale(${innerHeight/Height})`;}else{//如果缩放后??屏幕[窄],使用屏幕宽度计算缩放root.style.width=`${innerWidth}px`;//宽度填充根.style.height=`${innerWidth/Width*Height}px`;//设置新计算的比例canvas.style.transform=`scale(${innerWidth/Width})`;}};canvas.style。width=`${Width}px`;canvas.style.height=`${Height}px`;resetSize();//页面初始化时执行一次,设置画布的样式window.onresize=resetSize;//监听调整大小事件。当页面大小发生变化时,保持宽高比并动态缩放画布。最后我是公众号线下派对游戏的作者HullQin(欢迎关注公众号,发送加微信,交友),转载本文需要作者HullQin授权。我独立开发了《联机桌游合集》,这是一个网页,在这里你可以轻松地和朋友一起玩网络游戏,五子棋等游戏,不收费,也没有广告。还为GameJam2022开发了《Dice Crush》,喜欢的话可以关注我HullQin哦~有空我会分享制作游戏的相关技术。